merged dev

This commit is contained in:
Master Kwoth 2017-05-19 20:48:28 +02:00
commit d08bc60be5
5 changed files with 169 additions and 123 deletions

View File

@ -12,6 +12,9 @@ using Discord.WebSocket;
using NadekoBot.Services; using NadekoBot.Services;
using NadekoBot.Services.Database.Models; using NadekoBot.Services.Database.Models;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using System.Collections.Immutable;
using NadekoBot.DataStructures;
using NLog;
namespace NadekoBot.Modules.Administration namespace NadekoBot.Modules.Administration
{ {
@ -25,8 +28,11 @@ namespace NadekoBot.Modules.Administration
private static readonly object _locker = new object(); private static readonly object _locker = new object();
private new static readonly Logger _log;
static SelfCommands() static SelfCommands()
{ {
_log = LogManager.GetCurrentClassLogger();
using (var uow = DbHandler.UnitOfWork()) using (var uow = DbHandler.UnitOfWork())
{ {
var config = uow.BotConfig.GetOrCreate(); var config = uow.BotConfig.GetOrCreate();
@ -36,7 +42,7 @@ namespace NadekoBot.Modules.Administration
var _ = Task.Run(async () => var _ = Task.Run(async () =>
{ {
while(!NadekoBot.Ready) while (!NadekoBot.Ready)
await Task.Delay(1000); await Task.Delay(1000);
foreach (var cmd in NadekoBot.BotConfig.StartupCommands) foreach (var cmd in NadekoBot.BotConfig.StartupCommands)
@ -113,7 +119,7 @@ namespace NadekoBot.Modules.Administration
{Format.Code(GetText("channel"))}: {x.ChannelName}/{x.ChannelId} {Format.Code(GetText("channel"))}: {x.ChannelName}/{x.ChannelId}
{Format.Code(GetText("command_text"))}: {x.CommandText}"; {Format.Code(GetText("command_text"))}: {x.CommandText}";
return str; return str;
})),footer: GetText("page", page + 1)) })), footer: GetText("page", page + 1))
.ConfigureAwait(false); .ConfigureAwait(false);
} }
} }
@ -123,7 +129,7 @@ namespace NadekoBot.Modules.Administration
public async Task Wait(int miliseconds) public async Task Wait(int miliseconds)
{ {
if (miliseconds <= 0) if (miliseconds <= 0)
return; return;
Context.Message.DeleteAfter(0); Context.Message.DeleteAfter(0);
try try
{ {
@ -157,7 +163,7 @@ namespace NadekoBot.Modules.Administration
} }
} }
if(cmd == null) if (cmd == null)
await ReplyErrorLocalized("scrm_fail").ConfigureAwait(false); await ReplyErrorLocalized("scrm_fail").ConfigureAwait(false);
else else
await ReplyConfirmLocalized("scrm").ConfigureAwait(false); await ReplyConfirmLocalized("scrm").ConfigureAwait(false);
@ -215,9 +221,9 @@ namespace NadekoBot.Modules.Administration
} }
public static async Task HandleDmForwarding(IUserMessage msg, List<IDMChannel> ownerChannels) public static async Task HandleDmForwarding(IUserMessage msg, ImmutableArray<AsyncLazy<IDMChannel>> ownerChannels)
{ {
if (_forwardDMs && ownerChannels.Any()) if (_forwardDMs && ownerChannels.Length > 0)
{ {
var title = GetTextStatic("dm_from", var title = GetTextStatic("dm_from",
NadekoBot.Localization.DefaultCultureInfo, NadekoBot.Localization.DefaultCultureInfo,
@ -238,26 +244,39 @@ namespace NadekoBot.Modules.Administration
if (_forwardDMsToAllOwners) if (_forwardDMsToAllOwners)
{ {
await Task.WhenAll(ownerChannels.Where(ch => ch.Recipient.Id != msg.Author.Id) var allOwnerChannels = await Task.WhenAll(ownerChannels
.Select(ch => ch.SendConfirmAsync(title, toSend))).ConfigureAwait(false); .Select(x => x.Value))
} .ConfigureAwait(false);
else
{ foreach (var ownerCh in allOwnerChannels.Where(ch => ch.Recipient.Id != msg.Author.Id))
var firstOwnerChannel = ownerChannels.First();
if (firstOwnerChannel.Recipient.Id != msg.Author.Id)
{ {
try try
{ {
await firstOwnerChannel.SendConfirmAsync(title, toSend).ConfigureAwait(false); await ownerCh.SendConfirmAsync(title, toSend).ConfigureAwait(false);
} }
catch catch
{ {
// ignored _log.Warn("Can't contact owner with id {0}", ownerCh.Recipient.Id);
}
}
}
else
{
var firstOwnerChannel = await ownerChannels[0];
if (firstOwnerChannel.Recipient.Id != msg.Author.Id)
{
try
{
await firstOwnerChannel.SendConfirmAsync(title, toSend).ConfigureAwait(false);
}
catch
{
// ignored
}
} }
} }
} }
} }
}
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]

View File

@ -36,10 +36,7 @@ namespace NadekoBot.Modules.Games
static PlantPickCommands() static PlantPickCommands()
{ {
#if !GLOBAL_NADEKO
NadekoBot.Client.MessageReceived += PotentialFlowerGeneration; NadekoBot.Client.MessageReceived += PotentialFlowerGeneration;
#endif
generationChannels = new ConcurrentHashSet<ulong>(NadekoBot.AllGuildConfigs generationChannels = new ConcurrentHashSet<ulong>(NadekoBot.AllGuildConfigs
.SelectMany(c => c.GenerateCurrencyChannelIds.Select(obj => obj.ChannelId))); .SelectMany(c => c.GenerateCurrencyChannelIds.Select(obj => obj.ChannelId)));
} }

View File

@ -8,59 +8,55 @@ namespace NadekoBot.Modules.Searches.Models
{ {
public OverwatchPlayer Player { get; set; } public OverwatchPlayer Player { get; set; }
public class OverwatchResponse
{
public object _request;
public OverwatchPlayer Eu { get; set; }
public OverwatchPlayer Kr { get; set; }
public OverwatchPlayer Us { get; set; }
}
public class OverwatchPlayer public class OverwatchPlayer
{ {
public Data data { get; set; } public StatsField Stats { get; set; }
public class Data
{
public bool Missing { get; set; } = false;
public string username { get; set; }
public int level { get; set; }
public string avatar { get; set; }
public string levelFrame { get; set; }
public string star { get; set; }
[JsonProperty("games")]
public OverwatchGames Games { get; set; }
[JsonProperty("playtime")]
public OverwatchPlaytime Playtime { get; set; }
[JsonProperty("competitive")]
public OverwatchCompetitive Competitive { get; set; }
public class OverwatchGames
{
[JsonProperty("quick")]
public OverwatchQG Quick { get; set; }
[JsonProperty("competitive")]
public OverwatchCOMP Competitive { get; set; }
public class OverwatchQG
{
public string wins { get; set; }
}
public class OverwatchCOMP
{
public string wins { get; set; }
public int lost { get; set; }
public string played { get; set; }
}
}
public class OverwatchCompetitive
{
public string rank { get; set; }
public string rank_img { get; set; }
}
public class OverwatchPlaytime
{
public string quick { get; set; }
public string competitive { get; set; }
}
}
} }
//This is to strip the html from patch notes content
internal static string StripHTML(string input) public class StatsField
{ {
var re = Regex.Replace(input, "<.*?>", String.Empty); public Stats Quickplay { get; set; }
re = Regex.Replace(re, "&#160;", $@" "); public Stats Competitive { get; set; }
return re;
}
public class Stats
{
[JsonProperty("overall_stats")]
public OverallStats OverallStats { get; set; }
[JsonProperty("game_stats")]
public GameStats GameStats { get; set; }
}
public class OverallStats
{
public int? comprank;
public int level;
public int prestige;
public string avatar;
public int wins;
public int losses;
public int games;
public string rank_image;
}
public class GameStats
{
[JsonProperty("time_played")]
public float timePlayed;
}
public class Competitive
{
} }
} }
} }

View File

@ -15,61 +15,67 @@ namespace NadekoBot.Modules.Searches
[Group] [Group]
public class OverwatchCommands : NadekoSubmodule public class OverwatchCommands : NadekoSubmodule
{ {
public enum Region
{
Eu,
Us,
Kr
}
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
public async Task Overwatch(string region, [Remainder] string query = null) public async Task Overwatch(Region region, [Remainder] string query = null)
{ {
if (string.IsNullOrWhiteSpace(query)) if (string.IsNullOrWhiteSpace(query))
return; return;
var battletag = query.Replace("#", "-"); var battletag = query.Replace("#", "-");
await Context.Channel.TriggerTypingAsync().ConfigureAwait(false); await Context.Channel.TriggerTypingAsync().ConfigureAwait(false);
try var model = (await GetProfile(region, battletag))?.Stats;
if (model != null)
{ {
await Context.Channel.TriggerTypingAsync().ConfigureAwait(false); if (model.Competitive == null)
var model = await GetProfile(region, battletag);
var rankimg = model.Competitive.rank_img;
var rank = model.Competitive.rank;
if (string.IsNullOrWhiteSpace(rank))
{ {
var qp = model.Quickplay;
var embed = new EmbedBuilder() var embed = new EmbedBuilder()
.WithAuthor(eau => eau.WithName($"{model.username}") .WithAuthor(eau => eau.WithName(query)
.WithUrl($"https://www.overbuff.com/players/pc/{battletag}") .WithUrl($"https://www.overbuff.com/players/pc/{battletag}")
.WithIconUrl($"{model.avatar}")) .WithIconUrl("https://cdn.discordapp.com/attachments/155726317222887425/255653487512256512/YZ4w2ey.png"))
.WithThumbnailUrl("https://cdn.discordapp.com/attachments/155726317222887425/255653487512256512/YZ4w2ey.png") .WithThumbnailUrl(qp.OverallStats.avatar)
.AddField(fb => fb.WithName(GetText("level")).WithValue($"{model.level}").WithIsInline(true)) .AddField(fb => fb.WithName(GetText("level")).WithValue((qp.OverallStats.level + (qp.OverallStats.prestige * 100)).ToString()).WithIsInline(true))
.AddField(fb => fb.WithName(GetText("quick_wins")).WithValue($"{model.Games.Quick.wins}").WithIsInline(true)) .AddField(fb => fb.WithName(GetText("quick_wins")).WithValue(qp.OverallStats.wins.ToString()).WithIsInline(true))
.AddField(fb => fb.WithName(GetText("compet_rank")).WithValue("0").WithIsInline(true)) .AddField(fb => fb.WithName(GetText("compet_rank")).WithValue("0").WithIsInline(true))
.AddField(fb => fb.WithName(GetText("quick_playtime")).WithValue($"{model.Playtime.quick}").WithIsInline(true)) .AddField(fb => fb.WithName(GetText("quick_playtime")).WithValue($"{qp.GameStats.timePlayed}hrs").WithIsInline(true))
.WithOkColor(); .WithOkColor();
await Context.Channel.EmbedAsync(embed).ConfigureAwait(false); await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
} }
else else
{ {
var qp = model.Quickplay;
var compet = model.Competitive;
var embed = new EmbedBuilder() var embed = new EmbedBuilder()
.WithAuthor(eau => eau.WithName($"{model.username}") .WithAuthor(eau => eau.WithName(query)
.WithUrl($"https://www.overbuff.com/players/pc/{battletag}") .WithUrl($"https://www.overbuff.com/players/pc/{battletag}")
.WithIconUrl($"{model.avatar}")) .WithIconUrl(compet.OverallStats.rank_image))
.WithThumbnailUrl(rankimg) .WithThumbnailUrl(compet.OverallStats.avatar)
.AddField(fb => fb.WithName(GetText("level")).WithValue($"{model.level}").WithIsInline(true)) .AddField(fb => fb.WithName(GetText("level")).WithValue((qp.OverallStats.level + (qp.OverallStats.prestige * 100)).ToString()).WithIsInline(true))
.AddField(fb => fb.WithName(GetText("quick_wins")).WithValue($"{model.Games.Quick.wins}").WithIsInline(true)) .AddField(fb => fb.WithName(GetText("quick_wins")).WithValue(qp.OverallStats.wins.ToString()).WithIsInline(true))
.AddField(fb => fb.WithName(GetText("compet_wins")).WithValue($"{model.Games.Competitive.wins}").WithIsInline(true)) .AddField(fb => fb.WithName(GetText("compet_wins")).WithValue(compet.OverallStats.wins.ToString()).WithIsInline(true))
.AddField(fb => fb.WithName(GetText("compet_loses")).WithValue($"{model.Games.Competitive.lost}").WithIsInline(true)) .AddField(fb => fb.WithName(GetText("compet_loses")).WithValue(compet.OverallStats.losses.ToString()).WithIsInline(true))
.AddField(fb => fb.WithName(GetText("compet_played")).WithValue($"{model.Games.Competitive.played}").WithIsInline(true)) .AddField(fb => fb.WithName(GetText("compet_played")).WithValue(compet.OverallStats.games.ToString()).WithIsInline(true))
.AddField(fb => fb.WithName(GetText("compet_rank")).WithValue(rank).WithIsInline(true)) .AddField(fb => fb.WithName(GetText("compet_rank")).WithValue(compet.OverallStats.comprank.ToString()).WithIsInline(true))
.AddField(fb => fb.WithName(GetText("compet_playtime")).WithValue($"{model.Playtime.competitive}").WithIsInline(true)) .AddField(fb => fb.WithName(GetText("compet_playtime")).WithValue(compet.GameStats.timePlayed + "hrs").WithIsInline(true))
.AddField(fb => fb.WithName(GetText("quick_playtime")).WithValue($"{model.Playtime.quick}").WithIsInline(true)) .AddField(fb => fb.WithName(GetText("quick_playtime")).WithValue(qp.GameStats.timePlayed.ToString("F1") + "hrs").WithIsInline(true))
.WithColor(NadekoBot.OkColor); .WithColor(NadekoBot.OkColor);
await Context.Channel.EmbedAsync(embed).ConfigureAwait(false); await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
} }
} }
catch else
{ {
await ReplyErrorLocalized("ow_user_not_found").ConfigureAwait(false); await ReplyErrorLocalized("ow_user_not_found").ConfigureAwait(false);
} }
} }
public async Task<OverwatchApiModel.OverwatchPlayer.Data> GetProfile(string region, string battletag) public async Task<OverwatchApiModel.OverwatchPlayer> GetProfile(Region region, string battletag)
{ {
try try
{ {
@ -78,11 +84,20 @@ namespace NadekoBot.Modules.Searches
handler.ServerCertificateCustomValidationCallback = (x, y, z, e) => true; handler.ServerCertificateCustomValidationCallback = (x, y, z, e) => true;
using (var http = new HttpClient(handler)) using (var http = new HttpClient(handler))
{ {
var url = http.AddFakeHeaders();
await http.GetStringAsync( var url = $"https://owapi.nadekobot.me/api/v3/u/{battletag}/stats";
$"https://api.lootbox.eu/pc/{region.ToLower()}/{battletag}/profile"); System.Console.WriteLine(url);
var model = JsonConvert.DeserializeObject<OverwatchApiModel.OverwatchPlayer>(url); var res = await http.GetStringAsync($"https://owapi.nadekobot.me/api/v3/u/{battletag}/stats");
return model.data; var model = JsonConvert.DeserializeObject<OverwatchApiModel.OverwatchResponse>(res);
switch (region)
{
case Region.Eu:
return model.Eu;
case Region.Kr:
return model.Kr;
default:
return model.Us;
}
} }
} }
} }

View File

@ -17,6 +17,8 @@ using NadekoBot.Modules.Games;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Threading; using System.Threading;
using NadekoBot.DataStructures; using NadekoBot.DataStructures;
using System.Diagnostics;
using System.Collections.Immutable;
namespace NadekoBot.Services namespace NadekoBot.Services
{ {
@ -34,7 +36,7 @@ namespace NadekoBot.Services
private readonly CommandService _commandService; private readonly CommandService _commandService;
private readonly Logger _log; private readonly Logger _log;
private List<IDMChannel> OwnerChannels { get; set; } = new List<IDMChannel>(); private ImmutableArray<AsyncLazy<IDMChannel>> ownerChannels { get; set; } = new ImmutableArray<AsyncLazy<IDMChannel>>();
public event Func<IUserMessage, CommandInfo, Task> CommandExecuted = delegate { return Task.CompletedTask; }; public event Func<IUserMessage, CommandInfo, Task> CommandExecuted = delegate { return Task.CompletedTask; };
@ -84,28 +86,15 @@ namespace NadekoBot.Services
var _ = Task.Run(async () => var _ = Task.Run(async () =>
{ {
await Task.Delay(5000).ConfigureAwait(false); await Task.Delay(5000).ConfigureAwait(false);
OwnerChannels = (await Task.WhenAll(_client.Guilds.SelectMany(g => g.Users)
.Where(u => NadekoBot.Credentials.OwnerIds.Contains(u.Id))
.Distinct(new GuildUserComparer())
.Select(async u =>
{
try
{
return await u.CreateDMChannelAsync();
}
catch
{
return null;
}
})))
.Where(ch => ch != null)
.OrderBy(x => NadekoBot.Credentials.OwnerIds.IndexOf(x.Id))
.ToList();
if (!OwnerChannels.Any()) _client.GetGuilds().SelectMany(g => g.Users);
LoadOwnerChannels();
if (!ownerChannels.Any())
_log.Warn("No owner channels created! Make sure you've specified correct OwnerId in the credentials.json file."); _log.Warn("No owner channels created! Make sure you've specified correct OwnerId in the credentials.json file.");
else else
_log.Info($"Created {OwnerChannels.Count} out of {NadekoBot.Credentials.OwnerIds.Length} owner message channels."); _log.Info($"Created {ownerChannels.Length} out of {NadekoBot.Credentials.OwnerIds.Length} owner message channels.");
}); });
_client.MessageReceived += MessageReceivedHandler; _client.MessageReceived += MessageReceivedHandler;
@ -133,6 +122,36 @@ namespace NadekoBot.Services
return Task.CompletedTask; return Task.CompletedTask;
} }
private void LoadOwnerChannels()
{
var hs = new HashSet<ulong>(NadekoBot.Credentials.OwnerIds);
var channels = new Dictionary<ulong, AsyncLazy<IDMChannel>>();
foreach (var s in _client.Shards)
{
if(hs.Count == 0)
break;
foreach (var g in s.Guilds)
{
if(hs.Count == 0)
break;
foreach (var u in g.Users)
{
if(hs.Remove(u.Id))
{
channels.Add(u.Id, new AsyncLazy<IDMChannel>(async () => await u.CreateDMChannelAsync()));
if(hs.Count == 0)
break;
}
}
}
}
ownerChannels = channels.OrderBy(x => NadekoBot.Credentials.OwnerIds.IndexOf(x.Key))
.Select(x => x.Value)
.ToImmutableArray();
}
private async Task<bool> TryRunCleverbot(IUserMessage usrMsg, SocketGuild guild) private async Task<bool> TryRunCleverbot(IUserMessage usrMsg, SocketGuild guild)
{ {
if (guild == null) if (guild == null)
@ -427,7 +446,7 @@ namespace NadekoBot.Services
await usrMsg.Channel.SendMessageAsync(Help.DMHelpString).ConfigureAwait(false); await usrMsg.Channel.SendMessageAsync(Help.DMHelpString).ConfigureAwait(false);
await SelfCommands.HandleDmForwarding(usrMsg, OwnerChannels).ConfigureAwait(false); await SelfCommands.HandleDmForwarding(usrMsg, ownerChannels).ConfigureAwait(false);
} }
} }
} }