Fixes, more stuff, .stats added?
This commit is contained in:
		| @@ -16,10 +16,11 @@ using System.Text.RegularExpressions; | ||||
| namespace NadekoBot.Modules.Administration | ||||
| { | ||||
|     [Module(".", AppendSpace = false)] | ||||
|     public partial class AdministrationModule : DiscordModule | ||||
|     public partial class Administration : DiscordModule | ||||
|     { | ||||
|         public AdministrationModule(ILocalization loc, CommandService cmds, IBotConfiguration config, IDiscordClient client) : base(loc, cmds, config, client) | ||||
|         public Administration(ILocalization loc, CommandService cmds, IBotConfiguration config, IDiscordClient client) : base(loc, cmds, config, client) | ||||
|         { | ||||
|  | ||||
|         } | ||||
|  | ||||
|         ////todo owner only | ||||
| @@ -188,10 +189,12 @@ namespace NadekoBot.Modules.Administration | ||||
|         [LocalizedCommand, LocalizedDescription, LocalizedSummary] | ||||
|         [RequireContext(ContextType.Guild)] | ||||
|         [RequirePermission(GuildPermission.BanMembers)] | ||||
|         public async Task Ban(IMessage imsg, IGuildUser user, [Remainder] string msg = null) | ||||
|         public async Task Ban(IMessage imsg, IGuildUser user) | ||||
|         { | ||||
|             var channel = imsg.Channel as ITextChannel; | ||||
|  | ||||
|             var msg = ""; | ||||
|  | ||||
|             if (!string.IsNullOrWhiteSpace(msg)) | ||||
|             { | ||||
|                 await (await user.CreateDMChannelAsync()).SendMessageAsync($"**You have been BANNED from `{channel.Guild.Name}` server.**\n" + | ||||
| @@ -217,15 +220,10 @@ namespace NadekoBot.Modules.Administration | ||||
|         { | ||||
|             var channel = imsg.Channel as ITextChannel; | ||||
|  | ||||
|             if (user == null) | ||||
|             { | ||||
|                 await imsg.Channel.SendMessageAsync("User not found.").ConfigureAwait(false); | ||||
|                 return; | ||||
|             } | ||||
|             if (!string.IsNullOrWhiteSpace(msg)) | ||||
|             { | ||||
|                 await user.SendMessageAsync($"**You have been SOFT-BANNED from `{channel.Guild.Name}` server.**\n" + | ||||
|                                         $"Reason: {msg}").ConfigureAwait(false); | ||||
|                     $"Reason: {msg}").ConfigureAwait(false); | ||||
|                 await Task.Delay(2000).ConfigureAwait(false); // temp solution; give time for a message to be send, fu volt | ||||
|             } | ||||
|             try | ||||
| @@ -492,7 +490,7 @@ namespace NadekoBot.Modules.Administration | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         //todo owner only | ||||
|         ////todo owner only | ||||
|         //[LocalizedCommand, LocalizedDescription, LocalizedSummary] | ||||
|         //[RequireContext(ContextType.Guild)] | ||||
|         //public async Task Die(IMessage imsg) | ||||
|   | ||||
| @@ -1,184 +1,285 @@ | ||||
| using Discord; | ||||
| using Newtonsoft.Json; | ||||
| using Discord.Commands; | ||||
| using NadekoBot.Classes.ClashOfClans; | ||||
| using System; | ||||
| using System.Linq; | ||||
| using System.Collections.Concurrent; | ||||
| using System.Collections.Generic; | ||||
| using System.Text; | ||||
| using System.Threading.Tasks; | ||||
| using Discord; | ||||
| using NadekoBot.Services; | ||||
| using NadekoBot.Attributes; | ||||
|  | ||||
| namespace NadekoBot.Classes.ClashOfClans | ||||
| //todo DB | ||||
| namespace NadekoBot.Modules.ClashOfClans | ||||
| { | ||||
|     public enum DestroyStars | ||||
|     [Module(",",AppendSpace = false)] | ||||
|     internal class ClashOfClans : DiscordModule | ||||
|     { | ||||
|         One, Two, Three | ||||
|     } | ||||
|     public enum WarState | ||||
|     { | ||||
|         Started, Ended, Created | ||||
|     } | ||||
|         public static ConcurrentDictionary<ulong, List<ClashWar>> ClashWars { get; set; } = new ConcurrentDictionary<ulong, List<ClashWar>>(); | ||||
|  | ||||
|     internal class Caller | ||||
|     { | ||||
|         public string CallUser { get; set; } | ||||
|  | ||||
|         public DateTime TimeAdded { get; set; } | ||||
|  | ||||
|         public bool BaseDestroyed { get; set; } | ||||
|  | ||||
|         public int Stars { get; set; } = 3; | ||||
|  | ||||
|         public Caller() { } | ||||
|  | ||||
|         public Caller(string callUser, DateTime timeAdded, bool baseDestroyed) | ||||
|         public ClashOfClans(ILocalization loc, CommandService cmds, IBotConfiguration config, IDiscordClient client) : base(loc, cmds, config, client) | ||||
|         { | ||||
|             CallUser = callUser; | ||||
|             TimeAdded = timeAdded; | ||||
|             BaseDestroyed = baseDestroyed; | ||||
|         } | ||||
|  | ||||
|         public void ResetTime() | ||||
|         private static async Task CheckWar(TimeSpan callExpire, ClashWar war) | ||||
|         { | ||||
|             TimeAdded = DateTime.UtcNow; | ||||
|         } | ||||
|  | ||||
|         public void Destroy() | ||||
|         { | ||||
|             BaseDestroyed = true; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     internal class ClashWar | ||||
|     { | ||||
|         private static TimeSpan callExpire => new TimeSpan(2, 0, 0); | ||||
|  | ||||
|         public string EnemyClan { get; set; } | ||||
|         public int Size { get; set; } | ||||
|  | ||||
|         public Caller[] Bases { get; set; } | ||||
|         public WarState WarState { get; set; } = WarState.Created; | ||||
|         //public bool Started { get; set; } = false; | ||||
|         public DateTime StartedAt { get; set; } | ||||
|         //public bool Ended { get; private set; } = false; | ||||
|  | ||||
|         public ulong ServerId { get; set; } | ||||
|         public ulong ChannelId { get; set; } | ||||
|  | ||||
|         [JsonIgnore] | ||||
|         public ITextChannel Channel { get; internal set; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// This init is purely for the deserialization | ||||
|         /// </summary> | ||||
|         public ClashWar() { } | ||||
|  | ||||
|         public ClashWar(string enemyClan, int size, ulong serverId, ulong channelId) | ||||
|         { | ||||
|             this.EnemyClan = enemyClan; | ||||
|             this.Size = size; | ||||
|             this.Bases = new Caller[size]; | ||||
|             this.ServerId = serverId; | ||||
|             this.ChannelId = channelId; | ||||
|             this.Channel = NadekoBot.Client.GetGuildsAsync() //nice api you got here volt,  | ||||
|                                     .GetAwaiter() //especially like how getguildsasync isn't async at all internally.  | ||||
|                                     .GetResult() //But hey, lib has to be async kek | ||||
|                                     .FirstOrDefault(s => s.Id == serverId)? // srsly | ||||
|                                     .GetChannelsAsync() //wtf is this | ||||
|                                     .GetAwaiter() // oh i know, its the implementation detail | ||||
|                                     .GetResult() // and makes library look consistent | ||||
|                                     .FirstOrDefault(c => c.Id == channelId) // its not common sense to make library work like this. | ||||
|                                         as ITextChannel; // oh and don't forget to cast it to this arbitrary bullshit  | ||||
|         } | ||||
|  | ||||
|         internal void End() | ||||
|         { | ||||
|             //Ended = true; | ||||
|             WarState = WarState.Ended; | ||||
|         } | ||||
|  | ||||
|         internal void Call(string u, int baseNumber) | ||||
|         { | ||||
|             if (baseNumber < 0 || baseNumber >= Bases.Length) | ||||
|                 throw new ArgumentException("Invalid base number"); | ||||
|             if (Bases[baseNumber] != null) | ||||
|                 throw new ArgumentException("That base is already claimed."); | ||||
|             var Bases = war.Bases; | ||||
|             for (var i = 0; i < Bases.Length; i++) | ||||
|             { | ||||
|                 if (Bases[i]?.BaseDestroyed == false && Bases[i]?.CallUser == u) | ||||
|                     throw new ArgumentException($"@{u} You already claimed base #{i + 1}. You can't claim a new one."); | ||||
|             } | ||||
|  | ||||
|             Bases[baseNumber] = new Caller(u.Trim(), DateTime.UtcNow, false); | ||||
|         } | ||||
|  | ||||
|         internal void Start() | ||||
|         { | ||||
|             if (WarState == WarState.Started) | ||||
|                 throw new InvalidOperationException("War already started"); | ||||
|             //if (Started) | ||||
|             //    throw new InvalidOperationException(); | ||||
|             //Started = true; | ||||
|             WarState = WarState.Started; | ||||
|             StartedAt = DateTime.UtcNow; | ||||
|             foreach (var b in Bases.Where(b => b != null)) | ||||
|             { | ||||
|                 b.ResetTime(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         internal int Uncall(string user) | ||||
|         { | ||||
|             user = user.Trim(); | ||||
|             for (var i = 0; i < Bases.Length; i++) | ||||
|             { | ||||
|                 if (Bases[i]?.CallUser != user) continue; | ||||
|                 Bases[i] = null; | ||||
|                 return i; | ||||
|             } | ||||
|             throw new InvalidOperationException("You are not participating in that war."); | ||||
|         } | ||||
|  | ||||
|         public string ShortPrint() => | ||||
|             $"`{EnemyClan}` ({Size} v {Size})"; | ||||
|  | ||||
|         public override string ToString() | ||||
|         { | ||||
|             var sb = new StringBuilder(); | ||||
|  | ||||
|             sb.AppendLine($"🔰**WAR AGAINST `{EnemyClan}` ({Size} v {Size}) INFO:**"); | ||||
|             if (WarState == WarState.Created) | ||||
|                 sb.AppendLine("`not started`"); | ||||
|             for (var i = 0; i < Bases.Length; i++) | ||||
|             { | ||||
|                 if (Bases[i] == null) | ||||
|                 if (Bases[i] == null) continue; | ||||
|                 if (!Bases[i].BaseDestroyed && DateTime.UtcNow - Bases[i].TimeAdded >= callExpire) | ||||
|                 { | ||||
|                     sb.AppendLine($"`{i + 1}.` ❌*unclaimed*"); | ||||
|                     await war.Channel.SendMessageAsync($"❗🔰**Claim from @{Bases[i].CallUser} for a war against {war.ShortPrint()} has expired.**").ConfigureAwait(false); | ||||
|                     Bases[i] = null; | ||||
|                 } | ||||
|                 else | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         [LocalizedCommand, LocalizedDescription, LocalizedSummary] | ||||
|         [RequireContext(ContextType.Guild)] | ||||
|         public async Task CreateWar(IMessage imsg, int size, [Remainder] string enemyClan = null) | ||||
|         { | ||||
|             var channel = imsg.Channel as ITextChannel; | ||||
|  | ||||
|             if (!(imsg.Author as IGuildUser).GuildPermissions.ManageChannels) | ||||
|                 return; | ||||
|  | ||||
|             if (string.IsNullOrWhiteSpace(enemyClan)) | ||||
|                 return; | ||||
|  | ||||
|             if (size < 10 || size > 50 || size % 5 != 0) | ||||
|             { | ||||
|                 await imsg.Channel.SendMessageAsync("💢🔰 Not a Valid war size").ConfigureAwait(false); | ||||
|                 return; | ||||
|             } | ||||
|             List<ClashWar> wars; | ||||
|             if (!ClashWars.TryGetValue(channel.Guild.Id, out wars)) | ||||
|             { | ||||
|                 wars = new List<ClashWar>(); | ||||
|                 if (!ClashWars.TryAdd(channel.Guild.Id, wars)) | ||||
|                     return; | ||||
|             } | ||||
|  | ||||
|  | ||||
|             var cw = new ClashWar(enemyClan, size, channel.Guild.Id, imsg.Channel.Id); | ||||
|             //cw.Start(); | ||||
|  | ||||
|             wars.Add(cw); | ||||
|             await imsg.Channel.SendMessageAsync($"❗🔰**CREATED CLAN WAR AGAINST {cw.ShortPrint()}**").ConfigureAwait(false); | ||||
|         } | ||||
|  | ||||
|         [LocalizedCommand, LocalizedDescription, LocalizedSummary] | ||||
|         [RequireContext(ContextType.Guild)] | ||||
|         public async Task StartWar(IMessage imsg, [Remainder] string number = null) | ||||
|         { | ||||
|             var channel = imsg.Channel as ITextChannel; | ||||
|  | ||||
|             int num = 0; | ||||
|             int.TryParse(number, out num); | ||||
|  | ||||
|             var warsInfo = GetWarInfo(imsg, num); | ||||
|             if (warsInfo == null) | ||||
|             { | ||||
|                 await imsg.Channel.SendMessageAsync("💢🔰 **That war does not exist.**").ConfigureAwait(false); | ||||
|                 return; | ||||
|             } | ||||
|             var war = warsInfo.Item1[warsInfo.Item2]; | ||||
|             try | ||||
|             { | ||||
|                 war.Start(); | ||||
|                 await imsg.Channel.SendMessageAsync($"🔰**STARTED WAR AGAINST {war.ShortPrint()}**").ConfigureAwait(false); | ||||
|             } | ||||
|             catch | ||||
|             { | ||||
|                 await imsg.Channel.SendMessageAsync($"🔰**WAR AGAINST {war.ShortPrint()} HAS ALREADY STARTED**").ConfigureAwait(false); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         [LocalizedCommand, LocalizedDescription, LocalizedSummary] | ||||
|         [RequireContext(ContextType.Guild)] | ||||
|         public async Task ListWar(IMessage imsg, [Remainder] string number = null) | ||||
|         { | ||||
|             var channel = imsg.Channel as ITextChannel; | ||||
|  | ||||
|             // if number is null, print all wars in a short way | ||||
|             if (string.IsNullOrWhiteSpace(number)) | ||||
|             { | ||||
|                 //check if there are any wars | ||||
|                 List<ClashWar> wars = null; | ||||
|                 ClashWars.TryGetValue(channel.Guild.Id, out wars); | ||||
|                 if (wars == null || wars.Count == 0) | ||||
|                 { | ||||
|                     if (Bases[i].BaseDestroyed) | ||||
|                     { | ||||
|                         sb.AppendLine($"`{i + 1}.` ✅ `{Bases[i].CallUser}` {new string('⭐', Bases[i].Stars)}"); | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         var left = (WarState == WarState.Started) ? callExpire - (DateTime.UtcNow - Bases[i].TimeAdded) : callExpire; | ||||
|                         sb.AppendLine($"`{i + 1}.` ✅ `{Bases[i].CallUser}` {left.Hours}h {left.Minutes}m {left.Seconds}s left"); | ||||
|                     } | ||||
|                     await imsg.Channel.SendMessageAsync("🔰 **No active wars.**").ConfigureAwait(false); | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 var sb = new StringBuilder(); | ||||
|                 sb.AppendLine("🔰 **LIST OF ACTIVE WARS**"); | ||||
|                 sb.AppendLine("**-------------------------**"); | ||||
|                 for (var i = 0; i < wars.Count; i++) | ||||
|                 { | ||||
|                     sb.AppendLine($"**#{i + 1}.**  `Enemy:` **{wars[i].EnemyClan}**"); | ||||
|                     sb.AppendLine($"\t\t`Size:` **{wars[i].Size} v {wars[i].Size}**"); | ||||
|                     sb.AppendLine("**-------------------------**"); | ||||
|                 } | ||||
|                 await imsg.Channel.SendMessageAsync(sb.ToString()).ConfigureAwait(false); | ||||
|                 return; | ||||
|  | ||||
|             } | ||||
|             return sb.ToString(); | ||||
|             var num = 0; | ||||
|             int.TryParse(number, out num); | ||||
|             //if number is not null, print the war needed | ||||
|             var warsInfo = GetWarInfo(imsg, num); | ||||
|             if (warsInfo == null) | ||||
|             { | ||||
|                 await imsg.Channel.SendMessageAsync("💢🔰 **That war does not exist.**").ConfigureAwait(false); | ||||
|                 return; | ||||
|             } | ||||
|             await imsg.Channel.SendMessageAsync(warsInfo.Item1[warsInfo.Item2].ToString()).ConfigureAwait(false); | ||||
|         } | ||||
|  | ||||
|         internal int FinishClaim(string user, int stars = 3) | ||||
|         [LocalizedCommand, LocalizedDescription, LocalizedSummary] | ||||
|         [RequireContext(ContextType.Guild)] | ||||
|         public async Task Claim(IMessage imsg, int number, int baseNumber, [Remainder] string other_name = null) | ||||
|         { | ||||
|             user = user.Trim(); | ||||
|             for (var i = 0; i < Bases.Length; i++) | ||||
|             var channel = imsg.Channel as ITextChannel; | ||||
|             var warsInfo = GetWarInfo(imsg, number); | ||||
|             if (warsInfo == null || warsInfo.Item1.Count == 0) | ||||
|             { | ||||
|                 if (Bases[i]?.BaseDestroyed != false || Bases[i]?.CallUser != user) continue; | ||||
|                 Bases[i].BaseDestroyed = true; | ||||
|                 Bases[i].Stars = stars; | ||||
|                 return i; | ||||
|                 await imsg.Channel.SendMessageAsync("💢🔰 **That war does not exist.**").ConfigureAwait(false); | ||||
|                 return; | ||||
|             } | ||||
|             throw new InvalidOperationException($"@{user} You are either not participating in that war, or you already destroyed a base."); | ||||
|             var usr = | ||||
|                 string.IsNullOrWhiteSpace(other_name) ? | ||||
|                 imsg.Author.Username : | ||||
|                 other_name; | ||||
|             try | ||||
|             { | ||||
|                 var war = warsInfo.Item1[warsInfo.Item2]; | ||||
|                 war.Call(usr, baseNumber - 1); | ||||
|                 await imsg.Channel.SendMessageAsync($"🔰**{usr}** claimed a base #{baseNumber} for a war against {war.ShortPrint()}").ConfigureAwait(false); | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 await imsg.Channel.SendMessageAsync($"💢🔰 {ex.Message}").ConfigureAwait(false); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         [LocalizedCommand, LocalizedDescription, LocalizedSummary] | ||||
|         [RequireContext(ContextType.Guild)] | ||||
|         public async Task ClaimFinish1(IMessage imsg, int number, int baseNumber, [Remainder] string other_name = null) | ||||
|         { | ||||
|             var channel = imsg.Channel as ITextChannel; | ||||
|             await FinishClaim(imsg, number, baseNumber, other_name, 1); | ||||
|         } | ||||
|  | ||||
|         [LocalizedCommand, LocalizedDescription, LocalizedSummary] | ||||
|         [RequireContext(ContextType.Guild)] | ||||
|         public async Task ClaimFinish2(IMessage imsg, int number, int baseNumber, [Remainder] string other_name = null) | ||||
|         { | ||||
|             var channel = imsg.Channel as ITextChannel; | ||||
|             await FinishClaim(imsg, number, baseNumber, other_name, 2); | ||||
|         } | ||||
|  | ||||
|         [LocalizedCommand, LocalizedDescription, LocalizedSummary] | ||||
|         [RequireContext(ContextType.Guild)] | ||||
|         public async Task ClaimFinish(IMessage imsg, int number, int baseNumber, [Remainder] string other_name = null) | ||||
|         { | ||||
|             var channel = imsg.Channel as ITextChannel; | ||||
|             await FinishClaim(imsg, number, baseNumber, other_name); | ||||
|         } | ||||
|  | ||||
|         [LocalizedCommand, LocalizedDescription, LocalizedSummary] | ||||
|         [RequireContext(ContextType.Guild)] | ||||
|         public async Task EndWar(IMessage imsg, int number) | ||||
|         { | ||||
|             var channel = imsg.Channel as ITextChannel; | ||||
|  | ||||
|             var warsInfo = GetWarInfo(imsg,number); | ||||
|             if (warsInfo == null) | ||||
|             { | ||||
|                 await imsg.Channel.SendMessageAsync("💢🔰 That war does not exist.").ConfigureAwait(false); | ||||
|                 return; | ||||
|             } | ||||
|             warsInfo.Item1[warsInfo.Item2].End(); | ||||
|             await imsg.Channel.SendMessageAsync($"❗🔰**War against {warsInfo.Item1[warsInfo.Item2].ShortPrint()} ended.**").ConfigureAwait(false); | ||||
|  | ||||
|             var size = warsInfo.Item1[warsInfo.Item2].Size; | ||||
|             warsInfo.Item1.RemoveAt(warsInfo.Item2); | ||||
|         } | ||||
|  | ||||
|         [LocalizedCommand, LocalizedDescription, LocalizedSummary] | ||||
|         [RequireContext(ContextType.Guild)] | ||||
|         public async Task Unclaim(IMessage imsg, int number, [Remainder] string otherName = null) | ||||
|         { | ||||
|             var channel = imsg.Channel as ITextChannel; | ||||
|  | ||||
|             var warsInfo = GetWarInfo(imsg, number); | ||||
|             if (warsInfo == null || warsInfo.Item1.Count == 0) | ||||
|             { | ||||
|                 await imsg.Channel.SendMessageAsync("💢🔰 **That war does not exist.**").ConfigureAwait(false); | ||||
|                 return; | ||||
|             } | ||||
|             var usr = | ||||
|                 string.IsNullOrWhiteSpace(otherName) ? | ||||
|                 imsg.Author.Username : | ||||
|                 otherName; | ||||
|             try | ||||
|             { | ||||
|                 var war = warsInfo.Item1[warsInfo.Item2]; | ||||
|                 var baseNumber = war.Uncall(usr); | ||||
|                 await imsg.Channel.SendMessageAsync($"🔰 @{usr} has **UNCLAIMED** a base #{baseNumber + 1} from a war against {war.ShortPrint()}").ConfigureAwait(false); | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 await imsg.Channel.SendMessageAsync($"💢🔰 {ex.Message}").ConfigureAwait(false); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         private async Task FinishClaim(IMessage imsg, int number, int baseNumber, [Remainder] string other_name, int stars = 3) | ||||
|         { | ||||
|             var channel = imsg.Channel as ITextChannel; | ||||
|             var warInfo = GetWarInfo(imsg, number); | ||||
|             if (warInfo == null || warInfo.Item1.Count == 0) | ||||
|             { | ||||
|                 await imsg.Channel.SendMessageAsync("💢🔰 **That war does not exist.**").ConfigureAwait(false); | ||||
|                 return; | ||||
|             } | ||||
|             var usr = | ||||
|                 string.IsNullOrWhiteSpace(other_name) ? | ||||
|                 imsg.Author.Username : | ||||
|                 other_name; | ||||
|  | ||||
|             var war = warInfo.Item1[warInfo.Item2]; | ||||
|             try | ||||
|             { | ||||
|                 var baseNum = war.FinishClaim(usr, stars); | ||||
|                 await imsg.Channel.SendMessageAsync($"❗🔰{imsg.Author.Mention} **DESTROYED** a base #{baseNum + 1} in a war against {war.ShortPrint()}").ConfigureAwait(false); | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 await imsg.Channel.SendMessageAsync($"💢🔰 {ex.Message}").ConfigureAwait(false); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         private static Tuple<List<ClashWar>, int> GetWarInfo(IMessage imsg, int num) | ||||
|         { | ||||
|             var channel = imsg.Channel as ITextChannel; | ||||
|             //check if there are any wars | ||||
|             List<ClashWar> wars = null; | ||||
|             ClashWars.TryGetValue(channel.Guild.Id, out wars); | ||||
|             if (wars == null || wars.Count == 0) | ||||
|             { | ||||
|                 return null; | ||||
|             } | ||||
|             // get the number of the war | ||||
|             else if (num < 1 || num > wars.Count) | ||||
|             { | ||||
|                 return null; | ||||
|             } | ||||
|             num -= 1; | ||||
|             //get the actual war | ||||
|             return new Tuple<List<ClashWar>, int>(wars, num); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,285 +0,0 @@ | ||||
| using Discord.Commands; | ||||
| using NadekoBot.Classes.ClashOfClans; | ||||
| using System; | ||||
| using System.Collections.Concurrent; | ||||
| using System.Collections.Generic; | ||||
| using System.Text; | ||||
| using System.Threading.Tasks; | ||||
| using Discord; | ||||
| using NadekoBot.Services; | ||||
| using NadekoBot.Attributes; | ||||
|  | ||||
| //todo DB | ||||
| namespace NadekoBot.Modules.ClashOfClans | ||||
| { | ||||
|     [Module(",",AppendSpace = false)] | ||||
|     internal class ClashOfClansModule : DiscordModule | ||||
|     { | ||||
|         public static ConcurrentDictionary<ulong, List<ClashWar>> ClashWars { get; set; } = new ConcurrentDictionary<ulong, List<ClashWar>>(); | ||||
|  | ||||
|         public ClashOfClansModule(ILocalization loc, CommandService cmds, IBotConfiguration config, IDiscordClient client) : base(loc, cmds, config, client) | ||||
|         { | ||||
|         } | ||||
|  | ||||
|         private static async Task CheckWar(TimeSpan callExpire, ClashWar war) | ||||
|         { | ||||
|             var Bases = war.Bases; | ||||
|             for (var i = 0; i < Bases.Length; i++) | ||||
|             { | ||||
|                 if (Bases[i] == null) continue; | ||||
|                 if (!Bases[i].BaseDestroyed && DateTime.UtcNow - Bases[i].TimeAdded >= callExpire) | ||||
|                 { | ||||
|                     await war.Channel.SendMessageAsync($"❗🔰**Claim from @{Bases[i].CallUser} for a war against {war.ShortPrint()} has expired.**").ConfigureAwait(false); | ||||
|                     Bases[i] = null; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         [LocalizedCommand, LocalizedDescription, LocalizedSummary] | ||||
|         [RequireContext(ContextType.Guild)] | ||||
|         public async Task CreateWar(IMessage imsg, int size, [Remainder] string enemyClan = null) | ||||
|         { | ||||
|             var channel = imsg.Channel as ITextChannel; | ||||
|  | ||||
|             if (!(imsg.Author as IGuildUser).GuildPermissions.ManageChannels) | ||||
|                 return; | ||||
|  | ||||
|             if (string.IsNullOrWhiteSpace(enemyClan)) | ||||
|                 return; | ||||
|  | ||||
|             if (size < 10 || size > 50 || size % 5 != 0) | ||||
|             { | ||||
|                 await imsg.Channel.SendMessageAsync("💢🔰 Not a Valid war size").ConfigureAwait(false); | ||||
|                 return; | ||||
|             } | ||||
|             List<ClashWar> wars; | ||||
|             if (!ClashWars.TryGetValue(channel.Guild.Id, out wars)) | ||||
|             { | ||||
|                 wars = new List<ClashWar>(); | ||||
|                 if (!ClashWars.TryAdd(channel.Guild.Id, wars)) | ||||
|                     return; | ||||
|             } | ||||
|  | ||||
|  | ||||
|             var cw = new ClashWar(enemyClan, size, channel.Guild.Id, imsg.Channel.Id); | ||||
|             //cw.Start(); | ||||
|  | ||||
|             wars.Add(cw); | ||||
|             await imsg.Channel.SendMessageAsync($"❗🔰**CREATED CLAN WAR AGAINST {cw.ShortPrint()}**").ConfigureAwait(false); | ||||
|         } | ||||
|  | ||||
|         [LocalizedCommand, LocalizedDescription, LocalizedSummary] | ||||
|         [RequireContext(ContextType.Guild)] | ||||
|         public async Task StartWar(IMessage imsg, [Remainder] string number = null) | ||||
|         { | ||||
|             var channel = imsg.Channel as ITextChannel; | ||||
|  | ||||
|             int num = 0; | ||||
|             int.TryParse(number, out num); | ||||
|  | ||||
|             var warsInfo = GetWarInfo(imsg, num); | ||||
|             if (warsInfo == null) | ||||
|             { | ||||
|                 await imsg.Channel.SendMessageAsync("💢🔰 **That war does not exist.**").ConfigureAwait(false); | ||||
|                 return; | ||||
|             } | ||||
|             var war = warsInfo.Item1[warsInfo.Item2]; | ||||
|             try | ||||
|             { | ||||
|                 war.Start(); | ||||
|                 await imsg.Channel.SendMessageAsync($"🔰**STARTED WAR AGAINST {war.ShortPrint()}**").ConfigureAwait(false); | ||||
|             } | ||||
|             catch | ||||
|             { | ||||
|                 await imsg.Channel.SendMessageAsync($"🔰**WAR AGAINST {war.ShortPrint()} HAS ALREADY STARTED**").ConfigureAwait(false); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         [LocalizedCommand, LocalizedDescription, LocalizedSummary] | ||||
|         [RequireContext(ContextType.Guild)] | ||||
|         public async Task ListWar(IMessage imsg, [Remainder] string number = null) | ||||
|         { | ||||
|             var channel = imsg.Channel as ITextChannel; | ||||
|  | ||||
|             // if number is null, print all wars in a short way | ||||
|             if (string.IsNullOrWhiteSpace(number)) | ||||
|             { | ||||
|                 //check if there are any wars | ||||
|                 List<ClashWar> wars = null; | ||||
|                 ClashWars.TryGetValue(channel.Guild.Id, out wars); | ||||
|                 if (wars == null || wars.Count == 0) | ||||
|                 { | ||||
|                     await imsg.Channel.SendMessageAsync("🔰 **No active wars.**").ConfigureAwait(false); | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 var sb = new StringBuilder(); | ||||
|                 sb.AppendLine("🔰 **LIST OF ACTIVE WARS**"); | ||||
|                 sb.AppendLine("**-------------------------**"); | ||||
|                 for (var i = 0; i < wars.Count; i++) | ||||
|                 { | ||||
|                     sb.AppendLine($"**#{i + 1}.**  `Enemy:` **{wars[i].EnemyClan}**"); | ||||
|                     sb.AppendLine($"\t\t`Size:` **{wars[i].Size} v {wars[i].Size}**"); | ||||
|                     sb.AppendLine("**-------------------------**"); | ||||
|                 } | ||||
|                 await imsg.Channel.SendMessageAsync(sb.ToString()).ConfigureAwait(false); | ||||
|                 return; | ||||
|  | ||||
|             } | ||||
|             var num = 0; | ||||
|             int.TryParse(number, out num); | ||||
|             //if number is not null, print the war needed | ||||
|             var warsInfo = GetWarInfo(imsg, num); | ||||
|             if (warsInfo == null) | ||||
|             { | ||||
|                 await imsg.Channel.SendMessageAsync("💢🔰 **That war does not exist.**").ConfigureAwait(false); | ||||
|                 return; | ||||
|             } | ||||
|             await imsg.Channel.SendMessageAsync(warsInfo.Item1[warsInfo.Item2].ToString()).ConfigureAwait(false); | ||||
|         } | ||||
|  | ||||
|         [LocalizedCommand, LocalizedDescription, LocalizedSummary] | ||||
|         [RequireContext(ContextType.Guild)] | ||||
|         public async Task Claim(IMessage imsg, int number, int baseNumber, [Remainder] string other_name = null) | ||||
|         { | ||||
|             var channel = imsg.Channel as ITextChannel; | ||||
|             var warsInfo = GetWarInfo(imsg, number); | ||||
|             if (warsInfo == null || warsInfo.Item1.Count == 0) | ||||
|             { | ||||
|                 await imsg.Channel.SendMessageAsync("💢🔰 **That war does not exist.**").ConfigureAwait(false); | ||||
|                 return; | ||||
|             } | ||||
|             var usr = | ||||
|                 string.IsNullOrWhiteSpace(other_name) ? | ||||
|                 imsg.Author.Username : | ||||
|                 other_name; | ||||
|             try | ||||
|             { | ||||
|                 var war = warsInfo.Item1[warsInfo.Item2]; | ||||
|                 war.Call(usr, baseNumber - 1); | ||||
|                 await imsg.Channel.SendMessageAsync($"🔰**{usr}** claimed a base #{baseNumber} for a war against {war.ShortPrint()}").ConfigureAwait(false); | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 await imsg.Channel.SendMessageAsync($"💢🔰 {ex.Message}").ConfigureAwait(false); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         [LocalizedCommand, LocalizedDescription, LocalizedSummary] | ||||
|         [RequireContext(ContextType.Guild)] | ||||
|         public async Task ClaimFinish1(IMessage imsg, int number, int baseNumber, [Remainder] string other_name = null) | ||||
|         { | ||||
|             var channel = imsg.Channel as ITextChannel; | ||||
|             await FinishClaim(imsg, number, baseNumber, other_name, 1); | ||||
|         } | ||||
|  | ||||
|         [LocalizedCommand, LocalizedDescription, LocalizedSummary] | ||||
|         [RequireContext(ContextType.Guild)] | ||||
|         public async Task ClaimFinish2(IMessage imsg, int number, int baseNumber, [Remainder] string other_name = null) | ||||
|         { | ||||
|             var channel = imsg.Channel as ITextChannel; | ||||
|             await FinishClaim(imsg, number, baseNumber, other_name, 2); | ||||
|         } | ||||
|  | ||||
|         [LocalizedCommand, LocalizedDescription, LocalizedSummary] | ||||
|         [RequireContext(ContextType.Guild)] | ||||
|         public async Task ClaimFinish(IMessage imsg, int number, int baseNumber, [Remainder] string other_name = null) | ||||
|         { | ||||
|             var channel = imsg.Channel as ITextChannel; | ||||
|             await FinishClaim(imsg, number, baseNumber, other_name); | ||||
|         } | ||||
|  | ||||
|         [LocalizedCommand, LocalizedDescription, LocalizedSummary] | ||||
|         [RequireContext(ContextType.Guild)] | ||||
|         public async Task EndWar(IMessage imsg, int number) | ||||
|         { | ||||
|             var channel = imsg.Channel as ITextChannel; | ||||
|  | ||||
|             var warsInfo = GetWarInfo(imsg,number); | ||||
|             if (warsInfo == null) | ||||
|             { | ||||
|                 await imsg.Channel.SendMessageAsync("💢🔰 That war does not exist.").ConfigureAwait(false); | ||||
|                 return; | ||||
|             } | ||||
|             warsInfo.Item1[warsInfo.Item2].End(); | ||||
|             await imsg.Channel.SendMessageAsync($"❗🔰**War against {warsInfo.Item1[warsInfo.Item2].ShortPrint()} ended.**").ConfigureAwait(false); | ||||
|  | ||||
|             var size = warsInfo.Item1[warsInfo.Item2].Size; | ||||
|             warsInfo.Item1.RemoveAt(warsInfo.Item2); | ||||
|         } | ||||
|  | ||||
|         [LocalizedCommand, LocalizedDescription, LocalizedSummary] | ||||
|         [RequireContext(ContextType.Guild)] | ||||
|         public async Task Unclaim(IMessage imsg, int number, [Remainder] string otherName = null) | ||||
|         { | ||||
|             var channel = imsg.Channel as ITextChannel; | ||||
|  | ||||
|             var warsInfo = GetWarInfo(imsg, number); | ||||
|             if (warsInfo == null || warsInfo.Item1.Count == 0) | ||||
|             { | ||||
|                 await imsg.Channel.SendMessageAsync("💢🔰 **That war does not exist.**").ConfigureAwait(false); | ||||
|                 return; | ||||
|             } | ||||
|             var usr = | ||||
|                 string.IsNullOrWhiteSpace(otherName) ? | ||||
|                 imsg.Author.Username : | ||||
|                 otherName; | ||||
|             try | ||||
|             { | ||||
|                 var war = warsInfo.Item1[warsInfo.Item2]; | ||||
|                 var baseNumber = war.Uncall(usr); | ||||
|                 await imsg.Channel.SendMessageAsync($"🔰 @{usr} has **UNCLAIMED** a base #{baseNumber + 1} from a war against {war.ShortPrint()}").ConfigureAwait(false); | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 await imsg.Channel.SendMessageAsync($"💢🔰 {ex.Message}").ConfigureAwait(false); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         private async Task FinishClaim(IMessage imsg, int number, int baseNumber, [Remainder] string other_name, int stars = 3) | ||||
|         { | ||||
|             var channel = imsg.Channel as ITextChannel; | ||||
|             var warInfo = GetWarInfo(imsg, number); | ||||
|             if (warInfo == null || warInfo.Item1.Count == 0) | ||||
|             { | ||||
|                 await imsg.Channel.SendMessageAsync("💢🔰 **That war does not exist.**").ConfigureAwait(false); | ||||
|                 return; | ||||
|             } | ||||
|             var usr = | ||||
|                 string.IsNullOrWhiteSpace(other_name) ? | ||||
|                 imsg.Author.Username : | ||||
|                 other_name; | ||||
|  | ||||
|             var war = warInfo.Item1[warInfo.Item2]; | ||||
|             try | ||||
|             { | ||||
|                 var baseNum = war.FinishClaim(usr, stars); | ||||
|                 await imsg.Channel.SendMessageAsync($"❗🔰{imsg.Author.Mention} **DESTROYED** a base #{baseNum + 1} in a war against {war.ShortPrint()}").ConfigureAwait(false); | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 await imsg.Channel.SendMessageAsync($"💢🔰 {ex.Message}").ConfigureAwait(false); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         private static Tuple<List<ClashWar>, int> GetWarInfo(IMessage imsg, int num) | ||||
|         { | ||||
|             var channel = imsg.Channel as ITextChannel; | ||||
|             //check if there are any wars | ||||
|             List<ClashWar> wars = null; | ||||
|             ClashWars.TryGetValue(channel.Guild.Id, out wars); | ||||
|             if (wars == null || wars.Count == 0) | ||||
|             { | ||||
|                 return null; | ||||
|             } | ||||
|             // get the number of the war | ||||
|             else if (num < 1 || num > wars.Count) | ||||
|             { | ||||
|                 return null; | ||||
|             } | ||||
|             num -= 1; | ||||
|             //get the actual war | ||||
|             return new Tuple<List<ClashWar>, int>(wars, num); | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										183
									
								
								src/NadekoBot/Modules/ClashOfClans/ClashWar.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										183
									
								
								src/NadekoBot/Modules/ClashOfClans/ClashWar.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,183 @@ | ||||
| using Discord; | ||||
| using Newtonsoft.Json; | ||||
| using System; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
|  | ||||
| namespace NadekoBot.Classes.ClashOfClans | ||||
| { | ||||
|     internal class ClashWar | ||||
|     { | ||||
|         public enum DestroyStars | ||||
|         { | ||||
|             One, Two, Three | ||||
|         } | ||||
|         public enum StateOfWar | ||||
|         { | ||||
|             Started, Ended, Created | ||||
|         } | ||||
|  | ||||
|         internal class Caller | ||||
|         { | ||||
|             public string CallUser { get; set; } | ||||
|  | ||||
|             public DateTime TimeAdded { get; set; } | ||||
|  | ||||
|             public bool BaseDestroyed { get; set; } | ||||
|  | ||||
|             public int Stars { get; set; } = 3; | ||||
|  | ||||
|             public Caller() { } | ||||
|  | ||||
|             public Caller(string callUser, DateTime timeAdded, bool baseDestroyed) | ||||
|             { | ||||
|                 CallUser = callUser; | ||||
|                 TimeAdded = timeAdded; | ||||
|                 BaseDestroyed = baseDestroyed; | ||||
|             } | ||||
|  | ||||
|             public void ResetTime() | ||||
|             { | ||||
|                 TimeAdded = DateTime.UtcNow; | ||||
|             } | ||||
|  | ||||
|             public void Destroy() | ||||
|             { | ||||
|                 BaseDestroyed = true; | ||||
|             } | ||||
|         } | ||||
|         private static TimeSpan callExpire => new TimeSpan(2, 0, 0); | ||||
|  | ||||
|         public string EnemyClan { get; set; } | ||||
|         public int Size { get; set; } | ||||
|  | ||||
|         public Caller[] Bases { get; set; } | ||||
|         public StateOfWar WarState { get; set; } = StateOfWar.Created; | ||||
|         //public bool Started { get; set; } = false; | ||||
|         public DateTime StartedAt { get; set; } | ||||
|         //public bool Ended { get; private set; } = false; | ||||
|  | ||||
|         public ulong ServerId { get; set; } | ||||
|         public ulong ChannelId { get; set; } | ||||
|  | ||||
|         [JsonIgnore] | ||||
|         public ITextChannel Channel { get; internal set; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// This init is purely for the deserialization | ||||
|         /// </summary> | ||||
|         public ClashWar() { } | ||||
|  | ||||
|         public ClashWar(string enemyClan, int size, ulong serverId, ulong channelId) | ||||
|         { | ||||
|             this.EnemyClan = enemyClan; | ||||
|             this.Size = size; | ||||
|             this.Bases = new Caller[size]; | ||||
|             this.ServerId = serverId; | ||||
|             this.ChannelId = channelId; | ||||
|             this.Channel = NadekoBot.Client.GetGuildsAsync() //nice api you got here volt,  | ||||
|                                     .GetAwaiter() //especially like how getguildsasync isn't async at all internally.  | ||||
|                                     .GetResult() //But hey, lib has to be async kek | ||||
|                                     .FirstOrDefault(s => s.Id == serverId)? // srsly | ||||
|                                     .GetChannelsAsync() //wtf is this | ||||
|                                     .GetAwaiter() // oh i know, its the implementation detail | ||||
|                                     .GetResult() // and makes library look consistent | ||||
|                                     .FirstOrDefault(c => c.Id == channelId) // its not common sense to make library work like this. | ||||
|                                         as ITextChannel; // oh and don't forget to cast it to this arbitrary bullshit  | ||||
|         } | ||||
|  | ||||
|         internal void End() | ||||
|         { | ||||
|             //Ended = true; | ||||
|             WarState = StateOfWar.Ended; | ||||
|         } | ||||
|  | ||||
|         internal void Call(string u, int baseNumber) | ||||
|         { | ||||
|             if (baseNumber < 0 || baseNumber >= Bases.Length) | ||||
|                 throw new ArgumentException("Invalid base number"); | ||||
|             if (Bases[baseNumber] != null) | ||||
|                 throw new ArgumentException("That base is already claimed."); | ||||
|             for (var i = 0; i < Bases.Length; i++) | ||||
|             { | ||||
|                 if (Bases[i]?.BaseDestroyed == false && Bases[i]?.CallUser == u) | ||||
|                     throw new ArgumentException($"@{u} You already claimed base #{i + 1}. You can't claim a new one."); | ||||
|             } | ||||
|  | ||||
|             Bases[baseNumber] = new Caller(u.Trim(), DateTime.UtcNow, false); | ||||
|         } | ||||
|  | ||||
|         internal void Start() | ||||
|         { | ||||
|             if (WarState == StateOfWar.Started) | ||||
|                 throw new InvalidOperationException("War already started"); | ||||
|             //if (Started) | ||||
|             //    throw new InvalidOperationException(); | ||||
|             //Started = true; | ||||
|             WarState = StateOfWar.Started; | ||||
|             StartedAt = DateTime.UtcNow; | ||||
|             foreach (var b in Bases.Where(b => b != null)) | ||||
|             { | ||||
|                 b.ResetTime(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         internal int Uncall(string user) | ||||
|         { | ||||
|             user = user.Trim(); | ||||
|             for (var i = 0; i < Bases.Length; i++) | ||||
|             { | ||||
|                 if (Bases[i]?.CallUser != user) continue; | ||||
|                 Bases[i] = null; | ||||
|                 return i; | ||||
|             } | ||||
|             throw new InvalidOperationException("You are not participating in that war."); | ||||
|         } | ||||
|  | ||||
|         public string ShortPrint() => | ||||
|             $"`{EnemyClan}` ({Size} v {Size})"; | ||||
|  | ||||
|         public override string ToString() | ||||
|         { | ||||
|             var sb = new StringBuilder(); | ||||
|  | ||||
|             sb.AppendLine($"🔰**WAR AGAINST `{EnemyClan}` ({Size} v {Size}) INFO:**"); | ||||
|             if (WarState == StateOfWar.Created) | ||||
|                 sb.AppendLine("`not started`"); | ||||
|             for (var i = 0; i < Bases.Length; i++) | ||||
|             { | ||||
|                 if (Bases[i] == null) | ||||
|                 { | ||||
|                     sb.AppendLine($"`{i + 1}.` ❌*unclaimed*"); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     if (Bases[i].BaseDestroyed) | ||||
|                     { | ||||
|                         sb.AppendLine($"`{i + 1}.` ✅ `{Bases[i].CallUser}` {new string('⭐', Bases[i].Stars)}"); | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         var left = (WarState == StateOfWar.Started) ? callExpire - (DateTime.UtcNow - Bases[i].TimeAdded) : callExpire; | ||||
|                         sb.AppendLine($"`{i + 1}.` ✅ `{Bases[i].CallUser}` {left.Hours}h {left.Minutes}m {left.Seconds}s left"); | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|             } | ||||
|             return sb.ToString(); | ||||
|         } | ||||
|  | ||||
|         internal int FinishClaim(string user, int stars = 3) | ||||
|         { | ||||
|             user = user.Trim(); | ||||
|             for (var i = 0; i < Bases.Length; i++) | ||||
|             { | ||||
|                 if (Bases[i]?.BaseDestroyed != false || Bases[i]?.CallUser != user) continue; | ||||
|                 Bases[i].BaseDestroyed = true; | ||||
|                 Bases[i].Stars = stars; | ||||
|                 return i; | ||||
|             } | ||||
|             throw new InvalidOperationException($"@{user} You are either not participating in that war, or you already destroyed a base."); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1,6 +1,7 @@ | ||||
| using Discord; | ||||
| using Discord.Commands; | ||||
| using NadekoBot.Services; | ||||
| using NLog; | ||||
|  | ||||
| namespace NadekoBot.Modules | ||||
| { | ||||
| @@ -10,6 +11,7 @@ namespace NadekoBot.Modules | ||||
|         protected CommandService _commands; | ||||
|         protected IBotConfiguration _config; | ||||
|         protected IDiscordClient _client; | ||||
|         protected Logger _log; | ||||
|  | ||||
|         public DiscordModule(ILocalization loc, CommandService cmds, IBotConfiguration config,IDiscordClient client) | ||||
|         { | ||||
| @@ -17,6 +19,7 @@ namespace NadekoBot.Modules | ||||
|             _commands = cmds; | ||||
|             _config = config; | ||||
|             _client = client; | ||||
|             _log = LogManager.GetCurrentClassLogger(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -11,11 +11,11 @@ using NadekoBot.Extensions; | ||||
| namespace NadekoBot.Modules.Games | ||||
| { | ||||
|     [Module(">", AppendSpace = false)] | ||||
|     public partial class GamesModule : DiscordModule | ||||
|     public partial class Games : DiscordModule | ||||
|     { | ||||
|         //todo DB | ||||
|         private IEnumerable<string> _8BallResponses; | ||||
|         public GamesModule(ILocalization loc, CommandService cmds, IBotConfiguration config, IDiscordClient client) : base(loc, cmds, config, client) | ||||
|         public Games(ILocalization loc, CommandService cmds, IBotConfiguration config, IDiscordClient client) : base(loc, cmds, config, client) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
| @@ -12,7 +12,7 @@ using System.Text; | ||||
| namespace NadekoBot.Modules.Help | ||||
| { | ||||
|     [Module("-", AppendSpace = false)] | ||||
|     public partial class HelpModule : DiscordModule | ||||
|     public partial class Help : DiscordModule | ||||
|     { | ||||
|         public string HelpString { | ||||
|             get { | ||||
| @@ -20,7 +20,7 @@ namespace NadekoBot.Modules.Help | ||||
|                 return str + String.Format(str, NadekoBot.Credentials.ClientId); | ||||
|             } | ||||
|         } | ||||
|         public HelpModule(ILocalization loc, CommandService cmds, IBotConfiguration config, IDiscordClient client) : base(loc, cmds, config, client) | ||||
|         public Help(ILocalization loc, CommandService cmds, IBotConfiguration config, IDiscordClient client) : base(loc, cmds, config, client) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
| @@ -66,7 +66,7 @@ namespace NadekoBot.Modules.Help | ||||
| 
 | ||||
|         [LocalizedCommand, LocalizedDescription, LocalizedSummary] | ||||
|         [RequireContext(ContextType.Guild)] | ||||
|         public async Task Help(IMessage imsg, [Remainder] string comToFind = null) | ||||
|         public async Task H(IMessage imsg, [Remainder] string comToFind = null) | ||||
|         { | ||||
|             var channel = imsg.Channel as ITextChannel; | ||||
| 
 | ||||
| @@ -106,7 +106,7 @@ namespace NadekoBot.Modules.Help | ||||
|             } | ||||
|             helpstr = helpstr.Replace((await NadekoBot.Client.GetCurrentUserAsync()).Username , "@BotName"); | ||||
| #if DEBUG | ||||
|             File.WriteAllText("../../../docs/Commands List.md", helpstr.ToString()); | ||||
|             File.WriteAllText("../../../../../docs/Commands List.md", helpstr.ToString()); | ||||
| #else | ||||
|             File.WriteAllText("commandlist.md", helpstr.ToString()); | ||||
| #endif | ||||
| @@ -9,13 +9,14 @@ using NadekoBot.Services; | ||||
| using System.Net.Http; | ||||
| using System.Text.RegularExpressions; | ||||
| using System.Xml.Linq; | ||||
| using System.Net; | ||||
| 
 | ||||
| namespace NadekoBot.Modules.NSFW | ||||
| { | ||||
|     [Module("~", AppendSpace = false)] | ||||
|     public class NSFWModule : DiscordModule | ||||
|     public class NSFW : DiscordModule | ||||
|     { | ||||
|         public NSFWModule(ILocalization loc, CommandService cmds, IBotConfiguration config, IDiscordClient client) : base(loc, cmds, config, client) | ||||
|         public NSFW(ILocalization loc, CommandService cmds, IBotConfiguration config, IDiscordClient client) : base(loc, cmds, config, client) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
| @@ -212,7 +213,7 @@ namespace NadekoBot.Modules.NSFW | ||||
|                     http.DefaultRequestHeaders.Clear(); | ||||
|                     http.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.202 Safari/535.1"); | ||||
|                     http.DefaultRequestHeaders.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"); | ||||
|                     var data = await http.GetStringAsync("http://e621.net/post/index.xml?tags=" + Uri.EscapeUriString(tags) + "%20order:random&limit=1"); | ||||
|                     var data = await http.GetStreamAsync("http://e621.net/post/index.xml?tags=" + Uri.EscapeUriString(tags) + "%20order:random&limit=1"); | ||||
|                     var doc = XDocument.Load(data); | ||||
|                     return doc.Descendants("file_url").FirstOrDefault().Value; | ||||
|                 } | ||||
| @@ -7,9 +7,9 @@ using NadekoBot.Services; | ||||
| namespace NadekoBot.Modules.Games.Commands | ||||
| { | ||||
|     [Module(">", AppendSpace = false)] | ||||
|     public partial class PokemonModule : DiscordModule | ||||
|     public partial class Pokemon : DiscordModule | ||||
|     { | ||||
|         public PokemonModule(ILocalization loc, CommandService cmds, IBotConfiguration config, IDiscordClient client) : base(loc, cmds, config, client) | ||||
|         public Pokemon(ILocalization loc, CommandService cmds, IBotConfiguration config, IDiscordClient client) : base(loc, cmds, config, client) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
| @@ -76,7 +76,7 @@ | ||||
| //                        var reqString = $"https://osu.ppy.sh/api/get_beatmaps?k={NadekoBot.Creds.OsuAPIKey}&{mapId}"; | ||||
| //                        var obj = JArray.Parse(await http.GetStringAsync(reqString).ConfigureAwait(false))[0]; | ||||
| //                        var sb = new System.Text.StringBuilder(); | ||||
| //                        var starRating = Math.Round(Double.Parse($"{obj["difficultyrating"]}"), 2); | ||||
| //                        var starRating = Math.Round(Double.Parse($"{obj["difficultyrating"]}", CultureInfo.InvariantCulture), 2); | ||||
| //                        var time = TimeSpan.FromSeconds(Double.Parse($"{obj["total_length"]}")).ToString(@"mm\:ss"); | ||||
| //                        sb.AppendLine($"{obj["artist"]} - {obj["title"]}, mapped by {obj["creator"]}. https://osu.ppy.sh/s/{obj["beatmapset_id"]}"); | ||||
| //                        sb.AppendLine($"{starRating} stars, {obj["bpm"]} BPM | AR{obj["diff_approach"]}, CS{obj["diff_size"]}, OD{obj["diff_overall"]} | Length: {time}"); | ||||
| @@ -121,7 +121,7 @@ | ||||
| //                        { | ||||
| //                            var mapReqString = $"https://osu.ppy.sh/api/get_beatmaps?k={NadekoBot.Creds.OsuAPIKey}&b={item["beatmap_id"]}"; | ||||
| //                            var map = JArray.Parse(await http.GetStringAsync(mapReqString).ConfigureAwait(false))[0]; | ||||
| //                            var pp = Math.Round(Double.Parse($"{item["pp"]}"), 2); | ||||
| //                            var pp = Math.Round(Double.Parse($"{item["pp"]}", CultureInfo.InvariantCulture), 2); | ||||
| //                            var acc = CalculateAcc(item, m); | ||||
| //                            var mods = ResolveMods(Int32.Parse($"{item["enabled_mods"]}")); | ||||
| //                            if (mods != "+") | ||||
|   | ||||
| @@ -17,13 +17,13 @@ using NadekoBot.Modules.Searches.Commands.Models; | ||||
| namespace NadekoBot.Modules.Searches | ||||
| { | ||||
|     [Module("~", AppendSpace = false)] | ||||
|     public class SearchesModule : DiscordModule | ||||
|     public class Searches : DiscordModule | ||||
|     { | ||||
|         private readonly Random rng; | ||||
| 
 | ||||
|         private IYoutubeService _yt { get; } | ||||
| 
 | ||||
|         public SearchesModule(ILocalization loc, CommandService cmds, IBotConfiguration config, IDiscordClient client, IYoutubeService youtube) : base(loc, cmds, config, client) | ||||
|         public Searches(ILocalization loc, CommandService cmds, IBotConfiguration config, IDiscordClient client, IYoutubeService youtube) : base(loc, cmds, config, client) | ||||
|         { | ||||
|             rng = new Random(); | ||||
|             _yt = youtube; | ||||
| @@ -94,6 +94,7 @@ namespace NadekoBot.Modules.Translator | ||||
|                     { "bn", "bn"}, | ||||
|                     { "bg", "bg"}, | ||||
|                     { "ca", "ca"}, | ||||
|                     { "zh-TW", "zh-TW"}, | ||||
|                     { "zh-CN", "zh-CN"}, | ||||
|                     { "hr", "hr"}, | ||||
|                     { "cs", "cs"}, | ||||
|   | ||||
| @@ -9,9 +9,9 @@ using NadekoBot.Services; | ||||
| namespace NadekoBot.Modules.Translator | ||||
| { | ||||
|     [Module("~", AppendSpace = false)] | ||||
|     public class TranslatorModule : DiscordModule | ||||
|     public class Translator : DiscordModule | ||||
|     { | ||||
|         public TranslatorModule(ILocalization loc, CommandService cmds, IBotConfiguration config, IDiscordClient client) : base(loc, cmds, config, client) | ||||
|         public Translator(ILocalization loc, CommandService cmds, IBotConfiguration config, IDiscordClient client) : base(loc, cmds, config, client) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
| @@ -11,7 +11,7 @@ | ||||
| ////todo rewrite | ||||
| //namespace NadekoBot.Modules.Trello | ||||
| //{ | ||||
| //    internal class TrelloModule : DiscordModule | ||||
| //    internal class Trello : DiscordModule | ||||
| //    { | ||||
| //        private readonly Timer t = new Timer { Interval = 2000 }; | ||||
| //        public override string Prefix { get; } = NadekoBot.Config.CommandPrefixes.Trello; | ||||
| @@ -9,7 +9,7 @@ using System.Threading.Tasks; | ||||
|  | ||||
| namespace NadekoBot.Modules.Utility | ||||
| { | ||||
|     partial class UtilityModule : DiscordModule | ||||
|     partial class Utility : DiscordModule | ||||
|     { | ||||
|         [LocalizedCommand, LocalizedDescription, LocalizedSummary] | ||||
|         [RequireContext(ContextType.Guild)] | ||||
|   | ||||
| @@ -15,9 +15,9 @@ namespace NadekoBot.Modules.Utility | ||||
| { | ||||
| 
 | ||||
|     [Module(".", AppendSpace = false)] | ||||
|     public partial class UtilityModule : DiscordModule | ||||
|     public partial class Utility : DiscordModule | ||||
|     { | ||||
|         public UtilityModule(ILocalization loc, CommandService cmds, IBotConfiguration config, IDiscordClient client) : base(loc, cmds, config, client) | ||||
|         public Utility(ILocalization loc, CommandService cmds, IBotConfiguration config, IDiscordClient client) : base(loc, cmds, config, client) | ||||
|         { | ||||
| 
 | ||||
|         } | ||||
| @@ -127,6 +127,15 @@ namespace NadekoBot.Modules.Utility | ||||
|                 await msg.Reply("`List of roles:` \n• " + string.Join("\n• ", (msg.Channel as ITextChannel).Guild.Roles.Except(new[] { guild.EveryoneRole }))); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         [LocalizedCommand, LocalizedDescription, LocalizedSummary] | ||||
|         [RequireContext(ContextType.Guild)] | ||||
|         public async Task Stats(IMessage imsg) | ||||
|         { | ||||
|             var channel = imsg.Channel as ITextChannel; | ||||
| 
 | ||||
|             await channel.SendMessageAsync(await NadekoBot.Stats.Print()); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @@ -3,6 +3,9 @@ using Discord.Commands; | ||||
| using Discord.WebSocket; | ||||
| using NadekoBot.Services; | ||||
| using NadekoBot.Services.Impl; | ||||
| using NLog; | ||||
| using NLog.Config; | ||||
| using NLog.Targets; | ||||
| using System; | ||||
| using System.Linq; | ||||
| using System.Reflection; | ||||
| @@ -12,6 +15,8 @@ namespace NadekoBot | ||||
| { | ||||
|     public class NadekoBot | ||||
|     { | ||||
|         private Logger _log; | ||||
|  | ||||
|         public static CommandService Commands { get; private set; } | ||||
|         public static DiscordSocketClient Client { get; private set; } | ||||
|         public static BotConfiguration Config { get; private set; } | ||||
| @@ -19,9 +24,12 @@ namespace NadekoBot | ||||
|         public static BotCredentials Credentials { get; private set; } | ||||
|  | ||||
|         private static YoutubeService Youtube { get; set; } | ||||
|         public static StatsService Stats { get; private set; } | ||||
|  | ||||
|         public async Task RunAsync(string[] args) | ||||
|         { | ||||
|             SetupLogger(); | ||||
|  | ||||
|             //create client | ||||
|             Client = new DiscordSocketClient(new DiscordSocketConfig | ||||
|             { | ||||
| @@ -37,7 +45,9 @@ namespace NadekoBot | ||||
|             Config = new BotConfiguration(); | ||||
|             Localizer = new Localization(); | ||||
|             Youtube = new YoutubeService(); | ||||
|                          | ||||
|             Stats = new StatsService(Client); | ||||
|             _log = LogManager.GetCurrentClassLogger(); | ||||
|  | ||||
|             //setup DI | ||||
|             var depMap = new DependencyMap(); | ||||
|             depMap.Add<ILocalization>(Localizer); | ||||
| @@ -47,23 +57,56 @@ namespace NadekoBot | ||||
|             depMap.Add<IYoutubeService>(Youtube); | ||||
|  | ||||
|             //connect | ||||
|             await Client.LoginAsync(TokenType.Bot, "MTE5Nzc3MDIxMzE5NTc3NjEw.CpGoCA.yQBJbLWurrjSk7IlGpGzBm-tPTg"); | ||||
|             await Client.LoginAsync(TokenType.Bot, "MTE5Nzc3MDIxMzE5NTc3NjEw.CpdrFA.0rex01uCrn9dBTJOV2tXwMLo0wE"); | ||||
|             await Client.ConnectAsync(); | ||||
|              | ||||
|  | ||||
|             _log.Info("Connected"); | ||||
|  | ||||
|             //load commands | ||||
|             await Commands.LoadAssembly(Assembly.GetEntryAssembly(), depMap); | ||||
|             Client.MessageReceived += Client_MessageReceived; | ||||
|  | ||||
|             Console.WriteLine(Commands.Commands.Count()); | ||||
|             Console.WriteLine(await Stats.Print()); | ||||
|  | ||||
|             await Task.Delay(-1); | ||||
|         } | ||||
|  | ||||
|         private async Task Client_MessageReceived(IMessage arg) | ||||
|         private void SetupLogger() | ||||
|         { | ||||
|                 var t = await Commands.Execute(arg, 0); | ||||
|                 if(!t.IsSuccess && t.Error != CommandError.UnknownCommand) | ||||
|                     Console.WriteLine(t.ErrorReason); | ||||
|             try | ||||
|             { | ||||
|                 var logConfig = new LoggingConfiguration(); | ||||
|                 var consoleTarget = new ColoredConsoleTarget(); | ||||
|  | ||||
|                 consoleTarget.Layout = @"${date:format=HH\:mm\:ss} ${logger} | ${message}"; | ||||
|  | ||||
|                 logConfig.AddTarget("Console", consoleTarget); | ||||
|  | ||||
|                 logConfig.LoggingRules.Add(new LoggingRule("*", LogLevel.Debug, consoleTarget)); | ||||
|  | ||||
|                 LogManager.Configuration = logConfig; | ||||
|             } | ||||
|             catch (Exception ex) { | ||||
|                 Console.WriteLine(ex); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         private Task Client_MessageReceived(IMessage imsg) | ||||
|         { | ||||
|             var throwaway = Task.Run(async () => | ||||
|             { | ||||
|                 var t = await Commands.Execute(imsg, imsg.Content); | ||||
|                 if (t.IsSuccess) | ||||
|                 { | ||||
|                     _log.Info("Command Executed\n\tFull Message: {0}",imsg.Content); | ||||
|                 } | ||||
|                 else if (!t.IsSuccess && t.Error != CommandError.UnknownCommand) | ||||
|                 { | ||||
|                     _log.Warn("Command errored!\n\tFull Message: {0}\n\tError:{1}", imsg.Content, t.Error); | ||||
|                 } | ||||
|             }); | ||||
|  | ||||
|             return Task.CompletedTask; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
							
								
								
									
										15
									
								
								src/NadekoBot/Services/IStatsService.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/NadekoBot/Services/IStatsService.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| using Discord.WebSocket; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using System.Threading.Tasks; | ||||
|  | ||||
| namespace NadekoBot.Services | ||||
| { | ||||
|     public interface IStatsService | ||||
|     { | ||||
|         Task<string> Print(); | ||||
|         Task Reset(); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										58
									
								
								src/NadekoBot/Services/Impl/StatsService.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								src/NadekoBot/Services/Impl/StatsService.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,58 @@ | ||||
| using Discord; | ||||
| using Discord.WebSocket; | ||||
| using NadekoBot.Extensions; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Diagnostics; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using System.Threading.Tasks; | ||||
|  | ||||
| namespace NadekoBot.Services.Impl | ||||
| { | ||||
|     public class StatsService : IStatsService | ||||
|     { | ||||
|         private int messageCounter; | ||||
|         private DiscordSocketClient client; | ||||
|         private DateTime started; | ||||
|  | ||||
|         public string BotVersion => "1.0-alpha"; | ||||
|  | ||||
|         public string Heap => Math.Round((double)GC.GetTotalMemory(false) / 1.MiB(), 2).ToString(); | ||||
|  | ||||
|  | ||||
|         public StatsService(DiscordSocketClient client) | ||||
|         { | ||||
|  | ||||
|             this.client = client; | ||||
|  | ||||
|             Reset(); | ||||
|             this.client.MessageReceived += _ => Task.FromResult(messageCounter++); | ||||
|  | ||||
|             this.client.Disconnected += _ => Reset(); | ||||
|         } | ||||
|         public Task<string> Print() => Task.FromResult($@"`Author: Kwoth` `Library: Discord.Net` | ||||
| `Bot Version: {BotVersion}` | ||||
| `Bot id: {(client.GetCurrentUser()).Id}` | ||||
| `Owners' Ids:` | ||||
| `Uptime: {GetUptimeString()}` | ||||
| `Servers: {client.GetGuilds().Count} | TextChannels: {client.GetGuilds().SelectMany(g => g.GetChannels().Where(c => c is ITextChannel)).Count()} | VoiceChannels: {client.GetGuilds().SelectMany(g => g.GetChannels().Where(c => c is IVoiceChannel)).Count()}` | ||||
| `Messages: {messageCounter} ({messageCounter / (double)GetUptime().TotalSeconds:F2}/sec)` `Heap: {Heap} MB`"); | ||||
|  | ||||
|         public Task Reset() | ||||
|         { | ||||
|             messageCounter = 0; | ||||
|             started = DateTime.Now; | ||||
|             return Task.CompletedTask; | ||||
|         } | ||||
|  | ||||
|         public TimeSpan GetUptime() => | ||||
|             DateTime.Now - started; | ||||
|  | ||||
|         public string GetUptimeString() | ||||
|         { | ||||
|             var time = GetUptime(); | ||||
|             return time.Days + " days, " + time.Hours + " hours, and " + time.Minutes + " minutes."; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -19,7 +19,8 @@ | ||||
|     "Discord.Net.Commands": "1.0.0-dev", | ||||
|     "System.Resources.ResourceWriter": "4.0.0-beta-22816", | ||||
|     "Google.Apis.YouTube.v3": "1.15.0.582", | ||||
|     "System.Diagnostics.Contracts": "4.0.1" | ||||
|     "System.Diagnostics.Contracts": "4.0.1", | ||||
|     "NLog": "4.4.0-betaV15" | ||||
|   }, | ||||
|  | ||||
|   "frameworks": { | ||||
|   | ||||
| @@ -339,7 +339,7 @@ | ||||
|       "Microsoft.NETCore.Jit/1.0.2": { | ||||
|         "type": "package" | ||||
|       }, | ||||
|       "Microsoft.NETCore.Platforms/1.0.1": { | ||||
|       "Microsoft.NETCore.Platforms/1.0.2-beta-24410-01": { | ||||
|         "type": "package", | ||||
|         "compile": { | ||||
|           "lib/netstandard1.0/_._": {} | ||||
| @@ -513,6 +513,33 @@ | ||||
|           "lib/netstandard1.0/Newtonsoft.Json.dll": {} | ||||
|         } | ||||
|       }, | ||||
|       "NLog/4.4.0-betav15": { | ||||
|         "type": "package", | ||||
|         "dependencies": { | ||||
|           "Microsoft.Extensions.PlatformAbstractions": "1.0.0", | ||||
|           "NETStandard.Library": "1.6.0", | ||||
|           "System.Collections.NonGeneric": "4.0.1", | ||||
|           "System.ComponentModel.TypeConverter": "4.1.0", | ||||
|           "System.Data.Common": "4.1.0", | ||||
|           "System.Diagnostics.Contracts": "4.0.1", | ||||
|           "System.Diagnostics.StackTrace": "4.0.1", | ||||
|           "System.Diagnostics.TraceSource": "4.0.0", | ||||
|           "System.IO.FileSystem.Watcher": "4.0.0", | ||||
|           "System.Net.NameResolution": "4.0.0", | ||||
|           "System.Net.Requests": "4.0.11", | ||||
|           "System.Reflection.TypeExtensions": "4.1.0", | ||||
|           "System.Runtime.Serialization.Primitives": "4.1.1", | ||||
|           "System.Threading.Thread": "4.0.0", | ||||
|           "System.Threading.ThreadPool": "4.0.10", | ||||
|           "System.Xml.XmlDocument": "4.0.1" | ||||
|         }, | ||||
|         "compile": { | ||||
|           "lib/netstandard1.5/NLog.dll": {} | ||||
|         }, | ||||
|         "runtime": { | ||||
|           "lib/netstandard1.5/NLog.dll": {} | ||||
|         } | ||||
|       }, | ||||
|       "Portable.BouncyCastle/1.8.1.1": { | ||||
|         "type": "package", | ||||
|         "dependencies": { | ||||
| @@ -628,7 +655,7 @@ | ||||
|           "lib/netstandard1.1/System.Buffers.dll": {} | ||||
|         }, | ||||
|         "runtime": { | ||||
|           "lib/netstandard1.1/_._": {} | ||||
|           "lib/netstandard1.1/System.Buffers.dll": {} | ||||
|         } | ||||
|       }, | ||||
|       "System.Collections/4.0.11": { | ||||
| @@ -682,6 +709,41 @@ | ||||
|           "lib/netstandard1.0/System.Collections.Immutable.dll": {} | ||||
|         } | ||||
|       }, | ||||
|       "System.Collections.NonGeneric/4.0.1": { | ||||
|         "type": "package", | ||||
|         "dependencies": { | ||||
|           "System.Diagnostics.Debug": "4.0.11", | ||||
|           "System.Globalization": "4.0.11", | ||||
|           "System.Resources.ResourceManager": "4.0.1", | ||||
|           "System.Runtime": "4.1.0", | ||||
|           "System.Runtime.Extensions": "4.1.0", | ||||
|           "System.Threading": "4.0.11" | ||||
|         }, | ||||
|         "compile": { | ||||
|           "ref/netstandard1.3/System.Collections.NonGeneric.dll": {} | ||||
|         }, | ||||
|         "runtime": { | ||||
|           "lib/netstandard1.3/System.Collections.NonGeneric.dll": {} | ||||
|         } | ||||
|       }, | ||||
|       "System.Collections.Specialized/4.0.1": { | ||||
|         "type": "package", | ||||
|         "dependencies": { | ||||
|           "System.Collections.NonGeneric": "4.0.1", | ||||
|           "System.Globalization": "4.0.11", | ||||
|           "System.Globalization.Extensions": "4.0.1", | ||||
|           "System.Resources.ResourceManager": "4.0.1", | ||||
|           "System.Runtime": "4.1.0", | ||||
|           "System.Runtime.Extensions": "4.1.0", | ||||
|           "System.Threading": "4.0.11" | ||||
|         }, | ||||
|         "compile": { | ||||
|           "ref/netstandard1.3/_._": {} | ||||
|         }, | ||||
|         "runtime": { | ||||
|           "lib/netstandard1.3/System.Collections.Specialized.dll": {} | ||||
|         } | ||||
|       }, | ||||
|       "System.ComponentModel/4.0.1": { | ||||
|         "type": "package", | ||||
|         "dependencies": { | ||||
| @@ -716,6 +778,46 @@ | ||||
|           "lib/netstandard1.4/_._": {} | ||||
|         } | ||||
|       }, | ||||
|       "System.ComponentModel.Primitives/4.1.0": { | ||||
|         "type": "package", | ||||
|         "dependencies": { | ||||
|           "System.ComponentModel": "4.0.1", | ||||
|           "System.Resources.ResourceManager": "4.0.1", | ||||
|           "System.Runtime": "4.1.0" | ||||
|         }, | ||||
|         "compile": { | ||||
|           "ref/netstandard1.0/System.ComponentModel.Primitives.dll": {} | ||||
|         }, | ||||
|         "runtime": { | ||||
|           "lib/netstandard1.0/System.ComponentModel.Primitives.dll": {} | ||||
|         } | ||||
|       }, | ||||
|       "System.ComponentModel.TypeConverter/4.1.0": { | ||||
|         "type": "package", | ||||
|         "dependencies": { | ||||
|           "System.Collections": "4.0.11", | ||||
|           "System.Collections.NonGeneric": "4.0.1", | ||||
|           "System.Collections.Specialized": "4.0.1", | ||||
|           "System.ComponentModel": "4.0.1", | ||||
|           "System.ComponentModel.Primitives": "4.1.0", | ||||
|           "System.Globalization": "4.0.11", | ||||
|           "System.Linq": "4.1.0", | ||||
|           "System.Reflection": "4.1.0", | ||||
|           "System.Reflection.Extensions": "4.0.1", | ||||
|           "System.Reflection.Primitives": "4.0.1", | ||||
|           "System.Reflection.TypeExtensions": "4.1.0", | ||||
|           "System.Resources.ResourceManager": "4.0.1", | ||||
|           "System.Runtime": "4.1.0", | ||||
|           "System.Runtime.Extensions": "4.1.0", | ||||
|           "System.Threading": "4.0.11" | ||||
|         }, | ||||
|         "compile": { | ||||
|           "ref/netstandard1.5/System.ComponentModel.TypeConverter.dll": {} | ||||
|         }, | ||||
|         "runtime": { | ||||
|           "lib/netstandard1.5/System.ComponentModel.TypeConverter.dll": {} | ||||
|         } | ||||
|       }, | ||||
|       "System.Console/4.0.0": { | ||||
|         "type": "package", | ||||
|         "dependencies": { | ||||
| @@ -729,6 +831,25 @@ | ||||
|           "ref/netstandard1.3/System.Console.dll": {} | ||||
|         } | ||||
|       }, | ||||
|       "System.Data.Common/4.1.0": { | ||||
|         "type": "package", | ||||
|         "dependencies": { | ||||
|           "System.Collections": "4.0.11", | ||||
|           "System.Globalization": "4.0.11", | ||||
|           "System.IO": "4.1.0", | ||||
|           "System.Resources.ResourceManager": "4.0.1", | ||||
|           "System.Runtime": "4.1.0", | ||||
|           "System.Runtime.Extensions": "4.1.0", | ||||
|           "System.Text.RegularExpressions": "4.1.0", | ||||
|           "System.Threading.Tasks": "4.0.11" | ||||
|         }, | ||||
|         "compile": { | ||||
|           "ref/netstandard1.2/System.Data.Common.dll": {} | ||||
|         }, | ||||
|         "runtime": { | ||||
|           "lib/netstandard1.2/System.Data.Common.dll": {} | ||||
|         } | ||||
|       }, | ||||
|       "System.Diagnostics.Contracts/4.0.1": { | ||||
|         "type": "package", | ||||
|         "dependencies": { | ||||
| @@ -845,10 +966,10 @@ | ||||
|           "System.Runtime.Extensions": "4.1.0" | ||||
|         }, | ||||
|         "compile": { | ||||
|           "ref/netstandard1.3/_._": {} | ||||
|           "ref/netstandard1.3/System.Diagnostics.StackTrace.dll": {} | ||||
|         }, | ||||
|         "runtime": { | ||||
|           "lib/netstandard1.3/_._": {} | ||||
|           "lib/netstandard1.3/System.Diagnostics.StackTrace.dll": {} | ||||
|         } | ||||
|       }, | ||||
|       "System.Diagnostics.Tools/4.0.1": { | ||||
| @@ -862,6 +983,33 @@ | ||||
|           "ref/netstandard1.0/System.Diagnostics.Tools.dll": {} | ||||
|         } | ||||
|       }, | ||||
|       "System.Diagnostics.TraceSource/4.0.0": { | ||||
|         "type": "package", | ||||
|         "dependencies": { | ||||
|           "Microsoft.NETCore.Platforms": "1.0.1", | ||||
|           "System.Collections": "4.0.11", | ||||
|           "System.Diagnostics.Debug": "4.0.11", | ||||
|           "System.Globalization": "4.0.11", | ||||
|           "System.Resources.ResourceManager": "4.0.1", | ||||
|           "System.Runtime": "4.1.0", | ||||
|           "System.Runtime.Extensions": "4.1.0", | ||||
|           "System.Threading": "4.0.11", | ||||
|           "runtime.native.System": "4.0.0" | ||||
|         }, | ||||
|         "compile": { | ||||
|           "ref/netstandard1.3/System.Diagnostics.TraceSource.dll": {} | ||||
|         }, | ||||
|         "runtimeTargets": { | ||||
|           "runtimes/unix/lib/netstandard1.3/System.Diagnostics.TraceSource.dll": { | ||||
|             "assetType": "runtime", | ||||
|             "rid": "unix" | ||||
|           }, | ||||
|           "runtimes/win/lib/netstandard1.3/System.Diagnostics.TraceSource.dll": { | ||||
|             "assetType": "runtime", | ||||
|             "rid": "win" | ||||
|           } | ||||
|         } | ||||
|       }, | ||||
|       "System.Diagnostics.Tracing/4.1.0": { | ||||
|         "type": "package", | ||||
|         "dependencies": { | ||||
| @@ -1008,7 +1156,7 @@ | ||||
|           "ref/netstandard1.3/System.IO.Compression.ZipFile.dll": {} | ||||
|         }, | ||||
|         "runtime": { | ||||
|           "lib/netstandard1.3/_._": {} | ||||
|           "lib/netstandard1.3/System.IO.Compression.ZipFile.dll": {} | ||||
|         } | ||||
|       }, | ||||
|       "System.IO.FileSystem/4.0.1": { | ||||
| @@ -1063,9 +1211,17 @@ | ||||
|           "ref/netstandard1.3/System.IO.FileSystem.Watcher.dll": {} | ||||
|         }, | ||||
|         "runtimeTargets": { | ||||
|           "runtimes/osx/lib/netstandard1.3/_._": { | ||||
|           "runtimes/linux/lib/netstandard1.3/System.IO.FileSystem.Watcher.dll": { | ||||
|             "assetType": "runtime", | ||||
|             "rid": "linux" | ||||
|           }, | ||||
|           "runtimes/osx/lib/netstandard1.3/System.IO.FileSystem.Watcher.dll": { | ||||
|             "assetType": "runtime", | ||||
|             "rid": "osx" | ||||
|           }, | ||||
|           "runtimes/win/lib/netstandard1.3/System.IO.FileSystem.Watcher.dll": { | ||||
|             "assetType": "runtime", | ||||
|             "rid": "win" | ||||
|           } | ||||
|         } | ||||
|       }, | ||||
| @@ -1353,7 +1509,11 @@ | ||||
|           "ref/netstandard1.3/System.Net.Security.dll": {} | ||||
|         }, | ||||
|         "runtimeTargets": { | ||||
|           "runtimes/win/lib/netstandard1.3/_._": { | ||||
|           "runtimes/unix/lib/netstandard1.6/System.Net.Security.dll": { | ||||
|             "assetType": "runtime", | ||||
|             "rid": "unix" | ||||
|           }, | ||||
|           "runtimes/win/lib/netstandard1.3/System.Net.Security.dll": { | ||||
|             "assetType": "runtime", | ||||
|             "rid": "win" | ||||
|           } | ||||
| @@ -1403,16 +1563,20 @@ | ||||
|           "lib/netstandard1.3/System.Net.WebSockets.dll": {} | ||||
|         } | ||||
|       }, | ||||
|       "System.Net.WebSockets.Client/4.0.0": { | ||||
|       "System.Net.WebSockets.Client/4.0.1-beta-24410-01": { | ||||
|         "type": "package", | ||||
|         "dependencies": { | ||||
|           "Microsoft.NETCore.Platforms": "1.0.1", | ||||
|           "Microsoft.NETCore.Platforms": "1.0.2-beta-24410-01", | ||||
|           "Microsoft.Win32.Primitives": "4.0.1", | ||||
|           "System.Collections": "4.0.11", | ||||
|           "System.Diagnostics.Debug": "4.0.11", | ||||
|           "System.Diagnostics.Tracing": "4.1.0", | ||||
|           "System.Globalization": "4.0.11", | ||||
|           "System.IO": "4.1.0", | ||||
|           "System.Net.NameResolution": "4.0.0", | ||||
|           "System.Net.Primitives": "4.0.11", | ||||
|           "System.Net.Security": "4.0.0", | ||||
|           "System.Net.Sockets": "4.1.0", | ||||
|           "System.Net.WebHeaderCollection": "4.0.1", | ||||
|           "System.Net.WebSockets": "4.0.0", | ||||
|           "System.Resources.ResourceManager": "4.0.1", | ||||
| @@ -1420,10 +1584,14 @@ | ||||
|           "System.Runtime.Extensions": "4.1.0", | ||||
|           "System.Runtime.Handles": "4.0.1", | ||||
|           "System.Runtime.InteropServices": "4.1.0", | ||||
|           "System.Security.Cryptography.Algorithms": "4.2.0", | ||||
|           "System.Security.Cryptography.Primitives": "4.0.0", | ||||
|           "System.Security.Cryptography.X509Certificates": "4.1.0", | ||||
|           "System.Text.Encoding": "4.0.11", | ||||
|           "System.Text.Encoding.Extensions": "4.0.11", | ||||
|           "System.Threading": "4.0.11", | ||||
|           "System.Threading.Tasks": "4.0.11" | ||||
|           "System.Threading.Tasks": "4.0.11", | ||||
|           "System.Threading.Timer": "4.0.1" | ||||
|         }, | ||||
|         "compile": { | ||||
|           "ref/netstandard1.3/System.Net.WebSockets.Client.dll": {} | ||||
| @@ -1584,7 +1752,7 @@ | ||||
|           "lib/netstandard1.1/System.Reflection.Metadata.dll": {} | ||||
|         }, | ||||
|         "runtime": { | ||||
|           "lib/netstandard1.1/_._": {} | ||||
|           "lib/netstandard1.1/System.Reflection.Metadata.dll": {} | ||||
|         } | ||||
|       }, | ||||
|       "System.Reflection.Primitives/4.0.1": { | ||||
| @@ -2131,7 +2299,11 @@ | ||||
|           "ref/netstandard1.3/_._": {} | ||||
|         }, | ||||
|         "runtimeTargets": { | ||||
|           "runtimes/win/lib/netstandard1.3/_._": { | ||||
|           "runtimes/unix/lib/netstandard1.3/System.Threading.Overlapped.dll": { | ||||
|             "assetType": "runtime", | ||||
|             "rid": "unix" | ||||
|           }, | ||||
|           "runtimes/win/lib/netstandard1.3/System.Threading.Overlapped.dll": { | ||||
|             "assetType": "runtime", | ||||
|             "rid": "win" | ||||
|           } | ||||
| @@ -2303,10 +2475,10 @@ | ||||
|           "System.Xml.ReaderWriter": "4.0.11" | ||||
|         }, | ||||
|         "compile": { | ||||
|           "ref/netstandard1.3/_._": {} | ||||
|           "ref/netstandard1.3/System.Xml.XmlDocument.dll": {} | ||||
|         }, | ||||
|         "runtime": { | ||||
|           "lib/netstandard1.3/_._": {} | ||||
|           "lib/netstandard1.3/System.Xml.XmlDocument.dll": {} | ||||
|         } | ||||
|       }, | ||||
|       "System.Xml.XPath/4.0.1": { | ||||
| @@ -2362,7 +2534,7 @@ | ||||
|           "System.Net.Http": "4.1.0", | ||||
|           "System.Net.NameResolution": "4.0.0", | ||||
|           "System.Net.Sockets": "4.1.0", | ||||
|           "System.Net.WebSockets.Client": "4.0.0", | ||||
|           "System.Net.WebSockets.Client": "4.0.1-beta-24410-01", | ||||
|           "System.Reflection.Extensions": "4.0.1", | ||||
|           "System.Runtime.InteropServices": "4.1.0", | ||||
|           "System.Runtime.InteropServices.RuntimeInformation": "4.0.0", | ||||
| @@ -2746,12 +2918,12 @@ | ||||
|         "runtime.json" | ||||
|       ] | ||||
|     }, | ||||
|     "Microsoft.NETCore.Platforms/1.0.1": { | ||||
|       "sha512": "2G6OjjJzwBfNOO8myRV/nFrbTw5iA+DEm0N+qUqhrOmaVtn4pC77h38I1jsXGw5VH55+dPfQsqHD0We9sCl9FQ==", | ||||
|     "Microsoft.NETCore.Platforms/1.0.2-beta-24410-01": { | ||||
|       "sha512": "uc/pGYdE4sVy3OovFF8hg79MvCxptzICxn0jdA6WusGWZa7VieqFoZYc+a6bHUVhMI0s/7SfBriux0RUq+PpbA==", | ||||
|       "type": "package", | ||||
|       "path": "Microsoft.NETCore.Platforms/1.0.1", | ||||
|       "path": "Microsoft.NETCore.Platforms/1.0.2-beta-24410-01", | ||||
|       "files": [ | ||||
|         "Microsoft.NETCore.Platforms.1.0.1.nupkg.sha512", | ||||
|         "Microsoft.NETCore.Platforms.1.0.2-beta-24410-01.nupkg.sha512", | ||||
|         "Microsoft.NETCore.Platforms.nuspec", | ||||
|         "ThirdPartyNotices.txt", | ||||
|         "dotnet_library_license.txt", | ||||
| @@ -2938,6 +3110,35 @@ | ||||
|         "tools/install.ps1" | ||||
|       ] | ||||
|     }, | ||||
|     "NLog/4.4.0-betav15": { | ||||
|       "sha512": "LDRcdjv5VG9EWz+mnFqdSolUci+j+DBPIPjm7Xdam3xa1F9Rt7o0UpYoCnNRulqHzpKbU704o7Ad4ck9WxDhnw==", | ||||
|       "type": "package", | ||||
|       "path": "NLog/4.4.0-betav15", | ||||
|       "files": [ | ||||
|         "NLog.4.4.0-betav15.nupkg.sha512", | ||||
|         "NLog.nuspec", | ||||
|         "lib/monoandroid23/NLog.dll", | ||||
|         "lib/monoandroid23/NLog.xml", | ||||
|         "lib/net35/NLog.dll", | ||||
|         "lib/net35/NLog.xml", | ||||
|         "lib/net40/NLog.dll", | ||||
|         "lib/net40/NLog.xml", | ||||
|         "lib/net45/NLog.dll", | ||||
|         "lib/net45/NLog.xml", | ||||
|         "lib/netstandard1.3/NLog.dll", | ||||
|         "lib/netstandard1.3/NLog.xml", | ||||
|         "lib/netstandard1.5/NLog.dll", | ||||
|         "lib/netstandard1.5/NLog.xml", | ||||
|         "lib/sl40/NLog.dll", | ||||
|         "lib/sl40/NLog.xml", | ||||
|         "lib/sl50/NLog.dll", | ||||
|         "lib/sl50/NLog.xml", | ||||
|         "lib/wp80/NLog.dll", | ||||
|         "lib/wp80/NLog.xml", | ||||
|         "lib/xamarinios10/NLog.dll", | ||||
|         "lib/xamarinios10/NLog.xml" | ||||
|       ] | ||||
|     }, | ||||
|     "Portable.BouncyCastle/1.8.1.1": { | ||||
|       "sha512": "bKqC2Me9ukybNYTBhlYd2sJ6j2kRV7SgB+JfiP2GueYq6QdM4Ym6PYV5eyrqb6KViOyd3zqQfJp0o6UW5ZG+GQ==", | ||||
|       "type": "package", | ||||
| @@ -3230,6 +3431,80 @@ | ||||
|         "lib/portable-net45+win8+wp8+wpa81/System.Collections.Immutable.xml" | ||||
|       ] | ||||
|     }, | ||||
|     "System.Collections.NonGeneric/4.0.1": { | ||||
|       "sha512": "hMxFT2RhhlffyCdKLDXjx8WEC5JfCvNozAZxCablAuFRH74SCV4AgzE8yJCh/73bFnEoZgJ9MJmkjQ0dJmnKqA==", | ||||
|       "type": "package", | ||||
|       "path": "System.Collections.NonGeneric/4.0.1", | ||||
|       "files": [ | ||||
|         "System.Collections.NonGeneric.4.0.1.nupkg.sha512", | ||||
|         "System.Collections.NonGeneric.nuspec", | ||||
|         "ThirdPartyNotices.txt", | ||||
|         "dotnet_library_license.txt", | ||||
|         "lib/MonoAndroid10/_._", | ||||
|         "lib/MonoTouch10/_._", | ||||
|         "lib/net46/System.Collections.NonGeneric.dll", | ||||
|         "lib/netstandard1.3/System.Collections.NonGeneric.dll", | ||||
|         "lib/xamarinios10/_._", | ||||
|         "lib/xamarinmac20/_._", | ||||
|         "lib/xamarintvos10/_._", | ||||
|         "lib/xamarinwatchos10/_._", | ||||
|         "ref/MonoAndroid10/_._", | ||||
|         "ref/MonoTouch10/_._", | ||||
|         "ref/net46/System.Collections.NonGeneric.dll", | ||||
|         "ref/netstandard1.3/System.Collections.NonGeneric.dll", | ||||
|         "ref/netstandard1.3/System.Collections.NonGeneric.xml", | ||||
|         "ref/netstandard1.3/de/System.Collections.NonGeneric.xml", | ||||
|         "ref/netstandard1.3/es/System.Collections.NonGeneric.xml", | ||||
|         "ref/netstandard1.3/fr/System.Collections.NonGeneric.xml", | ||||
|         "ref/netstandard1.3/it/System.Collections.NonGeneric.xml", | ||||
|         "ref/netstandard1.3/ja/System.Collections.NonGeneric.xml", | ||||
|         "ref/netstandard1.3/ko/System.Collections.NonGeneric.xml", | ||||
|         "ref/netstandard1.3/ru/System.Collections.NonGeneric.xml", | ||||
|         "ref/netstandard1.3/zh-hans/System.Collections.NonGeneric.xml", | ||||
|         "ref/netstandard1.3/zh-hant/System.Collections.NonGeneric.xml", | ||||
|         "ref/xamarinios10/_._", | ||||
|         "ref/xamarinmac20/_._", | ||||
|         "ref/xamarintvos10/_._", | ||||
|         "ref/xamarinwatchos10/_._" | ||||
|       ] | ||||
|     }, | ||||
|     "System.Collections.Specialized/4.0.1": { | ||||
|       "sha512": "/HKQyVP0yH1I0YtK7KJL/28snxHNH/bi+0lgk/+MbURF6ULhAE31MDI+NZDerNWu264YbxklXCCygISgm+HMug==", | ||||
|       "type": "package", | ||||
|       "path": "System.Collections.Specialized/4.0.1", | ||||
|       "files": [ | ||||
|         "System.Collections.Specialized.4.0.1.nupkg.sha512", | ||||
|         "System.Collections.Specialized.nuspec", | ||||
|         "ThirdPartyNotices.txt", | ||||
|         "dotnet_library_license.txt", | ||||
|         "lib/MonoAndroid10/_._", | ||||
|         "lib/MonoTouch10/_._", | ||||
|         "lib/net46/System.Collections.Specialized.dll", | ||||
|         "lib/netstandard1.3/System.Collections.Specialized.dll", | ||||
|         "lib/xamarinios10/_._", | ||||
|         "lib/xamarinmac20/_._", | ||||
|         "lib/xamarintvos10/_._", | ||||
|         "lib/xamarinwatchos10/_._", | ||||
|         "ref/MonoAndroid10/_._", | ||||
|         "ref/MonoTouch10/_._", | ||||
|         "ref/net46/System.Collections.Specialized.dll", | ||||
|         "ref/netstandard1.3/System.Collections.Specialized.dll", | ||||
|         "ref/netstandard1.3/System.Collections.Specialized.xml", | ||||
|         "ref/netstandard1.3/de/System.Collections.Specialized.xml", | ||||
|         "ref/netstandard1.3/es/System.Collections.Specialized.xml", | ||||
|         "ref/netstandard1.3/fr/System.Collections.Specialized.xml", | ||||
|         "ref/netstandard1.3/it/System.Collections.Specialized.xml", | ||||
|         "ref/netstandard1.3/ja/System.Collections.Specialized.xml", | ||||
|         "ref/netstandard1.3/ko/System.Collections.Specialized.xml", | ||||
|         "ref/netstandard1.3/ru/System.Collections.Specialized.xml", | ||||
|         "ref/netstandard1.3/zh-hans/System.Collections.Specialized.xml", | ||||
|         "ref/netstandard1.3/zh-hant/System.Collections.Specialized.xml", | ||||
|         "ref/xamarinios10/_._", | ||||
|         "ref/xamarinmac20/_._", | ||||
|         "ref/xamarintvos10/_._", | ||||
|         "ref/xamarinwatchos10/_._" | ||||
|       ] | ||||
|     }, | ||||
|     "System.ComponentModel/4.0.1": { | ||||
|       "sha512": "oBZFnm7seFiVfugsIyOvQCWobNZs7FzqDV/B7tx20Ep/l3UUFCPDkdTnCNaJZTU27zjeODmy2C/cP60u3D4c9w==", | ||||
|       "type": "package", | ||||
| @@ -3364,6 +3639,94 @@ | ||||
|         "ref/xamarinwatchos10/_._" | ||||
|       ] | ||||
|     }, | ||||
|     "System.ComponentModel.Primitives/4.1.0": { | ||||
|       "sha512": "sc/7eVCdxPrp3ljpgTKVaQGUXiW05phNWvtv/m2kocXqrUQvTVWKou1Edas2aDjTThLPZOxPYIGNb/HN0QjURg==", | ||||
|       "type": "package", | ||||
|       "path": "System.ComponentModel.Primitives/4.1.0", | ||||
|       "files": [ | ||||
|         "System.ComponentModel.Primitives.4.1.0.nupkg.sha512", | ||||
|         "System.ComponentModel.Primitives.nuspec", | ||||
|         "ThirdPartyNotices.txt", | ||||
|         "dotnet_library_license.txt", | ||||
|         "lib/MonoAndroid10/_._", | ||||
|         "lib/MonoTouch10/_._", | ||||
|         "lib/net45/System.ComponentModel.Primitives.dll", | ||||
|         "lib/netstandard1.0/System.ComponentModel.Primitives.dll", | ||||
|         "lib/xamarinios10/_._", | ||||
|         "lib/xamarinmac20/_._", | ||||
|         "lib/xamarintvos10/_._", | ||||
|         "lib/xamarinwatchos10/_._", | ||||
|         "ref/MonoAndroid10/_._", | ||||
|         "ref/MonoTouch10/_._", | ||||
|         "ref/net45/System.ComponentModel.Primitives.dll", | ||||
|         "ref/netstandard1.0/System.ComponentModel.Primitives.dll", | ||||
|         "ref/netstandard1.0/System.ComponentModel.Primitives.xml", | ||||
|         "ref/netstandard1.0/de/System.ComponentModel.Primitives.xml", | ||||
|         "ref/netstandard1.0/es/System.ComponentModel.Primitives.xml", | ||||
|         "ref/netstandard1.0/fr/System.ComponentModel.Primitives.xml", | ||||
|         "ref/netstandard1.0/it/System.ComponentModel.Primitives.xml", | ||||
|         "ref/netstandard1.0/ja/System.ComponentModel.Primitives.xml", | ||||
|         "ref/netstandard1.0/ko/System.ComponentModel.Primitives.xml", | ||||
|         "ref/netstandard1.0/ru/System.ComponentModel.Primitives.xml", | ||||
|         "ref/netstandard1.0/zh-hans/System.ComponentModel.Primitives.xml", | ||||
|         "ref/netstandard1.0/zh-hant/System.ComponentModel.Primitives.xml", | ||||
|         "ref/xamarinios10/_._", | ||||
|         "ref/xamarinmac20/_._", | ||||
|         "ref/xamarintvos10/_._", | ||||
|         "ref/xamarinwatchos10/_._" | ||||
|       ] | ||||
|     }, | ||||
|     "System.ComponentModel.TypeConverter/4.1.0": { | ||||
|       "sha512": "MnDAlaeJZy9pdB5ZdOlwdxfpI+LJQ6e0hmH7d2+y2LkiD8DRJynyDYl4Xxf3fWFm7SbEwBZh4elcfzONQLOoQw==", | ||||
|       "type": "package", | ||||
|       "path": "System.ComponentModel.TypeConverter/4.1.0", | ||||
|       "files": [ | ||||
|         "System.ComponentModel.TypeConverter.4.1.0.nupkg.sha512", | ||||
|         "System.ComponentModel.TypeConverter.nuspec", | ||||
|         "ThirdPartyNotices.txt", | ||||
|         "dotnet_library_license.txt", | ||||
|         "lib/MonoAndroid10/_._", | ||||
|         "lib/MonoTouch10/_._", | ||||
|         "lib/net45/System.ComponentModel.TypeConverter.dll", | ||||
|         "lib/net462/System.ComponentModel.TypeConverter.dll", | ||||
|         "lib/netstandard1.0/System.ComponentModel.TypeConverter.dll", | ||||
|         "lib/netstandard1.5/System.ComponentModel.TypeConverter.dll", | ||||
|         "lib/xamarinios10/_._", | ||||
|         "lib/xamarinmac20/_._", | ||||
|         "lib/xamarintvos10/_._", | ||||
|         "lib/xamarinwatchos10/_._", | ||||
|         "ref/MonoAndroid10/_._", | ||||
|         "ref/MonoTouch10/_._", | ||||
|         "ref/net45/System.ComponentModel.TypeConverter.dll", | ||||
|         "ref/net462/System.ComponentModel.TypeConverter.dll", | ||||
|         "ref/netstandard1.0/System.ComponentModel.TypeConverter.dll", | ||||
|         "ref/netstandard1.0/System.ComponentModel.TypeConverter.xml", | ||||
|         "ref/netstandard1.0/de/System.ComponentModel.TypeConverter.xml", | ||||
|         "ref/netstandard1.0/es/System.ComponentModel.TypeConverter.xml", | ||||
|         "ref/netstandard1.0/fr/System.ComponentModel.TypeConverter.xml", | ||||
|         "ref/netstandard1.0/it/System.ComponentModel.TypeConverter.xml", | ||||
|         "ref/netstandard1.0/ja/System.ComponentModel.TypeConverter.xml", | ||||
|         "ref/netstandard1.0/ko/System.ComponentModel.TypeConverter.xml", | ||||
|         "ref/netstandard1.0/ru/System.ComponentModel.TypeConverter.xml", | ||||
|         "ref/netstandard1.0/zh-hans/System.ComponentModel.TypeConverter.xml", | ||||
|         "ref/netstandard1.0/zh-hant/System.ComponentModel.TypeConverter.xml", | ||||
|         "ref/netstandard1.5/System.ComponentModel.TypeConverter.dll", | ||||
|         "ref/netstandard1.5/System.ComponentModel.TypeConverter.xml", | ||||
|         "ref/netstandard1.5/de/System.ComponentModel.TypeConverter.xml", | ||||
|         "ref/netstandard1.5/es/System.ComponentModel.TypeConverter.xml", | ||||
|         "ref/netstandard1.5/fr/System.ComponentModel.TypeConverter.xml", | ||||
|         "ref/netstandard1.5/it/System.ComponentModel.TypeConverter.xml", | ||||
|         "ref/netstandard1.5/ja/System.ComponentModel.TypeConverter.xml", | ||||
|         "ref/netstandard1.5/ko/System.ComponentModel.TypeConverter.xml", | ||||
|         "ref/netstandard1.5/ru/System.ComponentModel.TypeConverter.xml", | ||||
|         "ref/netstandard1.5/zh-hans/System.ComponentModel.TypeConverter.xml", | ||||
|         "ref/netstandard1.5/zh-hant/System.ComponentModel.TypeConverter.xml", | ||||
|         "ref/xamarinios10/_._", | ||||
|         "ref/xamarinmac20/_._", | ||||
|         "ref/xamarintvos10/_._", | ||||
|         "ref/xamarinwatchos10/_._" | ||||
|       ] | ||||
|     }, | ||||
|     "System.Console/4.0.0": { | ||||
|       "sha512": "qSKUSOIiYA/a0g5XXdxFcUFmv1hNICBD7QZ0QhGYVipPIhvpiydY8VZqr1thmCXvmn8aipMg64zuanB4eotK9A==", | ||||
|       "type": "package", | ||||
| @@ -3400,6 +3763,55 @@ | ||||
|         "ref/xamarinwatchos10/_._" | ||||
|       ] | ||||
|     }, | ||||
|     "System.Data.Common/4.1.0": { | ||||
|       "sha512": "epU8jeTe7aE7RqGHq9rZ8b0Q4Ah7DgubzHQblgZMSqgW1saW868WmooSyC5ywf8upLBkcVLDu93W9GPWUYsU2Q==", | ||||
|       "type": "package", | ||||
|       "path": "System.Data.Common/4.1.0", | ||||
|       "files": [ | ||||
|         "System.Data.Common.4.1.0.nupkg.sha512", | ||||
|         "System.Data.Common.nuspec", | ||||
|         "ThirdPartyNotices.txt", | ||||
|         "dotnet_library_license.txt", | ||||
|         "lib/MonoAndroid10/_._", | ||||
|         "lib/MonoTouch10/_._", | ||||
|         "lib/net451/System.Data.Common.dll", | ||||
|         "lib/netstandard1.2/System.Data.Common.dll", | ||||
|         "lib/portable-net451+win8+wp8+wpa81/System.Data.Common.dll", | ||||
|         "lib/xamarinios10/_._", | ||||
|         "lib/xamarinmac20/_._", | ||||
|         "lib/xamarintvos10/_._", | ||||
|         "lib/xamarinwatchos10/_._", | ||||
|         "ref/MonoAndroid10/_._", | ||||
|         "ref/MonoTouch10/_._", | ||||
|         "ref/net451/System.Data.Common.dll", | ||||
|         "ref/netstandard1.2/System.Data.Common.dll", | ||||
|         "ref/netstandard1.2/System.Data.Common.xml", | ||||
|         "ref/netstandard1.2/de/System.Data.Common.xml", | ||||
|         "ref/netstandard1.2/es/System.Data.Common.xml", | ||||
|         "ref/netstandard1.2/fr/System.Data.Common.xml", | ||||
|         "ref/netstandard1.2/it/System.Data.Common.xml", | ||||
|         "ref/netstandard1.2/ja/System.Data.Common.xml", | ||||
|         "ref/netstandard1.2/ko/System.Data.Common.xml", | ||||
|         "ref/netstandard1.2/ru/System.Data.Common.xml", | ||||
|         "ref/netstandard1.2/zh-hans/System.Data.Common.xml", | ||||
|         "ref/netstandard1.2/zh-hant/System.Data.Common.xml", | ||||
|         "ref/portable-net451+win8+wp8+wpa81/System.Data.Common.dll", | ||||
|         "ref/portable-net451+win8+wp8+wpa81/System.Data.Common.xml", | ||||
|         "ref/portable-net451+win8+wp8+wpa81/de/System.Data.Common.xml", | ||||
|         "ref/portable-net451+win8+wp8+wpa81/es/System.Data.Common.xml", | ||||
|         "ref/portable-net451+win8+wp8+wpa81/fr/System.Data.Common.xml", | ||||
|         "ref/portable-net451+win8+wp8+wpa81/it/System.Data.Common.xml", | ||||
|         "ref/portable-net451+win8+wp8+wpa81/ja/System.Data.Common.xml", | ||||
|         "ref/portable-net451+win8+wp8+wpa81/ko/System.Data.Common.xml", | ||||
|         "ref/portable-net451+win8+wp8+wpa81/ru/System.Data.Common.xml", | ||||
|         "ref/portable-net451+win8+wp8+wpa81/zh-hans/System.Data.Common.xml", | ||||
|         "ref/portable-net451+win8+wp8+wpa81/zh-hant/System.Data.Common.xml", | ||||
|         "ref/xamarinios10/_._", | ||||
|         "ref/xamarinmac20/_._", | ||||
|         "ref/xamarintvos10/_._", | ||||
|         "ref/xamarinwatchos10/_._" | ||||
|       ] | ||||
|     }, | ||||
|     "System.Diagnostics.Contracts/4.0.1": { | ||||
|       "sha512": "HvQQjy712vnlpPxaloZYkuE78Gn353L0SJLJVeLcNASeg9c4qla2a1Xq8I7B3jZoDzKPtHTkyVO7AZ5tpeQGuA==", | ||||
|       "type": "package", | ||||
| @@ -3731,6 +4143,45 @@ | ||||
|         "ref/xamarinwatchos10/_._" | ||||
|       ] | ||||
|     }, | ||||
|     "System.Diagnostics.TraceSource/4.0.0": { | ||||
|       "sha512": "6WVCczFZKXwpWpzd/iJkYnsmWTSFFiU24Xx/YdHXBcu+nFI/ehTgeqdJQFbtRPzbrO3KtRNjvkhtj4t5/WwWsA==", | ||||
|       "type": "package", | ||||
|       "path": "System.Diagnostics.TraceSource/4.0.0", | ||||
|       "files": [ | ||||
|         "System.Diagnostics.TraceSource.4.0.0.nupkg.sha512", | ||||
|         "System.Diagnostics.TraceSource.nuspec", | ||||
|         "ThirdPartyNotices.txt", | ||||
|         "dotnet_library_license.txt", | ||||
|         "lib/MonoAndroid10/_._", | ||||
|         "lib/MonoTouch10/_._", | ||||
|         "lib/net46/System.Diagnostics.TraceSource.dll", | ||||
|         "lib/xamarinios10/_._", | ||||
|         "lib/xamarinmac20/_._", | ||||
|         "lib/xamarintvos10/_._", | ||||
|         "lib/xamarinwatchos10/_._", | ||||
|         "ref/MonoAndroid10/_._", | ||||
|         "ref/MonoTouch10/_._", | ||||
|         "ref/net46/System.Diagnostics.TraceSource.dll", | ||||
|         "ref/netstandard1.3/System.Diagnostics.TraceSource.dll", | ||||
|         "ref/netstandard1.3/System.Diagnostics.TraceSource.xml", | ||||
|         "ref/netstandard1.3/de/System.Diagnostics.TraceSource.xml", | ||||
|         "ref/netstandard1.3/es/System.Diagnostics.TraceSource.xml", | ||||
|         "ref/netstandard1.3/fr/System.Diagnostics.TraceSource.xml", | ||||
|         "ref/netstandard1.3/it/System.Diagnostics.TraceSource.xml", | ||||
|         "ref/netstandard1.3/ja/System.Diagnostics.TraceSource.xml", | ||||
|         "ref/netstandard1.3/ko/System.Diagnostics.TraceSource.xml", | ||||
|         "ref/netstandard1.3/ru/System.Diagnostics.TraceSource.xml", | ||||
|         "ref/netstandard1.3/zh-hans/System.Diagnostics.TraceSource.xml", | ||||
|         "ref/netstandard1.3/zh-hant/System.Diagnostics.TraceSource.xml", | ||||
|         "ref/xamarinios10/_._", | ||||
|         "ref/xamarinmac20/_._", | ||||
|         "ref/xamarintvos10/_._", | ||||
|         "ref/xamarinwatchos10/_._", | ||||
|         "runtimes/unix/lib/netstandard1.3/System.Diagnostics.TraceSource.dll", | ||||
|         "runtimes/win/lib/net46/System.Diagnostics.TraceSource.dll", | ||||
|         "runtimes/win/lib/netstandard1.3/System.Diagnostics.TraceSource.dll" | ||||
|       ] | ||||
|     }, | ||||
|     "System.Diagnostics.Tracing/4.1.0": { | ||||
|       "sha512": "vDN1PoMZCkkdNjvZLql592oYJZgS7URcJzJ7bxeBgGtx5UtR5leNm49VmfHGqIffX4FKacHbI3H6UyNSHQknBg==", | ||||
|       "type": "package", | ||||
| @@ -5097,12 +5548,12 @@ | ||||
|         "ref/xamarinwatchos10/_._" | ||||
|       ] | ||||
|     }, | ||||
|     "System.Net.WebSockets.Client/4.0.0": { | ||||
|       "sha512": "GY5h9cn0ZVsG4ORQqMytTldrqxet2RC2CSEsgWGf4XNW5jhL5SxzcUZph03xbZsgn7K3qMr+Rq+gkbJNI+FEXg==", | ||||
|     "System.Net.WebSockets.Client/4.0.1-beta-24410-01": { | ||||
|       "sha512": "IOqAcR7k+3LwNI6aL7qN61HcCOA9X4MM9LbrZhDeNbeB/IeWTk7zpeb7kh3d7H678s7ndIqN6a7okO8dAAfcYQ==", | ||||
|       "type": "package", | ||||
|       "path": "System.Net.WebSockets.Client/4.0.0", | ||||
|       "path": "System.Net.WebSockets.Client/4.0.1-beta-24410-01", | ||||
|       "files": [ | ||||
|         "System.Net.WebSockets.Client.4.0.0.nupkg.sha512", | ||||
|         "System.Net.WebSockets.Client.4.0.1-beta-24410-01.nupkg.sha512", | ||||
|         "System.Net.WebSockets.Client.nuspec", | ||||
|         "ThirdPartyNotices.txt", | ||||
|         "dotnet_library_license.txt", | ||||
| @@ -7421,6 +7872,7 @@ | ||||
|       "Microsoft.Extensions.DependencyInjection.Abstractions >= 1.0.0", | ||||
|       "Microsoft.Extensions.PlatformAbstractions >= 1.0.0", | ||||
|       "Microsoft.NETCore.App >= 1.0.0", | ||||
|       "NLog >= 4.4.0-betaV15", | ||||
|       "Newtonsoft.Json >= 9.0.1", | ||||
|       "System.Diagnostics.Contracts >= 4.0.1", | ||||
|       "System.Resources.ResourceWriter >= 4.0.0-beta-22816" | ||||
|   | ||||
		Reference in New Issue
	
	Block a user