Fixes, more stuff, .stats added?

This commit is contained in:
Kwoth 2016-08-18 23:00:54 +02:00
parent 64f7680fe7
commit 9d128f1ff3
21 changed files with 1086 additions and 506 deletions

View File

@ -16,10 +16,11 @@ using System.Text.RegularExpressions;
namespace NadekoBot.Modules.Administration namespace NadekoBot.Modules.Administration
{ {
[Module(".", AppendSpace = false)] [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 ////todo owner only
@ -188,10 +189,12 @@ namespace NadekoBot.Modules.Administration
[LocalizedCommand, LocalizedDescription, LocalizedSummary] [LocalizedCommand, LocalizedDescription, LocalizedSummary]
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]
[RequirePermission(GuildPermission.BanMembers)] [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 channel = imsg.Channel as ITextChannel;
var msg = "";
if (!string.IsNullOrWhiteSpace(msg)) if (!string.IsNullOrWhiteSpace(msg))
{ {
await (await user.CreateDMChannelAsync()).SendMessageAsync($"**You have been BANNED from `{channel.Guild.Name}` server.**\n" + 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; var channel = imsg.Channel as ITextChannel;
if (user == null)
{
await imsg.Channel.SendMessageAsync("User not found.").ConfigureAwait(false);
return;
}
if (!string.IsNullOrWhiteSpace(msg)) if (!string.IsNullOrWhiteSpace(msg))
{ {
await user.SendMessageAsync($"**You have been SOFT-BANNED from `{channel.Guild.Name}` server.**\n" + 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 await Task.Delay(2000).ConfigureAwait(false); // temp solution; give time for a message to be send, fu volt
} }
try try
@ -492,7 +490,7 @@ namespace NadekoBot.Modules.Administration
} }
} }
//todo owner only ////todo owner only
//[LocalizedCommand, LocalizedDescription, LocalizedSummary] //[LocalizedCommand, LocalizedDescription, LocalizedSummary]
//[RequireContext(ContextType.Guild)] //[RequireContext(ContextType.Guild)]
//public async Task Die(IMessage imsg) //public async Task Die(IMessage imsg)

View File

@ -1,184 +1,285 @@
using Discord; using Discord.Commands;
using Newtonsoft.Json; using NadekoBot.Classes.ClashOfClans;
using System; using System;
using System.Linq; using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Text; 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 static ConcurrentDictionary<ulong, List<ClashWar>> ClashWars { get; set; } = new ConcurrentDictionary<ulong, List<ClashWar>>();
}
public enum WarState
{
Started, Ended, Created
}
internal class Caller public ClashOfClans(ILocalization loc, CommandService cmds, IBotConfiguration config, IDiscordClient client) : base(loc, cmds, config, client)
{
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() private static async Task CheckWar(TimeSpan callExpire, ClashWar war)
{ {
TimeAdded = DateTime.UtcNow; var Bases = war.Bases;
}
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.");
for (var i = 0; i < Bases.Length; i++) for (var i = 0; i < Bases.Length; i++)
{ {
if (Bases[i]?.BaseDestroyed == false && Bases[i]?.CallUser == u) if (Bases[i] == null) continue;
throw new ArgumentException($"@{u} You already claimed base #{i + 1}. You can't claim a new one."); if (!Bases[i].BaseDestroyed && DateTime.UtcNow - Bases[i].TimeAdded >= callExpire)
}
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)
{ {
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) await imsg.Channel.SendMessageAsync("🔰 **No active wars.**").ConfigureAwait(false);
{ return;
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");
}
} }
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(); var channel = imsg.Channel as ITextChannel;
for (var i = 0; i < Bases.Length; i++) var warsInfo = GetWarInfo(imsg, number);
if (warsInfo == null || warsInfo.Item1.Count == 0)
{ {
if (Bases[i]?.BaseDestroyed != false || Bases[i]?.CallUser != user) continue; await imsg.Channel.SendMessageAsync("💢🔰 **That war does not exist.**").ConfigureAwait(false);
Bases[i].BaseDestroyed = true; return;
Bases[i].Stars = stars;
return i;
} }
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);
} }
} }
} }

View File

@ -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);
}
}
}

View 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.");
}
}
}

View File

@ -1,6 +1,7 @@
using Discord; using Discord;
using Discord.Commands; using Discord.Commands;
using NadekoBot.Services; using NadekoBot.Services;
using NLog;
namespace NadekoBot.Modules namespace NadekoBot.Modules
{ {
@ -10,6 +11,7 @@ namespace NadekoBot.Modules
protected CommandService _commands; protected CommandService _commands;
protected IBotConfiguration _config; protected IBotConfiguration _config;
protected IDiscordClient _client; protected IDiscordClient _client;
protected Logger _log;
public DiscordModule(ILocalization loc, CommandService cmds, IBotConfiguration config,IDiscordClient client) public DiscordModule(ILocalization loc, CommandService cmds, IBotConfiguration config,IDiscordClient client)
{ {
@ -17,6 +19,7 @@ namespace NadekoBot.Modules
_commands = cmds; _commands = cmds;
_config = config; _config = config;
_client = client; _client = client;
_log = LogManager.GetCurrentClassLogger();
} }
} }
} }

View File

@ -11,11 +11,11 @@ using NadekoBot.Extensions;
namespace NadekoBot.Modules.Games namespace NadekoBot.Modules.Games
{ {
[Module(">", AppendSpace = false)] [Module(">", AppendSpace = false)]
public partial class GamesModule : DiscordModule public partial class Games : DiscordModule
{ {
//todo DB //todo DB
private IEnumerable<string> _8BallResponses; 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)
{ {
} }

View File

@ -12,7 +12,7 @@ using System.Text;
namespace NadekoBot.Modules.Help namespace NadekoBot.Modules.Help
{ {
[Module("-", AppendSpace = false)] [Module("-", AppendSpace = false)]
public partial class HelpModule : DiscordModule public partial class Help : DiscordModule
{ {
public string HelpString { public string HelpString {
get { get {
@ -20,7 +20,7 @@ namespace NadekoBot.Modules.Help
return str + String.Format(str, NadekoBot.Credentials.ClientId); 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] [LocalizedCommand, LocalizedDescription, LocalizedSummary]
[RequireContext(ContextType.Guild)] [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; var channel = imsg.Channel as ITextChannel;
@ -106,7 +106,7 @@ namespace NadekoBot.Modules.Help
} }
helpstr = helpstr.Replace((await NadekoBot.Client.GetCurrentUserAsync()).Username , "@BotName"); helpstr = helpstr.Replace((await NadekoBot.Client.GetCurrentUserAsync()).Username , "@BotName");
#if DEBUG #if DEBUG
File.WriteAllText("../../../docs/Commands List.md", helpstr.ToString()); File.WriteAllText("../../../../../docs/Commands List.md", helpstr.ToString());
#else #else
File.WriteAllText("commandlist.md", helpstr.ToString()); File.WriteAllText("commandlist.md", helpstr.ToString());
#endif #endif

View File

@ -9,13 +9,14 @@ using NadekoBot.Services;
using System.Net.Http; using System.Net.Http;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Xml.Linq; using System.Xml.Linq;
using System.Net;
namespace NadekoBot.Modules.NSFW namespace NadekoBot.Modules.NSFW
{ {
[Module("~", AppendSpace = false)] [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.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("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"); 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); var doc = XDocument.Load(data);
return doc.Descendants("file_url").FirstOrDefault().Value; return doc.Descendants("file_url").FirstOrDefault().Value;
} }

View File

@ -7,9 +7,9 @@ using NadekoBot.Services;
namespace NadekoBot.Modules.Games.Commands namespace NadekoBot.Modules.Games.Commands
{ {
[Module(">", AppendSpace = false)] [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)
{ {
} }

View File

@ -76,7 +76,7 @@
// var reqString = $"https://osu.ppy.sh/api/get_beatmaps?k={NadekoBot.Creds.OsuAPIKey}&{mapId}"; // 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 obj = JArray.Parse(await http.GetStringAsync(reqString).ConfigureAwait(false))[0];
// var sb = new System.Text.StringBuilder(); // 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"); // 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($"{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}"); // 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 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 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 acc = CalculateAcc(item, m);
// var mods = ResolveMods(Int32.Parse($"{item["enabled_mods"]}")); // var mods = ResolveMods(Int32.Parse($"{item["enabled_mods"]}"));
// if (mods != "+") // if (mods != "+")

View File

@ -17,13 +17,13 @@ using NadekoBot.Modules.Searches.Commands.Models;
namespace NadekoBot.Modules.Searches namespace NadekoBot.Modules.Searches
{ {
[Module("~", AppendSpace = false)] [Module("~", AppendSpace = false)]
public class SearchesModule : DiscordModule public class Searches : DiscordModule
{ {
private readonly Random rng; private readonly Random rng;
private IYoutubeService _yt { get; } 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(); rng = new Random();
_yt = youtube; _yt = youtube;

View File

@ -94,6 +94,7 @@ namespace NadekoBot.Modules.Translator
{ "bn", "bn"}, { "bn", "bn"},
{ "bg", "bg"}, { "bg", "bg"},
{ "ca", "ca"}, { "ca", "ca"},
{ "zh-TW", "zh-TW"},
{ "zh-CN", "zh-CN"}, { "zh-CN", "zh-CN"},
{ "hr", "hr"}, { "hr", "hr"},
{ "cs", "cs"}, { "cs", "cs"},

View File

@ -9,9 +9,9 @@ using NadekoBot.Services;
namespace NadekoBot.Modules.Translator namespace NadekoBot.Modules.Translator
{ {
[Module("~", AppendSpace = false)] [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)
{ {
} }

View File

@ -11,7 +11,7 @@
////todo rewrite ////todo rewrite
//namespace NadekoBot.Modules.Trello //namespace NadekoBot.Modules.Trello
//{ //{
// internal class TrelloModule : DiscordModule // internal class Trello : DiscordModule
// { // {
// private readonly Timer t = new Timer { Interval = 2000 }; // private readonly Timer t = new Timer { Interval = 2000 };
// public override string Prefix { get; } = NadekoBot.Config.CommandPrefixes.Trello; // public override string Prefix { get; } = NadekoBot.Config.CommandPrefixes.Trello;

View File

@ -9,7 +9,7 @@ using System.Threading.Tasks;
namespace NadekoBot.Modules.Utility namespace NadekoBot.Modules.Utility
{ {
partial class UtilityModule : DiscordModule partial class Utility : DiscordModule
{ {
[LocalizedCommand, LocalizedDescription, LocalizedSummary] [LocalizedCommand, LocalizedDescription, LocalizedSummary]
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]

View File

@ -15,9 +15,9 @@ namespace NadekoBot.Modules.Utility
{ {
[Module(".", AppendSpace = false)] [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 }))); 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());
}
} }
} }

View File

@ -3,6 +3,9 @@ using Discord.Commands;
using Discord.WebSocket; using Discord.WebSocket;
using NadekoBot.Services; using NadekoBot.Services;
using NadekoBot.Services.Impl; using NadekoBot.Services.Impl;
using NLog;
using NLog.Config;
using NLog.Targets;
using System; using System;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
@ -12,6 +15,8 @@ namespace NadekoBot
{ {
public class NadekoBot public class NadekoBot
{ {
private Logger _log;
public static CommandService Commands { get; private set; } public static CommandService Commands { get; private set; }
public static DiscordSocketClient Client { get; private set; } public static DiscordSocketClient Client { get; private set; }
public static BotConfiguration Config { get; private set; } public static BotConfiguration Config { get; private set; }
@ -19,9 +24,12 @@ namespace NadekoBot
public static BotCredentials Credentials { get; private set; } public static BotCredentials Credentials { get; private set; }
private static YoutubeService Youtube { get; set; } private static YoutubeService Youtube { get; set; }
public static StatsService Stats { get; private set; }
public async Task RunAsync(string[] args) public async Task RunAsync(string[] args)
{ {
SetupLogger();
//create client //create client
Client = new DiscordSocketClient(new DiscordSocketConfig Client = new DiscordSocketClient(new DiscordSocketConfig
{ {
@ -37,6 +45,8 @@ namespace NadekoBot
Config = new BotConfiguration(); Config = new BotConfiguration();
Localizer = new Localization(); Localizer = new Localization();
Youtube = new YoutubeService(); Youtube = new YoutubeService();
Stats = new StatsService(Client);
_log = LogManager.GetCurrentClassLogger();
//setup DI //setup DI
var depMap = new DependencyMap(); var depMap = new DependencyMap();
@ -47,23 +57,56 @@ namespace NadekoBot
depMap.Add<IYoutubeService>(Youtube); depMap.Add<IYoutubeService>(Youtube);
//connect //connect
await Client.LoginAsync(TokenType.Bot, "MTE5Nzc3MDIxMzE5NTc3NjEw.CpGoCA.yQBJbLWurrjSk7IlGpGzBm-tPTg"); await Client.LoginAsync(TokenType.Bot, "MTE5Nzc3MDIxMzE5NTc3NjEw.CpdrFA.0rex01uCrn9dBTJOV2tXwMLo0wE");
await Client.ConnectAsync(); await Client.ConnectAsync();
_log.Info("Connected");
//load commands //load commands
await Commands.LoadAssembly(Assembly.GetEntryAssembly(), depMap); await Commands.LoadAssembly(Assembly.GetEntryAssembly(), depMap);
Client.MessageReceived += Client_MessageReceived; Client.MessageReceived += Client_MessageReceived;
Console.WriteLine(Commands.Commands.Count()); Console.WriteLine(await Stats.Print());
await Task.Delay(-1); await Task.Delay(-1);
} }
private async Task Client_MessageReceived(IMessage arg) private void SetupLogger()
{ {
var t = await Commands.Execute(arg, 0); try
if(!t.IsSuccess && t.Error != CommandError.UnknownCommand) {
Console.WriteLine(t.ErrorReason); 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;
} }
} }
} }

View 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();
}
}

View 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.";
}
}
}

View File

@ -19,7 +19,8 @@
"Discord.Net.Commands": "1.0.0-dev", "Discord.Net.Commands": "1.0.0-dev",
"System.Resources.ResourceWriter": "4.0.0-beta-22816", "System.Resources.ResourceWriter": "4.0.0-beta-22816",
"Google.Apis.YouTube.v3": "1.15.0.582", "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": { "frameworks": {

View File

@ -339,7 +339,7 @@
"Microsoft.NETCore.Jit/1.0.2": { "Microsoft.NETCore.Jit/1.0.2": {
"type": "package" "type": "package"
}, },
"Microsoft.NETCore.Platforms/1.0.1": { "Microsoft.NETCore.Platforms/1.0.2-beta-24410-01": {
"type": "package", "type": "package",
"compile": { "compile": {
"lib/netstandard1.0/_._": {} "lib/netstandard1.0/_._": {}
@ -513,6 +513,33 @@
"lib/netstandard1.0/Newtonsoft.Json.dll": {} "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": { "Portable.BouncyCastle/1.8.1.1": {
"type": "package", "type": "package",
"dependencies": { "dependencies": {
@ -628,7 +655,7 @@
"lib/netstandard1.1/System.Buffers.dll": {} "lib/netstandard1.1/System.Buffers.dll": {}
}, },
"runtime": { "runtime": {
"lib/netstandard1.1/_._": {} "lib/netstandard1.1/System.Buffers.dll": {}
} }
}, },
"System.Collections/4.0.11": { "System.Collections/4.0.11": {
@ -682,6 +709,41 @@
"lib/netstandard1.0/System.Collections.Immutable.dll": {} "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": { "System.ComponentModel/4.0.1": {
"type": "package", "type": "package",
"dependencies": { "dependencies": {
@ -716,6 +778,46 @@
"lib/netstandard1.4/_._": {} "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": { "System.Console/4.0.0": {
"type": "package", "type": "package",
"dependencies": { "dependencies": {
@ -729,6 +831,25 @@
"ref/netstandard1.3/System.Console.dll": {} "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": { "System.Diagnostics.Contracts/4.0.1": {
"type": "package", "type": "package",
"dependencies": { "dependencies": {
@ -845,10 +966,10 @@
"System.Runtime.Extensions": "4.1.0" "System.Runtime.Extensions": "4.1.0"
}, },
"compile": { "compile": {
"ref/netstandard1.3/_._": {} "ref/netstandard1.3/System.Diagnostics.StackTrace.dll": {}
}, },
"runtime": { "runtime": {
"lib/netstandard1.3/_._": {} "lib/netstandard1.3/System.Diagnostics.StackTrace.dll": {}
} }
}, },
"System.Diagnostics.Tools/4.0.1": { "System.Diagnostics.Tools/4.0.1": {
@ -862,6 +983,33 @@
"ref/netstandard1.0/System.Diagnostics.Tools.dll": {} "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": { "System.Diagnostics.Tracing/4.1.0": {
"type": "package", "type": "package",
"dependencies": { "dependencies": {
@ -1008,7 +1156,7 @@
"ref/netstandard1.3/System.IO.Compression.ZipFile.dll": {} "ref/netstandard1.3/System.IO.Compression.ZipFile.dll": {}
}, },
"runtime": { "runtime": {
"lib/netstandard1.3/_._": {} "lib/netstandard1.3/System.IO.Compression.ZipFile.dll": {}
} }
}, },
"System.IO.FileSystem/4.0.1": { "System.IO.FileSystem/4.0.1": {
@ -1063,9 +1211,17 @@
"ref/netstandard1.3/System.IO.FileSystem.Watcher.dll": {} "ref/netstandard1.3/System.IO.FileSystem.Watcher.dll": {}
}, },
"runtimeTargets": { "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", "assetType": "runtime",
"rid": "osx" "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": {} "ref/netstandard1.3/System.Net.Security.dll": {}
}, },
"runtimeTargets": { "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", "assetType": "runtime",
"rid": "win" "rid": "win"
} }
@ -1403,16 +1563,20 @@
"lib/netstandard1.3/System.Net.WebSockets.dll": {} "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", "type": "package",
"dependencies": { "dependencies": {
"Microsoft.NETCore.Platforms": "1.0.1", "Microsoft.NETCore.Platforms": "1.0.2-beta-24410-01",
"Microsoft.Win32.Primitives": "4.0.1", "Microsoft.Win32.Primitives": "4.0.1",
"System.Collections": "4.0.11", "System.Collections": "4.0.11",
"System.Diagnostics.Debug": "4.0.11", "System.Diagnostics.Debug": "4.0.11",
"System.Diagnostics.Tracing": "4.1.0", "System.Diagnostics.Tracing": "4.1.0",
"System.Globalization": "4.0.11", "System.Globalization": "4.0.11",
"System.IO": "4.1.0",
"System.Net.NameResolution": "4.0.0",
"System.Net.Primitives": "4.0.11", "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.WebHeaderCollection": "4.0.1",
"System.Net.WebSockets": "4.0.0", "System.Net.WebSockets": "4.0.0",
"System.Resources.ResourceManager": "4.0.1", "System.Resources.ResourceManager": "4.0.1",
@ -1420,10 +1584,14 @@
"System.Runtime.Extensions": "4.1.0", "System.Runtime.Extensions": "4.1.0",
"System.Runtime.Handles": "4.0.1", "System.Runtime.Handles": "4.0.1",
"System.Runtime.InteropServices": "4.1.0", "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.Security.Cryptography.X509Certificates": "4.1.0",
"System.Text.Encoding": "4.0.11", "System.Text.Encoding": "4.0.11",
"System.Text.Encoding.Extensions": "4.0.11",
"System.Threading": "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": { "compile": {
"ref/netstandard1.3/System.Net.WebSockets.Client.dll": {} "ref/netstandard1.3/System.Net.WebSockets.Client.dll": {}
@ -1584,7 +1752,7 @@
"lib/netstandard1.1/System.Reflection.Metadata.dll": {} "lib/netstandard1.1/System.Reflection.Metadata.dll": {}
}, },
"runtime": { "runtime": {
"lib/netstandard1.1/_._": {} "lib/netstandard1.1/System.Reflection.Metadata.dll": {}
} }
}, },
"System.Reflection.Primitives/4.0.1": { "System.Reflection.Primitives/4.0.1": {
@ -2131,7 +2299,11 @@
"ref/netstandard1.3/_._": {} "ref/netstandard1.3/_._": {}
}, },
"runtimeTargets": { "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", "assetType": "runtime",
"rid": "win" "rid": "win"
} }
@ -2303,10 +2475,10 @@
"System.Xml.ReaderWriter": "4.0.11" "System.Xml.ReaderWriter": "4.0.11"
}, },
"compile": { "compile": {
"ref/netstandard1.3/_._": {} "ref/netstandard1.3/System.Xml.XmlDocument.dll": {}
}, },
"runtime": { "runtime": {
"lib/netstandard1.3/_._": {} "lib/netstandard1.3/System.Xml.XmlDocument.dll": {}
} }
}, },
"System.Xml.XPath/4.0.1": { "System.Xml.XPath/4.0.1": {
@ -2362,7 +2534,7 @@
"System.Net.Http": "4.1.0", "System.Net.Http": "4.1.0",
"System.Net.NameResolution": "4.0.0", "System.Net.NameResolution": "4.0.0",
"System.Net.Sockets": "4.1.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.Reflection.Extensions": "4.0.1",
"System.Runtime.InteropServices": "4.1.0", "System.Runtime.InteropServices": "4.1.0",
"System.Runtime.InteropServices.RuntimeInformation": "4.0.0", "System.Runtime.InteropServices.RuntimeInformation": "4.0.0",
@ -2746,12 +2918,12 @@
"runtime.json" "runtime.json"
] ]
}, },
"Microsoft.NETCore.Platforms/1.0.1": { "Microsoft.NETCore.Platforms/1.0.2-beta-24410-01": {
"sha512": "2G6OjjJzwBfNOO8myRV/nFrbTw5iA+DEm0N+qUqhrOmaVtn4pC77h38I1jsXGw5VH55+dPfQsqHD0We9sCl9FQ==", "sha512": "uc/pGYdE4sVy3OovFF8hg79MvCxptzICxn0jdA6WusGWZa7VieqFoZYc+a6bHUVhMI0s/7SfBriux0RUq+PpbA==",
"type": "package", "type": "package",
"path": "Microsoft.NETCore.Platforms/1.0.1", "path": "Microsoft.NETCore.Platforms/1.0.2-beta-24410-01",
"files": [ "files": [
"Microsoft.NETCore.Platforms.1.0.1.nupkg.sha512", "Microsoft.NETCore.Platforms.1.0.2-beta-24410-01.nupkg.sha512",
"Microsoft.NETCore.Platforms.nuspec", "Microsoft.NETCore.Platforms.nuspec",
"ThirdPartyNotices.txt", "ThirdPartyNotices.txt",
"dotnet_library_license.txt", "dotnet_library_license.txt",
@ -2938,6 +3110,35 @@
"tools/install.ps1" "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": { "Portable.BouncyCastle/1.8.1.1": {
"sha512": "bKqC2Me9ukybNYTBhlYd2sJ6j2kRV7SgB+JfiP2GueYq6QdM4Ym6PYV5eyrqb6KViOyd3zqQfJp0o6UW5ZG+GQ==", "sha512": "bKqC2Me9ukybNYTBhlYd2sJ6j2kRV7SgB+JfiP2GueYq6QdM4Ym6PYV5eyrqb6KViOyd3zqQfJp0o6UW5ZG+GQ==",
"type": "package", "type": "package",
@ -3230,6 +3431,80 @@
"lib/portable-net45+win8+wp8+wpa81/System.Collections.Immutable.xml" "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": { "System.ComponentModel/4.0.1": {
"sha512": "oBZFnm7seFiVfugsIyOvQCWobNZs7FzqDV/B7tx20Ep/l3UUFCPDkdTnCNaJZTU27zjeODmy2C/cP60u3D4c9w==", "sha512": "oBZFnm7seFiVfugsIyOvQCWobNZs7FzqDV/B7tx20Ep/l3UUFCPDkdTnCNaJZTU27zjeODmy2C/cP60u3D4c9w==",
"type": "package", "type": "package",
@ -3364,6 +3639,94 @@
"ref/xamarinwatchos10/_._" "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": { "System.Console/4.0.0": {
"sha512": "qSKUSOIiYA/a0g5XXdxFcUFmv1hNICBD7QZ0QhGYVipPIhvpiydY8VZqr1thmCXvmn8aipMg64zuanB4eotK9A==", "sha512": "qSKUSOIiYA/a0g5XXdxFcUFmv1hNICBD7QZ0QhGYVipPIhvpiydY8VZqr1thmCXvmn8aipMg64zuanB4eotK9A==",
"type": "package", "type": "package",
@ -3400,6 +3763,55 @@
"ref/xamarinwatchos10/_._" "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": { "System.Diagnostics.Contracts/4.0.1": {
"sha512": "HvQQjy712vnlpPxaloZYkuE78Gn353L0SJLJVeLcNASeg9c4qla2a1Xq8I7B3jZoDzKPtHTkyVO7AZ5tpeQGuA==", "sha512": "HvQQjy712vnlpPxaloZYkuE78Gn353L0SJLJVeLcNASeg9c4qla2a1Xq8I7B3jZoDzKPtHTkyVO7AZ5tpeQGuA==",
"type": "package", "type": "package",
@ -3731,6 +4143,45 @@
"ref/xamarinwatchos10/_._" "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": { "System.Diagnostics.Tracing/4.1.0": {
"sha512": "vDN1PoMZCkkdNjvZLql592oYJZgS7URcJzJ7bxeBgGtx5UtR5leNm49VmfHGqIffX4FKacHbI3H6UyNSHQknBg==", "sha512": "vDN1PoMZCkkdNjvZLql592oYJZgS7URcJzJ7bxeBgGtx5UtR5leNm49VmfHGqIffX4FKacHbI3H6UyNSHQknBg==",
"type": "package", "type": "package",
@ -5097,12 +5548,12 @@
"ref/xamarinwatchos10/_._" "ref/xamarinwatchos10/_._"
] ]
}, },
"System.Net.WebSockets.Client/4.0.0": { "System.Net.WebSockets.Client/4.0.1-beta-24410-01": {
"sha512": "GY5h9cn0ZVsG4ORQqMytTldrqxet2RC2CSEsgWGf4XNW5jhL5SxzcUZph03xbZsgn7K3qMr+Rq+gkbJNI+FEXg==", "sha512": "IOqAcR7k+3LwNI6aL7qN61HcCOA9X4MM9LbrZhDeNbeB/IeWTk7zpeb7kh3d7H678s7ndIqN6a7okO8dAAfcYQ==",
"type": "package", "type": "package",
"path": "System.Net.WebSockets.Client/4.0.0", "path": "System.Net.WebSockets.Client/4.0.1-beta-24410-01",
"files": [ "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", "System.Net.WebSockets.Client.nuspec",
"ThirdPartyNotices.txt", "ThirdPartyNotices.txt",
"dotnet_library_license.txt", "dotnet_library_license.txt",
@ -7421,6 +7872,7 @@
"Microsoft.Extensions.DependencyInjection.Abstractions >= 1.0.0", "Microsoft.Extensions.DependencyInjection.Abstractions >= 1.0.0",
"Microsoft.Extensions.PlatformAbstractions >= 1.0.0", "Microsoft.Extensions.PlatformAbstractions >= 1.0.0",
"Microsoft.NETCore.App >= 1.0.0", "Microsoft.NETCore.App >= 1.0.0",
"NLog >= 4.4.0-betaV15",
"Newtonsoft.Json >= 9.0.1", "Newtonsoft.Json >= 9.0.1",
"System.Diagnostics.Contracts >= 4.0.1", "System.Diagnostics.Contracts >= 4.0.1",
"System.Resources.ResourceWriter >= 4.0.0-beta-22816" "System.Resources.ResourceWriter >= 4.0.0-beta-22816"