Using declarations and other code reformats

This commit is contained in:
Kwoth
2021-12-26 03:22:45 +01:00
parent d18f9429c6
commit b85ba177cd
64 changed files with 2349 additions and 2736 deletions

View File

@@ -1,4 +1,24 @@
[*]
charset = utf-8-bom
end_of_line = crlf
trim_trailing_whitespace = false
insert_final_newline = false
indent_style = space
indent_size = 4
[{*.har,*.inputactions,*.jsb2,*.jsb3,*.json,.babelrc,.eslintrc,.stylelintrc,bowerrc,jest.config}]
indent_style = space
indent_size = 2
[{*.yaml,*.yml}]
indent_style = space
indent_size = 2
[*.proto]
indent_style = space
indent_size = 2
[*.{appxmanifest,asax,ascx,aspx,axaml,build,cg,cginc,compute,cs,cshtml,dtd,hlsl,hlsli,hlslinc,master,nuspec,paml,razor,resw,resx,shader,skin,usf,ush,vb,xaml,xamlx,xoml,xsd}] [*.{appxmanifest,asax,ascx,aspx,axaml,build,cg,cginc,compute,cs,cshtml,dtd,hlsl,hlsli,hlslinc,master,nuspec,paml,razor,resw,resx,shader,skin,usf,ush,vb,xaml,xamlx,xoml,xsd}]
indent_style = space indent_style = space
indent_size = 4 indent_size = 4
@@ -24,28 +44,15 @@ dotnet_naming_rule.private_constants_rule.import_to_resharper = as_predefined
dotnet_naming_rule.private_constants_rule.severity = suggestion dotnet_naming_rule.private_constants_rule.severity = suggestion
dotnet_naming_rule.private_constants_rule.style = all_upper_style dotnet_naming_rule.private_constants_rule.style = all_upper_style
dotnet_naming_rule.private_constants_rule.symbols = private_constants_symbols dotnet_naming_rule.private_constants_rule.symbols = private_constants_symbols
dotnet_naming_rule.private_static_readonly_rule.import_to_resharper = as_predefined
dotnet_naming_rule.private_static_readonly_rule.resharper_style = _ + aaBb, aaBb
dotnet_naming_rule.private_static_readonly_rule.severity = suggestion
dotnet_naming_rule.private_static_readonly_rule.style = lower_camel_case_style_1
dotnet_naming_rule.private_static_readonly_rule.symbols = private_static_readonly_symbols
dotnet_naming_rule.unity_serialized_field_rule.import_to_resharper = True dotnet_naming_rule.unity_serialized_field_rule.import_to_resharper = True
dotnet_naming_rule.unity_serialized_field_rule.resharper_description = Unity serialized field dotnet_naming_rule.unity_serialized_field_rule.resharper_description = Unity serialized field
dotnet_naming_rule.unity_serialized_field_rule.resharper_guid = 5f0fdb63-c892-4d2c-9324-15c80b22a7ef dotnet_naming_rule.unity_serialized_field_rule.resharper_guid = 5f0fdb63-c892-4d2c-9324-15c80b22a7ef
dotnet_naming_rule.unity_serialized_field_rule.severity = suggestion dotnet_naming_rule.unity_serialized_field_rule.severity = suggestion
dotnet_naming_rule.unity_serialized_field_rule.style = lower_camel_case_style dotnet_naming_rule.unity_serialized_field_rule.style = lower_camel_case_style
dotnet_naming_rule.unity_serialized_field_rule.symbols = unity_serialized_field_symbols dotnet_naming_rule.unity_serialized_field_rule.symbols = unity_serialized_field_symbols
dotnet_naming_rule.unity_serialized_field_rule_1.import_to_resharper = True
dotnet_naming_rule.unity_serialized_field_rule_1.resharper_description = Unity serialized field
dotnet_naming_rule.unity_serialized_field_rule_1.resharper_guid = 5f0fdb63-c892-4d2c-9324-15c80b22a7ef
dotnet_naming_rule.unity_serialized_field_rule_1.severity = suggestion
dotnet_naming_rule.unity_serialized_field_rule_1.style = lower_camel_case_style
dotnet_naming_rule.unity_serialized_field_rule_1.symbols = unity_serialized_field_symbols_1
dotnet_naming_style.all_upper_style.capitalization = all_upper dotnet_naming_style.all_upper_style.capitalization = all_upper
dotnet_naming_style.all_upper_style.word_separator = _ dotnet_naming_style.all_upper_style.word_separator = _
dotnet_naming_style.lower_camel_case_style.capitalization = camel_case dotnet_naming_style.lower_camel_case_style.capitalization = camel_case
dotnet_naming_style.lower_camel_case_style_1.capitalization = camel_case
dotnet_naming_style.lower_camel_case_style_1.required_prefix = _
dotnet_naming_symbols.constants_symbols.applicable_accessibilities = public,internal,protected,protected_internal,private_protected dotnet_naming_symbols.constants_symbols.applicable_accessibilities = public,internal,protected,protected_internal,private_protected
dotnet_naming_symbols.constants_symbols.applicable_kinds = field dotnet_naming_symbols.constants_symbols.applicable_kinds = field
dotnet_naming_symbols.constants_symbols.required_modifiers = const dotnet_naming_symbols.constants_symbols.required_modifiers = const
@@ -55,17 +62,10 @@ dotnet_naming_symbols.local_constants_symbols.required_modifiers = const
dotnet_naming_symbols.private_constants_symbols.applicable_accessibilities = private dotnet_naming_symbols.private_constants_symbols.applicable_accessibilities = private
dotnet_naming_symbols.private_constants_symbols.applicable_kinds = field dotnet_naming_symbols.private_constants_symbols.applicable_kinds = field
dotnet_naming_symbols.private_constants_symbols.required_modifiers = const dotnet_naming_symbols.private_constants_symbols.required_modifiers = const
dotnet_naming_symbols.private_static_readonly_symbols.applicable_accessibilities = private
dotnet_naming_symbols.private_static_readonly_symbols.applicable_kinds = field
dotnet_naming_symbols.private_static_readonly_symbols.required_modifiers = static,readonly
dotnet_naming_symbols.unity_serialized_field_symbols.applicable_accessibilities = * dotnet_naming_symbols.unity_serialized_field_symbols.applicable_accessibilities = *
dotnet_naming_symbols.unity_serialized_field_symbols.applicable_kinds = dotnet_naming_symbols.unity_serialized_field_symbols.applicable_kinds =
dotnet_naming_symbols.unity_serialized_field_symbols.resharper_applicable_kinds = unity_serialised_field dotnet_naming_symbols.unity_serialized_field_symbols.resharper_applicable_kinds = unity_serialised_field
dotnet_naming_symbols.unity_serialized_field_symbols.resharper_required_modifiers = instance dotnet_naming_symbols.unity_serialized_field_symbols.resharper_required_modifiers = instance
dotnet_naming_symbols.unity_serialized_field_symbols_1.applicable_accessibilities = *
dotnet_naming_symbols.unity_serialized_field_symbols_1.applicable_kinds =
dotnet_naming_symbols.unity_serialized_field_symbols_1.resharper_applicable_kinds = unity_serialised_field
dotnet_naming_symbols.unity_serialized_field_symbols_1.resharper_required_modifiers = instance
dotnet_style_parentheses_in_arithmetic_binary_operators = never_if_unnecessary:none dotnet_style_parentheses_in_arithmetic_binary_operators = never_if_unnecessary:none
dotnet_style_parentheses_in_other_binary_operators = never_if_unnecessary:none dotnet_style_parentheses_in_other_binary_operators = never_if_unnecessary:none
dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary:none dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary:none

View File

@@ -1,7 +1,7 @@
namespace NadekoBot.Common.Attributes; namespace NadekoBot.Common.Attributes;
[AttributeUsage(AttributeTargets.Class)] [AttributeUsage(AttributeTargets.Class)]
sealed class NadekoModuleAttribute : GroupAttribute internal sealed class NadekoModuleAttribute : GroupAttribute
{ {
public NadekoModuleAttribute(string moduleName) : base(moduleName) public NadekoModuleAttribute(string moduleName) : base(moduleName)
{ {

View File

@@ -4,7 +4,7 @@ namespace NadekoBot.Common;
public class NadekoRandom : Random public class NadekoRandom : Random
{ {
readonly RandomNumberGenerator _rng; private readonly RandomNumberGenerator _rng;
public NadekoRandom() : base() public NadekoRandom() : base()
{ {

View File

@@ -9,15 +9,13 @@ public static class OptionsParser
public static (T, bool) ParseFrom<T>(T options, string[] args) where T : INadekoCommandOptions public static (T, bool) ParseFrom<T>(T options, string[] args) where T : INadekoCommandOptions
{ {
using (var p = new Parser(x => using var p = new Parser(x =>
{
x.HelpWriter = null;
}))
{ {
var res = p.ParseArguments<T>(args); x.HelpWriter = null;
options = res.MapResult(x => x, x => options); });
options.NormalizeOptions(); var res = p.ParseArguments<T>(args);
return (options, res.Tag == ParserResultType.Parsed); options = res.MapResult(x => x, x => options);
} options.NormalizeOptions();
return (options, res.Tag == ParserResultType.Parsed);
} }
} }

View File

@@ -32,13 +32,11 @@ public class AdministrationService : INService
public (bool DelMsgOnCmd, IEnumerable<DelMsgOnCmdChannel> channels) GetDelMsgOnCmdData(ulong guildId) public (bool DelMsgOnCmd, IEnumerable<DelMsgOnCmdChannel> channels) GetDelMsgOnCmdData(ulong guildId)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ var conf = uow.GuildConfigsForId(guildId,
var conf = uow.GuildConfigsForId(guildId, set => set.Include(x => x.DelMsgOnCmdChannels));
set => set.Include(x => x.DelMsgOnCmdChannels));
return (conf.DeleteMessageOnCommand, conf.DelMsgOnCmdChannels); return (conf.DeleteMessageOnCommand, conf.DelMsgOnCmdChannels);
}
} }
private Task DelMsgOnCmd_Handler(IUserMessage msg, CommandInfo cmd) private Task DelMsgOnCmd_Handler(IUserMessage msg, CommandInfo cmd)
@@ -70,13 +68,11 @@ public class AdministrationService : INService
public bool ToggleDeleteMessageOnCommand(ulong guildId) public bool ToggleDeleteMessageOnCommand(ulong guildId)
{ {
bool enabled; bool enabled;
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ var conf = uow.GuildConfigsForId(guildId, set => set);
var conf = uow.GuildConfigsForId(guildId, set => set); enabled = conf.DeleteMessageOnCommand = !conf.DeleteMessageOnCommand;
enabled = conf.DeleteMessageOnCommand = !conf.DeleteMessageOnCommand;
uow.SaveChanges(); uow.SaveChanges();
}
return enabled; return enabled;
} }

View File

@@ -40,10 +40,8 @@ DELETE FROM Clubs;";
public async Task<int> ExecuteSql(string sql) public async Task<int> ExecuteSql(string sql)
{ {
int res; int res;
await using (var uow = _db.GetDbContext()) await using var uow = _db.GetDbContext();
{ res = await uow.Database.ExecuteSqlRawAsync(sql);
res = await uow.Database.ExecuteSqlRawAsync(sql);
}
return res; return res;
} }
@@ -61,30 +59,25 @@ DELETE FROM Clubs;";
Results = new(), Results = new(),
}; };
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
var conn = uow.Database.GetDbConnection();
using var cmd = conn.CreateCommand();
cmd.CommandText = sql;
using var reader = cmd.ExecuteReader();
if (reader.HasRows)
{ {
var conn = uow.Database.GetDbConnection(); for (var i = 0; i < reader.FieldCount; i++)
using (var cmd = conn.CreateCommand())
{ {
cmd.CommandText = sql; result.ColumnNames.Add(reader.GetName(i));
using (var reader = cmd.ExecuteReader()) }
{ while (reader.Read())
if (reader.HasRows) {
{ var obj = new object[reader.FieldCount];
for (var i = 0; i < reader.FieldCount; i++) reader.GetValues(obj);
{ result.Results.Add(obj.Select(x => x.ToString()).ToArray());
result.ColumnNames.Add(reader.GetName(i));
}
while (reader.Read())
{
var obj = new object[reader.FieldCount];
reader.GetValues(obj);
result.Results.Add(obj.Select(x => x.ToString()).ToArray());
}
}
}
} }
} }
return result; return result;
} }

View File

@@ -24,7 +24,7 @@ public class DiscordPermOverrideService : INService, ILateBlocker
.ToDictionary(o => (o.GuildId ?? 0, o.Command), o => o) .ToDictionary(o => (o.GuildId ?? 0, o.Command), o => o)
.ToConcurrent(); .ToConcurrent();
} }
public bool TryGetOverrides(ulong guildId, string commandName, out GuildPerm? perm) public bool TryGetOverrides(ulong guildId, string commandName, out GuildPerm? perm)
{ {
commandName = commandName.ToLowerInvariant(); commandName = commandName.ToLowerInvariant();
@@ -48,95 +48,82 @@ public class DiscordPermOverrideService : INService, ILateBlocker
public async Task AddOverride(ulong guildId, string commandName, GuildPerm perm) public async Task AddOverride(ulong guildId, string commandName, GuildPerm perm)
{ {
commandName = commandName.ToLowerInvariant(); commandName = commandName.ToLowerInvariant();
await using (var uow = _db.GetDbContext()) await using var uow = _db.GetDbContext();
var over = await uow
.Set<DiscordPermOverride>()
.AsQueryable()
.FirstOrDefaultAsync(x => x.GuildId == guildId && commandName == x.Command);
if (over is null)
{ {
var over = await uow uow.Set<DiscordPermOverride>()
.Set<DiscordPermOverride>() .Add(over = new() { Command = commandName, Perm = perm, GuildId = guildId, });
.AsQueryable()
.FirstOrDefaultAsync(x => x.GuildId == guildId && commandName == x.Command);
if (over is null)
{
uow.Set<DiscordPermOverride>()
.Add(over = new()
{
Command = commandName,
Perm = perm,
GuildId = guildId,
});
}
else
{
over.Perm = perm;
}
_overrides[(guildId, commandName)] = over;
await uow.SaveChangesAsync();
} }
else
{
over.Perm = perm;
}
_overrides[(guildId, commandName)] = over;
await uow.SaveChangesAsync();
} }
public async Task ClearAllOverrides(ulong guildId) public async Task ClearAllOverrides(ulong guildId)
{ {
await using (var uow = _db.GetDbContext()) await using var uow = _db.GetDbContext();
{ var overrides = await uow
var overrides = await uow .Set<DiscordPermOverride>()
.Set<DiscordPermOverride>() .AsQueryable()
.AsQueryable() .AsNoTracking()
.AsNoTracking() .Where(x => x.GuildId == guildId)
.Where(x => x.GuildId == guildId) .ToListAsync();
.ToListAsync();
uow.RemoveRange(overrides);
await uow.SaveChangesAsync();
foreach (var over in overrides) uow.RemoveRange(overrides);
{ await uow.SaveChangesAsync();
_overrides.TryRemove((guildId, over.Command), out _);
} foreach (var over in overrides)
{
_overrides.TryRemove((guildId, over.Command), out _);
} }
} }
public async Task RemoveOverride(ulong guildId, string commandName) public async Task RemoveOverride(ulong guildId, string commandName)
{ {
commandName = commandName.ToLowerInvariant(); commandName = commandName.ToLowerInvariant();
await using (var uow = _db.GetDbContext()) await using var uow = _db.GetDbContext();
{ var over = await uow
var over = await uow .Set<DiscordPermOverride>()
.Set<DiscordPermOverride>() .AsQueryable()
.AsQueryable() .AsNoTracking()
.AsNoTracking() .FirstOrDefaultAsync(x => x.GuildId == guildId && x.Command == commandName);
.FirstOrDefaultAsync(x => x.GuildId == guildId && x.Command == commandName);
if (over is null) if (over is null)
return; return;
uow.Remove(over);
await uow.SaveChangesAsync();
_overrides.TryRemove((guildId, commandName), out _); uow.Remove(over);
} await uow.SaveChangesAsync();
_overrides.TryRemove((guildId, commandName), out _);
} }
public Task<List<DiscordPermOverride>> GetAllOverrides(ulong guildId) public async Task<List<DiscordPermOverride>> GetAllOverrides(ulong guildId)
{ {
using (var uow = _db.GetDbContext()) await using var uow = _db.GetDbContext();
{ return await uow
return uow .Set<DiscordPermOverride>()
.Set<DiscordPermOverride>() .AsQueryable()
.AsQueryable() .AsNoTracking()
.AsNoTracking() .Where(x => x.GuildId == guildId)
.Where(x => x.GuildId == guildId) .ToListAsync();
.ToListAsync();
}
} }
public async Task<bool> TryBlockLate(ICommandContext context, string moduleName, CommandInfo command) public async Task<bool> TryBlockLate(ICommandContext context, string moduleName, CommandInfo command)
{ {
if (TryGetOverrides(context.Guild?.Id ?? 0, command.Name, out var perm) && perm is not null) if (TryGetOverrides(context.Guild?.Id ?? 0, command.Name, out var perm) && perm is not null)
{ {
var result = await new RequireUserPermissionAttribute((GuildPermission) perm) var result = await new RequireUserPermissionAttribute((GuildPermission)perm)
.CheckPermissionsAsync(context, command, _services); .CheckPermissionsAsync(context, command, _services);
return !result.IsSuccess; return !result.IsSuccess;

View File

@@ -56,25 +56,23 @@ public class GameVoiceChannelService : INService
public ulong? ToggleGameVoiceChannel(ulong guildId, ulong vchId) public ulong? ToggleGameVoiceChannel(ulong guildId, ulong vchId)
{ {
ulong? id; ulong? id;
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
var gc = uow.GuildConfigsForId(guildId, set => set);
if (gc.GameVoiceChannel == vchId)
{ {
var gc = uow.GuildConfigsForId(guildId, set => set); GameVoiceChannels.TryRemove(vchId);
id = gc.GameVoiceChannel = null;
if (gc.GameVoiceChannel == vchId)
{
GameVoiceChannels.TryRemove(vchId);
id = gc.GameVoiceChannel = null;
}
else
{
if (gc.GameVoiceChannel != null)
GameVoiceChannels.TryRemove(gc.GameVoiceChannel.Value);
GameVoiceChannels.Add(vchId);
id = gc.GameVoiceChannel = vchId;
}
uow.SaveChanges();
} }
else
{
if (gc.GameVoiceChannel != null)
GameVoiceChannels.TryRemove(gc.GameVoiceChannel.Value);
GameVoiceChannels.Add(vchId);
id = gc.GameVoiceChannel = vchId;
}
uow.SaveChanges();
return id; return id;
} }

View File

@@ -59,18 +59,16 @@ public class GuildTimezoneService : INService
public void SetTimeZone(ulong guildId, TimeZoneInfo tz) public void SetTimeZone(ulong guildId, TimeZoneInfo tz)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ var gc = uow.GuildConfigsForId(guildId, set => set);
var gc = uow.GuildConfigsForId(guildId, set => set);
gc.TimeZoneId = tz?.Id; gc.TimeZoneId = tz?.Id;
uow.SaveChanges(); uow.SaveChanges();
if (tz is null) if (tz is null)
_timezones.TryRemove(guildId, out tz); _timezones.TryRemove(guildId, out tz);
else else
_timezones.AddOrUpdate(guildId, tz, (key, old) => tz); _timezones.AddOrUpdate(guildId, tz, (key, old) => tz);
}
} }
public TimeZoneInfo GetTimeZoneOrUtc(ulong guildId) public TimeZoneInfo GetTimeZoneOrUtc(ulong guildId)

View File

@@ -198,30 +198,28 @@ public sealed class LogCommandService : ILogCommandService
public async Task LogServer(ulong guildId, ulong channelId, bool value) public async Task LogServer(ulong guildId, ulong channelId, bool value)
{ {
await using (var uow = _db.GetDbContext()) await using var uow = _db.GetDbContext();
{ var logSetting = uow.LogSettingsFor(guildId);
var logSetting = uow.LogSettingsFor(guildId);
logSetting.LogOtherId = logSetting.LogOtherId =
logSetting.MessageUpdatedId = logSetting.MessageUpdatedId =
logSetting.MessageDeletedId = logSetting.MessageDeletedId =
logSetting.UserJoinedId = logSetting.UserJoinedId =
logSetting.UserLeftId = logSetting.UserLeftId =
logSetting.UserBannedId = logSetting.UserBannedId =
logSetting.UserUnbannedId = logSetting.UserUnbannedId =
logSetting.UserUpdatedId = logSetting.UserUpdatedId =
logSetting.ChannelCreatedId = logSetting.ChannelCreatedId =
logSetting.ChannelDestroyedId = logSetting.ChannelDestroyedId =
logSetting.ChannelUpdatedId = logSetting.ChannelUpdatedId =
logSetting.LogUserPresenceId = logSetting.LogUserPresenceId =
logSetting.LogVoicePresenceId = logSetting.LogVoicePresenceId =
logSetting.UserMutedId = logSetting.UserMutedId =
logSetting.LogVoicePresenceTTSId = logSetting.LogVoicePresenceTTSId =
value ? channelId : null; value ? channelId : null;
; ;
await uow.SaveChangesAsync(); await uow.SaveChangesAsync();
GuildLogSettings.AddOrUpdate(guildId, id => logSetting, (id, old) => logSetting); GuildLogSettings.AddOrUpdate(guildId, id => logSetting, (id, old) => logSetting);
}
} }
private Task _client_UserUpdated(SocketUser before, SocketUser uAfter) private Task _client_UserUpdated(SocketUser before, SocketUser uAfter)
@@ -1193,60 +1191,58 @@ public sealed class LogCommandService : ILogCommandService
private void UnsetLogSetting(ulong guildId, LogType logChannelType) private void UnsetLogSetting(ulong guildId, LogType logChannelType)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
var newLogSetting = uow.LogSettingsFor(guildId);
switch (logChannelType)
{ {
var newLogSetting = uow.LogSettingsFor(guildId); case LogType.Other:
switch (logChannelType) newLogSetting.LogOtherId = null;
{ break;
case LogType.Other: case LogType.MessageUpdated:
newLogSetting.LogOtherId = null; newLogSetting.MessageUpdatedId = null;
break; break;
case LogType.MessageUpdated: case LogType.MessageDeleted:
newLogSetting.MessageUpdatedId = null; newLogSetting.MessageDeletedId = null;
break; break;
case LogType.MessageDeleted: case LogType.UserJoined:
newLogSetting.MessageDeletedId = null; newLogSetting.UserJoinedId = null;
break; break;
case LogType.UserJoined: case LogType.UserLeft:
newLogSetting.UserJoinedId = null; newLogSetting.UserLeftId = null;
break; break;
case LogType.UserLeft: case LogType.UserBanned:
newLogSetting.UserLeftId = null; newLogSetting.UserBannedId = null;
break; break;
case LogType.UserBanned: case LogType.UserUnbanned:
newLogSetting.UserBannedId = null; newLogSetting.UserUnbannedId = null;
break; break;
case LogType.UserUnbanned: case LogType.UserUpdated:
newLogSetting.UserUnbannedId = null; newLogSetting.UserUpdatedId = null;
break; break;
case LogType.UserUpdated: case LogType.UserMuted:
newLogSetting.UserUpdatedId = null; newLogSetting.UserMutedId = null;
break; break;
case LogType.UserMuted: case LogType.ChannelCreated:
newLogSetting.UserMutedId = null; newLogSetting.ChannelCreatedId = null;
break; break;
case LogType.ChannelCreated: case LogType.ChannelDestroyed:
newLogSetting.ChannelCreatedId = null; newLogSetting.ChannelDestroyedId = null;
break; break;
case LogType.ChannelDestroyed: case LogType.ChannelUpdated:
newLogSetting.ChannelDestroyedId = null; newLogSetting.ChannelUpdatedId = null;
break; break;
case LogType.ChannelUpdated: case LogType.UserPresence:
newLogSetting.ChannelUpdatedId = null; newLogSetting.LogUserPresenceId = null;
break; break;
case LogType.UserPresence: case LogType.VoicePresence:
newLogSetting.LogUserPresenceId = null; newLogSetting.LogVoicePresenceId = null;
break; break;
case LogType.VoicePresence: case LogType.VoicePresenceTTS:
newLogSetting.LogVoicePresenceId = null; newLogSetting.LogVoicePresenceTTSId = null;
break; break;
case LogType.VoicePresenceTTS:
newLogSetting.LogVoicePresenceTTSId = null;
break;
}
GuildLogSettings.AddOrUpdate(guildId, newLogSetting, (gid, old) => newLogSetting);
uow.SaveChanges();
} }
GuildLogSettings.AddOrUpdate(guildId, newLogSetting, (gid, old) => newLogSetting);
uow.SaveChanges();
} }
} }

View File

@@ -163,13 +163,11 @@ public class MuteService : INService
public async Task SetMuteRoleAsync(ulong guildId, string name) public async Task SetMuteRoleAsync(ulong guildId, string name)
{ {
await using (var uow = _db.GetDbContext()) await using var uow = _db.GetDbContext();
{ var config = uow.GuildConfigsForId(guildId, set => set);
var config = uow.GuildConfigsForId(guildId, set => set); config.MuteRoleName = name;
config.MuteRoleName = name; GuildMuteRoles.AddOrUpdate(guildId, name, (id, old) => name);
GuildMuteRoles.AddOrUpdate(guildId, name, (id, old) => name); await uow.SaveChangesAsync();
await uow.SaveChangesAsync();
}
} }
public async Task MuteUser(IGuildUser usr, IUser mod, MuteType type = MuteType.All, string reason = "") public async Task MuteUser(IGuildUser usr, IUser mod, MuteType type = MuteType.All, string reason = "")
@@ -445,24 +443,22 @@ public class MuteService : INService
private void RemoveTimerFromDb(ulong guildId, ulong userId, TimerType type) private void RemoveTimerFromDb(ulong guildId, ulong userId, TimerType type)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
object toDelete;
if (type == TimerType.Mute)
{ {
object toDelete; var config = uow.GuildConfigsForId(guildId, set => set.Include(x => x.UnmuteTimers));
if (type == TimerType.Mute) toDelete = config.UnmuteTimers.FirstOrDefault(x => x.UserId == userId);
{
var config = uow.GuildConfigsForId(guildId, set => set.Include(x => x.UnmuteTimers));
toDelete = config.UnmuteTimers.FirstOrDefault(x => x.UserId == userId);
}
else
{
var config = uow.GuildConfigsForId(guildId, set => set.Include(x => x.UnbanTimer));
toDelete = config.UnbanTimer.FirstOrDefault(x => x.UserId == userId);
}
if (toDelete != null)
{
uow.Remove(toDelete);
}
uow.SaveChanges();
} }
else
{
var config = uow.GuildConfigsForId(guildId, set => set.Include(x => x.UnbanTimer));
toDelete = config.UnbanTimer.FirstOrDefault(x => x.UserId == userId);
}
if (toDelete != null)
{
uow.Remove(toDelete);
}
uow.SaveChanges();
} }
} }

View File

@@ -290,13 +290,11 @@ public class ProtectionService : INService
_antiRaidGuilds.AddOrUpdate(guildId, stats, (key, old) => stats); _antiRaidGuilds.AddOrUpdate(guildId, stats, (key, old) => stats);
await using (var uow = _db.GetDbContext()) await using var uow = _db.GetDbContext();
{ var gc = uow.GuildConfigsForId(guildId, set => set.Include(x => x.AntiRaidSetting));
var gc = uow.GuildConfigsForId(guildId, set => set.Include(x => x.AntiRaidSetting));
gc.AntiRaidSetting = stats.AntiRaidSettings; gc.AntiRaidSetting = stats.AntiRaidSettings;
await uow.SaveChangesAsync(); await uow.SaveChangesAsync();
}
return stats; return stats;
} }
@@ -305,13 +303,11 @@ public class ProtectionService : INService
{ {
if (_antiRaidGuilds.TryRemove(guildId, out _)) if (_antiRaidGuilds.TryRemove(guildId, out _))
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ var gc = uow.GuildConfigsForId(guildId, set => set.Include(x => x.AntiRaidSetting));
var gc = uow.GuildConfigsForId(guildId, set => set.Include(x => x.AntiRaidSetting));
gc.AntiRaidSetting = null; gc.AntiRaidSetting = null;
uow.SaveChanges(); uow.SaveChanges();
}
return true; return true;
} }
return false; return false;
@@ -322,14 +318,12 @@ public class ProtectionService : INService
if (_antiSpamGuilds.TryRemove(guildId, out var removed)) if (_antiSpamGuilds.TryRemove(guildId, out var removed))
{ {
removed.UserStats.ForEach(x => x.Value.Dispose()); removed.UserStats.ForEach(x => x.Value.Dispose());
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ var gc = uow.GuildConfigsForId(guildId, set => set.Include(x => x.AntiSpamSetting)
var gc = uow.GuildConfigsForId(guildId, set => set.Include(x => x.AntiSpamSetting) .ThenInclude(x => x.IgnoredChannels));
.ThenInclude(x => x.IgnoredChannels));
gc.AntiSpamSetting = null; gc.AntiSpamSetting = null;
uow.SaveChanges(); uow.SaveChanges();
}
return true; return true;
} }
return false; return false;
@@ -361,23 +355,21 @@ public class ProtectionService : INService
return stats; return stats;
}); });
await using (var uow = _db.GetDbContext()) await using var uow = _db.GetDbContext();
{ var gc = uow.GuildConfigsForId(guildId, set => set.Include(x => x.AntiSpamSetting));
var gc = uow.GuildConfigsForId(guildId, set => set.Include(x => x.AntiSpamSetting));
if (gc.AntiSpamSetting != null) if (gc.AntiSpamSetting != null)
{ {
gc.AntiSpamSetting.Action = stats.AntiSpamSettings.Action; gc.AntiSpamSetting.Action = stats.AntiSpamSettings.Action;
gc.AntiSpamSetting.MessageThreshold = stats.AntiSpamSettings.MessageThreshold; gc.AntiSpamSetting.MessageThreshold = stats.AntiSpamSettings.MessageThreshold;
gc.AntiSpamSetting.MuteTime = stats.AntiSpamSettings.MuteTime; gc.AntiSpamSetting.MuteTime = stats.AntiSpamSettings.MuteTime;
gc.AntiSpamSetting.RoleId = stats.AntiSpamSettings.RoleId; gc.AntiSpamSetting.RoleId = stats.AntiSpamSettings.RoleId;
}
else
{
gc.AntiSpamSetting = stats.AntiSpamSettings;
}
await uow.SaveChangesAsync();
} }
else
{
gc.AntiSpamSetting = stats.AntiSpamSettings;
}
await uow.SaveChangesAsync();
return stats; return stats;
} }
@@ -388,34 +380,32 @@ public class ProtectionService : INService
ChannelId = channelId ChannelId = channelId
}; };
bool added; bool added;
await using (var uow = _db.GetDbContext()) await using var uow = _db.GetDbContext();
var gc = uow.GuildConfigsForId(guildId, set => set.Include(x => x.AntiSpamSetting).ThenInclude(x => x.IgnoredChannels));
var spam = gc.AntiSpamSetting;
if (spam is null)
{ {
var gc = uow.GuildConfigsForId(guildId, set => set.Include(x => x.AntiSpamSetting).ThenInclude(x => x.IgnoredChannels)); return null;
var spam = gc.AntiSpamSetting;
if (spam is null)
{
return null;
}
if (spam.IgnoredChannels.Add(obj)) // if adding to db is successful
{
if (_antiSpamGuilds.TryGetValue(guildId, out var temp))
temp.AntiSpamSettings.IgnoredChannels.Add(obj); // add to local cache
added = true;
}
else
{
var toRemove = spam.IgnoredChannels.First(x => x.ChannelId == channelId);
uow.Set<AntiSpamIgnore>().Remove(toRemove); // remove from db
if (_antiSpamGuilds.TryGetValue(guildId, out var temp))
{
temp.AntiSpamSettings.IgnoredChannels.Remove(toRemove); // remove from local cache
}
added = false;
}
await uow.SaveChangesAsync();
} }
if (spam.IgnoredChannels.Add(obj)) // if adding to db is successful
{
if (_antiSpamGuilds.TryGetValue(guildId, out var temp))
temp.AntiSpamSettings.IgnoredChannels.Add(obj); // add to local cache
added = true;
}
else
{
var toRemove = spam.IgnoredChannels.First(x => x.ChannelId == channelId);
uow.Set<AntiSpamIgnore>().Remove(toRemove); // remove from db
if (_antiSpamGuilds.TryGetValue(guildId, out var temp))
{
temp.AntiSpamSettings.IgnoredChannels.Remove(toRemove); // remove from local cache
}
added = false;
}
await uow.SaveChangesAsync();
return added; return added;
} }

View File

@@ -163,19 +163,17 @@ public class RoleCommandsService : INService
public void Remove(ulong id, int index) public void Remove(ulong id, int index)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ var gc = uow.GuildConfigsForId(id,
var gc = uow.GuildConfigsForId(id, set => set.Include(x => x.ReactionRoleMessages)
set => set.Include(x => x.ReactionRoleMessages) .ThenInclude(x => x.ReactionRoles));
.ThenInclude(x => x.ReactionRoles)); uow.Set<ReactionRole>()
uow.Set<ReactionRole>() .RemoveRange(gc.ReactionRoleMessages[index].ReactionRoles);
.RemoveRange(gc.ReactionRoleMessages[index].ReactionRoles); gc.ReactionRoleMessages.RemoveAt(index);
gc.ReactionRoleMessages.RemoveAt(index); _models.AddOrUpdate(id,
_models.AddOrUpdate(id, gc.ReactionRoleMessages,
gc.ReactionRoleMessages, delegate { return gc.ReactionRoleMessages; });
delegate { return gc.ReactionRoleMessages; }); uow.SaveChanges();
uow.SaveChanges();
}
} }
/// <summary> /// <summary>

View File

@@ -33,34 +33,30 @@ public class SelfAssignedRolesService : INService
public bool AddNew(ulong guildId, IRole role, int group) public bool AddNew(ulong guildId, IRole role, int group)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
var roles = uow.SelfAssignableRoles.GetFromGuild(guildId);
if (roles.Any(s => s.RoleId == role.Id && s.GuildId == role.Guild.Id))
{ {
var roles = uow.SelfAssignableRoles.GetFromGuild(guildId); return false;
if (roles.Any(s => s.RoleId == role.Id && s.GuildId == role.Guild.Id))
{
return false;
}
uow.SelfAssignableRoles.Add(new()
{
Group = group,
RoleId = role.Id,
GuildId = role.Guild.Id
});
uow.SaveChanges();
} }
uow.SelfAssignableRoles.Add(new()
{
Group = @group,
RoleId = role.Id,
GuildId = role.Guild.Id
});
uow.SaveChanges();
return true; return true;
} }
public bool ToggleAdSarm(ulong guildId) public bool ToggleAdSarm(ulong guildId)
{ {
bool newval; bool newval;
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ var config = uow.GuildConfigsForId(guildId, set => set);
var config = uow.GuildConfigsForId(guildId, set => set); newval = config.AutoDeleteSelfAssignedRoleMessages = !config.AutoDeleteSelfAssignedRoleMessages;
newval = config.AutoDeleteSelfAssignedRoleMessages = !config.AutoDeleteSelfAssignedRoleMessages; uow.SaveChanges();
uow.SaveChanges();
}
return newval; return newval;
} }
@@ -129,33 +125,31 @@ public class SelfAssignedRolesService : INService
public async Task<bool> SetNameAsync(ulong guildId, int group, string name) public async Task<bool> SetNameAsync(ulong guildId, int group, string name)
{ {
var set = false; var set = false;
await using (var uow = _db.GetDbContext()) await using var uow = _db.GetDbContext();
var gc = uow.GuildConfigsForId(guildId, y => y.Include(x => x.SelfAssignableRoleGroupNames));
var toUpdate = gc.SelfAssignableRoleGroupNames.FirstOrDefault(x => x.Number == @group);
if (string.IsNullOrWhiteSpace(name))
{ {
var gc = uow.GuildConfigsForId(guildId, y => y.Include(x => x.SelfAssignableRoleGroupNames)); if (toUpdate != null)
var toUpdate = gc.SelfAssignableRoleGroupNames.FirstOrDefault(x => x.Number == group); gc.SelfAssignableRoleGroupNames.Remove(toUpdate);
if (string.IsNullOrWhiteSpace(name))
{
if (toUpdate != null)
gc.SelfAssignableRoleGroupNames.Remove(toUpdate);
}
else if (toUpdate is null)
{
gc.SelfAssignableRoleGroupNames.Add(new()
{
Name = name,
Number = group,
});
set = true;
}
else
{
toUpdate.Name = name;
set = true;
}
await uow.SaveChangesAsync();
} }
else if (toUpdate is null)
{
gc.SelfAssignableRoleGroupNames.Add(new()
{
Name = name,
Number = @group,
});
set = true;
}
else
{
toUpdate.Name = name;
set = true;
}
await uow.SaveChangesAsync();
return set; return set;
} }
@@ -187,42 +181,36 @@ public class SelfAssignedRolesService : INService
public bool RemoveSar(ulong guildId, ulong roleId) public bool RemoveSar(ulong guildId, ulong roleId)
{ {
bool success; bool success;
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ success = uow.SelfAssignableRoles.DeleteByGuildAndRoleId(guildId, roleId);
success = uow.SelfAssignableRoles.DeleteByGuildAndRoleId(guildId, roleId); uow.SaveChanges();
uow.SaveChanges();
}
return success; return success;
} }
public (bool AutoDelete, bool Exclusive, IEnumerable<SelfAssignedRole>) GetAdAndRoles(ulong guildId) public (bool AutoDelete, bool Exclusive, IEnumerable<SelfAssignedRole>) GetAdAndRoles(ulong guildId)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ var gc = uow.GuildConfigsForId(guildId, set => set);
var gc = uow.GuildConfigsForId(guildId, set => set); var autoDelete = gc.AutoDeleteSelfAssignedRoleMessages;
var autoDelete = gc.AutoDeleteSelfAssignedRoleMessages; var exclusive = gc.ExclusiveSelfAssignedRoles;
var exclusive = gc.ExclusiveSelfAssignedRoles; var roles = uow.SelfAssignableRoles.GetFromGuild(guildId);
var roles = uow.SelfAssignableRoles.GetFromGuild(guildId);
return (autoDelete, exclusive, roles); return (autoDelete, exclusive, roles);
}
} }
public bool SetLevelReq(ulong guildId, IRole role, int level) public bool SetLevelReq(ulong guildId, IRole role, int level)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
var roles = uow.SelfAssignableRoles.GetFromGuild(guildId);
var sar = roles.FirstOrDefault(x => x.RoleId == role.Id);
if (sar != null)
{ {
var roles = uow.SelfAssignableRoles.GetFromGuild(guildId); sar.LevelRequirement = level;
var sar = roles.FirstOrDefault(x => x.RoleId == role.Id); uow.SaveChanges();
if (sar != null) }
{ else
sar.LevelRequirement = level; {
uow.SaveChanges(); return false;
}
else
{
return false;
}
} }
return true; return true;
@@ -231,13 +219,11 @@ public class SelfAssignedRolesService : INService
public bool ToggleEsar(ulong guildId) public bool ToggleEsar(ulong guildId)
{ {
bool areExclusive; bool areExclusive;
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ var config = uow.GuildConfigsForId(guildId, set => set);
var config = uow.GuildConfigsForId(guildId, set => set);
areExclusive = config.ExclusiveSelfAssignedRoles = !config.ExclusiveSelfAssignedRoles; areExclusive = config.ExclusiveSelfAssignedRoles = !config.ExclusiveSelfAssignedRoles;
uow.SaveChanges(); uow.SaveChanges();
}
return areExclusive; return areExclusive;
} }

View File

@@ -273,20 +273,18 @@ public sealed class SelfService : ILateExecutor, IReadyExecutor, INService
public bool RemoveStartupCommand(int index, out AutoCommand cmd) public bool RemoveStartupCommand(int index, out AutoCommand cmd)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ cmd = uow.AutoCommands
cmd = uow.AutoCommands .AsNoTracking()
.AsNoTracking() .Where(x => x.Interval == 0)
.Where(x => x.Interval == 0) .Skip(index)
.Skip(index) .FirstOrDefault();
.FirstOrDefault();
if (cmd != null) if (cmd != null)
{ {
uow.Remove(cmd); uow.Remove(cmd);
uow.SaveChanges(); uow.SaveChanges();
return true; return true;
}
} }
return false; return false;
@@ -294,23 +292,21 @@ public sealed class SelfService : ILateExecutor, IReadyExecutor, INService
public bool RemoveAutoCommand(int index, out AutoCommand cmd) public bool RemoveAutoCommand(int index, out AutoCommand cmd)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ cmd = uow.AutoCommands
cmd = uow.AutoCommands .AsNoTracking()
.AsNoTracking() .Where(x => x.Interval >= 5)
.Where(x => x.Interval >= 5) .Skip(index)
.Skip(index) .FirstOrDefault();
.FirstOrDefault();
if (cmd != null) if (cmd != null)
{ {
uow.Remove(cmd); uow.Remove(cmd);
if (_autoCommands.TryGetValue(cmd.GuildId, out var autos)) if (_autoCommands.TryGetValue(cmd.GuildId, out var autos))
if (autos.TryRemove(cmd.Id, out var timer)) if (autos.TryRemove(cmd.Id, out var timer))
timer.Change(Timeout.Infinite, Timeout.Infinite); timer.Change(Timeout.Infinite, Timeout.Infinite);
uow.SaveChanges(); uow.SaveChanges();
return true; return true;
}
} }
return false; return false;
@@ -326,35 +322,29 @@ public sealed class SelfService : ILateExecutor, IReadyExecutor, INService
var uri = new Uri(img); var uri = new Uri(img);
using (var http = _httpFactory.CreateClient()) using var http = _httpFactory.CreateClient();
using (var sr = await http.GetAsync(uri, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false)) using var sr = await http.GetAsync(uri, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
{ if (!sr.IsImage())
if (!sr.IsImage()) return false;
return false;
// i can't just do ReadAsStreamAsync because dicord.net's image poops itself // i can't just do ReadAsStreamAsync because dicord.net's image poops itself
var imgData = await sr.Content.ReadAsByteArrayAsync().ConfigureAwait(false); var imgData = await sr.Content.ReadAsByteArrayAsync().ConfigureAwait(false);
await using (var imgStream = imgData.ToStream()) await using var imgStream = imgData.ToStream();
{ await _client.CurrentUser.ModifyAsync(u => u.Avatar = new Image(imgStream)).ConfigureAwait(false);
await _client.CurrentUser.ModifyAsync(u => u.Avatar = new Image(imgStream)).ConfigureAwait(false);
}
}
return true; return true;
} }
public void ClearStartupCommands() public void ClearStartupCommands()
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ var toRemove = uow
var toRemove = uow .AutoCommands
.AutoCommands .AsNoTracking()
.AsNoTracking() .Where(x => x.Interval == 0);
.Where(x => x.Interval == 0);
uow.AutoCommands.RemoveRange(toRemove); uow.AutoCommands.RemoveRange(toRemove);
uow.SaveChanges(); uow.SaveChanges();
}
} }
public Task ReloadImagesAsync() public Task ReloadImagesAsync()

View File

@@ -198,54 +198,50 @@ public class UserPunishService : INService
public async Task CheckAllWarnExpiresAsync() public async Task CheckAllWarnExpiresAsync()
{ {
await using (var uow = _db.GetDbContext()) await using var uow = _db.GetDbContext();
{ var cleared = await uow.Database.ExecuteSqlRawAsync($@"UPDATE Warnings
var cleared = await uow.Database.ExecuteSqlRawAsync($@"UPDATE Warnings
SET Forgiven = 1, SET Forgiven = 1,
ForgivenBy = 'Expiry' ForgivenBy = 'Expiry'
WHERE GuildId in (SELECT GuildId FROM GuildConfigs WHERE WarnExpireHours > 0 AND WarnExpireAction = 0) WHERE GuildId in (SELECT GuildId FROM GuildConfigs WHERE WarnExpireHours > 0 AND WarnExpireAction = 0)
AND Forgiven = 0 AND Forgiven = 0
AND DateAdded < datetime('now', (SELECT '-' || WarnExpireHours || ' hours' FROM GuildConfigs as gc WHERE gc.GuildId = Warnings.GuildId));"); AND DateAdded < datetime('now', (SELECT '-' || WarnExpireHours || ' hours' FROM GuildConfigs as gc WHERE gc.GuildId = Warnings.GuildId));");
var deleted = await uow.Database.ExecuteSqlRawAsync($@"DELETE FROM Warnings var deleted = await uow.Database.ExecuteSqlRawAsync($@"DELETE FROM Warnings
WHERE GuildId in (SELECT GuildId FROM GuildConfigs WHERE WarnExpireHours > 0 AND WarnExpireAction = 1) WHERE GuildId in (SELECT GuildId FROM GuildConfigs WHERE WarnExpireHours > 0 AND WarnExpireAction = 1)
AND DateAdded < datetime('now', (SELECT '-' || WarnExpireHours || ' hours' FROM GuildConfigs as gc WHERE gc.GuildId = Warnings.GuildId));"); AND DateAdded < datetime('now', (SELECT '-' || WarnExpireHours || ' hours' FROM GuildConfigs as gc WHERE gc.GuildId = Warnings.GuildId));");
if(cleared > 0 || deleted > 0) if(cleared > 0 || deleted > 0)
{ {
Log.Information($"Cleared {cleared} warnings and deleted {deleted} warnings due to expiry."); Log.Information($"Cleared {cleared} warnings and deleted {deleted} warnings due to expiry.");
}
} }
} }
public async Task CheckWarnExpiresAsync(ulong guildId) public async Task CheckWarnExpiresAsync(ulong guildId)
{ {
await using (var uow = _db.GetDbContext()) await using var uow = _db.GetDbContext();
var config = uow.GuildConfigsForId(guildId, inc => inc);
if (config.WarnExpireHours == 0)
return;
var hours = $"{-config.WarnExpireHours} hours";
if (config.WarnExpireAction == WarnExpireAction.Clear)
{ {
var config = uow.GuildConfigsForId(guildId, inc => inc); await uow.Database.ExecuteSqlInterpolatedAsync($@"UPDATE warnings
if (config.WarnExpireHours == 0)
return;
var hours = $"{-config.WarnExpireHours} hours";
if (config.WarnExpireAction == WarnExpireAction.Clear)
{
await uow.Database.ExecuteSqlInterpolatedAsync($@"UPDATE warnings
SET Forgiven = 1, SET Forgiven = 1,
ForgivenBy = 'Expiry' ForgivenBy = 'Expiry'
WHERE GuildId={guildId} WHERE GuildId={guildId}
AND Forgiven = 0 AND Forgiven = 0
AND DateAdded < datetime('now', {hours})"); AND DateAdded < datetime('now', {hours})");
} }
else if (config.WarnExpireAction == WarnExpireAction.Delete) else if (config.WarnExpireAction == WarnExpireAction.Delete)
{ {
await uow.Database.ExecuteSqlInterpolatedAsync($@"DELETE FROM warnings await uow.Database.ExecuteSqlInterpolatedAsync($@"DELETE FROM warnings
WHERE GuildId={guildId} WHERE GuildId={guildId}
AND DateAdded < datetime('now', {hours})"); AND DateAdded < datetime('now', {hours})");
}
await uow.SaveChangesAsync();
} }
await uow.SaveChangesAsync();
} }
public Task<int> GetWarnExpire(ulong guildId) public Task<int> GetWarnExpire(ulong guildId)
@@ -275,35 +271,29 @@ WHERE GuildId={guildId}
public IGrouping<ulong, Warning>[] WarnlogAll(ulong gid) public IGrouping<ulong, Warning>[] WarnlogAll(ulong gid)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ return uow.Warnings.GetForGuild(gid).GroupBy(x => x.UserId).ToArray();
return uow.Warnings.GetForGuild(gid).GroupBy(x => x.UserId).ToArray();
}
} }
public Warning[] UserWarnings(ulong gid, ulong userId) public Warning[] UserWarnings(ulong gid, ulong userId)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ return uow.Warnings.ForId(gid, userId);
return uow.Warnings.ForId(gid, userId);
}
} }
public async Task<bool> WarnClearAsync(ulong guildId, ulong userId, int index, string moderator) public async Task<bool> WarnClearAsync(ulong guildId, ulong userId, int index, string moderator)
{ {
var toReturn = true; var toReturn = true;
await using (var uow = _db.GetDbContext()) await using var uow = _db.GetDbContext();
if (index == 0)
{ {
if (index == 0) await uow.Warnings.ForgiveAll(guildId, userId, moderator);
{
await uow.Warnings.ForgiveAll(guildId, userId, moderator);
}
else
{
toReturn = uow.Warnings.Forgive(guildId, userId, moderator, index - 1);
}
uow.SaveChanges();
} }
else
{
toReturn = uow.Warnings.Forgive(guildId, userId, moderator, index - 1);
}
uow.SaveChanges();
return toReturn; return toReturn;
} }
@@ -315,22 +305,20 @@ WHERE GuildId={guildId}
if (number <= 0 || (time != null && time.Time > TimeSpan.FromDays(49))) if (number <= 0 || (time != null && time.Time > TimeSpan.FromDays(49)))
return false; return false;
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
var ps = uow.GuildConfigsForId(guildId, set => set.Include(x => x.WarnPunishments)).WarnPunishments;
var toDelete = ps.Where(x => x.Count == number);
uow.RemoveRange(toDelete);
ps.Add(new()
{ {
var ps = uow.GuildConfigsForId(guildId, set => set.Include(x => x.WarnPunishments)).WarnPunishments; Count = number,
var toDelete = ps.Where(x => x.Count == number); Punishment = punish,
Time = (int?)time?.Time.TotalMinutes ?? 0,
uow.RemoveRange(toDelete); RoleId = punish == PunishmentAction.AddRole ? role.Id : default(ulong?),
});
ps.Add(new() uow.SaveChanges();
{
Count = number,
Punishment = punish,
Time = (int?)time?.Time.TotalMinutes ?? 0,
RoleId = punish == PunishmentAction.AddRole ? role.Id : default(ulong?),
});
uow.SaveChanges();
}
return true; return true;
} }
@@ -339,29 +327,26 @@ WHERE GuildId={guildId}
if (number <= 0) if (number <= 0)
return false; return false;
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ var ps = uow.GuildConfigsForId(guildId, set => set.Include(x => x.WarnPunishments)).WarnPunishments;
var ps = uow.GuildConfigsForId(guildId, set => set.Include(x => x.WarnPunishments)).WarnPunishments; var p = ps.FirstOrDefault(x => x.Count == number);
var p = ps.FirstOrDefault(x => x.Count == number);
if (p != null) if (p != null)
{ {
uow.Remove(p); uow.Remove(p);
uow.SaveChanges(); uow.SaveChanges();
}
} }
return true; return true;
} }
public WarningPunishment[] WarnPunishList(ulong guildId) public WarningPunishment[] WarnPunishList(ulong guildId)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ return uow.GuildConfigsForId(guildId, gc => gc.Include(x => x.WarnPunishments))
return uow.GuildConfigsForId(guildId, gc => gc.Include(x => x.WarnPunishments)) .WarnPunishments
.WarnPunishments .OrderBy(x => x.Count)
.OrderBy(x => x.Count) .ToArray();
.ToArray();
}
} }
public (IEnumerable<(string Original, ulong? Id, string Reason)> Bans, int Missing) MassKill(SocketGuild guild, string people) public (IEnumerable<(string Original, ulong? Id, string Reason)> Bans, int Missing) MassKill(SocketGuild guild, string people)
@@ -403,45 +388,41 @@ WHERE GuildId={guildId}
public string GetBanTemplate(ulong guildId) public string GetBanTemplate(ulong guildId)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ var template = uow.BanTemplates
var template = uow.BanTemplates .AsQueryable()
.AsQueryable() .FirstOrDefault(x => x.GuildId == guildId);
.FirstOrDefault(x => x.GuildId == guildId); return template?.Text;
return template?.Text;
}
} }
public void SetBanTemplate(ulong guildId, string text) public void SetBanTemplate(ulong guildId, string text)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
var template = uow.BanTemplates
.AsQueryable()
.FirstOrDefault(x => x.GuildId == guildId);
if (text is null)
{ {
var template = uow.BanTemplates if (template is null)
.AsQueryable() return;
.FirstOrDefault(x => x.GuildId == guildId);
if (text is null)
{
if (template is null)
return;
uow.Remove(template); uow.Remove(template);
}
else if (template is null)
{
uow.BanTemplates.Add(new()
{
GuildId = guildId,
Text = text,
});
}
else
{
template.Text = text;
}
uow.SaveChanges();
} }
else if (template is null)
{
uow.BanTemplates.Add(new()
{
GuildId = guildId,
Text = text,
});
}
else
{
template.Text = text;
}
uow.SaveChanges();
} }
public SmartText GetBanUserDmEmbed(ICommandContext context, IGuildUser target, string defaultMessage, public SmartText GetBanUserDmEmbed(ICommandContext context, IGuildUser target, string defaultMessage,

View File

@@ -117,12 +117,10 @@ public class VcRoleService : INService
if (missingRoles.Any()) if (missingRoles.Any())
{ {
await using (var uow = _db.GetDbContext()) await using var uow = _db.GetDbContext();
{ Log.Warning($"Removing {missingRoles.Count} missing roles from {nameof(VcRoleService)}");
Log.Warning($"Removing {missingRoles.Count} missing roles from {nameof(VcRoleService)}"); uow.RemoveRange(missingRoles);
uow.RemoveRange(missingRoles); await uow.SaveChangesAsync();
await uow.SaveChangesAsync();
}
} }
} }
@@ -134,21 +132,19 @@ public class VcRoleService : INService
var guildVcRoles = VcRoles.GetOrAdd(guildId, new ConcurrentDictionary<ulong, IRole>()); var guildVcRoles = VcRoles.GetOrAdd(guildId, new ConcurrentDictionary<ulong, IRole>());
guildVcRoles.AddOrUpdate(vcId, role, (key, old) => role); guildVcRoles.AddOrUpdate(vcId, role, (key, old) => role);
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
var conf = uow.GuildConfigsForId(guildId, set => set.Include(x => x.VcRoleInfos));
var toDelete = conf.VcRoleInfos.FirstOrDefault(x => x.VoiceChannelId == vcId); // remove old one
if(toDelete != null)
{ {
var conf = uow.GuildConfigsForId(guildId, set => set.Include(x => x.VcRoleInfos)); uow.Remove(toDelete);
var toDelete = conf.VcRoleInfos.FirstOrDefault(x => x.VoiceChannelId == vcId); // remove old one
if(toDelete != null)
{
uow.Remove(toDelete);
}
conf.VcRoleInfos.Add(new()
{
VoiceChannelId = vcId,
RoleId = role.Id,
}); // add new one
uow.SaveChanges();
} }
conf.VcRoleInfos.Add(new()
{
VoiceChannelId = vcId,
RoleId = role.Id,
}); // add new one
uow.SaveChanges();
} }
public bool RemoveVcRole(ulong guildId, ulong vcId) public bool RemoveVcRole(ulong guildId, ulong vcId)
@@ -159,13 +155,11 @@ public class VcRoleService : INService
if (!guildVcRoles.TryRemove(vcId, out _)) if (!guildVcRoles.TryRemove(vcId, out _))
return false; return false;
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ var conf = uow.GuildConfigsForId(guildId, set => set.Include(x => x.VcRoleInfos));
var conf = uow.GuildConfigsForId(guildId, set => set.Include(x => x.VcRoleInfos)); var toRemove = conf.VcRoleInfos.Where(x => x.VoiceChannelId == vcId).ToList();
var toRemove = conf.VcRoleInfos.Where(x => x.VoiceChannelId == vcId).ToList(); uow.RemoveRange(toRemove);
uow.RemoveRange(toRemove); uow.SaveChanges();
uow.SaveChanges();
}
return true; return true;
} }

View File

@@ -30,15 +30,13 @@ public partial class Gambling
var num1 = gen / 10; var num1 = gen / 10;
var num2 = gen % 10; var num2 = gen % 10;
using (var img1 = GetDice(num1)) using var img1 = GetDice(num1);
using (var img2 = GetDice(num2)) using var img2 = GetDice(num2);
using (var img = new[] { img1, img2 }.Merge(out var format)) using var img = new[] { img1, img2 }.Merge(out var format);
await using (var ms = img.ToStream(format)) await using var ms = img.ToStream(format);
{ await ctx.Channel.SendFileAsync(ms,
await ctx.Channel.SendFileAsync(ms, $"dice.{format.FileExtensions.First()}",
$"dice.{format.FileExtensions.First()}", Format.Bold(ctx.User.ToString()) + " " + GetText(strs.dice_rolled(Format.Code(gen.ToString()))));
Format.Bold(ctx.User.ToString()) + " " + GetText(strs.dice_rolled(Format.Code(gen.ToString()))));
}
} }
[NadekoCommand, Aliases] [NadekoCommand, Aliases]
@@ -108,21 +106,19 @@ public partial class Gambling
values.Insert(toInsert, randomNumber); values.Insert(toInsert, randomNumber);
} }
using (var bitmap = dice.Merge(out var format)) using var bitmap = dice.Merge(out var format);
await using (var ms = bitmap.ToStream(format)) await using var ms = bitmap.ToStream(format);
foreach (var d in dice)
{ {
foreach (var d in dice) d.Dispose();
{
d.Dispose();
}
await ctx.Channel.SendFileAsync(ms, $"dice.{format.FileExtensions.First()}",
Format.Bold(ctx.User.ToString()) + " " +
GetText(strs.dice_rolled_num(Format.Bold(values.Count.ToString()))) +
" " + GetText(strs.total_average(
Format.Bold(values.Sum().ToString()),
Format.Bold((values.Sum() / (1.0f * values.Count)).ToString("N2")))));
} }
await ctx.Channel.SendFileAsync(ms, $"dice.{format.FileExtensions.First()}",
Format.Bold(ctx.User.ToString()) + " " +
GetText(strs.dice_rolled_num(Format.Bold(values.Count.ToString()))) +
" " + GetText(strs.total_average(
Format.Bold(values.Sum().ToString()),
Format.Bold((values.Sum() / (1.0f * values.Count)).ToString("N2")))));
} }
private async Task InternallDndRoll(string arg, bool ordered) private async Task InternallDndRoll(string arg, bool ordered)
@@ -211,11 +207,9 @@ public partial class Gambling
if (num == 10) if (num == 10)
{ {
var images = _images.Dice; var images = _images.Dice;
using (var imgOne = Image.Load(images[1])) using var imgOne = Image.Load(images[1]);
using (var imgZero = Image.Load(images[0])) using var imgZero = Image.Load(images[0]);
{ return new[] { imgOne, imgZero }.Merge();
return new[] { imgOne, imgZero }.Merge();
}
} }
return Image.Load(_images.Dice[num]); return Image.Load(_images.Dice[num]);
} }

View File

@@ -44,22 +44,21 @@ public partial class Gambling
cardObjects.Add(currentCard); cardObjects.Add(currentCard);
images.Add(Image.Load(_images.GetCard(currentCard.ToString().ToLowerInvariant().Replace(' ', '_')))); images.Add(Image.Load(_images.GetCard(currentCard.ToString().ToLowerInvariant().Replace(' ', '_'))));
} }
using (var img = images.Merge())
using var img = images.Merge();
foreach (var i in images)
{ {
foreach (var i in images) i.Dispose();
{
i.Dispose();
}
var toSend = $"{Format.Bold(ctx.User.ToString())}";
if (cardObjects.Count == 5)
toSend += $" drew `{Deck.GetHandValue(cardObjects)}`";
if (guildId != null)
toSend += "\n" + GetText(strs.cards_left(Format.Bold(cards.CardPool.Count.ToString())));
return (img.ToStream(), toSend);
} }
var toSend = $"{Format.Bold(ctx.User.ToString())}";
if (cardObjects.Count == 5)
toSend += $" drew `{Deck.GetHandValue(cardObjects)}`";
if (guildId != null)
toSend += "\n" + GetText(strs.cards_left(Format.Bold(cards.CardPool.Count.ToString())));
return (img.ToStream(), toSend);
} }
[NadekoCommand, Aliases] [NadekoCommand, Aliases]

View File

@@ -47,20 +47,19 @@ public partial class Gambling
tailCount++; tailCount++;
} }
} }
using (var img = imgs.Merge(out var format))
await using (var stream = img.ToStream(format)) using var img = imgs.Merge(out var format);
await using var stream = img.ToStream(format);
foreach (var i in imgs)
{ {
foreach (var i in imgs) i.Dispose();
{
i.Dispose();
}
var msg = count != 1
? Format.Bold(ctx.User.ToString()) + " " + GetText(strs.flip_results(count, headCount, tailCount))
: Format.Bold(ctx.User.ToString()) + " " + GetText(strs.flipped(headCount > 0
? Format.Bold(GetText(strs.heads))
: Format.Bold(GetText(strs.tails))));
await ctx.Channel.SendFileAsync(stream, $"{count} coins.{format.FileExtensions.First()}", msg).ConfigureAwait(false);
} }
var msg = count != 1
? Format.Bold(ctx.User.ToString()) + " " + GetText(strs.flip_results(count, headCount, tailCount))
: Format.Bold(ctx.User.ToString()) + " " + GetText(strs.flipped(headCount > 0
? Format.Bold(GetText(strs.heads))
: Format.Bold(GetText(strs.tails))));
await ctx.Channel.SendFileAsync(stream, $"{count} coins.{format.FileExtensions.First()}", msg).ConfigureAwait(false);
} }
public enum BetFlipGuess public enum BetFlipGuess

View File

@@ -538,10 +538,8 @@ public partial class Gambling : GamblingModule<GamblingService>
} }
else else
{ {
await using (var uow = _db.GetDbContext()) await using var uow = _db.GetDbContext();
{ cleanRichest = uow.DiscordUser.GetTopRichest(_client.CurrentUser.Id, 9, page).ToList();
cleanRichest = uow.DiscordUser.GetTopRichest(_client.CurrentUser.Id, 9, page).ToList();
}
} }
await ctx.SendPaginatedConfirmAsync(page, curPage => await ctx.SendPaginatedConfirmAsync(page, curPage =>
@@ -553,10 +551,8 @@ public partial class Gambling : GamblingModule<GamblingService>
List<DiscordUser> toSend; List<DiscordUser> toSend;
if (!opts.Clean) if (!opts.Clean)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ toSend = uow.DiscordUser.GetTopRichest(_client.CurrentUser.Id, 9, curPage);
toSend = uow.DiscordUser.GetTopRichest(_client.CurrentUser.Id, 9, curPage);
}
} }
else else
{ {

View File

@@ -41,21 +41,20 @@ public class GamblingService : INService
if (config.Decay.Percent <= 0 || config.Decay.Percent > 1 || maxDecay < 0) if (config.Decay.Percent <= 0 || config.Decay.Percent > 1 || maxDecay < 0)
return; return;
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ var lastCurrencyDecay = _cache.GetLastCurrencyDecay();
var lastCurrencyDecay = _cache.GetLastCurrencyDecay();
if (DateTime.UtcNow - lastCurrencyDecay < TimeSpan.FromHours(config.Decay.HourInterval)) if (DateTime.UtcNow - lastCurrencyDecay < TimeSpan.FromHours(config.Decay.HourInterval))
return; return;
Log.Information($"Decaying users' currency - decay: {config.Decay.Percent * 100}% " + Log.Information($"Decaying users' currency - decay: {config.Decay.Percent * 100}% " +
$"| max: {maxDecay} " + $"| max: {maxDecay} " +
$"| threshold: {config.Decay.MinThreshold}"); $"| threshold: {config.Decay.MinThreshold}");
if (maxDecay == 0) if (maxDecay == 0)
maxDecay = int.MaxValue; maxDecay = int.MaxValue;
uow.Database.ExecuteSqlInterpolated($@" uow.Database.ExecuteSqlInterpolated($@"
UPDATE DiscordUser UPDATE DiscordUser
SET CurrencyAmount= SET CurrencyAmount=
CASE WHEN CASE WHEN
@@ -67,9 +66,8 @@ SET CurrencyAmount=
END END
WHERE CurrencyAmount > {config.Decay.MinThreshold} AND UserId!={_client.CurrentUser.Id};"); WHERE CurrencyAmount > {config.Decay.MinThreshold} AND UserId!={_client.CurrentUser.Id};");
_cache.SetLastCurrencyDecay(); _cache.SetLastCurrencyDecay();
uow.SaveChanges(); uow.SaveChanges();
}
}, null, TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(5)); }, null, TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(5));
} }
} }

View File

@@ -44,18 +44,16 @@ public class PlantPickService : INService
_gss = gss; _gss = gss;
cmd.OnMessageNoTrigger += PotentialFlowerGeneration; cmd.OnMessageNoTrigger += PotentialFlowerGeneration;
using (var uow = db.GetDbContext()) using var uow = db.GetDbContext();
{ var guildIds = client.Guilds.Select(x => x.Id).ToList();
var guildIds = client.Guilds.Select(x => x.Id).ToList(); var configs = uow.Set<GuildConfig>()
var configs = uow.Set<GuildConfig>() .AsQueryable()
.AsQueryable() .Include(x => x.GenerateCurrencyChannelIds)
.Include(x => x.GenerateCurrencyChannelIds) .Where(x => guildIds.Contains(x.GuildId))
.Where(x => guildIds.Contains(x.GuildId)) .ToList();
.ToList();
_generationChannels = new(configs _generationChannels = new(configs
.SelectMany(c => c.GenerateCurrencyChannelIds.Select(obj => obj.ChannelId))); .SelectMany(c => c.GenerateCurrencyChannelIds.Select(obj => obj.ChannelId)));
}
} }
private string GetText(ulong gid, LocStr str) private string GetText(ulong gid, LocStr str)
@@ -64,39 +62,35 @@ public class PlantPickService : INService
public bool ToggleCurrencyGeneration(ulong gid, ulong cid) public bool ToggleCurrencyGeneration(ulong gid, ulong cid)
{ {
bool enabled; bool enabled;
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ var guildConfig = uow.GuildConfigsForId(gid, set => set.Include(gc => gc.GenerateCurrencyChannelIds));
var guildConfig = uow.GuildConfigsForId(gid, set => set.Include(gc => gc.GenerateCurrencyChannelIds));
var toAdd = new GCChannelId() { ChannelId = cid }; var toAdd = new GCChannelId() { ChannelId = cid };
if (!guildConfig.GenerateCurrencyChannelIds.Contains(toAdd)) if (!guildConfig.GenerateCurrencyChannelIds.Contains(toAdd))
{ {
guildConfig.GenerateCurrencyChannelIds.Add(toAdd); guildConfig.GenerateCurrencyChannelIds.Add(toAdd);
_generationChannels.Add(cid); _generationChannels.Add(cid);
enabled = true; enabled = true;
}
else
{
var toDelete = guildConfig.GenerateCurrencyChannelIds.FirstOrDefault(x => x.Equals(toAdd));
if (toDelete != null)
{
uow.Remove(toDelete);
}
_generationChannels.TryRemove(cid);
enabled = false;
}
uow.SaveChanges();
} }
else
{
var toDelete = guildConfig.GenerateCurrencyChannelIds.FirstOrDefault(x => x.Equals(toAdd));
if (toDelete != null)
{
uow.Remove(toDelete);
}
_generationChannels.TryRemove(cid);
enabled = false;
}
uow.SaveChanges();
return enabled; return enabled;
} }
public IEnumerable<GuildConfigExtensions.GeneratingChannel> GetAllGeneratingChannels() public IEnumerable<GuildConfigExtensions.GeneratingChannel> GetAllGeneratingChannels()
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ var chs = uow.GuildConfigs.GetGeneratingChannels();
var chs = uow.GuildConfigs.GetGeneratingChannels(); return chs;
return chs;
}
} }
/// <summary> /// <summary>
@@ -139,31 +133,29 @@ public class PlantPickService : INService
{ {
// draw lower, it looks better // draw lower, it looks better
pass = pass.TrimTo(10, true).ToLowerInvariant(); pass = pass.TrimTo(10, true).ToLowerInvariant();
using (var img = Image.Load<Rgba32>(curImg, out var format)) using var img = Image.Load<Rgba32>(curImg, out var format);
// choose font size based on the image height, so that it's visible
var font = _fonts.NotoSans.CreateFont(img.Height / 12, FontStyle.Bold);
img.Mutate(x =>
{ {
// choose font size based on the image height, so that it's visible // measure the size of the text to be drawing
var font = _fonts.NotoSans.CreateFont(img.Height / 12, FontStyle.Bold); var size = TextMeasurer.Measure(pass, new(font, new PointF(0, 0)));
img.Mutate(x =>
{
// measure the size of the text to be drawing
var size = TextMeasurer.Measure(pass, new(font, new PointF(0, 0)));
// fill the background with black, add 5 pixels on each side to make it look better // fill the background with black, add 5 pixels on each side to make it look better
x.FillPolygon(Color.ParseHex("00000080"), x.FillPolygon(Color.ParseHex("00000080"),
new PointF(0, 0), new PointF(0, 0),
new PointF(size.Width + 5, 0), new PointF(size.Width + 5, 0),
new PointF(size.Width + 5, size.Height + 10), new PointF(size.Width + 5, size.Height + 10),
new PointF(0, size.Height + 10)); new PointF(0, size.Height + 10));
// draw the password over the background // draw the password over the background
x.DrawText(pass, x.DrawText(pass,
font, font,
SixLabors.ImageSharp.Color.White, SixLabors.ImageSharp.Color.White,
new(0, 0)); new(0, 0));
}); });
// return image as a stream for easy sending // return image as a stream for easy sending
return (img.ToStream(format), format.FileExtensions.FirstOrDefault() ?? "png"); return (img.ToStream(format), format.FileExtensions.FirstOrDefault() ?? "png");
}
} }
private Task PotentialFlowerGeneration(IUserMessage imsg) private Task PotentialFlowerGeneration(IUserMessage imsg)
@@ -309,13 +301,11 @@ public class PlantPickService : INService
msgToSend += " " + GetText(gid, strs.pick_sn(prefix)); msgToSend += " " + GetText(gid, strs.pick_sn(prefix));
//get the image //get the image
await using (var stream = GetRandomCurrencyImage(pass, out var ext)) await using var stream = GetRandomCurrencyImage(pass, out var ext);
{ // send it
// send it var msg = await ch.SendFileAsync(stream, $"img.{ext}", msgToSend).ConfigureAwait(false);
var msg = await ch.SendFileAsync(stream, $"img.{ext}", msgToSend).ConfigureAwait(false); // return sent message's id (in order to be able to delete it when it's picked)
// return sent message's id (in order to be able to delete it when it's picked) return msg.Id;
return msg.Id;
}
} }
catch catch
{ {
@@ -353,18 +343,16 @@ public class PlantPickService : INService
private async Task AddPlantToDatabase(ulong gid, ulong cid, ulong uid, ulong mid, long amount, string pass) private async Task AddPlantToDatabase(ulong gid, ulong cid, ulong uid, ulong mid, long amount, string pass)
{ {
await using (var uow = _db.GetDbContext()) await using var uow = _db.GetDbContext();
uow.PlantedCurrency.Add(new()
{ {
uow.PlantedCurrency.Add(new() Amount = amount,
{ GuildId = gid,
Amount = amount, ChannelId = cid,
GuildId = gid, Password = pass,
ChannelId = cid, UserId = uid,
Password = pass, MessageId = mid,
UserId = uid, });
MessageId = mid, await uow.SaveChangesAsync();
});
await uow.SaveChangesAsync();
}
} }
} }

View File

@@ -37,49 +37,47 @@ public class WaifuService : INService
var settings = _gss.Data; var settings = _gss.Data;
await using (var uow = _db.GetDbContext()) await using var uow = _db.GetDbContext();
{ var waifu = uow.WaifuInfo.ByWaifuUserId(waifuId);
var waifu = uow.WaifuInfo.ByWaifuUserId(waifuId); var ownerUser = uow.GetOrCreateUser(owner);
var ownerUser = uow.GetOrCreateUser(owner);
// owner has to be the owner of the waifu // owner has to be the owner of the waifu
if (waifu is null || waifu.ClaimerId != ownerUser.Id) if (waifu is null || waifu.ClaimerId != ownerUser.Id)
return false; return false;
// if waifu likes the person, gotta pay the penalty // if waifu likes the person, gotta pay the penalty
if (waifu.AffinityId == ownerUser.Id) if (waifu.AffinityId == ownerUser.Id)
{
if (!await _cs.RemoveAsync(owner.Id,
"Waifu Transfer - affinity penalty",
(int)(waifu.Price * 0.6),
true))
{ {
if (!await _cs.RemoveAsync(owner.Id, // unable to pay 60% penalty
"Waifu Transfer - affinity penalty", return false;
(int)(waifu.Price * 0.6),
true))
{
// unable to pay 60% penalty
return false;
}
waifu.Price = (int)(waifu.Price * 0.7); // half of 60% = 30% price reduction
if (waifu.Price < settings.Waifu.MinPrice)
waifu.Price = settings.Waifu.MinPrice;
}
else // if not, pay 10% fee
{
if (!await _cs.RemoveAsync(owner.Id, "Waifu Transfer", waifu.Price / 10, gamble: true))
{
return false;
}
waifu.Price = (int) (waifu.Price * 0.95); // half of 10% = 5% price reduction
if (waifu.Price < settings.Waifu.MinPrice)
waifu.Price = settings.Waifu.MinPrice;
} }
//new claimerId is the id of the new owner waifu.Price = (int)(waifu.Price * 0.7); // half of 60% = 30% price reduction
var newOwnerUser = uow.GetOrCreateUser(newOwner); if (waifu.Price < settings.Waifu.MinPrice)
waifu.ClaimerId = newOwnerUser.Id; waifu.Price = settings.Waifu.MinPrice;
await uow.SaveChangesAsync();
} }
else // if not, pay 10% fee
{
if (!await _cs.RemoveAsync(owner.Id, "Waifu Transfer", waifu.Price / 10, gamble: true))
{
return false;
}
waifu.Price = (int) (waifu.Price * 0.95); // half of 10% = 5% price reduction
if (waifu.Price < settings.Waifu.MinPrice)
waifu.Price = settings.Waifu.MinPrice;
}
//new claimerId is the id of the new owner
var newOwnerUser = uow.GetOrCreateUser(newOwner);
waifu.ClaimerId = newOwnerUser.Id;
await uow.SaveChangesAsync();
return true; return true;
} }
@@ -87,67 +85,63 @@ public class WaifuService : INService
public int GetResetPrice(IUser user) public int GetResetPrice(IUser user)
{ {
var settings = _gss.Data; var settings = _gss.Data;
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ var waifu = uow.WaifuInfo.ByWaifuUserId(user.Id);
var waifu = uow.WaifuInfo.ByWaifuUserId(user.Id);
if (waifu is null) if (waifu is null)
return settings.Waifu.MinPrice; return settings.Waifu.MinPrice;
var divorces = uow.WaifuUpdates.Count(x => x.Old != null && var divorces = uow.WaifuUpdates.Count(x => x.Old != null &&
x.Old.UserId == user.Id && x.Old.UserId == user.Id &&
x.UpdateType == WaifuUpdateType.Claimed && x.UpdateType == WaifuUpdateType.Claimed &&
x.New == null); x.New == null);
var affs = uow.WaifuUpdates var affs = uow.WaifuUpdates
.AsQueryable() .AsQueryable()
.Where(w => w.User.UserId == user.Id && w.UpdateType == WaifuUpdateType.AffinityChanged && .Where(w => w.User.UserId == user.Id && w.UpdateType == WaifuUpdateType.AffinityChanged &&
w.New != null) w.New != null)
.ToList() .ToList()
.GroupBy(x => x.New) .GroupBy(x => x.New)
.Count(); .Count();
return (int) Math.Ceiling(waifu.Price * 1.25f) + return (int) Math.Ceiling(waifu.Price * 1.25f) +
((divorces + affs + 2) * settings.Waifu.Multipliers.WaifuReset); ((divorces + affs + 2) * settings.Waifu.Multipliers.WaifuReset);
}
} }
public async Task<bool> TryReset(IUser user) public async Task<bool> TryReset(IUser user)
{ {
await using (var uow = _db.GetDbContext()) await using var uow = _db.GetDbContext();
{ var price = GetResetPrice(user);
var price = GetResetPrice(user); if (!await _cs.RemoveAsync(user.Id, "Waifu Reset", price, gamble: true))
if (!await _cs.RemoveAsync(user.Id, "Waifu Reset", price, gamble: true)) return false;
return false;
var affs = uow.WaifuUpdates var affs = uow.WaifuUpdates
.AsQueryable() .AsQueryable()
.Where(w => w.User.UserId == user.Id .Where(w => w.User.UserId == user.Id
&& w.UpdateType == WaifuUpdateType.AffinityChanged && w.UpdateType == WaifuUpdateType.AffinityChanged
&& w.New != null); && w.New != null);
var divorces = uow.WaifuUpdates var divorces = uow.WaifuUpdates
.AsQueryable() .AsQueryable()
.Where(x => x.Old != null && .Where(x => x.Old != null &&
x.Old.UserId == user.Id && x.Old.UserId == user.Id &&
x.UpdateType == WaifuUpdateType.Claimed && x.UpdateType == WaifuUpdateType.Claimed &&
x.New == null); x.New == null);
//reset changes of heart to 0 //reset changes of heart to 0
uow.WaifuUpdates.RemoveRange(affs); uow.WaifuUpdates.RemoveRange(affs);
//reset divorces to 0 //reset divorces to 0
uow.WaifuUpdates.RemoveRange(divorces); uow.WaifuUpdates.RemoveRange(divorces);
var waifu = uow.WaifuInfo.ByWaifuUserId(user.Id); var waifu = uow.WaifuInfo.ByWaifuUserId(user.Id);
//reset price, remove items //reset price, remove items
//remove owner, remove affinity //remove owner, remove affinity
waifu.Price = 50; waifu.Price = 50;
waifu.Items.Clear(); waifu.Items.Clear();
waifu.ClaimerId = null; waifu.ClaimerId = null;
waifu.AffinityId = null; waifu.AffinityId = null;
//wives stay though //wives stay though
uow.SaveChanges(); uow.SaveChanges();
}
return true; return true;
} }
@@ -302,10 +296,8 @@ public class WaifuService : INService
public IEnumerable<WaifuLbResult> GetTopWaifusAtPage(int page) public IEnumerable<WaifuLbResult> GetTopWaifusAtPage(int page)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ return uow.WaifuInfo.GetTop(9, page * 9);
return uow.WaifuInfo.GetTop(9, page * 9);
}
} }
public ulong GetWaifuUserId(ulong ownerId, string name) public ulong GetWaifuUserId(ulong ownerId, string name)
@@ -372,85 +364,79 @@ public class WaifuService : INService
return false; return false;
} }
await using (var uow = _db.GetDbContext()) await using var uow = _db.GetDbContext();
var w = uow.WaifuInfo.ByWaifuUserId(giftedWaifu.Id,
set => set.Include(x => x.Items)
.Include(x => x.Claimer));
if (w is null)
{ {
var w = uow.WaifuInfo.ByWaifuUserId(giftedWaifu.Id, uow.WaifuInfo.Add(w = new()
set => set.Include(x => x.Items)
.Include(x => x.Claimer));
if (w is null)
{ {
uow.WaifuInfo.Add(w = new() Affinity = null,
{ Claimer = null,
Affinity = null, Price = 1,
Claimer = null, Waifu = uow.GetOrCreateUser(giftedWaifu),
Price = 1, });
Waifu = uow.GetOrCreateUser(giftedWaifu), }
});
}
if (!itemObj.Negative) if (!itemObj.Negative)
{
w.Items.Add(new()
{ {
w.Items.Add(new() Name = itemObj.Name.ToLowerInvariant(),
{ ItemEmoji = itemObj.ItemEmoji,
Name = itemObj.Name.ToLowerInvariant(), });
ItemEmoji = itemObj.ItemEmoji,
});
if (w.Claimer?.UserId == from.Id) if (w.Claimer?.UserId == @from.Id)
{ {
w.Price += (int)(itemObj.Price * _gss.Data.Waifu.Multipliers.GiftEffect); w.Price += (int)(itemObj.Price * _gss.Data.Waifu.Multipliers.GiftEffect);
}
else
{
w.Price += itemObj.Price / 2;
}
} }
else else
{ {
w.Price -= (int)(itemObj.Price * _gss.Data.Waifu.Multipliers.NegativeGiftEffect); w.Price += itemObj.Price / 2;
if (w.Price < 1)
w.Price = 1;
} }
await uow.SaveChangesAsync();
} }
else
{
w.Price -= (int)(itemObj.Price * _gss.Data.Waifu.Multipliers.NegativeGiftEffect);
if (w.Price < 1)
w.Price = 1;
}
await uow.SaveChangesAsync();
return true; return true;
} }
public WaifuInfoStats GetFullWaifuInfoAsync(ulong targetId) public WaifuInfoStats GetFullWaifuInfoAsync(ulong targetId)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
var wi = uow.GetWaifuInfo(targetId);
if (wi is null)
{ {
var wi = uow.GetWaifuInfo(targetId); wi = new()
if (wi is null)
{ {
wi = new() AffinityCount = 0,
{ AffinityName = null,
AffinityCount = 0, ClaimCount = 0,
AffinityName = null, ClaimerName = null,
ClaimCount = 0, Claims = new(),
ClaimerName = null, Fans = new(),
Claims = new(), DivorceCount = 0,
Fans = new(), FullName = null,
DivorceCount = 0, Items = new(),
FullName = null, Price = 1
Items = new(), };
Price = 1
};
}
return wi;
} }
return wi;
} }
public WaifuInfoStats GetFullWaifuInfoAsync(IGuildUser target) public WaifuInfoStats GetFullWaifuInfoAsync(IGuildUser target)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ var du = uow.GetOrCreateUser(target);
var du = uow.GetOrCreateUser(target);
return GetFullWaifuInfoAsync(target.Id); return GetFullWaifuInfoAsync(target.Id);
}
} }
public string GetClaimTitle(int count) public string GetClaimTitle(int count)

View File

@@ -41,18 +41,18 @@ public partial class Gambling
public sealed class SlotMachine public sealed class SlotMachine
{ {
public const int MaxValue = 5; public const int MAX_VALUE = 5;
static readonly List<Func<int[], int>> _winningCombos = new() private static readonly List<Func<int[], int>> _winningCombos = new()
{ {
//three flowers //three flowers
arr => arr.All(a=>a==MaxValue) ? 30 : 0, arr => arr.All(a=>a==MAX_VALUE) ? 30 : 0,
//three of the same //three of the same
arr => !arr.Any(a => a != arr[0]) ? 10 : 0, arr => !arr.Any(a => a != arr[0]) ? 10 : 0,
//two flowers //two flowers
arr => arr.Count(a => a == MaxValue) == 2 ? 4 : 0, arr => arr.Count(a => a == MAX_VALUE) == 2 ? 4 : 0,
//one flower //one flower
arr => arr.Any(a => a == MaxValue) ? 1 : 0, arr => arr.Any(a => a == MAX_VALUE) ? 1 : 0,
}; };
public static SlotResult Pull() public static SlotResult Pull()
@@ -60,7 +60,7 @@ public partial class Gambling
var numbers = new int[3]; var numbers = new int[3];
for (var i = 0; i < numbers.Length; i++) for (var i = 0; i < numbers.Length; i++)
{ {
numbers[i] = new NadekoRandom().Next(0, MaxValue + 1); numbers[i] = new NadekoRandom().Next(0, MAX_VALUE + 1);
} }
var multi = 0; var multi = 0;
foreach (var t in _winningCombos) foreach (var t in _winningCombos)
@@ -84,6 +84,8 @@ public partial class Gambling
} }
} }
} }
public Task Test() => Task.CompletedTask;
[NadekoCommand, Aliases] [NadekoCommand, Aliases]
[OwnerOnly] [OwnerOnly]
@@ -124,7 +126,6 @@ public partial class Gambling
} }
var sb = new StringBuilder(); var sb = new StringBuilder();
const int bet = 1;
var payout = 0; var payout = 0;
foreach (var key in dict.Keys.OrderByDescending(x => x)) foreach (var key in dict.Keys.OrderByDescending(x => x))
{ {
@@ -132,7 +133,7 @@ public partial class Gambling
payout += key * dict[key]; payout += key * dict[key];
} }
await SendConfirmAsync("Slot Test Results", sb.ToString(), await SendConfirmAsync("Slot Test Results", sb.ToString(),
footer: $"Total Bet: {tests * bet} | Payout: {payout * bet} | {payout * 1.0f / tests * 100}%").ConfigureAwait(false); footer: $"Total Bet: {tests} | Payout: {payout} | {payout * 1.0f / tests * 100}%").ConfigureAwait(false);
} }
[NadekoCommand, Aliases] [NadekoCommand, Aliases]
@@ -170,7 +171,7 @@ public partial class Gambling
.FirstOrDefault(x => x.UserId == ctx.User.Id) .FirstOrDefault(x => x.UserId == ctx.User.Id)
?.CurrencyAmount ?? 0; ?.CurrencyAmount ?? 0;
} }
using (var bgImage = Image.Load<Rgba32>(_images.SlotBackground, out var format)) using (var bgImage = Image.Load<Rgba32>(_images.SlotBackground, out var format))
{ {
var numbers = new int[3]; var numbers = new int[3];
@@ -216,22 +217,20 @@ public partial class Gambling
for (var i = 0; i < 3; i++) for (var i = 0; i < 3; i++)
{ {
using (var img = Image.Load(_images.SlotEmojis[numbers[i]])) using var img = Image.Load(_images.SlotEmojis[numbers[i]]);
{ bgImage.Mutate(x => x.DrawImage(img, new Point(148 + (105 * i), 217), 1f));
bgImage.Mutate(x => x.DrawImage(img, new Point(148 + (105 * i), 217), 1f));
}
} }
var msg = GetText(strs.better_luck); var msg = GetText(strs.better_luck);
if (result.Multiplier > 0) if (result.Multiplier > 0)
{ {
if (result.Multiplier == 1f) if (Math.Abs(result.Multiplier - 1f) <= float.Epsilon)
msg = GetText(strs.slot_single(CurrencySign, 1)); msg = GetText(strs.slot_single(CurrencySign, 1));
else if (result.Multiplier == 4f) else if (Math.Abs(result.Multiplier - 4f) < float.Epsilon)
msg = GetText(strs.slot_two(CurrencySign, 4)); msg = GetText(strs.slot_two(CurrencySign, 4));
else if (result.Multiplier == 10f) else if (Math.Abs(result.Multiplier - 10f) <= float.Epsilon)
msg = GetText(strs.slot_three(10)); msg = GetText(strs.slot_three(10));
else if (result.Multiplier == 30f) else if (Math.Abs(result.Multiplier - 30f) <= float.Epsilon)
msg = GetText(strs.slot_jackpot(30)); msg = GetText(strs.slot_jackpot(30));
} }

View File

@@ -24,11 +24,9 @@ public class ChatterBotSession : IChatterBotSession
public async Task<string> Think(string message) public async Task<string> Think(string message)
{ {
using (var http = _httpFactory.CreateClient()) using var http = _httpFactory.CreateClient();
{ var res = await http.GetStringAsync(string.Format(ApiEndpoint, message)).ConfigureAwait(false);
var res = await http.GetStringAsync(string.Format(ApiEndpoint, message)).ConfigureAwait(false); var cbr = JsonConvert.DeserializeObject<ChatterBotResponse>(res);
var cbr = JsonConvert.DeserializeObject<ChatterBotResponse>(res); return cbr.BotSay.Replace("<br/>", "\n", StringComparison.InvariantCulture);
return cbr.BotSay.Replace("<br/>", "\n", StringComparison.InvariantCulture);
}
} }
} }

View File

@@ -21,22 +21,20 @@ public class OfficialCleverbotSession : IChatterBotSession
public async Task<string> Think(string input) public async Task<string> Think(string input)
{ {
using (var http = _httpFactory.CreateClient()) using var http = _httpFactory.CreateClient();
var dataString = await http.GetStringAsync(string.Format(QueryString, input, _cs ?? "")).ConfigureAwait(false);
try
{ {
var dataString = await http.GetStringAsync(string.Format(QueryString, input, _cs ?? "")).ConfigureAwait(false); var data = JsonConvert.DeserializeObject<CleverbotResponse>(dataString);
try
{
var data = JsonConvert.DeserializeObject<CleverbotResponse>(dataString);
_cs = data?.Cs; _cs = data?.Cs;
return data?.Output; return data?.Output;
} }
catch catch
{ {
Log.Warning("Unexpected cleverbot response received: "); Log.Warning("Unexpected cleverbot response received: ");
Log.Warning(dataString); Log.Warning(dataString);
return null; return null;
}
} }
} }
} }
@@ -62,41 +60,37 @@ public class CleverbotIOSession : IChatterBotSession
private async Task<string> GetNick() private async Task<string> GetNick()
{ {
using (var _http = _httpFactory.CreateClient()) using var _http = _httpFactory.CreateClient();
using (var msg = new FormUrlEncodedContent(new[] using var msg = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("user", _user),
new KeyValuePair<string, string>("key", _key),
}))
using (var data = await _http.PostAsync(_createEndpoint, msg).ConfigureAwait(false))
{ {
var str = await data.Content.ReadAsStringAsync().ConfigureAwait(false); new KeyValuePair<string, string>("user", _user),
var obj = JsonConvert.DeserializeObject<CleverbotIOCreateResponse>(str); new KeyValuePair<string, string>("key", _key),
if (obj.Status != "success") });
throw new OperationCanceledException(obj.Status); using var data = await _http.PostAsync(_createEndpoint, msg).ConfigureAwait(false);
var str = await data.Content.ReadAsStringAsync().ConfigureAwait(false);
var obj = JsonConvert.DeserializeObject<CleverbotIOCreateResponse>(str);
if (obj.Status != "success")
throw new OperationCanceledException(obj.Status);
return obj.Nick; return obj.Nick;
}
} }
public async Task<string> Think(string input) public async Task<string> Think(string input)
{ {
using (var _http = _httpFactory.CreateClient()) using var _http = _httpFactory.CreateClient();
using (var msg = new FormUrlEncodedContent(new[] using var msg = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("user", _user),
new KeyValuePair<string, string>("key", _key),
new KeyValuePair<string, string>("nick", await _nick),
new KeyValuePair<string, string>("text", input),
}))
using (var data = await _http.PostAsync(_askEndpoint, msg).ConfigureAwait(false))
{ {
var str = await data.Content.ReadAsStringAsync().ConfigureAwait(false); new KeyValuePair<string, string>("user", _user),
var obj = JsonConvert.DeserializeObject<CleverbotIOAskResponse>(str); new KeyValuePair<string, string>("key", _key),
if (obj.Status != "success") new KeyValuePair<string, string>("nick", await _nick),
throw new OperationCanceledException(obj.Status); new KeyValuePair<string, string>("text", input),
});
using var data = await _http.PostAsync(_askEndpoint, msg).ConfigureAwait(false);
var str = await data.Content.ReadAsStringAsync().ConfigureAwait(false);
var obj = JsonConvert.DeserializeObject<CleverbotIOAskResponse>(str);
if (obj.Status != "success")
throw new OperationCanceledException(obj.Status);
return obj.Response; return obj.Response;
}
} }
} }

View File

@@ -30,33 +30,31 @@ public class GirlRating
{ {
try try
{ {
using (var img = Image.Load(_images.RategirlMatrix)) using var img = Image.Load(_images.RategirlMatrix);
const int minx = 35;
const int miny = 385;
const int length = 345;
var pointx = (int)(minx + (length * (Hot / 10)));
var pointy = (int)(miny - (length * ((Crazy - 4) / 6)));
using (var pointImg = Image.Load(_images.RategirlDot))
{ {
const int minx = 35; img.Mutate(x => x.DrawImage(pointImg, new(pointx - 10, pointy - 10), new GraphicsOptions()));
const int miny = 385;
const int length = 345;
var pointx = (int)(minx + (length * (Hot / 10)));
var pointy = (int)(miny - (length * ((Crazy - 4) / 6)));
using (var pointImg = Image.Load(_images.RategirlDot))
{
img.Mutate(x => x.DrawImage(pointImg, new(pointx - 10, pointy - 10), new GraphicsOptions()));
}
var imgStream = new MemoryStream();
img.SaveAsPng(imgStream);
return imgStream;
//using (var byteContent = new ByteArrayContent(imgStream.ToArray()))
//{
// http.AddFakeHeaders();
// using (var reponse = await http.PutAsync("https://transfer.sh/img.png", byteContent).ConfigureAwait(false))
// {
// url = await reponse.Content.ReadAsStringAsync().ConfigureAwait(false);
// }
//}
} }
var imgStream = new MemoryStream();
img.SaveAsPng(imgStream);
return imgStream;
//using (var byteContent = new ByteArrayContent(imgStream.ToArray()))
//{
// http.AddFakeHeaders();
// using (var reponse = await http.PutAsync("https://transfer.sh/img.png", byteContent).ConfigureAwait(false))
// {
// url = await reponse.Content.ReadAsStringAsync().ConfigureAwait(false);
// }
//}
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@@ -51,12 +51,10 @@ public class PollRunner
} }
finally { _locker.Release(); } finally { _locker.Release(); }
await using (var uow = _db.GetDbContext()) await using var uow = _db.GetDbContext();
{ var trackedPoll = uow.Poll.FirstOrDefault(x => x.Id == Poll.Id);
var trackedPoll = uow.Poll.FirstOrDefault(x => x.Id == Poll.Id); trackedPoll.Votes.Add(voteObj);
trackedPoll.Votes.Add(voteObj); uow.SaveChanges();
uow.SaveChanges();
}
return true; return true;
} }

View File

@@ -17,7 +17,7 @@ public class TicTacToe
public int TurnTimer { get; set; } = 15; public int TurnTimer { get; set; } = 15;
} }
enum Phase private enum Phase
{ {
Starting, Starting,
Started, Started,

View File

@@ -57,24 +57,22 @@ public partial class Games : NadekoModule<GamesService>
return; return;
} }
await using (var imgStream = new MemoryStream()) await using var imgStream = new MemoryStream();
lock (gr)
{ {
lock (gr) originalStream.Position = 0;
{ originalStream.CopyTo(imgStream);
originalStream.Position = 0;
originalStream.CopyTo(imgStream);
}
imgStream.Position = 0;
await ctx.Channel.SendFileAsync(stream: imgStream,
filename: $"girl_{usr}.png",
text: Format.Bold($"{ctx.User.Mention} Girl Rating For {usr}"),
embed: _eb.Create()
.WithOkColor()
.AddField("Hot", gr.Hot.ToString("F2"), true)
.AddField("Crazy", gr.Crazy.ToString("F2"), true)
.AddField("Advice", gr.Advice, false)
.Build()).ConfigureAwait(false);
} }
imgStream.Position = 0;
await ctx.Channel.SendFileAsync(stream: imgStream,
filename: $"girl_{usr}.png",
text: Format.Bold($"{ctx.User.Mention} Girl Rating For {usr}"),
embed: _eb.Create()
.WithOkColor()
.AddField("Hot", gr.Hot.ToString("F2"), true)
.AddField("Crazy", gr.Crazy.ToString("F2"), true)
.AddField("Advice", gr.Advice, false)
.Build()).ConfigureAwait(false);
} }
private double NextDouble(double x, double y) private double NextDouble(double x, double y)

View File

@@ -76,11 +76,9 @@ public class GamesService : INService
private async Task<RatingTexts> GetRatingTexts() private async Task<RatingTexts> GetRatingTexts()
{ {
using (var http = _httpFactory.CreateClient()) using var http = _httpFactory.CreateClient();
{ var text = await http.GetStringAsync("https://nadeko-pictures.nyc3.digitaloceanspaces.com/other/rategirl/rates.json");
var text = await http.GetStringAsync("https://nadeko-pictures.nyc3.digitaloceanspaces.com/other/rategirl/rates.json"); return JsonConvert.DeserializeObject<RatingTexts>(text);
return JsonConvert.DeserializeObject<RatingTexts>(text);
}
} }
public void AddTypingArticle(IUser user, string text) public void AddTypingArticle(IUser user, string text)

View File

@@ -22,17 +22,15 @@ public class PollService : IEarlyBehavior
_strs = strs; _strs = strs;
_eb = eb; _eb = eb;
using (var uow = db.GetDbContext()) using var uow = db.GetDbContext();
{ ActivePolls = uow.Poll.GetAllPolls()
ActivePolls = uow.Poll.GetAllPolls() .ToDictionary(x => x.GuildId, x =>
.ToDictionary(x => x.GuildId, x => {
{ var pr = new PollRunner(db, x);
var pr = new PollRunner(db, x); pr.OnVoted += Pr_OnVoted;
pr.OnVoted += Pr_OnVoted; return pr;
return pr; })
}) .ToConcurrent();
.ToConcurrent();
}
} }
public Poll CreatePoll(ulong guildId, ulong channelId, string input) public Poll CreatePoll(ulong guildId, ulong channelId, string input)

View File

@@ -42,10 +42,8 @@ public class RadioResolver : IRadioResolver
string file = null; string file = null;
try try
{ {
using (var http = new HttpClient()) using var http = new HttpClient();
{ file = await http.GetStringAsync(query).ConfigureAwait(false);
file = await http.GetStringAsync(query).ConfigureAwait(false);
}
} }
catch catch
{ {

View File

@@ -64,18 +64,16 @@ public sealed partial class Music
var success = false; var success = false;
try try
{ {
await using (var uow = _db.GetDbContext()) await using var uow = _db.GetDbContext();
{ var pl = uow.MusicPlaylists.FirstOrDefault(x => x.Id == id);
var pl = uow.MusicPlaylists.FirstOrDefault(x => x.Id == id);
if (pl != null) if (pl != null)
{
if (_creds.IsOwner(ctx.User) || pl.AuthorId == ctx.User.Id)
{ {
if (_creds.IsOwner(ctx.User) || pl.AuthorId == ctx.User.Id) uow.MusicPlaylists.Remove(pl);
{ await uow.SaveChangesAsync();
uow.MusicPlaylists.Remove(pl); success = true;
await uow.SaveChangesAsync();
success = true;
}
} }
} }
} }

View File

@@ -34,26 +34,24 @@ public sealed class FilterService : IEarlyBehavior
public void ClearFilteredWords(ulong guildId) public void ClearFilteredWords(ulong guildId)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
var gc = uow.GuildConfigsForId(guildId,
set => set.Include(x => x.FilteredWords)
.Include(x => x.FilterWordsChannelIds));
WordFilteringServers.TryRemove(guildId);
ServerFilteredWords.TryRemove(guildId, out _);
foreach (var c in gc.FilterWordsChannelIds)
{ {
var gc = uow.GuildConfigsForId(guildId, WordFilteringChannels.TryRemove(c.ChannelId);
set => set.Include(x => x.FilteredWords)
.Include(x => x.FilterWordsChannelIds));
WordFilteringServers.TryRemove(guildId);
ServerFilteredWords.TryRemove(guildId, out _);
foreach (var c in gc.FilterWordsChannelIds)
{
WordFilteringChannels.TryRemove(c.ChannelId);
}
gc.FilterWords = false;
gc.FilteredWords.Clear();
gc.FilterWordsChannelIds.Clear();
uow.SaveChanges();
} }
gc.FilterWords = false;
gc.FilteredWords.Clear();
gc.FilterWordsChannelIds.Clear();
uow.SaveChanges();
} }
public ConcurrentHashSet<string> FilteredWordsForServer(ulong guildId) public ConcurrentHashSet<string> FilteredWordsForServer(ulong guildId)

View File

@@ -29,18 +29,16 @@ public class PermissionService : ILateBlocker, INService
_strings = strings; _strings = strings;
_eb = eb; _eb = eb;
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
foreach (var x in uow.GuildConfigs.Permissionsv2ForAll(client.Guilds.ToArray().Select(x => x.Id)
.ToList()))
{ {
foreach (var x in uow.GuildConfigs.Permissionsv2ForAll(client.Guilds.ToArray().Select(x => x.Id) Cache.TryAdd(x.GuildId, new()
.ToList()))
{ {
Cache.TryAdd(x.GuildId, new() Verbose = x.VerbosePermissions,
{ PermRole = x.PermissionRole,
Verbose = x.VerbosePermissions, Permissions = new(x.Permissions)
PermRole = x.PermissionRole, });
Permissions = new(x.Permissions)
});
}
} }
} }
@@ -63,19 +61,17 @@ public class PermissionService : ILateBlocker, INService
public async Task AddPermissions(ulong guildId, params Permissionv2[] perms) public async Task AddPermissions(ulong guildId, params Permissionv2[] perms)
{ {
await using (var uow = _db.GetDbContext()) await using var uow = _db.GetDbContext();
var config = uow.GcWithPermissionsv2For(guildId);
//var orderedPerms = new PermissionsCollection<Permissionv2>(config.Permissions);
var max = config.Permissions.Max(x => x.Index); //have to set its index to be the highest
foreach (var perm in perms)
{ {
var config = uow.GcWithPermissionsv2For(guildId); perm.Index = ++max;
//var orderedPerms = new PermissionsCollection<Permissionv2>(config.Permissions); config.Permissions.Add(perm);
var max = config.Permissions.Max(x => x.Index); //have to set its index to be the highest
foreach (var perm in perms)
{
perm.Index = ++max;
config.Permissions.Add(perm);
}
await uow.SaveChangesAsync();
UpdateCache(config);
} }
await uow.SaveChangesAsync();
UpdateCache(config);
} }
public void UpdateCache(GuildConfig config) public void UpdateCache(GuildConfig config)
@@ -170,12 +166,10 @@ public class PermissionService : ILateBlocker, INService
public async Task Reset(ulong guildId) public async Task Reset(ulong guildId)
{ {
await using (var uow = _db.GetDbContext()) await using var uow = _db.GetDbContext();
{ var config = uow.GcWithPermissionsv2For(guildId);
var config = uow.GcWithPermissionsv2For(guildId); config.Permissions = Permissionv2.GetDefaultPermlist;
config.Permissions = Permissionv2.GetDefaultPermlist; await uow.SaveChangesAsync();
await uow.SaveChangesAsync(); UpdateCache(config);
UpdateCache(config);
}
} }
} }

View File

@@ -47,64 +47,62 @@ public partial class Searches
var fullQueryLink = "https://myanimelist.net/profile/" + name; var fullQueryLink = "https://myanimelist.net/profile/" + name;
var config = Configuration.Default.WithDefaultLoader(); var config = Configuration.Default.WithDefaultLoader();
using (var document = await BrowsingContext.New(config).OpenAsync(fullQueryLink).ConfigureAwait(false)) using var document = await BrowsingContext.New(config).OpenAsync(fullQueryLink).ConfigureAwait(false);
{ var imageElem = document.QuerySelector("body > div#myanimelist > div.wrapper > div#contentWrapper > div#content > div.content-container > div.container-left > div.user-profile > div.user-image > img");
var imageElem = document.QuerySelector("body > div#myanimelist > div.wrapper > div#contentWrapper > div#content > div.content-container > div.container-left > div.user-profile > div.user-image > img"); var imageUrl = ((IHtmlImageElement)imageElem)?.Source ?? "http://icecream.me/uploads/870b03f36b59cc16ebfe314ef2dde781.png";
var imageUrl = ((IHtmlImageElement)imageElem)?.Source ?? "http://icecream.me/uploads/870b03f36b59cc16ebfe314ef2dde781.png";
var stats = document.QuerySelectorAll("body > div#myanimelist > div.wrapper > div#contentWrapper > div#content > div.content-container > div.container-right > div#statistics > div.user-statistics-stats > div.stats > div.clearfix > ul.stats-status > li > span").Select(x => x.InnerHtml).ToList(); var stats = document.QuerySelectorAll("body > div#myanimelist > div.wrapper > div#contentWrapper > div#content > div.content-container > div.container-right > div#statistics > div.user-statistics-stats > div.stats > div.clearfix > ul.stats-status > li > span").Select(x => x.InnerHtml).ToList();
var favorites = document.QuerySelectorAll("div.user-favorites > div.di-tc"); var favorites = document.QuerySelectorAll("div.user-favorites > div.di-tc");
var favAnime = GetText(strs.anime_no_fav); var favAnime = GetText(strs.anime_no_fav);
if (favorites.Length > 0 && favorites[0].QuerySelector("p") is null) if (favorites.Length > 0 && favorites[0].QuerySelector("p") is null)
favAnime = string.Join("\n", favorites[0].QuerySelectorAll("ul > li > div.di-tc.va-t > a") favAnime = string.Join("\n", favorites[0].QuerySelectorAll("ul > li > div.di-tc.va-t > a")
.Shuffle() .Shuffle()
.Take(3) .Take(3)
.Select(x => .Select(x =>
{ {
var elem = (IHtmlAnchorElement)x; var elem = (IHtmlAnchorElement)x;
return $"[{elem.InnerHtml}]({elem.Href})"; return $"[{elem.InnerHtml}]({elem.Href})";
})); }));
var info = document.QuerySelectorAll("ul.user-status:nth-child(3) > li.clearfix") var info = document.QuerySelectorAll("ul.user-status:nth-child(3) > li.clearfix")
.Select(x => Tuple.Create(x.Children[0].InnerHtml, x.Children[1].InnerHtml)) .Select(x => Tuple.Create(x.Children[0].InnerHtml, x.Children[1].InnerHtml))
.ToList(); .ToList();
var daysAndMean = document.QuerySelectorAll("div.anime:nth-child(1) > div:nth-child(2) > div") var daysAndMean = document.QuerySelectorAll("div.anime:nth-child(1) > div:nth-child(2) > div")
.Select(x => x.TextContent.Split(':').Select(y => y.Trim()).ToArray()) .Select(x => x.TextContent.Split(':').Select(y => y.Trim()).ToArray())
.ToArray(); .ToArray();
var embed = _eb.Create() var embed = _eb.Create()
.WithOkColor() .WithOkColor()
.WithTitle(GetText(strs.mal_profile(name))) .WithTitle(GetText(strs.mal_profile(name)))
.AddField("💚 " + GetText(strs.watching), stats[0], true) .AddField("💚 " + GetText(strs.watching), stats[0], true)
.AddField("💙 " + GetText(strs.completed), stats[1], true); .AddField("💙 " + GetText(strs.completed), stats[1], true);
if (info.Count < 3) if (info.Count < 3)
embed.AddField("💛 " + GetText(strs.on_hold), stats[2], true); embed.AddField("💛 " + GetText(strs.on_hold), stats[2], true);
embed embed
.AddField("💔 " + GetText(strs.dropped), stats[3], true) .AddField("💔 " + GetText(strs.dropped), stats[3], true)
.AddField("⚪ " + GetText(strs.plan_to_watch), stats[4], true) .AddField("⚪ " + GetText(strs.plan_to_watch), stats[4], true)
.AddField("🕐 " + daysAndMean[0][0], daysAndMean[0][1], true) .AddField("🕐 " + daysAndMean[0][0], daysAndMean[0][1], true)
.AddField("📊 " + daysAndMean[1][0], daysAndMean[1][1], true) .AddField("📊 " + daysAndMean[1][0], daysAndMean[1][1], true)
.AddField(MalInfoToEmoji(info[0].Item1) + " " + info[0].Item1, info[0].Item2.TrimTo(20), true) .AddField(MalInfoToEmoji(info[0].Item1) + " " + info[0].Item1, info[0].Item2.TrimTo(20), true)
.AddField(MalInfoToEmoji(info[1].Item1) + " " + info[1].Item1, info[1].Item2.TrimTo(20), true); .AddField(MalInfoToEmoji(info[1].Item1) + " " + info[1].Item1, info[1].Item2.TrimTo(20), true);
if (info.Count > 2) if (info.Count > 2)
embed.AddField(MalInfoToEmoji(info[2].Item1) + " " + info[2].Item1, info[2].Item2.TrimTo(20), true); embed.AddField(MalInfoToEmoji(info[2].Item1) + " " + info[2].Item1, info[2].Item2.TrimTo(20), true);
embed embed
.WithDescription($@" .WithDescription($@"
** https://myanimelist.net/animelist/{ name } ** ** https://myanimelist.net/animelist/{ name } **
**{GetText(strs.top_3_fav_anime)}** **{GetText(strs.top_3_fav_anime)}**
{favAnime}" {favAnime}"
) )
.WithUrl(fullQueryLink) .WithUrl(fullQueryLink)
.WithImageUrl(imageUrl); .WithImageUrl(imageUrl);
await ctx.Channel.EmbedAsync(embed).ConfigureAwait(false); await ctx.Channel.EmbedAsync(embed).ConfigureAwait(false);
}
} }
private static string MalInfoToEmoji(string info) private static string MalInfoToEmoji(string info)

View File

@@ -53,34 +53,32 @@ public class PicartoProvider : Provider
if (logins.Count == 0) if (logins.Count == 0)
return new(); return new();
using (var http = _httpClientFactory.CreateClient()) using var http = _httpClientFactory.CreateClient();
var toReturn = new List<StreamData>();
foreach (var login in logins)
{ {
var toReturn = new List<StreamData>(); try
foreach (var login in logins)
{ {
try http.DefaultRequestHeaders.Accept.Add(new("application/json"));
{ // get id based on the username
http.DefaultRequestHeaders.Accept.Add(new("application/json")); var res = await http.GetAsync($"https://api.picarto.tv/v1/channel/name/{login}");
// get id based on the username
var res = await http.GetAsync($"https://api.picarto.tv/v1/channel/name/{login}");
if (!res.IsSuccessStatusCode) if (!res.IsSuccessStatusCode)
continue; continue;
var userData = JsonConvert.DeserializeObject<PicartoChannelResponse>(await res.Content.ReadAsStringAsync())!; var userData = JsonConvert.DeserializeObject<PicartoChannelResponse>(await res.Content.ReadAsStringAsync())!;
toReturn.Add(ToStreamData(userData)); toReturn.Add(ToStreamData(userData));
_failingStreams.TryRemove(login, out _); _failingStreams.TryRemove(login, out _);
} }
catch (Exception ex) catch (Exception ex)
{ {
Log.Warning(ex, $"Something went wrong retreiving {Platform} stream data for {login}: {ex.Message}"); Log.Warning(ex, $"Something went wrong retreiving {Platform} stream data for {login}: {ex.Message}");
_failingStreams.TryAdd(login, DateTime.UtcNow); _failingStreams.TryAdd(login, DateTime.UtcNow);
}
} }
return toReturn;
} }
return toReturn;
} }
private StreamData ToStreamData(PicartoChannelResponse stream) private StreamData ToStreamData(PicartoChannelResponse stream)

View File

@@ -53,63 +53,61 @@ public class TwitchProvider : Provider
if (logins.Count == 0) if (logins.Count == 0)
return new(); return new();
using (var http = _httpClientFactory.CreateClient()) using var http = _httpClientFactory.CreateClient();
http.DefaultRequestHeaders.Add("Client-Id", "67w6z9i09xv2uoojdm9l0wsyph4hxo6");
http.DefaultRequestHeaders.Add("Accept", "application/vnd.twitchtv.v5+json");
var toReturn = new List<StreamData>();
foreach (var login in logins)
{ {
http.DefaultRequestHeaders.Add("Client-Id", "67w6z9i09xv2uoojdm9l0wsyph4hxo6"); try
http.DefaultRequestHeaders.Add("Accept", "application/vnd.twitchtv.v5+json");
var toReturn = new List<StreamData>();
foreach (var login in logins)
{ {
try // get id based on the username
var idsStr = await http.GetStringAsync($"https://api.twitch.tv/kraken/users?login={login}");
var userData = JsonConvert.DeserializeObject<TwitchUsersResponseV5>(idsStr);
var user = userData?.Users.FirstOrDefault();
// if user can't be found, skip, it means there is no such user
if (user is null)
continue;
// get stream data
var str = await http.GetStringAsync($"https://api.twitch.tv/kraken/streams/{user.Id}");
var resObj =
JsonConvert.DeserializeAnonymousType(str, new {Stream = new TwitchResponseV5.Stream()});
// if stream is null, user is not streaming
if (resObj?.Stream is null)
{ {
// get id based on the username // if user is not streaming, get his offline banner
var idsStr = await http.GetStringAsync($"https://api.twitch.tv/kraken/users?login={login}"); var chStr = await http.GetStringAsync($"https://api.twitch.tv/kraken/channels/{user.Id}");
var userData = JsonConvert.DeserializeObject<TwitchUsersResponseV5>(idsStr); var ch = JsonConvert.DeserializeObject<TwitchResponseV5.Channel>(chStr)!;
var user = userData?.Users.FirstOrDefault();
// if user can't be found, skip, it means there is no such user
if (user is null)
continue;
// get stream data
var str = await http.GetStringAsync($"https://api.twitch.tv/kraken/streams/{user.Id}");
var resObj =
JsonConvert.DeserializeAnonymousType(str, new {Stream = new TwitchResponseV5.Stream()});
// if stream is null, user is not streaming
if (resObj?.Stream is null)
{
// if user is not streaming, get his offline banner
var chStr = await http.GetStringAsync($"https://api.twitch.tv/kraken/channels/{user.Id}");
var ch = JsonConvert.DeserializeObject<TwitchResponseV5.Channel>(chStr)!;
toReturn.Add(new() toReturn.Add(new()
{ {
StreamType = FollowedStream.FType.Twitch, StreamType = FollowedStream.FType.Twitch,
Name = ch.DisplayName, Name = ch.DisplayName,
UniqueName = ch.Name, UniqueName = ch.Name,
Title = ch.Status, Title = ch.Status,
IsLive = false, IsLive = false,
AvatarUrl = ch.Logo, AvatarUrl = ch.Logo,
StreamUrl = $"https://twitch.tv/{ch.Name}", StreamUrl = $"https://twitch.tv/{ch.Name}",
Preview = ch.VideoBanner // set video banner as the preview, Preview = ch.VideoBanner // set video banner as the preview,
}); });
continue; // move on continue; // move on
} }
toReturn.Add(ToStreamData(resObj.Stream)); toReturn.Add(ToStreamData(resObj.Stream));
_failingStreams.TryRemove(login, out _); _failingStreams.TryRemove(login, out _);
} }
catch (Exception ex) catch (Exception ex)
{ {
Log.Warning($"Something went wrong retreiving {Platform} stream data for {login}: {ex.Message}"); Log.Warning($"Something went wrong retreiving {Platform} stream data for {login}: {ex.Message}");
_failingStreams.TryAdd(login, DateTime.UtcNow); _failingStreams.TryAdd(login, DateTime.UtcNow);
}
} }
return toReturn;
} }
return toReturn;
} }
private StreamData ToStreamData(TwitchResponseV5.Stream stream) private StreamData ToStreamData(TwitchResponseV5.Stream stream)

View File

@@ -39,29 +39,27 @@ public partial class Searches
if (--page < 0) if (--page < 0)
return; return;
using (var http = _httpFactory.CreateClient("memelist")) using var http = _httpFactory.CreateClient("memelist");
{ var res = await http.GetAsync("https://api.memegen.link/templates/")
var res = await http.GetAsync("https://api.memegen.link/templates/") .ConfigureAwait(false);
.ConfigureAwait(false);
var rawJson = await res.Content.ReadAsStringAsync(); var rawJson = await res.Content.ReadAsStringAsync();
var data = JsonConvert.DeserializeObject<List<MemegenTemplate>>(rawJson); var data = JsonConvert.DeserializeObject<List<MemegenTemplate>>(rawJson);
await ctx.SendPaginatedConfirmAsync(page, curPage => await ctx.SendPaginatedConfirmAsync(page, curPage =>
{
var templates = string.Empty;
foreach (var template in data.Skip(curPage * 15).Take(15))
{ {
var templates = string.Empty; templates += $"**{template.Name}:**\n key: `{template.Id}`\n";
foreach (var template in data.Skip(curPage * 15).Take(15)) }
{ var embed = _eb.Create()
templates += $"**{template.Name}:**\n key: `{template.Id}`\n"; .WithOkColor()
} .WithDescription(templates);
var embed = _eb.Create()
.WithOkColor()
.WithDescription(templates);
return embed; return embed;
}, data.Count, 15).ConfigureAwait(false); }, data.Count, 15).ConfigureAwait(false);
}
} }
[NadekoCommand, Aliases] [NadekoCommand, Aliases]

View File

@@ -23,101 +23,97 @@ public partial class Searches
if (string.IsNullOrWhiteSpace(user)) if (string.IsNullOrWhiteSpace(user))
return; return;
using (var http = _httpFactory.CreateClient()) using var http = _httpFactory.CreateClient();
var modeNumber = string.IsNullOrWhiteSpace(mode)
? 0
: ResolveGameMode(mode);
try
{ {
var modeNumber = string.IsNullOrWhiteSpace(mode) if (string.IsNullOrWhiteSpace(_creds.OsuApiKey))
? 0
: ResolveGameMode(mode);
try
{ {
if (string.IsNullOrWhiteSpace(_creds.OsuApiKey)) await ReplyErrorLocalizedAsync(strs.osu_api_key).ConfigureAwait(false);
{ return;
await ReplyErrorLocalizedAsync(strs.osu_api_key).ConfigureAwait(false);
return;
}
var smode = ResolveGameMode(modeNumber);
var userReq = $"https://osu.ppy.sh/api/get_user?k={_creds.OsuApiKey}&u={user}&m={modeNumber}";
var userResString = await http.GetStringAsync(userReq)
.ConfigureAwait(false);
var objs = JsonConvert.DeserializeObject<List<OsuUserData>>(userResString);
if (objs.Count == 0)
{
await ReplyErrorLocalizedAsync(strs.osu_user_not_found).ConfigureAwait(false);
return;
}
var obj = objs[0];
var userId = obj.UserId;
await ctx.Channel.EmbedAsync(_eb.Create()
.WithOkColor()
.WithTitle($"osu! {smode} profile for {user}")
.WithThumbnailUrl($"https://a.ppy.sh/{userId}")
.WithDescription($"https://osu.ppy.sh/u/{userId}")
.AddField("Official Rank", $"#{obj.PpRank}", true)
.AddField("Country Rank", $"#{obj.PpCountryRank} :flag_{obj.Country.ToLower()}:", true)
.AddField("Total PP", Math.Round(obj.PpRaw, 2), true)
.AddField("Accuracy", Math.Round(obj.Accuracy, 2) + "%", true)
.AddField("Playcount", obj.Playcount, true)
.AddField("Level", Math.Round(obj.Level), true)
);
} }
catch (ArgumentOutOfRangeException)
var smode = ResolveGameMode(modeNumber);
var userReq = $"https://osu.ppy.sh/api/get_user?k={_creds.OsuApiKey}&u={user}&m={modeNumber}";
var userResString = await http.GetStringAsync(userReq)
.ConfigureAwait(false);
var objs = JsonConvert.DeserializeObject<List<OsuUserData>>(userResString);
if (objs.Count == 0)
{ {
await ReplyErrorLocalizedAsync(strs.osu_user_not_found).ConfigureAwait(false); await ReplyErrorLocalizedAsync(strs.osu_user_not_found).ConfigureAwait(false);
return;
} }
catch (Exception ex)
{ var obj = objs[0];
await ReplyErrorLocalizedAsync(strs.osu_failed).ConfigureAwait(false); var userId = obj.UserId;
Log.Warning(ex, "Osu command failed");
} await ctx.Channel.EmbedAsync(_eb.Create()
.WithOkColor()
.WithTitle($"osu! {smode} profile for {user}")
.WithThumbnailUrl($"https://a.ppy.sh/{userId}")
.WithDescription($"https://osu.ppy.sh/u/{userId}")
.AddField("Official Rank", $"#{obj.PpRank}", true)
.AddField("Country Rank", $"#{obj.PpCountryRank} :flag_{obj.Country.ToLower()}:", true)
.AddField("Total PP", Math.Round(obj.PpRaw, 2), true)
.AddField("Accuracy", Math.Round(obj.Accuracy, 2) + "%", true)
.AddField("Playcount", obj.Playcount, true)
.AddField("Level", Math.Round(obj.Level), true)
);
}
catch (ArgumentOutOfRangeException)
{
await ReplyErrorLocalizedAsync(strs.osu_user_not_found).ConfigureAwait(false);
}
catch (Exception ex)
{
await ReplyErrorLocalizedAsync(strs.osu_failed).ConfigureAwait(false);
Log.Warning(ex, "Osu command failed");
} }
} }
[NadekoCommand, Aliases] [NadekoCommand, Aliases]
public async Task Gatari(string user, [Leftover] string mode = null) public async Task Gatari(string user, [Leftover] string mode = null)
{ {
using (var http = _httpFactory.CreateClient()) using var http = _httpFactory.CreateClient();
var modeNumber = string.IsNullOrWhiteSpace(mode)
? 0
: ResolveGameMode(mode);
var modeStr = ResolveGameMode(modeNumber);
var resString = await http
.GetStringAsync($"https://api.gatari.pw/user/stats?u={user}&mode={modeNumber}")
.ConfigureAwait(false);
var statsResponse = JsonConvert.DeserializeObject<GatariUserStatsResponse>(resString);
if (statsResponse.Code != 200 || statsResponse.Stats.Id == 0)
{ {
var modeNumber = string.IsNullOrWhiteSpace(mode) await ReplyErrorLocalizedAsync(strs.osu_user_not_found).ConfigureAwait(false);
? 0 return;
: ResolveGameMode(mode);
var modeStr = ResolveGameMode(modeNumber);
var resString = await http
.GetStringAsync($"https://api.gatari.pw/user/stats?u={user}&mode={modeNumber}")
.ConfigureAwait(false);
var statsResponse = JsonConvert.DeserializeObject<GatariUserStatsResponse>(resString);
if (statsResponse.Code != 200 || statsResponse.Stats.Id == 0)
{
await ReplyErrorLocalizedAsync(strs.osu_user_not_found).ConfigureAwait(false);
return;
}
var usrResString = await http.GetStringAsync($"https://api.gatari.pw/users/get?u={user}")
.ConfigureAwait(false);
var userData = JsonConvert.DeserializeObject<GatariUserResponse>(usrResString).Users[0];
var userStats = statsResponse.Stats;
var embed = _eb.Create()
.WithOkColor()
.WithTitle($"osu!Gatari {modeStr} profile for {user}")
.WithThumbnailUrl($"https://a.gatari.pw/{userStats.Id}")
.WithDescription($"https://osu.gatari.pw/u/{userStats.Id}")
.AddField("Official Rank", $"#{userStats.Rank}", true)
.AddField("Country Rank", $"#{userStats.CountryRank} :flag_{userData.Country.ToLower()}:", true)
.AddField("Total PP", userStats.Pp, true)
.AddField("Accuracy", $"{Math.Round(userStats.AvgAccuracy, 2)}%", true)
.AddField("Playcount", userStats.Playcount, true)
.AddField("Level", userStats.Level, true);
await ctx.Channel.EmbedAsync(embed);
} }
var usrResString = await http.GetStringAsync($"https://api.gatari.pw/users/get?u={user}")
.ConfigureAwait(false);
var userData = JsonConvert.DeserializeObject<GatariUserResponse>(usrResString).Users[0];
var userStats = statsResponse.Stats;
var embed = _eb.Create()
.WithOkColor()
.WithTitle($"osu!Gatari {modeStr} profile for {user}")
.WithThumbnailUrl($"https://a.gatari.pw/{userStats.Id}")
.WithDescription($"https://osu.gatari.pw/u/{userStats.Id}")
.AddField("Official Rank", $"#{userStats.Rank}", true)
.AddField("Country Rank", $"#{userStats.CountryRank} :flag_{userData.Country.ToLower()}:", true)
.AddField("Total PP", userStats.Pp, true)
.AddField("Accuracy", $"{Math.Round(userStats.AvgAccuracy, 2)}%", true)
.AddField("Playcount", userStats.Playcount, true)
.AddField("Level", userStats.Level, true);
await ctx.Channel.EmbedAsync(embed);
} }
[NadekoCommand, Aliases] [NadekoCommand, Aliases]
@@ -135,62 +131,60 @@ public partial class Searches
return; return;
} }
using (var http = _httpFactory.CreateClient()) using var http = _httpFactory.CreateClient();
var m = 0;
if (!string.IsNullOrWhiteSpace(mode))
{ {
var m = 0; m = ResolveGameMode(mode);
if (!string.IsNullOrWhiteSpace(mode)) }
{
m = ResolveGameMode(mode);
}
var reqString = $"https://osu.ppy.sh/api/get_user_best" + var reqString = $"https://osu.ppy.sh/api/get_user_best" +
$"?k={_creds.OsuApiKey}" + $"?k={_creds.OsuApiKey}" +
$"&u={Uri.EscapeDataString(user)}" + $"&u={Uri.EscapeDataString(user)}" +
$"&type=string" + $"&type=string" +
$"&limit=5" + $"&limit=5" +
$"&m={m}"; $"&m={m}";
var resString = await http.GetStringAsync(reqString).ConfigureAwait(false); var resString = await http.GetStringAsync(reqString).ConfigureAwait(false);
var obj = JsonConvert.DeserializeObject<List<OsuUserBests>>(resString); var obj = JsonConvert.DeserializeObject<List<OsuUserBests>>(resString);
var mapTasks = obj.Select(async item => var mapTasks = obj.Select(async item =>
{ {
var mapReqString = $"https://osu.ppy.sh/api/get_beatmaps" + var mapReqString = $"https://osu.ppy.sh/api/get_beatmaps" +
$"?k={_creds.OsuApiKey}" + $"?k={_creds.OsuApiKey}" +
$"&b={item.BeatmapId}"; $"&b={item.BeatmapId}";
var mapResString = await http.GetStringAsync(mapReqString).ConfigureAwait(false); var mapResString = await http.GetStringAsync(mapReqString).ConfigureAwait(false);
var map = JsonConvert.DeserializeObject<List<OsuMapData>>(mapResString).FirstOrDefault(); var map = JsonConvert.DeserializeObject<List<OsuMapData>>(mapResString).FirstOrDefault();
if (map is null) if (map is null)
return default; return default;
var pp = Math.Round(item.Pp, 2); var pp = Math.Round(item.Pp, 2);
var acc = CalculateAcc(item, m); var acc = CalculateAcc(item, m);
var mods = ResolveMods(item.EnabledMods); var mods = ResolveMods(item.EnabledMods);
var title = $"{map.Artist}-{map.Title} ({map.Version})"; var title = $"{map.Artist}-{map.Title} ({map.Version})";
var desc = $@"[/b/{item.BeatmapId}](https://osu.ppy.sh/b/{item.BeatmapId}) var desc = $@"[/b/{item.BeatmapId}](https://osu.ppy.sh/b/{item.BeatmapId})
{pp + "pp",-7} | {acc + "%",-7} {pp + "pp",-7} | {acc + "%",-7}
"; ";
if (mods != "+") if (mods != "+")
{
desc += Format.Bold(mods);
}
return (title, desc);
});
var eb = _eb.Create()
.WithOkColor()
.WithTitle($"Top 5 plays for {user}");
var mapData = await Task.WhenAll(mapTasks);
foreach (var (title, desc) in mapData.Where(x => x != default))
{ {
eb.AddField(title, desc, false); desc += Format.Bold(mods);
} }
await ctx.Channel.EmbedAsync(eb).ConfigureAwait(false); return (title, desc);
});
var eb = _eb.Create()
.WithOkColor()
.WithTitle($"Top 5 plays for {user}");
var mapData = await Task.WhenAll(mapTasks);
foreach (var (title, desc) in mapData.Where(x => x != default))
{
eb.AddField(title, desc, false);
} }
await ctx.Channel.EmbedAsync(eb).ConfigureAwait(false);
} }
//https://osu.ppy.sh/wiki/Accuracy //https://osu.ppy.sh/wiki/Accuracy

View File

@@ -41,11 +41,9 @@ public partial class Searches
try try
{ {
using (var http = _httpFactory.CreateClient()) using var http = _httpFactory.CreateClient();
{ var res = await http.GetStringAsync($"{_poeURL}{usr}").ConfigureAwait(false);
var res = await http.GetStringAsync($"{_poeURL}{usr}").ConfigureAwait(false); characters = JsonConvert.DeserializeObject<List<Account>>(res);
characters = JsonConvert.DeserializeObject<List<Account>>(res);
}
} }
catch catch
{ {
@@ -102,11 +100,9 @@ public partial class Searches
try try
{ {
using (var http = _httpFactory.CreateClient()) using var http = _httpFactory.CreateClient();
{ var res = await http.GetStringAsync("http://api.pathofexile.com/leagues?type=main&compact=1").ConfigureAwait(false);
var res = await http.GetStringAsync("http://api.pathofexile.com/leagues?type=main&compact=1").ConfigureAwait(false); leagues = JsonConvert.DeserializeObject<List<Leagues>>(res);
leagues = JsonConvert.DeserializeObject<List<Leagues>>(res);
}
} }
catch catch
{ {
@@ -159,48 +155,46 @@ public partial class Searches
try try
{ {
var res = $"{_ponURL}{leagueName}"; var res = $"{_ponURL}{leagueName}";
using (var http = _httpFactory.CreateClient()) using var http = _httpFactory.CreateClient();
var obj = JObject.Parse(await http.GetStringAsync(res).ConfigureAwait(false));
var chaosEquivalent = 0.0F;
var conversionEquivalent = 0.0F;
// poe.ninja API does not include a "chaosEquivalent" property for Chaos Orbs.
if (cleanCurrency == "Chaos Orb")
{ {
var obj = JObject.Parse(await http.GetStringAsync(res).ConfigureAwait(false)); chaosEquivalent = 1.0F;
var chaosEquivalent = 0.0F;
var conversionEquivalent = 0.0F;
// poe.ninja API does not include a "chaosEquivalent" property for Chaos Orbs.
if (cleanCurrency == "Chaos Orb")
{
chaosEquivalent = 1.0F;
}
else
{
var currencyInput = obj["lines"].Values<JObject>()
.Where(i => i["currencyTypeName"].Value<string>() == cleanCurrency)
.FirstOrDefault();
chaosEquivalent = float.Parse(currencyInput["chaosEquivalent"].ToString(), System.Globalization.CultureInfo.InvariantCulture);
}
if (cleanConvert == "Chaos Orb")
{
conversionEquivalent = 1.0F;
}
else
{
var currencyOutput = obj["lines"].Values<JObject>()
.Where(i => i["currencyTypeName"].Value<string>() == cleanConvert)
.FirstOrDefault();
conversionEquivalent = float.Parse(currencyOutput["chaosEquivalent"].ToString(), System.Globalization.CultureInfo.InvariantCulture);
}
var embed = _eb.Create()
.WithAuthor($"{leagueName} Currency Exchange",
"https://web.poecdn.com/image/favicon/ogimage.png",
"http://poe.ninja")
.AddField("Currency Type", cleanCurrency, true)
.AddField($"{cleanConvert} Equivalent", chaosEquivalent / conversionEquivalent, true)
.WithOkColor();
await ctx.Channel.EmbedAsync(embed).ConfigureAwait(false);
} }
else
{
var currencyInput = obj["lines"].Values<JObject>()
.Where(i => i["currencyTypeName"].Value<string>() == cleanCurrency)
.FirstOrDefault();
chaosEquivalent = float.Parse(currencyInput["chaosEquivalent"].ToString(), System.Globalization.CultureInfo.InvariantCulture);
}
if (cleanConvert == "Chaos Orb")
{
conversionEquivalent = 1.0F;
}
else
{
var currencyOutput = obj["lines"].Values<JObject>()
.Where(i => i["currencyTypeName"].Value<string>() == cleanConvert)
.FirstOrDefault();
conversionEquivalent = float.Parse(currencyOutput["chaosEquivalent"].ToString(), System.Globalization.CultureInfo.InvariantCulture);
}
var embed = _eb.Create()
.WithAuthor($"{leagueName} Currency Exchange",
"https://web.poecdn.com/image/favicon/ogimage.png",
"http://poe.ninja")
.AddField("Currency Type", cleanCurrency, true)
.AddField($"{cleanConvert} Equivalent", chaosEquivalent / conversionEquivalent, true)
.WithOkColor();
await ctx.Channel.EmbedAsync(embed).ConfigureAwait(false);
} }
catch catch
{ {

View File

@@ -39,15 +39,13 @@ public partial class Searches : NadekoModule<SearchesService>
var av = usr.RealAvatarUrl(); var av = usr.RealAvatarUrl();
if (av is null) if (av is null)
return; return;
await using (var picStream = await _service.GetRipPictureAsync(usr.Nickname ?? usr.Username, av).ConfigureAwait(false)) await using var picStream = await _service.GetRipPictureAsync(usr.Nickname ?? usr.Username, av).ConfigureAwait(false);
{ await ctx.Channel.SendFileAsync(
await ctx.Channel.SendFileAsync( picStream,
picStream, "rip.png",
"rip.png", $"Rip {Format.Bold(usr.ToString())} \n\t- " +
$"Rip {Format.Bold(usr.ToString())} \n\t- " + Format.Italics(ctx.User.ToString()))
Format.Italics(ctx.User.ToString())) .ConfigureAwait(false);
.ConfigureAwait(false);
}
} }
[NadekoCommand, Aliases] [NadekoCommand, Aliases]
@@ -224,30 +222,28 @@ public partial class Searches : NadekoModule<SearchesService>
var fullQueryLink = $"http://imgur.com/search?q={ query }"; var fullQueryLink = $"http://imgur.com/search?q={ query }";
var config = Configuration.Default.WithDefaultLoader(); var config = Configuration.Default.WithDefaultLoader();
using (var document = await BrowsingContext.New(config).OpenAsync(fullQueryLink).ConfigureAwait(false)) using var document = await BrowsingContext.New(config).OpenAsync(fullQueryLink).ConfigureAwait(false);
{ var elems = document.QuerySelectorAll("a.image-list-link").ToList();
var elems = document.QuerySelectorAll("a.image-list-link").ToList();
if (!elems.Any()) if (!elems.Any())
return; return;
var img = elems.ElementAtOrDefault(new NadekoRandom().Next(0, elems.Count))?.Children?.FirstOrDefault() as IHtmlImageElement; var img = elems.ElementAtOrDefault(new NadekoRandom().Next(0, elems.Count))?.Children?.FirstOrDefault() as IHtmlImageElement;
if (img?.Source is null) if (img?.Source is null)
return; return;
var source = img.Source.Replace("b.", ".", StringComparison.InvariantCulture); var source = img.Source.Replace("b.", ".", StringComparison.InvariantCulture);
var embed = _eb.Create() var embed = _eb.Create()
.WithOkColor() .WithOkColor()
.WithAuthor(GetText(strs.image_search_for) + " " + oterms.TrimTo(50), .WithAuthor(GetText(strs.image_search_for) + " " + oterms.TrimTo(50),
"http://s.imgur.com/images/logo-1200-630.jpg?", "http://s.imgur.com/images/logo-1200-630.jpg?",
fullQueryLink) fullQueryLink)
.WithDescription(source) .WithDescription(source)
.WithImageUrl(source) .WithImageUrl(source)
.WithTitle(ctx.User.ToString()); .WithTitle(ctx.User.ToString());
await ctx.Channel.EmbedAsync(embed).ConfigureAwait(false); await ctx.Channel.EmbedAsync(embed).ConfigureAwait(false);
}
} }
} }
@@ -280,28 +276,24 @@ public partial class Searches : NadekoModule<SearchesService>
{ {
try try
{ {
using (var _http = _httpFactory.CreateClient()) using var _http = _httpFactory.CreateClient();
using (var req = new HttpRequestMessage(HttpMethod.Post, "https://goolnk.com/api/v1/shorten")) using var req = new HttpRequestMessage(HttpMethod.Post, "https://goolnk.com/api/v1/shorten");
var formData = new MultipartFormDataContent
{ {
var formData = new MultipartFormDataContent { new StringContent(query), "url" }
{ };
{ new StringContent(query), "url" } req.Content = formData;
};
req.Content = formData;
using (var res = await _http.SendAsync(req).ConfigureAwait(false)) using var res = await _http.SendAsync(req).ConfigureAwait(false);
{ var content = await res.Content.ReadAsStringAsync();
var content = await res.Content.ReadAsStringAsync(); var data = JsonConvert.DeserializeObject<ShortenData>(content);
var data = JsonConvert.DeserializeObject<ShortenData>(content);
if (!string.IsNullOrWhiteSpace(data?.ResultUrl)) if (!string.IsNullOrWhiteSpace(data?.ResultUrl))
cachedShortenedLinks.TryAdd(query, data.ResultUrl); cachedShortenedLinks.TryAdd(query, data.ResultUrl);
else else
return; return;
shortLink = data.ResultUrl; shortLink = data.ResultUrl;
}
}
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -477,78 +469,74 @@ public partial class Searches : NadekoModule<SearchesService>
if (!await ValidateQuery(word).ConfigureAwait(false)) if (!await ValidateQuery(word).ConfigureAwait(false))
return; return;
using (var _http = _httpFactory.CreateClient()) using var _http = _httpFactory.CreateClient();
string res;
try
{ {
string res; res = await _cache.GetOrCreateAsync($"define_{word}", e =>
try
{ {
res = await _cache.GetOrCreateAsync($"define_{word}", e => e.AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(12);
{ return _http.GetStringAsync("https://api.pearson.com/v2/dictionaries/entries?headword=" + WebUtility.UrlEncode(word));
e.AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(12); }).ConfigureAwait(false);
return _http.GetStringAsync("https://api.pearson.com/v2/dictionaries/entries?headword=" + WebUtility.UrlEncode(word));
}).ConfigureAwait(false);
var data = JsonConvert.DeserializeObject<DefineModel>(res); var data = JsonConvert.DeserializeObject<DefineModel>(res);
var datas = data.Results var datas = data.Results
.Where(x => x.Senses is not null && x.Senses.Count > 0 && x.Senses[0].Definition is not null) .Where(x => x.Senses is not null && x.Senses.Count > 0 && x.Senses[0].Definition is not null)
.Select(x => (Sense: x.Senses[0], x.PartOfSpeech)); .Select(x => (Sense: x.Senses[0], x.PartOfSpeech));
if (!datas.Any()) if (!datas.Any())
{
Log.Warning("Definition not found: {Word}", word);
await ReplyErrorLocalizedAsync(strs.define_unknown).ConfigureAwait(false);
}
var col = datas.Select(data => (
Definition: data.Sense.Definition is string
? data.Sense.Definition.ToString()
: ((JArray)JToken.Parse(data.Sense.Definition.ToString())).First.ToString(),
Example: data.Sense.Examples is null || data.Sense.Examples.Count == 0
? string.Empty
: data.Sense.Examples[0].Text,
Word: word,
WordType: string.IsNullOrWhiteSpace(data.PartOfSpeech) ? "-" : data.PartOfSpeech
)).ToList();
Log.Information($"Sending {col.Count} definition for: {word}");
await ctx.SendPaginatedConfirmAsync(0, page =>
{
var data = col.Skip(page).First();
var embed = _eb.Create()
.WithDescription(ctx.User.Mention)
.AddField(GetText(strs.word), data.Word, true)
.AddField(GetText(strs._class), data.WordType, true)
.AddField(GetText(strs.definition), data.Definition)
.WithOkColor();
if (!string.IsNullOrWhiteSpace(data.Example))
embed.AddField(GetText(strs.example), data.Example);
return embed;
}, col.Count, 1);
}
catch (Exception ex)
{ {
Log.Error(ex, "Error retrieving definition data for: {Word}", word); Log.Warning("Definition not found: {Word}", word);
await ReplyErrorLocalizedAsync(strs.define_unknown).ConfigureAwait(false);
} }
var col = datas.Select(data => (
Definition: data.Sense.Definition is string
? data.Sense.Definition.ToString()
: ((JArray)JToken.Parse(data.Sense.Definition.ToString())).First.ToString(),
Example: data.Sense.Examples is null || data.Sense.Examples.Count == 0
? string.Empty
: data.Sense.Examples[0].Text,
Word: word,
WordType: string.IsNullOrWhiteSpace(data.PartOfSpeech) ? "-" : data.PartOfSpeech
)).ToList();
Log.Information($"Sending {col.Count} definition for: {word}");
await ctx.SendPaginatedConfirmAsync(0, page =>
{
var data = col.Skip(page).First();
var embed = _eb.Create()
.WithDescription(ctx.User.Mention)
.AddField(GetText(strs.word), data.Word, true)
.AddField(GetText(strs._class), data.WordType, true)
.AddField(GetText(strs.definition), data.Definition)
.WithOkColor();
if (!string.IsNullOrWhiteSpace(data.Example))
embed.AddField(GetText(strs.example), data.Example);
return embed;
}, col.Count, 1);
}
catch (Exception ex)
{
Log.Error(ex, "Error retrieving definition data for: {Word}", word);
} }
} }
[NadekoCommand, Aliases] [NadekoCommand, Aliases]
public async Task Catfact() public async Task Catfact()
{ {
using (var http = _httpFactory.CreateClient()) using var http = _httpFactory.CreateClient();
{ var response = await http.GetStringAsync("https://catfact.ninja/fact").ConfigureAwait(false);
var response = await http.GetStringAsync("https://catfact.ninja/fact").ConfigureAwait(false); if (response is null)
if (response is null) return;
return;
var fact = JObject.Parse(response)["fact"].ToString(); var fact = JObject.Parse(response)["fact"].ToString();
await SendConfirmAsync("🐈" + GetText(strs.catfact), fact).ConfigureAwait(false); await SendConfirmAsync("🐈" + GetText(strs.catfact), fact).ConfigureAwait(false);
}
} }
//done in 3.0 //done in 3.0
@@ -585,15 +573,13 @@ public partial class Searches : NadekoModule<SearchesService>
if (!await ValidateQuery(query).ConfigureAwait(false)) if (!await ValidateQuery(query).ConfigureAwait(false))
return; return;
using (var http = _httpFactory.CreateClient()) using var http = _httpFactory.CreateClient();
{ var result = await http.GetStringAsync("https://en.wikipedia.org//w/api.php?action=query&format=json&prop=info&redirects=1&formatversion=2&inprop=url&titles=" + Uri.EscapeDataString(query)).ConfigureAwait(false);
var result = await http.GetStringAsync("https://en.wikipedia.org//w/api.php?action=query&format=json&prop=info&redirects=1&formatversion=2&inprop=url&titles=" + Uri.EscapeDataString(query)).ConfigureAwait(false); var data = JsonConvert.DeserializeObject<WikipediaApiModel>(result);
var data = JsonConvert.DeserializeObject<WikipediaApiModel>(result); if (data.Query.Pages[0].Missing || string.IsNullOrWhiteSpace(data.Query.Pages[0].FullUrl))
if (data.Query.Pages[0].Missing || string.IsNullOrWhiteSpace(data.Query.Pages[0].FullUrl)) await ReplyErrorLocalizedAsync(strs.wiki_page_not_found).ConfigureAwait(false);
await ReplyErrorLocalizedAsync(strs.wiki_page_not_found).ConfigureAwait(false); else
else await ctx.Channel.SendMessageAsync(data.Query.Pages[0].FullUrl).ConfigureAwait(false);
await ctx.Channel.SendMessageAsync(data.Query.Pages[0].FullUrl).ConfigureAwait(false);
}
} }
[NadekoCommand, Aliases] [NadekoCommand, Aliases]
@@ -605,24 +591,20 @@ public partial class Searches : NadekoModule<SearchesService>
var colorObjects = colors.Take(10) var colorObjects = colors.Take(10)
.ToArray(); .ToArray();
using (var img = new Image<Rgba32>(colorObjects.Length * 50, 50)) using var img = new Image<Rgba32>(colorObjects.Length * 50, 50);
for (var i = 0; i < colorObjects.Length; i++)
{ {
for (var i = 0; i < colorObjects.Length; i++) var x = i * 50;
{ img.Mutate(m => m.FillPolygon(colorObjects[i], new PointF[] {
var x = i * 50; new(x, 0),
img.Mutate(m => m.FillPolygon(colorObjects[i], new PointF[] { new(x + 50, 0),
new(x, 0), new(x + 50, 50),
new(x + 50, 0), new(x, 50)
new(x + 50, 50), }));
new(x, 50)
}));
}
await using (var ms = img.ToStream())
{
await ctx.Channel.SendFileAsync(ms, $"colors.png").ConfigureAwait(false);
}
} }
await using var ms = img.ToStream();
await ctx.Channel.SendFileAsync(ms, $"colors.png").ConfigureAwait(false);
} }
[NadekoCommand, Aliases] [NadekoCommand, Aliases]
@@ -655,35 +637,33 @@ public partial class Searches : NadekoModule<SearchesService>
return; return;
} }
await ctx.Channel.TriggerTypingAsync().ConfigureAwait(false); await ctx.Channel.TriggerTypingAsync().ConfigureAwait(false);
using (var http = _httpFactory.CreateClient()) using var http = _httpFactory.CreateClient();
http.DefaultRequestHeaders.Clear();
try
{ {
http.DefaultRequestHeaders.Clear(); var res = await http.GetStringAsync($"https://{Uri.EscapeDataString(target)}.fandom.com/api.php" +
try $"?action=query" +
{ $"&format=json" +
var res = await http.GetStringAsync($"https://{Uri.EscapeDataString(target)}.fandom.com/api.php" + $"&list=search" +
$"?action=query" + $"&srsearch={Uri.EscapeDataString(query)}" +
$"&format=json" + $"&srlimit=1").ConfigureAwait(false);
$"&list=search" + var items = JObject.Parse(res);
$"&srsearch={Uri.EscapeDataString(query)}" + var title = items["query"]?["search"]?.FirstOrDefault()?["title"]?.ToString();
$"&srlimit=1").ConfigureAwait(false);
var items = JObject.Parse(res);
var title = items["query"]?["search"]?.FirstOrDefault()?["title"]?.ToString();
if (string.IsNullOrWhiteSpace(title)) if (string.IsNullOrWhiteSpace(title))
{
await ReplyErrorLocalizedAsync(strs.wikia_error).ConfigureAwait(false);
return;
}
var url = Uri.EscapeDataString($"https://{target}.fandom.com/wiki/{title}");
var response = $@"`{GetText(strs.title)}` {title.SanitizeMentions()}
`{GetText(strs.url)}:` {url}";
await ctx.Channel.SendMessageAsync(response).ConfigureAwait(false);
}
catch
{ {
await ReplyErrorLocalizedAsync(strs.wikia_error).ConfigureAwait(false); await ReplyErrorLocalizedAsync(strs.wikia_error).ConfigureAwait(false);
return;
} }
var url = Uri.EscapeDataString($"https://{target}.fandom.com/wiki/{title}");
var response = $@"`{GetText(strs.title)}` {title.SanitizeMentions()}
`{GetText(strs.url)}:` {url}";
await ctx.Channel.SendMessageAsync(response).ConfigureAwait(false);
}
catch
{
await ReplyErrorLocalizedAsync(strs.wikia_error).ConfigureAwait(false);
} }
} }
@@ -694,13 +674,11 @@ public partial class Searches : NadekoModule<SearchesService>
var obj = new BibleVerses(); var obj = new BibleVerses();
try try
{ {
using (var http = _httpFactory.CreateClient()) using var http = _httpFactory.CreateClient();
{ var res = await http
var res = await http .GetStringAsync("https://bible-api.com/" + book + " " + chapterAndVerse).ConfigureAwait(false);
.GetStringAsync("https://bible-api.com/" + book + " " + chapterAndVerse).ConfigureAwait(false);
obj = JsonConvert.DeserializeObject<BibleVerses>(res); obj = JsonConvert.DeserializeObject<BibleVerses>(res);
}
} }
catch catch
{ {

View File

@@ -61,58 +61,56 @@ public class AnimeSearchService : INService
if (!ok) if (!ok)
{ {
var config = Configuration.Default.WithDefaultLoader(); var config = Configuration.Default.WithDefaultLoader();
using (var document = await BrowsingContext.New(config).OpenAsync(link).ConfigureAwait(false)) using var document = await BrowsingContext.New(config).OpenAsync(link).ConfigureAwait(false);
var imageElem = document.QuerySelector("div.seriesimg > img");
if (imageElem is null)
return null;
var imageUrl = ((IHtmlImageElement)imageElem).Source;
var descElem = document.QuerySelector("div#editdescription > p");
var desc = descElem.InnerHtml;
var genres = document.QuerySelector("div#seriesgenre").Children
.Select(x => x as IHtmlAnchorElement)
.Where(x => x != null)
.Select(x => $"[{x.InnerHtml}]({x.Href})")
.ToArray();
var authors = document
.QuerySelector("div#showauthors")
.Children
.Select(x => x as IHtmlAnchorElement)
.Where(x => x != null)
.Select(x => $"[{x.InnerHtml}]({x.Href})")
.ToArray();
var score = ((IHtmlSpanElement)document
.QuerySelector("h5.seriesother > span.uvotes"))
.InnerHtml;
var status = document
.QuerySelector("div#editstatus")
.InnerHtml;
var title = document
.QuerySelector("div.w-blog-content > div.seriestitlenu")
.InnerHtml;
var obj = new NovelResult()
{ {
var imageElem = document.QuerySelector("div.seriesimg > img"); Description = desc,
if (imageElem is null) Authors = authors,
return null; Genres = genres,
var imageUrl = ((IHtmlImageElement)imageElem).Source; ImageUrl = imageUrl,
Link = link,
Score = score,
Status = status,
Title = title,
};
var descElem = document.QuerySelector("div#editdescription > p"); await _cache.SetNovelDataAsync(link,
var desc = descElem.InnerHtml; JsonConvert.SerializeObject(obj)).ConfigureAwait(false);
var genres = document.QuerySelector("div#seriesgenre").Children return obj;
.Select(x => x as IHtmlAnchorElement)
.Where(x => x != null)
.Select(x => $"[{x.InnerHtml}]({x.Href})")
.ToArray();
var authors = document
.QuerySelector("div#showauthors")
.Children
.Select(x => x as IHtmlAnchorElement)
.Where(x => x != null)
.Select(x => $"[{x.InnerHtml}]({x.Href})")
.ToArray();
var score = ((IHtmlSpanElement)document
.QuerySelector("h5.seriesother > span.uvotes"))
.InnerHtml;
var status = document
.QuerySelector("div#editstatus")
.InnerHtml;
var title = document
.QuerySelector("div.w-blog-content > div.seriestitlenu")
.InnerHtml;
var obj = new NovelResult()
{
Description = desc,
Authors = authors,
Genres = genres,
ImageUrl = imageUrl,
Link = link,
Score = score,
Status = status,
Title = title,
};
await _cache.SetNovelDataAsync(link,
JsonConvert.SerializeObject(obj)).ConfigureAwait(false);
return obj;
}
} }
return JsonConvert.DeserializeObject<NovelResult>(data); return JsonConvert.DeserializeObject<NovelResult>(data);

View File

@@ -156,15 +156,13 @@ public class FeedsService : INService
public List<FeedSub> GetFeeds(ulong guildId) public List<FeedSub> GetFeeds(ulong guildId)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ return uow.GuildConfigsForId(guildId,
return uow.GuildConfigsForId(guildId, set => set.Include(x => x.FeedSubs)
set => set.Include(x => x.FeedSubs) .ThenInclude(x => x.GuildConfig))
.ThenInclude(x => x.GuildConfig)) .FeedSubs
.FeedSubs .OrderBy(x => x.Id)
.OrderBy(x => x.Id) .ToList();
.ToList();
}
} }
public bool AddFeed(ulong guildId, ulong channelId, string rssFeed) public bool AddFeed(ulong guildId, ulong channelId, string rssFeed)
@@ -177,32 +175,30 @@ public class FeedsService : INService
Url = rssFeed.Trim(), Url = rssFeed.Trim(),
}; };
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
var gc = uow.GuildConfigsForId(guildId,
set => set.Include(x => x.FeedSubs)
.ThenInclude(x => x.GuildConfig));
if (gc.FeedSubs.Any(x => x.Url.ToLower() == fs.Url.ToLower()))
{ {
var gc = uow.GuildConfigsForId(guildId, return false;
set => set.Include(x => x.FeedSubs) }
.ThenInclude(x => x.GuildConfig)); else if (gc.FeedSubs.Count >= 10)
{
return false;
}
if (gc.FeedSubs.Any(x => x.Url.ToLower() == fs.Url.ToLower())) gc.FeedSubs.Add(fs);
uow.SaveChanges();
//adding all, in case bot wasn't on this guild when it started
foreach (var feed in gc.FeedSubs)
{
_subs.AddOrUpdate(feed.Url.ToLower(), new HashSet<FeedSub>() {feed}, (k, old) =>
{ {
return false; old.Add(feed);
} return old;
else if (gc.FeedSubs.Count >= 10) });
{
return false;
}
gc.FeedSubs.Add(fs);
uow.SaveChanges();
//adding all, in case bot wasn't on this guild when it started
foreach (var feed in gc.FeedSubs)
{
_subs.AddOrUpdate(feed.Url.ToLower(), new HashSet<FeedSub>() {feed}, (k, old) =>
{
old.Add(feed);
return old;
});
}
} }
return true; return true;
@@ -213,24 +209,22 @@ public class FeedsService : INService
if (index < 0) if (index < 0)
return false; return false;
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ var items = uow.GuildConfigsForId(guildId, set => set.Include(x => x.FeedSubs))
var items = uow.GuildConfigsForId(guildId, set => set.Include(x => x.FeedSubs)) .FeedSubs
.FeedSubs .OrderBy(x => x.Id)
.OrderBy(x => x.Id) .ToList();
.ToList();
if (items.Count <= index) if (items.Count <= index)
return false; return false;
var toRemove = items[index]; var toRemove = items[index];
_subs.AddOrUpdate(toRemove.Url.ToLower(), new HashSet<FeedSub>(), (key, old) => _subs.AddOrUpdate(toRemove.Url.ToLower(), new HashSet<FeedSub>(), (key, old) =>
{ {
old.Remove(toRemove); old.Remove(toRemove);
return old; return old;
}); });
uow.Remove(toRemove); uow.Remove(toRemove);
uow.SaveChanges(); uow.SaveChanges();
}
return true; return true;
} }

View File

@@ -85,55 +85,49 @@ public class SearchesService : INService
public async Task<byte[]> GetRipPictureFactory((string text, Uri avatarUrl) arg) public async Task<byte[]> GetRipPictureFactory((string text, Uri avatarUrl) arg)
{ {
var (text, avatarUrl) = arg; var (text, avatarUrl) = arg;
using (var bg = Image.Load<Rgba32>(_imgs.Rip.ToArray())) using var bg = Image.Load<Rgba32>(_imgs.Rip.ToArray());
var (succ, data) = (false, (byte[])null); //await _cache.TryGetImageDataAsync(avatarUrl);
if (!succ)
{ {
var (succ, data) = (false, (byte[])null); //await _cache.TryGetImageDataAsync(avatarUrl); using var http = _httpFactory.CreateClient();
if (!succ) data = await http.GetByteArrayAsync(avatarUrl);
using (var avatarImg = Image.Load<Rgba32>(data))
{ {
using (var http = _httpFactory.CreateClient()) avatarImg.Mutate(x => x
{ .Resize(85, 85)
data = await http.GetByteArrayAsync(avatarUrl); .ApplyRoundedCorners(42));
using (var avatarImg = Image.Load<Rgba32>(data)) data = avatarImg.ToStream().ToArray();
{ DrawAvatar(bg, avatarImg);
avatarImg.Mutate(x => x
.Resize(85, 85)
.ApplyRoundedCorners(42));
data = avatarImg.ToStream().ToArray();
DrawAvatar(bg, avatarImg);
}
await _cache.SetImageDataAsync(avatarUrl, data);
}
} }
else await _cache.SetImageDataAsync(avatarUrl, data);
{
using (var avatarImg = Image.Load<Rgba32>(data))
{
DrawAvatar(bg, avatarImg);
}
}
bg.Mutate(x => x.DrawText(
new()
{
TextOptions = new TextOptions
{
HorizontalAlignment = HorizontalAlignment.Center,
WrapTextWidth = 190,
}.WithFallbackFonts(_fonts.FallBackFonts)
},
text,
_fonts.RipFont,
SixLabors.ImageSharp.Color.Black,
new(25, 225)));
//flowa
using (var flowers = Image.Load(_imgs.RipOverlay.ToArray()))
{
bg.Mutate(x => x.DrawImage(flowers, new(0, 0), new GraphicsOptions()));
}
return bg.ToStream().ToArray();
} }
else
{
using var avatarImg = Image.Load<Rgba32>(data);
DrawAvatar(bg, avatarImg);
}
bg.Mutate(x => x.DrawText(
new()
{
TextOptions = new TextOptions
{
HorizontalAlignment = HorizontalAlignment.Center,
WrapTextWidth = 190,
}.WithFallbackFonts(_fonts.FallBackFonts)
},
text,
_fonts.RipFont,
SixLabors.ImageSharp.Color.Black,
new(25, 225)));
//flowa
using (var flowers = Image.Load(_imgs.RipOverlay.ToArray()))
{
bg.Mutate(x => x.DrawImage(flowers, new(0, 0), new GraphicsOptions()));
}
return bg.ToStream().ToArray();
} }
public Task<WeatherData> GetWeatherDataAsync(string query) public Task<WeatherData> GetWeatherDataAsync(string query)
@@ -148,25 +142,23 @@ public class SearchesService : INService
private async Task<WeatherData> GetWeatherDataFactory(string query) private async Task<WeatherData> GetWeatherDataFactory(string query)
{ {
using (var http = _httpFactory.CreateClient()) using var http = _httpFactory.CreateClient();
try
{ {
try var data = await http.GetStringAsync($"http://api.openweathermap.org/data/2.5/weather?" +
{ $"q={query}&" +
var data = await http.GetStringAsync($"http://api.openweathermap.org/data/2.5/weather?" + $"appid=42cd627dd60debf25a5739e50a217d74&" +
$"q={query}&" + $"units=metric").ConfigureAwait(false);
$"appid=42cd627dd60debf25a5739e50a217d74&" +
$"units=metric").ConfigureAwait(false);
if (data is null) if (data is null)
return null;
return JsonConvert.DeserializeObject<WeatherData>(data);
}
catch (Exception ex)
{
Log.Warning(ex.Message);
return null; return null;
}
return JsonConvert.DeserializeObject<WeatherData>(data);
}
catch (Exception ex)
{
Log.Warning(ex.Message);
return null;
} }
} }
@@ -195,49 +187,42 @@ public class SearchesService : INService
try try
{ {
using (var _http = _httpFactory.CreateClient()) using var _http = _httpFactory.CreateClient();
var res = await _cache.GetOrAddCachedDataAsync($"geo_{query}", _ =>
{ {
var res = await _cache.GetOrAddCachedDataAsync($"geo_{query}", _ => var url = "https://eu1.locationiq.com/v1/search.php?" +
{ (string.IsNullOrWhiteSpace(_creds.LocationIqApiKey) ? "key=" : $"key={_creds.LocationIqApiKey}&") +
var url = "https://eu1.locationiq.com/v1/search.php?" + $"q={Uri.EscapeDataString(query)}&" +
(string.IsNullOrWhiteSpace(_creds.LocationIqApiKey) ? "key=" : $"key={_creds.LocationIqApiKey}&") + $"format=json";
$"q={Uri.EscapeDataString(query)}&" +
$"format=json";
var res = _http.GetStringAsync(url); var res = _http.GetStringAsync(url);
return res; return res;
}, "", TimeSpan.FromHours(1)); }, "", TimeSpan.FromHours(1));
var responses = JsonConvert.DeserializeObject<LocationIqResponse[]>(res); var responses = JsonConvert.DeserializeObject<LocationIqResponse[]>(res);
if (responses is null || responses.Length == 0) if (responses is null || responses.Length == 0)
{ {
Log.Warning("Geocode lookup failed for: {Query}", query); Log.Warning("Geocode lookup failed for: {Query}", query);
return (default, TimeErrors.NotFound); return (default, TimeErrors.NotFound);
}
var geoData = responses[0];
using (var req = new HttpRequestMessage(HttpMethod.Get, "http://api.timezonedb.com/v2.1/get-time-zone?" +
$"key={_creds.TimezoneDbApiKey}&format=json&" +
"by=position&" +
$"lat={geoData.Lat}&lng={geoData.Lon}"))
{
using (var geoRes = await _http.SendAsync(req))
{
var resString = await geoRes.Content.ReadAsStringAsync();
var timeObj = JsonConvert.DeserializeObject<TimeZoneResult>(resString);
var time = new DateTime(1970, 1, 1, 0, 0, 0, System.DateTimeKind.Utc).AddSeconds(timeObj.Timestamp);
return ((
Address: responses[0].DisplayName,
Time: time,
TimeZoneName: timeObj.TimezoneName
), default);
}
}
} }
var geoData = responses[0];
using var req = new HttpRequestMessage(HttpMethod.Get, "http://api.timezonedb.com/v2.1/get-time-zone?" +
$"key={_creds.TimezoneDbApiKey}&format=json&" +
"by=position&" +
$"lat={geoData.Lat}&lng={geoData.Lon}");
using var geoRes = await _http.SendAsync(req);
var resString = await geoRes.Content.ReadAsStringAsync();
var timeObj = JsonConvert.DeserializeObject<TimeZoneResult>(resString);
var time = new DateTime(1970, 1, 1, 0, 0, 0, System.DateTimeKind.Utc).AddSeconds(timeObj.Timestamp);
return ((
Address: responses[0].DisplayName,
Time: time,
TimeZoneName: timeObj.TimezoneName
), default);
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -310,21 +295,17 @@ public class SearchesService : INService
public async Task<(string Setup, string Punchline)> GetRandomJoke() public async Task<(string Setup, string Punchline)> GetRandomJoke()
{ {
using (var http = _httpFactory.CreateClient()) using var http = _httpFactory.CreateClient();
{ var res = await http.GetStringAsync("https://official-joke-api.appspot.com/random_joke");
var res = await http.GetStringAsync("https://official-joke-api.appspot.com/random_joke"); var resObj = JsonConvert.DeserializeAnonymousType(res, new {setup = "", punchline = ""});
var resObj = JsonConvert.DeserializeAnonymousType(res, new {setup = "", punchline = ""}); return (resObj.setup, resObj.punchline);
return (resObj.setup, resObj.punchline);
}
} }
public async Task<string> GetChuckNorrisJoke() public async Task<string> GetChuckNorrisJoke()
{ {
using (var http = _httpFactory.CreateClient()) using var http = _httpFactory.CreateClient();
{ var response = await http.GetStringAsync(new Uri("http://api.icndb.com/jokes/random/")).ConfigureAwait(false);
var response = await http.GetStringAsync(new Uri("http://api.icndb.com/jokes/random/")).ConfigureAwait(false); return JObject.Parse(response)["value"]["joke"].ToString() + " 😆";
return JObject.Parse(response)["value"]["joke"].ToString() + " 😆";
}
} }
public async Task<MtgData> GetMtgCardAsync(string search) public async Task<MtgData> GetMtgCardAsync(string search)
@@ -367,30 +348,28 @@ public class SearchesService : INService
}; };
} }
using (var http = _httpFactory.CreateClient()) using var http = _httpFactory.CreateClient();
http.DefaultRequestHeaders.Clear();
var response = await http.GetStringAsync($"https://api.magicthegathering.io/v1/cards?name={Uri.EscapeDataString(search)}")
.ConfigureAwait(false);
var responseObject = JsonConvert.DeserializeObject<MtgResponse>(response);
if (responseObject is null)
return new MtgData[0];
var cards = responseObject.Cards.Take(5).ToArray();
if (cards.Length == 0)
return new MtgData[0];
var tasks = new List<Task<MtgData>>(cards.Length);
for (var i = 0; i < cards.Length; i++)
{ {
http.DefaultRequestHeaders.Clear(); var card = cards[i];
var response = await http.GetStringAsync($"https://api.magicthegathering.io/v1/cards?name={Uri.EscapeDataString(search)}")
.ConfigureAwait(false);
var responseObject = JsonConvert.DeserializeObject<MtgResponse>(response); tasks.Add(GetMtgDataAsync(card));
if (responseObject is null)
return new MtgData[0];
var cards = responseObject.Cards.Take(5).ToArray();
if (cards.Length == 0)
return new MtgData[0];
var tasks = new List<Task<MtgData>>(cards.Length);
for (var i = 0; i < cards.Length; i++)
{
var card = cards[i];
tasks.Add(GetMtgDataAsync(card));
}
return await Task.WhenAll(tasks).ConfigureAwait(false);
} }
return await Task.WhenAll(tasks).ConfigureAwait(false);
} }
public Task<HearthstoneCardData> GetHearthstoneCardDataAsync(string name) public Task<HearthstoneCardData> GetHearthstoneCardDataAsync(string name)
@@ -404,38 +383,36 @@ public class SearchesService : INService
private async Task<HearthstoneCardData> HearthstoneCardDataFactory(string name) private async Task<HearthstoneCardData> HearthstoneCardDataFactory(string name)
{ {
using (var http = _httpFactory.CreateClient()) using var http = _httpFactory.CreateClient();
http.DefaultRequestHeaders.Clear();
http.DefaultRequestHeaders.Add("x-rapidapi-key", _creds.RapidApiKey);
try
{ {
http.DefaultRequestHeaders.Clear(); var response = await http.GetStringAsync($"https://omgvamp-hearthstone-v1.p.rapidapi.com/" +
http.DefaultRequestHeaders.Add("x-rapidapi-key", _creds.RapidApiKey); $"cards/search/{Uri.EscapeDataString(name)}").ConfigureAwait(false);
try var objs = JsonConvert.DeserializeObject<HearthstoneCardData[]>(response);
{ if (objs is null || objs.Length == 0)
var response = await http.GetStringAsync($"https://omgvamp-hearthstone-v1.p.rapidapi.com/" +
$"cards/search/{Uri.EscapeDataString(name)}").ConfigureAwait(false);
var objs = JsonConvert.DeserializeObject<HearthstoneCardData[]>(response);
if (objs is null || objs.Length == 0)
return null;
var data = objs.FirstOrDefault(x => x.Collectible)
?? objs.FirstOrDefault(x => !string.IsNullOrEmpty(x.PlayerClass))
?? objs.FirstOrDefault();
if (data is null)
return null;
if (!string.IsNullOrWhiteSpace(data.Img))
{
data.Img = await _google.ShortenUrl(data.Img).ConfigureAwait(false);
}
if (!string.IsNullOrWhiteSpace(data.Text))
{
var converter = new Html2Markdown.Converter();
data.Text = converter.Convert(data.Text);
}
return data;
}
catch (Exception ex)
{
Log.Error(ex.Message);
return null; return null;
var data = objs.FirstOrDefault(x => x.Collectible)
?? objs.FirstOrDefault(x => !string.IsNullOrEmpty(x.PlayerClass))
?? objs.FirstOrDefault();
if (data is null)
return null;
if (!string.IsNullOrWhiteSpace(data.Img))
{
data.Img = await _google.ShortenUrl(data.Img).ConfigureAwait(false);
} }
if (!string.IsNullOrWhiteSpace(data.Text))
{
var converter = new Html2Markdown.Converter();
data.Text = converter.Convert(data.Text);
}
return data;
}
catch (Exception ex)
{
Log.Error(ex.Message);
return null;
} }
} }
@@ -450,16 +427,14 @@ public class SearchesService : INService
private async Task<OmdbMovie> GetMovieDataFactory(string name) private async Task<OmdbMovie> GetMovieDataFactory(string name)
{ {
using (var http = _httpFactory.CreateClient()) using var http = _httpFactory.CreateClient();
{ var res = await http.GetStringAsync(string.Format("https://omdbapi.nadeko.bot/?t={0}&y=&plot=full&r=json",
var res = await http.GetStringAsync(string.Format("https://omdbapi.nadeko.bot/?t={0}&y=&plot=full&r=json", name.Trim().Replace(' ', '+'))).ConfigureAwait(false);
name.Trim().Replace(' ', '+'))).ConfigureAwait(false); var movie = JsonConvert.DeserializeObject<OmdbMovie>(res);
var movie = JsonConvert.DeserializeObject<OmdbMovie>(res); if (movie?.Title is null)
if (movie?.Title is null) return null;
return null; movie.Poster = await _google.ShortenUrl(movie.Poster).ConfigureAwait(false);
movie.Poster = await _google.ShortenUrl(movie.Poster).ConfigureAwait(false); return movie;
return movie;
}
} }
public async Task<int> GetSteamAppIdByName(string query) public async Task<int> GetSteamAppIdByName(string query)
@@ -486,20 +461,18 @@ public class SearchesService : INService
var gamesMap = await _cache.GetOrAddCachedDataAsync(STEAM_GAME_IDS_KEY, async _ => var gamesMap = await _cache.GetOrAddCachedDataAsync(STEAM_GAME_IDS_KEY, async _ =>
{ {
using (var http = _httpFactory.CreateClient()) using var http = _httpFactory.CreateClient();
{ // https://api.steampowered.com/ISteamApps/GetAppList/v2/
// https://api.steampowered.com/ISteamApps/GetAppList/v2/ var gamesStr = await http.GetStringAsync("https://api.steampowered.com/ISteamApps/GetAppList/v2/").ConfigureAwait(false);
var gamesStr = await http.GetStringAsync("https://api.steampowered.com/ISteamApps/GetAppList/v2/").ConfigureAwait(false); var apps = JsonConvert.DeserializeAnonymousType(gamesStr, new { applist = new { apps = new List<SteamGameId>() } }).applist.apps;
var apps = JsonConvert.DeserializeAnonymousType(gamesStr, new { applist = new { apps = new List<SteamGameId>() } }).applist.apps;
return apps return apps
.OrderBy(x => x.Name, StringComparer.OrdinalIgnoreCase) .OrderBy(x => x.Name, StringComparer.OrdinalIgnoreCase)
.GroupBy(x => x.Name) .GroupBy(x => x.Name)
.ToDictionary(x => x.Key, x => x.First().AppId); .ToDictionary(x => x.Key, x => x.First().AppId);
//await db.HashSetAsync("steam_game_ids", apps.Select(app => new HashEntry(app.Name.Trim().ToLowerInvariant(), app.AppId)).ToArray()).ConfigureAwait(false); //await db.HashSetAsync("steam_game_ids", apps.Select(app => new HashEntry(app.Name.Trim().ToLowerInvariant(), app.AppId)).ToArray()).ConfigureAwait(false);
//await db.StringSetAsync("steam_game_ids", gamesStr, TimeSpan.FromHours(24)); //await db.StringSetAsync("steam_game_ids", gamesStr, TimeSpan.FromHours(24));
//await db.KeyExpireAsync("steam_game_ids", TimeSpan.FromHours(24), CommandFlags.FireAndForget).ConfigureAwait(false); //await db.KeyExpireAsync("steam_game_ids", TimeSpan.FromHours(24), CommandFlags.FireAndForget).ConfigureAwait(false);
}
}, default(string), TimeSpan.FromHours(24)); }, default(string), TimeSpan.FromHours(24));
if (gamesMap is null) if (gamesMap is null)

View File

@@ -130,24 +130,22 @@ public sealed class StreamNotificationService : INService
var deleteGroups = failingStreams.GroupBy(x => x.Type) var deleteGroups = failingStreams.GroupBy(x => x.Type)
.ToDictionary(x => x.Key, x => x.Select(x => x.Name).ToList()); .ToDictionary(x => x.Key, x => x.Select(x => x.Name).ToList());
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
foreach (var kvp in deleteGroups)
{ {
foreach (var kvp in deleteGroups) Log.Information($"Deleting {kvp.Value.Count} {kvp.Key} streams because " +
{ $"they've been erroring for more than {errorLimit}: {string.Join(", ", kvp.Value)}");
Log.Information($"Deleting {kvp.Value.Count} {kvp.Key} streams because " +
$"they've been erroring for more than {errorLimit}: {string.Join(", ", kvp.Value)}");
var toDelete = uow.Set<FollowedStream>() var toDelete = uow.Set<FollowedStream>()
.AsQueryable() .AsQueryable()
.Where(x => x.Type == kvp.Key && kvp.Value.Contains(x.Username)) .Where(x => x.Type == kvp.Key && kvp.Value.Contains(x.Username))
.ToList(); .ToList();
uow.RemoveRange(toDelete); uow.RemoveRange(toDelete);
uow.SaveChanges(); uow.SaveChanges();
foreach(var loginToDelete in kvp.Value) foreach(var loginToDelete in kvp.Value)
_streamTracker.UntrackStreamByKey(new(kvp.Key, loginToDelete)); _streamTracker.UntrackStreamByKey(new(kvp.Key, loginToDelete));
}
} }
} }
catch (Exception ex) catch (Exception ex)
@@ -461,20 +459,18 @@ public sealed class StreamNotificationService : INService
public bool ToggleStreamOffline(ulong guildId) public bool ToggleStreamOffline(ulong guildId)
{ {
bool newValue; bool newValue;
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ var gc = uow.GuildConfigsForId(guildId, set => set);
var gc = uow.GuildConfigsForId(guildId, set => set); newValue = gc.NotifyStreamOffline = !gc.NotifyStreamOffline;
newValue = gc.NotifyStreamOffline = !gc.NotifyStreamOffline; uow.SaveChanges();
uow.SaveChanges();
if (newValue) if (newValue)
{ {
_offlineNotificationServers.Add(guildId); _offlineNotificationServers.Add(guildId);
} }
else else
{ {
_offlineNotificationServers.TryRemove(guildId); _offlineNotificationServers.TryRemove(guildId);
}
} }
return newValue; return newValue;
@@ -510,35 +506,33 @@ public sealed class StreamNotificationService : INService
public bool SetStreamMessage(ulong guildId, int index, string message, out FollowedStream fs) public bool SetStreamMessage(ulong guildId, int index, string message, out FollowedStream fs)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
var fss = uow.Set<FollowedStream>()
.AsQueryable()
.Where(x => x.GuildId == guildId)
.OrderBy(x => x.Id)
.ToList();
if (fss.Count <= index)
{ {
var fss = uow.Set<FollowedStream>() fs = null;
.AsQueryable() return false;
.Where(x => x.GuildId == guildId)
.OrderBy(x => x.Id)
.ToList();
if (fss.Count <= index)
{
fs = null;
return false;
}
fs = fss[index];
fs.Message = message;
lock (_shardLock)
{
var streams = GetLocalGuildStreams(fs.CreateKey(), guildId);
// message doesn't participate in equality checking
// removing and adding = update
streams.Remove(fs);
streams.Add(fs);
}
uow.SaveChanges();
} }
fs = fss[index];
fs.Message = message;
lock (_shardLock)
{
var streams = GetLocalGuildStreams(fs.CreateKey(), guildId);
// message doesn't participate in equality checking
// removing and adding = update
streams.Remove(fs);
streams.Add(fs);
}
uow.SaveChanges();
return true; return true;
} }

View File

@@ -23,22 +23,20 @@ public partial class Searches
{ {
try try
{ {
using (var http = _httpFactory.CreateClient()) using var http = _httpFactory.CreateClient();
{ var res = await http.GetStringAsync($"{_xkcdUrl}/info.0.json").ConfigureAwait(false);
var res = await http.GetStringAsync($"{_xkcdUrl}/info.0.json").ConfigureAwait(false); var comic = JsonConvert.DeserializeObject<XkcdComic>(res);
var comic = JsonConvert.DeserializeObject<XkcdComic>(res); var embed = _eb.Create().WithOkColor()
var embed = _eb.Create().WithOkColor() .WithImageUrl(comic.ImageLink)
.WithImageUrl(comic.ImageLink) .WithAuthor(comic.Title, "https://xkcd.com/s/919f27.ico", $"{_xkcdUrl}/{comic.Num}")
.WithAuthor(comic.Title, "https://xkcd.com/s/919f27.ico", $"{_xkcdUrl}/{comic.Num}") .AddField(GetText(strs.comic_number), comic.Num.ToString(), true)
.AddField(GetText(strs.comic_number), comic.Num.ToString(), true) .AddField(GetText(strs.date), $"{comic.Month}/{comic.Year}", true);
.AddField(GetText(strs.date), $"{comic.Month}/{comic.Year}", true); var sent = await ctx.Channel.EmbedAsync(embed)
var sent = await ctx.Channel.EmbedAsync(embed) .ConfigureAwait(false);
.ConfigureAwait(false);
await Task.Delay(10000).ConfigureAwait(false); await Task.Delay(10000).ConfigureAwait(false);
await sent.ModifyAsync(m => m.Embed = embed.AddField("Alt", comic.Alt.ToString(), false).Build()).ConfigureAwait(false); await sent.ModifyAsync(m => m.Embed = embed.AddField("Alt", comic.Alt.ToString(), false).Build()).ConfigureAwait(false);
}
} }
catch (HttpRequestException) catch (HttpRequestException)
{ {
@@ -57,25 +55,23 @@ public partial class Searches
return; return;
try try
{ {
using (var http = _httpFactory.CreateClient()) using var http = _httpFactory.CreateClient();
{ var res = await http.GetStringAsync($"{_xkcdUrl}/{num}/info.0.json").ConfigureAwait(false);
var res = await http.GetStringAsync($"{_xkcdUrl}/{num}/info.0.json").ConfigureAwait(false);
var comic = JsonConvert.DeserializeObject<XkcdComic>(res); var comic = JsonConvert.DeserializeObject<XkcdComic>(res);
var embed = _eb.Create() var embed = _eb.Create()
.WithOkColor() .WithOkColor()
.WithImageUrl(comic.ImageLink) .WithImageUrl(comic.ImageLink)
.WithAuthor(comic.Title, "https://xkcd.com/s/919f27.ico", $"{_xkcdUrl}/{num}") .WithAuthor(comic.Title, "https://xkcd.com/s/919f27.ico", $"{_xkcdUrl}/{num}")
.AddField(GetText(strs.comic_number), comic.Num.ToString(), true) .AddField(GetText(strs.comic_number), comic.Num.ToString(), true)
.AddField(GetText(strs.date), $"{comic.Month}/{comic.Year}", true); .AddField(GetText(strs.date), $"{comic.Month}/{comic.Year}", true);
var sent = await ctx.Channel.EmbedAsync(embed) var sent = await ctx.Channel.EmbedAsync(embed)
.ConfigureAwait(false); .ConfigureAwait(false);
await Task.Delay(10000).ConfigureAwait(false); await Task.Delay(10000).ConfigureAwait(false);
await sent.ModifyAsync(m => m.Embed = embed.AddField("Alt", comic.Alt.ToString(), false).Build()).ConfigureAwait(false); await sent.ModifyAsync(m => m.Embed = embed.AddField("Alt", comic.Alt.ToString(), false).Build()).ConfigureAwait(false);
}
} }
catch (HttpRequestException) catch (HttpRequestException)
{ {

View File

@@ -18,23 +18,21 @@ public class CommandMapService : IInputTransformer, INService
{ {
_eb = eb; _eb = eb;
using (var uow = db.GetDbContext()) using var uow = db.GetDbContext();
{ var guildIds = client.Guilds.Select(x => x.Id).ToList();
var guildIds = client.Guilds.Select(x => x.Id).ToList(); var configs = uow.Set<GuildConfig>()
var configs = uow.Set<GuildConfig>() .Include(gc => gc.CommandAliases)
.Include(gc => gc.CommandAliases) .Where(x => guildIds.Contains(x.GuildId))
.Where(x => guildIds.Contains(x.GuildId)) .ToList();
.ToList();
AliasMaps = new(configs AliasMaps = new(configs
.ToDictionary( .ToDictionary(
x => x.GuildId, x => x.GuildId,
x => new ConcurrentDictionary<string, string>(x.CommandAliases x => new ConcurrentDictionary<string, string>(x.CommandAliases
.DistinctBy(ca => ca.Trigger) .DistinctBy(ca => ca.Trigger)
.ToDictionary(ca => ca.Trigger, ca => ca.Mapping)))); .ToDictionary(ca => ca.Trigger, ca => ca.Mapping))));
_db = db; _db = db;
}
} }
public int ClearAliases(ulong guildId) public int ClearAliases(ulong guildId)
@@ -42,13 +40,11 @@ public class CommandMapService : IInputTransformer, INService
AliasMaps.TryRemove(guildId, out _); AliasMaps.TryRemove(guildId, out _);
int count; int count;
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ var gc = uow.GuildConfigsForId(guildId, set => set.Include(x => x.CommandAliases));
var gc = uow.GuildConfigsForId(guildId, set => set.Include(x => x.CommandAliases)); count = gc.CommandAliases.Count;
count = gc.CommandAliases.Count; gc.CommandAliases.Clear();
gc.CommandAliases.Clear(); uow.SaveChanges();
uow.SaveChanges();
}
return count; return count;
} }

View File

@@ -35,11 +35,9 @@ public class ConverterService : INService
private async Task<Rates> GetCurrencyRates() private async Task<Rates> GetCurrencyRates()
{ {
using (var http = _httpFactory.CreateClient()) using var http = _httpFactory.CreateClient();
{ var res = await http.GetStringAsync("https://convertapi.nadeko.bot/latest").ConfigureAwait(false);
var res = await http.GetStringAsync("https://convertapi.nadeko.bot/latest").ConfigureAwait(false); return JsonConvert.DeserializeObject<Rates>(res);
return JsonConvert.DeserializeObject<Rates>(res);
}
} }
private async Task UpdateCurrency(bool shouldLoad) private async Task UpdateCurrency(bool shouldLoad)

View File

@@ -224,64 +224,62 @@ public class PatreonRewardsService : INService
{ {
var eligibleFor = (int)(cents * settings.PatreonCurrencyPerCent); var eligibleFor = (int)(cents * settings.PatreonCurrencyPerCent);
await using (var uow = _db.GetDbContext()) await using var uow = _db.GetDbContext();
var users = uow.Set<RewardedUser>();
var usr = await users.FirstOrDefaultAsyncEF(x => x.PatreonUserId == patreonUserId);
if (usr is null)
{ {
var users = uow.Set<RewardedUser>(); users.Add(new()
var usr = await users.FirstOrDefaultAsyncEF(x => x.PatreonUserId == patreonUserId);
if (usr is null)
{ {
users.Add(new() PatreonUserId = patreonUserId,
{ LastReward = now,
PatreonUserId = patreonUserId, AmountRewardedThisMonth = eligibleFor,
LastReward = now, });
AmountRewardedThisMonth = eligibleFor,
});
await uow.SaveChangesAsync(); await uow.SaveChangesAsync();
await _currency.AddAsync(userId, "Patreon reward - new", eligibleFor, gamble: true); await _currency.AddAsync(userId, "Patreon reward - new", eligibleFor, gamble: true);
Log.Information($"Sending new currency reward to {userId}"); Log.Information($"Sending new currency reward to {userId}");
await SendMessageToUser(userId, $"Thank you for your pledge! " + await SendMessageToUser(userId, $"Thank you for your pledge! " +
$"You've been awarded **{eligibleFor}**{settings.Currency.Sign} !"); $"You've been awarded **{eligibleFor}**{settings.Currency.Sign} !");
return eligibleFor; return eligibleFor;
}
if (usr.LastReward.Month != now.Month)
{
usr.LastReward = now;
usr.AmountRewardedThisMonth = eligibleFor;
await uow.SaveChangesAsync();
await _currency.AddAsync(userId, "Patreon reward - recurring", eligibleFor, gamble: true);
Log.Information($"Sending recurring currency reward to {userId}");
await SendMessageToUser(userId, $"Thank you for your continued support! " +
$"You've been awarded **{eligibleFor}**{settings.Currency.Sign} for this month's support!");
return eligibleFor;
}
if (usr.AmountRewardedThisMonth < eligibleFor)
{
var toAward = eligibleFor - usr.AmountRewardedThisMonth;
usr.LastReward = now;
usr.AmountRewardedThisMonth = toAward;
await uow.SaveChangesAsync();
await _currency.AddAsync(userId, "Patreon reward - update", toAward, gamble: true);
Log.Information($"Sending updated currency reward to {userId}");
await SendMessageToUser(userId, $"Thank you for increasing your pledge! " +
$"You've been awarded an additional **{toAward}**{settings.Currency.Sign} !");
return toAward;
}
return 0;
} }
if (usr.LastReward.Month != now.Month)
{
usr.LastReward = now;
usr.AmountRewardedThisMonth = eligibleFor;
await uow.SaveChangesAsync();
await _currency.AddAsync(userId, "Patreon reward - recurring", eligibleFor, gamble: true);
Log.Information($"Sending recurring currency reward to {userId}");
await SendMessageToUser(userId, $"Thank you for your continued support! " +
$"You've been awarded **{eligibleFor}**{settings.Currency.Sign} for this month's support!");
return eligibleFor;
}
if (usr.AmountRewardedThisMonth < eligibleFor)
{
var toAward = eligibleFor - usr.AmountRewardedThisMonth;
usr.LastReward = now;
usr.AmountRewardedThisMonth = toAward;
await uow.SaveChangesAsync();
await _currency.AddAsync(userId, "Patreon reward - update", toAward, gamble: true);
Log.Information($"Sending updated currency reward to {userId}");
await SendMessageToUser(userId, $"Thank you for increasing your pledge! " +
$"You've been awarded an additional **{toAward}**{settings.Currency.Sign} !");
return toAward;
}
return 0;
} }
finally finally
{ {

View File

@@ -56,23 +56,19 @@ public class RemindService : INService
private async Task RemoveReminders(List<Reminder> reminders) private async Task RemoveReminders(List<Reminder> reminders)
{ {
await using (var uow = _db.GetDbContext()) await using var uow = _db.GetDbContext();
{ uow.Set<Reminder>()
uow.Set<Reminder>() .RemoveRange(reminders);
.RemoveRange(reminders);
await uow.SaveChangesAsync(); await uow.SaveChangesAsync();
}
} }
private Task<List<Reminder>> GetRemindersBeforeAsync(DateTime now) private Task<List<Reminder>> GetRemindersBeforeAsync(DateTime now)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ return uow.Reminders
return uow.Reminders .FromSqlInterpolated($"select * from reminders where ((serverid >> 22) % {_creds.TotalShards}) == {_client.ShardId} and \"when\" < {now};")
.FromSqlInterpolated($"select * from reminders where ((serverid >> 22) % {_creds.TotalShards}) == {_client.ShardId} and \"when\" < {now};") .ToListAsync();
.ToListAsync();
}
} }
public struct RemindObject public struct RemindObject

View File

@@ -431,10 +431,8 @@ public partial class Utility : NadekoModule
return msg; return msg;
}) })
}); });
await using (var stream = await JsonConvert.SerializeObject(grouping, Formatting.Indented).ToStream().ConfigureAwait(false)) await using var stream = await JsonConvert.SerializeObject(grouping, Formatting.Indented).ToStream().ConfigureAwait(false);
{ await ctx.User.SendFileAsync(stream, title, title, false).ConfigureAwait(false);
await ctx.User.SendFileAsync(stream, title, title, false).ConfigureAwait(false);
}
} }
private static SemaphoreSlim sem = new(1, 1); private static SemaphoreSlim sem = new(1, 1);

View File

@@ -52,42 +52,38 @@ public class ClubService : INService
public ClubInfo TransferClub(IUser from, IUser newOwner) public ClubInfo TransferClub(IUser from, IUser newOwner)
{ {
ClubInfo club; ClubInfo club;
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ club = uow.Clubs.GetByOwner(@from.Id);
club = uow.Clubs.GetByOwner(from.Id); var newOwnerUser = uow.GetOrCreateUser(newOwner);
var newOwnerUser = uow.GetOrCreateUser(newOwner);
if (club is null || if (club is null ||
club.Owner.UserId != from.Id || club.Owner.UserId != @from.Id ||
!club.Users.Contains(newOwnerUser)) !club.Users.Contains(newOwnerUser))
return null; return null;
club.Owner.IsClubAdmin = true; // old owner will stay as admin club.Owner.IsClubAdmin = true; // old owner will stay as admin
newOwnerUser.IsClubAdmin = true; newOwnerUser.IsClubAdmin = true;
club.Owner = newOwnerUser; club.Owner = newOwnerUser;
uow.SaveChanges(); uow.SaveChanges();
}
return club; return club;
} }
public bool ToggleAdmin(IUser owner, IUser toAdmin) public bool ToggleAdmin(IUser owner, IUser toAdmin)
{ {
bool newState; bool newState;
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ var club = uow.Clubs.GetByOwner(owner.Id);
var club = uow.Clubs.GetByOwner(owner.Id); var adminUser = uow.GetOrCreateUser(toAdmin);
var adminUser = uow.GetOrCreateUser(toAdmin);
if (club is null || club.Owner.UserId != owner.Id || if (club is null || club.Owner.UserId != owner.Id ||
!club.Users.Contains(adminUser)) !club.Users.Contains(adminUser))
throw new InvalidOperationException(); throw new InvalidOperationException();
if (club.OwnerId == adminUser.Id) if (club.OwnerId == adminUser.Id)
return true; return true;
newState = adminUser.IsClubAdmin = !adminUser.IsClubAdmin; newState = adminUser.IsClubAdmin = !adminUser.IsClubAdmin;
uow.SaveChanges(); uow.SaveChanges();
}
return newState; return newState;
} }
@@ -102,25 +98,21 @@ public class ClubService : INService
{ {
if (url != null) if (url != null)
{ {
using (var http = _httpFactory.CreateClient()) using var http = _httpFactory.CreateClient();
using (var temp = await http.GetAsync(url, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false)) using var temp = await http.GetAsync(url, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
{ if (!temp.IsImage() || temp.GetImageSize() > 11)
if (!temp.IsImage() || temp.GetImageSize() > 11)
return false;
}
}
await using (var uow = _db.GetDbContext())
{
var club = uow.Clubs.GetByOwner(ownerUserId);
if (club is null)
return false; return false;
club.ImageUrl = url.ToString();
uow.SaveChanges();
} }
await using var uow = _db.GetDbContext();
var club = uow.Clubs.GetByOwner(ownerUserId);
if (club is null)
return false;
club.ImageUrl = url.ToString();
uow.SaveChanges();
return true; return true;
} }
@@ -137,95 +129,85 @@ public class ClubService : INService
if (string.IsNullOrWhiteSpace(name)) if (string.IsNullOrWhiteSpace(name))
return false; return false;
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ club = uow.Clubs.GetByName(name, discrim);
club = uow.Clubs.GetByName(name, discrim); if (club is null)
if (club is null) return false;
return false; else
else return true;
return true;
}
} }
public bool ApplyToClub(IUser user, ClubInfo club) public bool ApplyToClub(IUser user, ClubInfo club)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
var du = uow.GetOrCreateUser(user);
uow.SaveChanges();
if (du.Club != null
|| new LevelStats(du.TotalXp).Level < club.MinimumLevelReq
|| club.Bans.Any(x => x.UserId == du.Id)
|| club.Applicants.Any(x => x.UserId == du.Id))
{ {
var du = uow.GetOrCreateUser(user); //user banned or a member of a club, or already applied,
uow.SaveChanges(); // or doesn't min minumum level requirement, can't apply
return false;
if (du.Club != null
|| new LevelStats(du.TotalXp).Level < club.MinimumLevelReq
|| club.Bans.Any(x => x.UserId == du.Id)
|| club.Applicants.Any(x => x.UserId == du.Id))
{
//user banned or a member of a club, or already applied,
// or doesn't min minumum level requirement, can't apply
return false;
}
var app = new ClubApplicants
{
ClubId = club.Id,
UserId = du.Id,
};
uow.Set<ClubApplicants>().Add(app);
uow.SaveChanges();
} }
var app = new ClubApplicants
{
ClubId = club.Id,
UserId = du.Id,
};
uow.Set<ClubApplicants>().Add(app);
uow.SaveChanges();
return true; return true;
} }
public bool AcceptApplication(ulong clubOwnerUserId, string userName, out DiscordUser discordUser) public bool AcceptApplication(ulong clubOwnerUserId, string userName, out DiscordUser discordUser)
{ {
discordUser = null; discordUser = null;
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ var club = uow.Clubs.GetByOwnerOrAdmin(clubOwnerUserId);
var club = uow.Clubs.GetByOwnerOrAdmin(clubOwnerUserId); if (club is null)
if (club is null) return false;
return false;
var applicant = club.Applicants.FirstOrDefault(x => x.User.ToString().ToUpperInvariant() == userName.ToUpperInvariant()); var applicant = club.Applicants.FirstOrDefault(x => x.User.ToString().ToUpperInvariant() == userName.ToUpperInvariant());
if (applicant is null) if (applicant is null)
return false; return false;
applicant.User.Club = club; applicant.User.Club = club;
applicant.User.IsClubAdmin = false; applicant.User.IsClubAdmin = false;
club.Applicants.Remove(applicant); club.Applicants.Remove(applicant);
//remove that user's all other applications //remove that user's all other applications
uow.Set<ClubApplicants>() uow.Set<ClubApplicants>()
.RemoveRange(uow.Set<ClubApplicants>() .RemoveRange(uow.Set<ClubApplicants>()
.AsQueryable() .AsQueryable()
.Where(x => x.UserId == applicant.User.Id)); .Where(x => x.UserId == applicant.User.Id));
discordUser = applicant.User; discordUser = applicant.User;
uow.SaveChanges(); uow.SaveChanges();
}
return true; return true;
} }
public ClubInfo GetClubWithBansAndApplications(ulong ownerUserId) public ClubInfo GetClubWithBansAndApplications(ulong ownerUserId)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ return uow.Clubs.GetByOwnerOrAdmin(ownerUserId);
return uow.Clubs.GetByOwnerOrAdmin(ownerUserId);
}
} }
public bool LeaveClub(IUser user) public bool LeaveClub(IUser user)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ var du = uow.GetOrCreateUser(user);
var du = uow.GetOrCreateUser(user); if (du.Club is null || du.Club.OwnerId == du.Id)
if (du.Club is null || du.Club.OwnerId == du.Id) return false;
return false;
du.Club = null; du.Club = null;
du.IsClubAdmin = false; du.IsClubAdmin = false;
uow.SaveChanges(); uow.SaveChanges();
}
return true; return true;
} }
@@ -234,121 +216,109 @@ public class ClubService : INService
if (level < 5) if (level < 5)
return false; return false;
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ var club = uow.Clubs.GetByOwner(userId);
var club = uow.Clubs.GetByOwner(userId); if (club is null)
if (club is null) return false;
return false;
club.MinimumLevelReq = level; club.MinimumLevelReq = level;
uow.SaveChanges(); uow.SaveChanges();
}
return true; return true;
} }
public bool ChangeClubDescription(ulong userId, string desc) public bool ChangeClubDescription(ulong userId, string desc)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ var club = uow.Clubs.GetByOwner(userId);
var club = uow.Clubs.GetByOwner(userId); if (club is null)
if (club is null) return false;
return false;
club.Description = desc?.TrimTo(150, true); club.Description = desc?.TrimTo(150, true);
uow.SaveChanges(); uow.SaveChanges();
}
return true; return true;
} }
public bool Disband(ulong userId, out ClubInfo club) public bool Disband(ulong userId, out ClubInfo club)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ club = uow.Clubs.GetByOwner(userId);
club = uow.Clubs.GetByOwner(userId); if (club is null)
if (club is null) return false;
return false;
uow.Clubs.Remove(club); uow.Clubs.Remove(club);
uow.SaveChanges(); uow.SaveChanges();
}
return true; return true;
} }
public bool Ban(ulong bannerId, string userName, out ClubInfo club) public bool Ban(ulong bannerId, string userName, out ClubInfo club)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
club = uow.Clubs.GetByOwnerOrAdmin(bannerId);
if (club is null)
return false;
var usr = club.Users.FirstOrDefault(x => x.ToString().ToUpperInvariant() == userName.ToUpperInvariant())
?? club.Applicants.FirstOrDefault(x => x.User.ToString().ToUpperInvariant() == userName.ToUpperInvariant())?.User;
if (usr is null)
return false;
if (club.OwnerId == usr.Id || (usr.IsClubAdmin && club.Owner.UserId != bannerId)) // can't ban the owner kek, whew
return false;
club.Bans.Add(new()
{ {
club = uow.Clubs.GetByOwnerOrAdmin(bannerId); Club = club,
if (club is null) User = usr,
return false; });
club.Users.Remove(usr);
var usr = club.Users.FirstOrDefault(x => x.ToString().ToUpperInvariant() == userName.ToUpperInvariant()) var app = club.Applicants.FirstOrDefault(x => x.UserId == usr.Id);
?? club.Applicants.FirstOrDefault(x => x.User.ToString().ToUpperInvariant() == userName.ToUpperInvariant())?.User; if (app != null)
if (usr is null) club.Applicants.Remove(app);
return false;
if (club.OwnerId == usr.Id || (usr.IsClubAdmin && club.Owner.UserId != bannerId)) // can't ban the owner kek, whew uow.SaveChanges();
return false;
club.Bans.Add(new()
{
Club = club,
User = usr,
});
club.Users.Remove(usr);
var app = club.Applicants.FirstOrDefault(x => x.UserId == usr.Id);
if (app != null)
club.Applicants.Remove(app);
uow.SaveChanges();
}
return true; return true;
} }
public bool UnBan(ulong ownerUserId, string userName, out ClubInfo club) public bool UnBan(ulong ownerUserId, string userName, out ClubInfo club)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ club = uow.Clubs.GetByOwnerOrAdmin(ownerUserId);
club = uow.Clubs.GetByOwnerOrAdmin(ownerUserId); if (club is null)
if (club is null) return false;
return false;
var ban = club.Bans.FirstOrDefault(x => x.User.ToString().ToUpperInvariant() == userName.ToUpperInvariant()); var ban = club.Bans.FirstOrDefault(x => x.User.ToString().ToUpperInvariant() == userName.ToUpperInvariant());
if (ban is null) if (ban is null)
return false; return false;
club.Bans.Remove(ban); club.Bans.Remove(ban);
uow.SaveChanges(); uow.SaveChanges();
}
return true; return true;
} }
public bool Kick(ulong kickerId, string userName, out ClubInfo club) public bool Kick(ulong kickerId, string userName, out ClubInfo club)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ club = uow.Clubs.GetByOwnerOrAdmin(kickerId);
club = uow.Clubs.GetByOwnerOrAdmin(kickerId); if (club is null)
if (club is null) return false;
return false;
var usr = club.Users.FirstOrDefault(x => x.ToString().ToUpperInvariant() == userName.ToUpperInvariant()); var usr = club.Users.FirstOrDefault(x => x.ToString().ToUpperInvariant() == userName.ToUpperInvariant());
if (usr is null) if (usr is null)
return false; return false;
if (club.OwnerId == usr.Id || (usr.IsClubAdmin && club.Owner.UserId != kickerId)) if (club.OwnerId == usr.Id || (usr.IsClubAdmin && club.Owner.UserId != kickerId))
return false; return false;
club.Users.Remove(usr); club.Users.Remove(usr);
var app = club.Applicants.FirstOrDefault(x => x.UserId == usr.Id); var app = club.Applicants.FirstOrDefault(x => x.UserId == usr.Id);
if (app != null) if (app != null)
club.Applicants.Remove(app); club.Applicants.Remove(app);
uow.SaveChanges(); uow.SaveChanges();
}
return true; return true;
} }

View File

@@ -32,7 +32,7 @@ public class XpService : INService
private readonly FontProvider _fonts; private readonly FontProvider _fonts;
private readonly IBotCredentials _creds; private readonly IBotCredentials _creds;
private readonly ICurrencyService _cs; private readonly ICurrencyService _cs;
private readonly Task updateXpTask; private readonly Task _updateXpTask;
private readonly IHttpClientFactory _httpFactory; private readonly IHttpClientFactory _httpFactory;
private readonly XpConfigService _xpConfig; private readonly XpConfigService _xpConfig;
private readonly IPubSub _pubSub; private readonly IPubSub _pubSub;
@@ -124,19 +124,19 @@ public class XpService : INService
allGuildConfigs.Where(x => x.XpSettings.ServerExcluded) allGuildConfigs.Where(x => x.XpSettings.ServerExcluded)
.Select(x => x.GuildId)); .Select(x => x.GuildId));
_cmd.OnMessageNoTrigger += _cmd_OnMessageNoTrigger; _cmd.OnMessageNoTrigger += Cmd_OnMessageNoTrigger;
#if !GLOBAL_NADEKO #if !GLOBAL_NADEKO
_client.UserVoiceStateUpdated += _client_OnUserVoiceStateUpdated; _client.UserVoiceStateUpdated += Client_OnUserVoiceStateUpdated;
// Scan guilds on startup. // Scan guilds on startup.
_client.GuildAvailable += _client_OnGuildAvailable; _client.GuildAvailable += Client_OnGuildAvailable;
foreach (var guild in _client.Guilds) foreach (var guild in _client.Guilds)
{ {
_client_OnGuildAvailable(guild); Client_OnGuildAvailable(guild);
} }
#endif #endif
updateXpTask = Task.Run(UpdateLoop); _updateXpTask = Task.Run(UpdateLoop);
} }
private async Task UpdateLoop() private async Task UpdateLoop()
@@ -318,45 +318,41 @@ public class XpService : INService
public void SetCurrencyReward(ulong guildId, int level, int amount) public void SetCurrencyReward(ulong guildId, int level, int amount)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
var settings = uow.XpSettingsFor(guildId);
if (amount <= 0)
{ {
var settings = uow.XpSettingsFor(guildId); var toRemove = settings.CurrencyRewards.FirstOrDefault(x => x.Level == level);
if (toRemove != null)
if (amount <= 0)
{ {
var toRemove = settings.CurrencyRewards.FirstOrDefault(x => x.Level == level); uow.Remove(toRemove);
if (toRemove != null) settings.CurrencyRewards.Remove(toRemove);
{
uow.Remove(toRemove);
settings.CurrencyRewards.Remove(toRemove);
}
} }
else
{
var rew = settings.CurrencyRewards.FirstOrDefault(x => x.Level == level);
if (rew != null)
rew.Amount = amount;
else
settings.CurrencyRewards.Add(new()
{
Level = level,
Amount = amount,
});
}
uow.SaveChanges();
} }
else
{
var rew = settings.CurrencyRewards.FirstOrDefault(x => x.Level == level);
if (rew != null)
rew.Amount = amount;
else
settings.CurrencyRewards.Add(new()
{
Level = level,
Amount = amount,
});
}
uow.SaveChanges();
} }
public IEnumerable<XpCurrencyReward> GetCurrencyRewards(ulong id) public IEnumerable<XpCurrencyReward> GetCurrencyRewards(ulong id)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ return uow.XpSettingsFor(id)
return uow.XpSettingsFor(id) .CurrencyRewards
.CurrencyRewards .ToArray();
.ToArray();
}
} }
public IEnumerable<XpRoleReward> GetRoleRewards(ulong id) public IEnumerable<XpRoleReward> GetRoleRewards(ulong id)
@@ -410,66 +406,52 @@ public class XpService : INService
public List<UserXpStats> GetUserXps(ulong guildId, int page) public List<UserXpStats> GetUserXps(ulong guildId, int page)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ return uow.UserXpStats.GetUsersFor(guildId, page);
return uow.UserXpStats.GetUsersFor(guildId, page);
}
} }
public List<UserXpStats> GetTopUserXps(ulong guildId, int count) public List<UserXpStats> GetTopUserXps(ulong guildId, int count)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ return uow.UserXpStats.GetTopUserXps(guildId, count);
return uow.UserXpStats.GetTopUserXps(guildId, count);
}
} }
public DiscordUser[] GetUserXps(int page) public DiscordUser[] GetUserXps(int page)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ return uow.DiscordUser.GetUsersXpLeaderboardFor(page);
return uow.DiscordUser.GetUsersXpLeaderboardFor(page);
}
} }
public async Task ChangeNotificationType(ulong userId, ulong guildId, XpNotificationLocation type) public async Task ChangeNotificationType(ulong userId, ulong guildId, XpNotificationLocation type)
{ {
await using (var uow = _db.GetDbContext()) await using var uow = _db.GetDbContext();
{ var user = uow.GetOrCreateUserXpStats(guildId, userId);
var user = uow.GetOrCreateUserXpStats(guildId, userId); user.NotifyOnLevelUp = type;
user.NotifyOnLevelUp = type; await uow.SaveChangesAsync();
await uow.SaveChangesAsync();
}
} }
public XpNotificationLocation GetNotificationType(ulong userId, ulong guildId) public XpNotificationLocation GetNotificationType(ulong userId, ulong guildId)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ var user = uow.GetOrCreateUserXpStats(guildId, userId);
var user = uow.GetOrCreateUserXpStats(guildId, userId); return user.NotifyOnLevelUp;
return user.NotifyOnLevelUp;
}
} }
public XpNotificationLocation GetNotificationType(IUser user) public XpNotificationLocation GetNotificationType(IUser user)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ return uow.GetOrCreateUser(user).NotifyOnLevelUp;
return uow.GetOrCreateUser(user).NotifyOnLevelUp;
}
} }
public async Task ChangeNotificationType(IUser user, XpNotificationLocation type) public async Task ChangeNotificationType(IUser user, XpNotificationLocation type)
{ {
await using (var uow = _db.GetDbContext()) await using var uow = _db.GetDbContext();
{ var du = uow.GetOrCreateUser(user);
var du = uow.GetOrCreateUser(user); du.NotifyOnLevelUp = type;
du.NotifyOnLevelUp = type; await uow.SaveChangesAsync();
await uow.SaveChangesAsync();
}
} }
private Task _client_OnGuildAvailable(SocketGuild guild) private Task Client_OnGuildAvailable(SocketGuild guild)
{ {
Task.Run(() => Task.Run(() =>
{ {
@@ -482,7 +464,7 @@ public class XpService : INService
return Task.CompletedTask; return Task.CompletedTask;
} }
private Task _client_OnUserVoiceStateUpdated(SocketUser socketUser, SocketVoiceState before, SocketVoiceState after) private Task Client_OnUserVoiceStateUpdated(SocketUser socketUser, SocketVoiceState before, SocketVoiceState after)
{ {
if (socketUser is not SocketGuildUser user || user.IsBot) if (socketUser is not SocketGuildUser user || user.IsBot)
return Task.CompletedTask; return Task.CompletedTask;
@@ -605,7 +587,7 @@ public class XpService : INService
return true; return true;
} }
private Task _cmd_OnMessageNoTrigger(IUserMessage arg) private Task Cmd_OnMessageNoTrigger(IUserMessage arg)
{ {
if (arg.Author is not SocketGuildUser user || user.IsBot) if (arg.Author is not SocketGuildUser user || user.IsBot)
return Task.CompletedTask; return Task.CompletedTask;
@@ -659,14 +641,12 @@ public class XpService : INService
public void AddXp(ulong userId, ulong guildId, int amount) public void AddXp(ulong userId, ulong guildId, int amount)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ var usr = uow.GetOrCreateUserXpStats(guildId, userId);
var usr = uow.GetOrCreateUserXpStats(guildId, userId);
usr.AwardedXp += amount; usr.AwardedXp += amount;
uow.SaveChanges(); uow.SaveChanges();
}
} }
public bool IsServerExcluded(ulong id) public bool IsServerExcluded(ulong id)
@@ -728,92 +708,86 @@ public class XpService : INService
public bool ToggleExcludeServer(ulong id) public bool ToggleExcludeServer(ulong id)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
var xpSetting = uow.XpSettingsFor(id);
if (_excludedServers.Add(id))
{ {
var xpSetting = uow.XpSettingsFor(id); xpSetting.ServerExcluded = true;
if (_excludedServers.Add(id))
{
xpSetting.ServerExcluded = true;
uow.SaveChanges();
return true;
}
_excludedServers.TryRemove(id);
xpSetting.ServerExcluded = false;
uow.SaveChanges(); uow.SaveChanges();
return false; return true;
} }
_excludedServers.TryRemove(id);
xpSetting.ServerExcluded = false;
uow.SaveChanges();
return false;
} }
public bool ToggleExcludeRole(ulong guildId, ulong rId) public bool ToggleExcludeRole(ulong guildId, ulong rId)
{ {
var roles = _excludedRoles.GetOrAdd(guildId, _ => new()); var roles = _excludedRoles.GetOrAdd(guildId, _ => new());
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
var xpSetting = uow.XpSettingsFor(guildId);
var excludeObj = new ExcludedItem
{ {
var xpSetting = uow.XpSettingsFor(guildId); ItemId = rId,
var excludeObj = new ExcludedItem ItemType = ExcludedItemType.Role,
{ };
ItemId = rId,
ItemType = ExcludedItemType.Role,
};
if (roles.Add(rId)) if (roles.Add(rId))
{
if (xpSetting.ExclusionList.Add(excludeObj))
{ {
if (xpSetting.ExclusionList.Add(excludeObj)) uow.SaveChanges();
{
uow.SaveChanges();
}
return true;
} }
else
return true;
}
else
{
roles.TryRemove(rId);
var toDelete = xpSetting.ExclusionList.FirstOrDefault(x => x.Equals(excludeObj));
if (toDelete != null)
{ {
roles.TryRemove(rId); uow.Remove(toDelete);
uow.SaveChanges();
var toDelete = xpSetting.ExclusionList.FirstOrDefault(x => x.Equals(excludeObj));
if (toDelete != null)
{
uow.Remove(toDelete);
uow.SaveChanges();
}
return false;
} }
return false;
} }
} }
public bool ToggleExcludeChannel(ulong guildId, ulong chId) public bool ToggleExcludeChannel(ulong guildId, ulong chId)
{ {
var channels = _excludedChannels.GetOrAdd(guildId, _ => new()); var channels = _excludedChannels.GetOrAdd(guildId, _ => new());
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
var xpSetting = uow.XpSettingsFor(guildId);
var excludeObj = new ExcludedItem
{ {
var xpSetting = uow.XpSettingsFor(guildId); ItemId = chId,
var excludeObj = new ExcludedItem ItemType = ExcludedItemType.Channel,
{ };
ItemId = chId,
ItemType = ExcludedItemType.Channel,
};
if (channels.Add(chId)) if (channels.Add(chId))
{
if (xpSetting.ExclusionList.Add(excludeObj))
{ {
if (xpSetting.ExclusionList.Add(excludeObj)) uow.SaveChanges();
{
uow.SaveChanges();
}
return true;
} }
else
return true;
}
else
{
channels.TryRemove(chId);
if (xpSetting.ExclusionList.Remove(excludeObj))
{ {
channels.TryRemove(chId); uow.SaveChanges();
if (xpSetting.ExclusionList.Remove(excludeObj))
{
uow.SaveChanges();
}
return false;
} }
return false;
} }
} }
@@ -844,230 +818,226 @@ public class XpService : INService
VerticalAlignment = VerticalAlignment.Top, VerticalAlignment = VerticalAlignment.Top,
} }
}.WithFallbackFonts(_fonts.FallBackFonts); }.WithFallbackFonts(_fonts.FallBackFonts);
using (var img = Image.Load<Rgba32>(_images.XpBackground, out var imageFormat)) using var img = Image.Load<Rgba32>(_images.XpBackground, out var imageFormat);
if (_template.User.Name.Show)
{ {
if (_template.User.Name.Show) var fontSize = (int)(_template.User.Name.FontSize * 0.9);
var username = stats.User.ToString();
var usernameFont = _fonts.NotoSans
.CreateFont(fontSize, FontStyle.Bold);
var size = TextMeasurer.Measure($"@{username}", new(usernameFont));
var scale = 400f / size.Width;
if (scale < 1)
{ {
var fontSize = (int)(_template.User.Name.FontSize * 0.9); usernameFont = _fonts.NotoSans
var username = stats.User.ToString(); .CreateFont(_template.User.Name.FontSize * scale, FontStyle.Bold);
var usernameFont = _fonts.NotoSans
.CreateFont(fontSize, FontStyle.Bold);
var size = TextMeasurer.Measure($"@{username}", new(usernameFont));
var scale = 400f / size.Width;
if (scale < 1)
{
usernameFont = _fonts.NotoSans
.CreateFont(_template.User.Name.FontSize * scale, FontStyle.Bold);
}
img.Mutate(x =>
{
x.DrawText(usernameTextOptions,
"@" + username,
usernameFont,
_template.User.Name.Color,
new(_template.User.Name.Pos.X, _template.User.Name.Pos.Y + 8));
});
} }
//club name img.Mutate(x =>
if (_template.Club.Name.Show)
{ {
var clubName = stats.User.Club?.ToString() ?? "-"; x.DrawText(usernameTextOptions,
"@" + username,
usernameFont,
_template.User.Name.Color,
new(_template.User.Name.Pos.X, _template.User.Name.Pos.Y + 8));
});
}
var clubFont = _fonts.NotoSans //club name
.CreateFont(_template.Club.Name.FontSize, FontStyle.Regular);
if (_template.Club.Name.Show)
{
var clubName = stats.User.Club?.ToString() ?? "-";
var clubFont = _fonts.NotoSans
.CreateFont(_template.Club.Name.FontSize, FontStyle.Regular);
img.Mutate(x => x.DrawText(clubTextOptions, img.Mutate(x => x.DrawText(clubTextOptions,
clubName, clubName,
clubFont, clubFont,
_template.Club.Name.Color, _template.Club.Name.Color,
new(_template.Club.Name.Pos.X + 50, _template.Club.Name.Pos.Y - 8)) new(_template.Club.Name.Pos.X + 50, _template.Club.Name.Pos.Y - 8))
);
}
if (_template.User.GlobalLevel.Show)
{
img.Mutate(x =>
{
x.DrawText(
stats.Global.Level.ToString(),
_fonts.NotoSans.CreateFont(_template.User.GlobalLevel.FontSize, FontStyle.Bold),
_template.User.GlobalLevel.Color,
new(_template.User.GlobalLevel.Pos.X, _template.User.GlobalLevel.Pos.Y)
); //level
});
}
if (_template.User.GuildLevel.Show)
{
img.Mutate(x =>
{
x.DrawText(
stats.Guild.Level.ToString(),
_fonts.NotoSans.CreateFont(_template.User.GuildLevel.FontSize, FontStyle.Bold),
_template.User.GuildLevel.Color,
new(_template.User.GuildLevel.Pos.X, _template.User.GuildLevel.Pos.Y)
); );
} });
}
if (_template.User.GlobalLevel.Show)
var pen = new Pen(SixLabors.ImageSharp.Color.Black, 1);
var global = stats.Global;
var guild = stats.Guild;
//xp bar
if (_template.User.Xp.Bar.Show)
{
var xpPercent = global.LevelXp / (float) global.RequiredXp;
DrawXpBar(xpPercent, _template.User.Xp.Bar.Global, img);
xpPercent = guild.LevelXp / (float) guild.RequiredXp;
DrawXpBar(xpPercent, _template.User.Xp.Bar.Guild, img);
}
if (_template.User.Xp.Global.Show)
{
img.Mutate(x => x.DrawText($"{global.LevelXp}/{global.RequiredXp}",
_fonts.NotoSans.CreateFont(_template.User.Xp.Global.FontSize, FontStyle.Bold),
Brushes.Solid(_template.User.Xp.Global.Color),
pen,
new(_template.User.Xp.Global.Pos.X, _template.User.Xp.Global.Pos.Y)));
}
if (_template.User.Xp.Guild.Show)
{
img.Mutate(x => x.DrawText($"{guild.LevelXp}/{guild.RequiredXp}",
_fonts.NotoSans.CreateFont(_template.User.Xp.Guild.FontSize, FontStyle.Bold),
Brushes.Solid(_template.User.Xp.Guild.Color),
pen,
new(_template.User.Xp.Guild.Pos.X, _template.User.Xp.Guild.Pos.Y)));
}
if (stats.FullGuildStats.AwardedXp != 0 && _template.User.Xp.Awarded.Show)
{
var sign = stats.FullGuildStats.AwardedXp > 0
? "+ "
: "";
var awX = _template.User.Xp.Awarded.Pos.X -
(Math.Max(0, stats.FullGuildStats.AwardedXp.ToString().Length - 2) * 5);
var awY = _template.User.Xp.Awarded.Pos.Y;
img.Mutate(x => x.DrawText($"({sign}{stats.FullGuildStats.AwardedXp})",
_fonts.NotoSans.CreateFont(_template.User.Xp.Awarded.FontSize, FontStyle.Bold),
Brushes.Solid(_template.User.Xp.Awarded.Color),
pen,
new(awX, awY)));
}
//ranking
if (_template.User.GlobalRank.Show)
{
img.Mutate(x => x.DrawText(stats.GlobalRanking.ToString(),
_fonts.UniSans.CreateFont(_template.User.GlobalRank.FontSize, FontStyle.Bold),
_template.User.GlobalRank.Color,
new(_template.User.GlobalRank.Pos.X, _template.User.GlobalRank.Pos.Y)));
}
if (_template.User.GuildRank.Show)
{
img.Mutate(x => x.DrawText(stats.GuildRanking.ToString(),
_fonts.UniSans.CreateFont(_template.User.GuildRank.FontSize, FontStyle.Bold),
_template.User.GuildRank.Color,
new(_template.User.GuildRank.Pos.X, _template.User.GuildRank.Pos.Y)));
}
//time on this level
string GetTimeSpent(DateTime time, string format)
{
var offset = DateTime.UtcNow - time;
return string.Format(format, offset.Days, offset.Hours, offset.Minutes);
}
if (_template.User.TimeOnLevel.Global.Show)
{
img.Mutate(x =>
x.DrawText(GetTimeSpent(stats.User.LastLevelUp, _template.User.TimeOnLevel.Format),
_fonts.NotoSans.CreateFont(_template.User.TimeOnLevel.Global.FontSize, FontStyle.Bold),
_template.User.TimeOnLevel.Global.Color,
new(_template.User.TimeOnLevel.Global.Pos.X,
_template.User.TimeOnLevel.Global.Pos.Y)));
}
if (_template.User.TimeOnLevel.Guild.Show)
{
img.Mutate(x =>
x.DrawText(
GetTimeSpent(stats.FullGuildStats.LastLevelUp, _template.User.TimeOnLevel.Format),
_fonts.NotoSans.CreateFont(_template.User.TimeOnLevel.Guild.FontSize, FontStyle.Bold),
_template.User.TimeOnLevel.Guild.Color,
new(_template.User.TimeOnLevel.Guild.Pos.X,
_template.User.TimeOnLevel.Guild.Pos.Y)));
}
//avatar
if (stats.User.AvatarId != null && _template.User.Icon.Show)
{
try
{ {
img.Mutate(x => var avatarUrl = stats.User.RealAvatarUrl();
var (succ, data) = await _cache.TryGetImageDataAsync(avatarUrl);
if (!succ)
{ {
x.DrawText( using (var http = _httpFactory.CreateClient())
stats.Global.Level.ToString(),
_fonts.NotoSans.CreateFont(_template.User.GlobalLevel.FontSize, FontStyle.Bold),
_template.User.GlobalLevel.Color,
new(_template.User.GlobalLevel.Pos.X, _template.User.GlobalLevel.Pos.Y)
); //level
});
}
if (_template.User.GuildLevel.Show)
{
img.Mutate(x =>
{
x.DrawText(
stats.Guild.Level.ToString(),
_fonts.NotoSans.CreateFont(_template.User.GuildLevel.FontSize, FontStyle.Bold),
_template.User.GuildLevel.Color,
new(_template.User.GuildLevel.Pos.X, _template.User.GuildLevel.Pos.Y)
);
});
}
var pen = new Pen(SixLabors.ImageSharp.Color.Black, 1);
var global = stats.Global;
var guild = stats.Guild;
//xp bar
if (_template.User.Xp.Bar.Show)
{
var xpPercent = global.LevelXp / (float) global.RequiredXp;
DrawXpBar(xpPercent, _template.User.Xp.Bar.Global, img);
xpPercent = guild.LevelXp / (float) guild.RequiredXp;
DrawXpBar(xpPercent, _template.User.Xp.Bar.Guild, img);
}
if (_template.User.Xp.Global.Show)
{
img.Mutate(x => x.DrawText($"{global.LevelXp}/{global.RequiredXp}",
_fonts.NotoSans.CreateFont(_template.User.Xp.Global.FontSize, FontStyle.Bold),
Brushes.Solid(_template.User.Xp.Global.Color),
pen,
new(_template.User.Xp.Global.Pos.X, _template.User.Xp.Global.Pos.Y)));
}
if (_template.User.Xp.Guild.Show)
{
img.Mutate(x => x.DrawText($"{guild.LevelXp}/{guild.RequiredXp}",
_fonts.NotoSans.CreateFont(_template.User.Xp.Guild.FontSize, FontStyle.Bold),
Brushes.Solid(_template.User.Xp.Guild.Color),
pen,
new(_template.User.Xp.Guild.Pos.X, _template.User.Xp.Guild.Pos.Y)));
}
if (stats.FullGuildStats.AwardedXp != 0 && _template.User.Xp.Awarded.Show)
{
var sign = stats.FullGuildStats.AwardedXp > 0
? "+ "
: "";
var awX = _template.User.Xp.Awarded.Pos.X -
(Math.Max(0, stats.FullGuildStats.AwardedXp.ToString().Length - 2) * 5);
var awY = _template.User.Xp.Awarded.Pos.Y;
img.Mutate(x => x.DrawText($"({sign}{stats.FullGuildStats.AwardedXp})",
_fonts.NotoSans.CreateFont(_template.User.Xp.Awarded.FontSize, FontStyle.Bold),
Brushes.Solid(_template.User.Xp.Awarded.Color),
pen,
new(awX, awY)));
}
//ranking
if (_template.User.GlobalRank.Show)
{
img.Mutate(x => x.DrawText(stats.GlobalRanking.ToString(),
_fonts.UniSans.CreateFont(_template.User.GlobalRank.FontSize, FontStyle.Bold),
_template.User.GlobalRank.Color,
new(_template.User.GlobalRank.Pos.X, _template.User.GlobalRank.Pos.Y)));
}
if (_template.User.GuildRank.Show)
{
img.Mutate(x => x.DrawText(stats.GuildRanking.ToString(),
_fonts.UniSans.CreateFont(_template.User.GuildRank.FontSize, FontStyle.Bold),
_template.User.GuildRank.Color,
new(_template.User.GuildRank.Pos.X, _template.User.GuildRank.Pos.Y)));
}
//time on this level
string GetTimeSpent(DateTime time, string format)
{
var offset = DateTime.UtcNow - time;
return string.Format(format, offset.Days, offset.Hours, offset.Minutes);
}
if (_template.User.TimeOnLevel.Global.Show)
{
img.Mutate(x =>
x.DrawText(GetTimeSpent(stats.User.LastLevelUp, _template.User.TimeOnLevel.Format),
_fonts.NotoSans.CreateFont(_template.User.TimeOnLevel.Global.FontSize, FontStyle.Bold),
_template.User.TimeOnLevel.Global.Color,
new(_template.User.TimeOnLevel.Global.Pos.X,
_template.User.TimeOnLevel.Global.Pos.Y)));
}
if (_template.User.TimeOnLevel.Guild.Show)
{
img.Mutate(x =>
x.DrawText(
GetTimeSpent(stats.FullGuildStats.LastLevelUp, _template.User.TimeOnLevel.Format),
_fonts.NotoSans.CreateFont(_template.User.TimeOnLevel.Guild.FontSize, FontStyle.Bold),
_template.User.TimeOnLevel.Guild.Color,
new(_template.User.TimeOnLevel.Guild.Pos.X,
_template.User.TimeOnLevel.Guild.Pos.Y)));
}
//avatar
if (stats.User.AvatarId != null && _template.User.Icon.Show)
{
try
{
var avatarUrl = stats.User.RealAvatarUrl();
var (succ, data) = await _cache.TryGetImageDataAsync(avatarUrl);
if (!succ)
{ {
using (var http = _httpFactory.CreateClient()) var avatarData = await http.GetByteArrayAsync(avatarUrl);
using (var tempDraw = Image.Load(avatarData))
{ {
var avatarData = await http.GetByteArrayAsync(avatarUrl); tempDraw.Mutate(x => x
using (var tempDraw = Image.Load(avatarData)) .Resize(_template.User.Icon.Size.X, _template.User.Icon.Size.Y)
.ApplyRoundedCorners(
Math.Max(_template.User.Icon.Size.X, _template.User.Icon.Size.Y) / 2));
await using (var stream = tempDraw.ToStream())
{ {
tempDraw.Mutate(x => x data = stream.ToArray();
.Resize(_template.User.Icon.Size.X, _template.User.Icon.Size.Y)
.ApplyRoundedCorners(
Math.Max(_template.User.Icon.Size.X, _template.User.Icon.Size.Y) / 2));
await using (var stream = tempDraw.ToStream())
{
data = stream.ToArray();
}
} }
} }
await _cache.SetImageDataAsync(avatarUrl, data);
} }
using (var toDraw = Image.Load(data)) await _cache.SetImageDataAsync(avatarUrl, data);
{
if (toDraw.Size() != new Size(_template.User.Icon.Size.X, _template.User.Icon.Size.Y))
{
toDraw.Mutate(x =>
x.Resize(_template.User.Icon.Size.X, _template.User.Icon.Size.Y));
}
img.Mutate(x => x.DrawImage(toDraw,
new Point(_template.User.Icon.Pos.X, _template.User.Icon.Pos.Y), 1));
}
} }
catch (Exception ex)
using var toDraw = Image.Load(data);
if (toDraw.Size() != new Size(_template.User.Icon.Size.X, _template.User.Icon.Size.Y))
{ {
Log.Warning(ex, "Error drawing avatar image"); toDraw.Mutate(x =>
x.Resize(_template.User.Icon.Size.X, _template.User.Icon.Size.Y));
} }
}
//club image img.Mutate(x => x.DrawImage(toDraw,
if (_template.Club.Icon.Show) new Point(_template.User.Icon.Pos.X, _template.User.Icon.Pos.Y), 1));
}
catch (Exception ex)
{ {
await DrawClubImage(img, stats); Log.Warning(ex, "Error drawing avatar image");
} }
img.Mutate(x => x.Resize(_template.OutputSize.X, _template.OutputSize.Y));
return ((Stream) img.ToStream(imageFormat), imageFormat);
} }
//club image
if (_template.Club.Icon.Show)
{
await DrawClubImage(img, stats);
}
img.Mutate(x => x.Resize(_template.OutputSize.X, _template.OutputSize.Y));
return ((Stream) img.ToStream(imageFormat), imageFormat);
}); });
void DrawXpBar(float percent, XpBar info, Image<Rgba32> img) private void DrawXpBar(float percent, XpBar info, Image<Rgba32> img)
{ {
var x1 = info.PointA.X; var x1 = info.PointA.X;
var y1 = info.PointA.Y; var y1 = info.PointA.Y;
@@ -1151,18 +1121,16 @@ public class XpService : INService
await _cache.SetImageDataAsync(imgUrl, data); await _cache.SetImageDataAsync(imgUrl, data);
} }
using (var toDraw = Image.Load(data)) using var toDraw = Image.Load(data);
if (toDraw.Size() != new Size(_template.Club.Icon.Size.X, _template.Club.Icon.Size.Y))
{ {
if (toDraw.Size() != new Size(_template.Club.Icon.Size.X, _template.Club.Icon.Size.Y)) toDraw.Mutate(x => x.Resize(_template.Club.Icon.Size.X, _template.Club.Icon.Size.Y));
{
toDraw.Mutate(x => x.Resize(_template.Club.Icon.Size.X, _template.Club.Icon.Size.Y));
}
img.Mutate(x => x.DrawImage(
toDraw,
new Point(_template.Club.Icon.Pos.X, _template.Club.Icon.Pos.Y),
1));
} }
img.Mutate(x => x.DrawImage(
toDraw,
new Point(_template.Club.Icon.Pos.X, _template.Club.Icon.Pos.Y),
1));
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -1173,20 +1141,16 @@ public class XpService : INService
public void XpReset(ulong guildId, ulong userId) public void XpReset(ulong guildId, ulong userId)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ uow.UserXpStats.ResetGuildUserXp(userId, guildId);
uow.UserXpStats.ResetGuildUserXp(userId, guildId); uow.SaveChanges();
uow.SaveChanges();
}
} }
public void XpReset(ulong guildId) public void XpReset(ulong guildId)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ uow.UserXpStats.ResetGuildXp(guildId);
uow.UserXpStats.ResetGuildXp(guildId); uow.SaveChanges();
uow.SaveChanges();
}
} }
public async Task ResetXpRewards(ulong guildId) public async Task ResetXpRewards(ulong guildId)

View File

@@ -8,6 +8,7 @@
<RunWorkingDirectory>$(MSBuildProjectDirectory)</RunWorkingDirectory> <RunWorkingDirectory>$(MSBuildProjectDirectory)</RunWorkingDirectory>
<OutputType>exe</OutputType> <OutputType>exe</OutputType>
<ApplicationIcon>nadeko_icon.ico</ApplicationIcon> <ApplicationIcon>nadeko_icon.ico</ApplicationIcon>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@@ -28,18 +28,16 @@ public class DbService
public void Setup() public void Setup()
{ {
using (var context = new NadekoContext(options)) using var context = new NadekoContext(options);
if (context.Database.GetPendingMigrations().Any())
{ {
if (context.Database.GetPendingMigrations().Any()) var mContext = new NadekoContext(migrateOptions);
{ mContext.Database.Migrate();
var mContext = new NadekoContext(migrateOptions); mContext.SaveChanges();
mContext.Database.Migrate(); mContext.Dispose();
mContext.SaveChanges();
mContext.Dispose();
}
context.Database.ExecuteSqlRaw("PRAGMA journal_mode=WAL");
context.SaveChanges();
} }
context.Database.ExecuteSqlRaw("PRAGMA journal_mode=WAL");
context.SaveChanges();
} }
private NadekoContext GetDbContextInternal() private NadekoContext GetDbContextInternal()
@@ -48,11 +46,9 @@ public class DbService
context.Database.SetCommandTimeout(60); context.Database.SetCommandTimeout(60);
var conn = context.Database.GetDbConnection(); var conn = context.Database.GetDbConnection();
conn.Open(); conn.Open();
using (var com = conn.CreateCommand()) using var com = conn.CreateCommand();
{ com.CommandText = "PRAGMA journal_mode=WAL; PRAGMA synchronous=OFF";
com.CommandText = "PRAGMA journal_mode=WAL; PRAGMA synchronous=OFF"; com.ExecuteNonQuery();
com.ExecuteNonQuery();
}
return context; return context;
} }

View File

@@ -148,18 +148,14 @@ public class GreetSettingsService : INService
public string GetDmGreetMsg(ulong id) public string GetDmGreetMsg(ulong id)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ return uow.GuildConfigsForId(id, set => set)?.DmGreetMessageText;
return uow.GuildConfigsForId(id, set => set)?.DmGreetMessageText;
}
} }
public string GetGreetMsg(ulong gid) public string GetGreetMsg(ulong gid)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ return uow.GuildConfigsForId(gid, set => set).ChannelGreetMessageText;
return uow.GuildConfigsForId(gid, set => set).ChannelGreetMessageText;
}
} }
public string GetBoostMessage(ulong gid) public string GetBoostMessage(ulong gid)
@@ -308,10 +304,8 @@ public class GreetSettingsService : INService
public string GetByeMessage(ulong gid) public string GetByeMessage(ulong gid)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ return uow.GuildConfigsForId(gid, set => set).ChannelByeMessageText;
return uow.GuildConfigsForId(gid, set => set).ChannelByeMessageText;
}
} }
public GreetSettings GetOrAddSettingsForGuild(ulong guildId) public GreetSettings GetOrAddSettingsForGuild(ulong guildId)
@@ -340,30 +334,28 @@ public class GreetSettingsService : INService
return false; return false;
} }
await using (var uow = _db.GetDbContext()) await using var uow = _db.GetDbContext();
{ var conf = uow.GuildConfigsForId(guildId, set => set);
var conf = uow.GuildConfigsForId(guildId, set => set); conf.DmGreetMessageText = settings.DmGreetMessageText?.SanitizeMentions();
conf.DmGreetMessageText = settings.DmGreetMessageText?.SanitizeMentions(); conf.ChannelGreetMessageText = settings.ChannelGreetMessageText?.SanitizeMentions();
conf.ChannelGreetMessageText = settings.ChannelGreetMessageText?.SanitizeMentions(); conf.ChannelByeMessageText = settings.ChannelByeMessageText?.SanitizeMentions();
conf.ChannelByeMessageText = settings.ChannelByeMessageText?.SanitizeMentions();
conf.AutoDeleteGreetMessagesTimer = settings.AutoDeleteGreetMessagesTimer; conf.AutoDeleteGreetMessagesTimer = settings.AutoDeleteGreetMessagesTimer;
conf.AutoDeleteGreetMessages = settings.AutoDeleteGreetMessagesTimer > 0; conf.AutoDeleteGreetMessages = settings.AutoDeleteGreetMessagesTimer > 0;
conf.AutoDeleteByeMessagesTimer = settings.AutoDeleteByeMessagesTimer; conf.AutoDeleteByeMessagesTimer = settings.AutoDeleteByeMessagesTimer;
conf.AutoDeleteByeMessages = settings.AutoDeleteByeMessagesTimer > 0; conf.AutoDeleteByeMessages = settings.AutoDeleteByeMessagesTimer > 0;
conf.GreetMessageChannelId = settings.GreetMessageChannelId; conf.GreetMessageChannelId = settings.GreetMessageChannelId;
conf.ByeMessageChannelId = settings.ByeMessageChannelId; conf.ByeMessageChannelId = settings.ByeMessageChannelId;
conf.SendChannelGreetMessage = settings.SendChannelGreetMessage; conf.SendChannelGreetMessage = settings.SendChannelGreetMessage;
conf.SendChannelByeMessage = settings.SendChannelByeMessage; conf.SendChannelByeMessage = settings.SendChannelByeMessage;
await uow.SaveChangesAsync(); await uow.SaveChangesAsync();
var toAdd = GreetSettings.Create(conf); var toAdd = GreetSettings.Create(conf);
GuildConfigsCache.AddOrUpdate(guildId, toAdd, (key, old) => toAdd); GuildConfigsCache.AddOrUpdate(guildId, toAdd, (key, old) => toAdd);
}
return true; return true;
} }
@@ -371,17 +363,15 @@ public class GreetSettingsService : INService
public async Task<bool> SetGreet(ulong guildId, ulong channelId, bool? value = null) public async Task<bool> SetGreet(ulong guildId, ulong channelId, bool? value = null)
{ {
bool enabled; bool enabled;
await using (var uow = _db.GetDbContext()) await using var uow = _db.GetDbContext();
{ var conf = uow.GuildConfigsForId(guildId, set => set);
var conf = uow.GuildConfigsForId(guildId, set => set); enabled = conf.SendChannelGreetMessage = value ?? !conf.SendChannelGreetMessage;
enabled = conf.SendChannelGreetMessage = value ?? !conf.SendChannelGreetMessage; conf.GreetMessageChannelId = channelId;
conf.GreetMessageChannelId = channelId;
var toAdd = GreetSettings.Create(conf); var toAdd = GreetSettings.Create(conf);
GuildConfigsCache.AddOrUpdate(guildId, toAdd, (key, old) => toAdd); GuildConfigsCache.AddOrUpdate(guildId, toAdd, (key, old) => toAdd);
await uow.SaveChangesAsync(); await uow.SaveChangesAsync();
}
return enabled; return enabled;
} }
@@ -393,62 +383,52 @@ public class GreetSettingsService : INService
throw new ArgumentNullException(nameof(message)); throw new ArgumentNullException(nameof(message));
bool greetMsgEnabled; bool greetMsgEnabled;
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ var conf = uow.GuildConfigsForId(guildId, set => set);
var conf = uow.GuildConfigsForId(guildId, set => set); conf.ChannelGreetMessageText = message;
conf.ChannelGreetMessageText = message; greetMsgEnabled = conf.SendChannelGreetMessage;
greetMsgEnabled = conf.SendChannelGreetMessage;
var toAdd = GreetSettings.Create(conf); var toAdd = GreetSettings.Create(conf);
GuildConfigsCache.AddOrUpdate(guildId, toAdd, (key, old) => toAdd); GuildConfigsCache.AddOrUpdate(guildId, toAdd, (key, old) => toAdd);
uow.SaveChanges(); uow.SaveChanges();
}
return greetMsgEnabled; return greetMsgEnabled;
} }
public async Task<bool> SetGreetDm(ulong guildId, bool? value = null) public async Task<bool> SetGreetDm(ulong guildId, bool? value = null)
{ {
bool enabled; bool enabled;
await using (var uow = _db.GetDbContext()) await using var uow = _db.GetDbContext();
{ var conf = uow.GuildConfigsForId(guildId, set => set);
var conf = uow.GuildConfigsForId(guildId, set => set); enabled = conf.SendDmGreetMessage = value ?? !conf.SendDmGreetMessage;
enabled = conf.SendDmGreetMessage = value ?? !conf.SendDmGreetMessage;
var toAdd = GreetSettings.Create(conf); var toAdd = GreetSettings.Create(conf);
GuildConfigsCache.AddOrUpdate(guildId, toAdd, (key, old) => toAdd); GuildConfigsCache.AddOrUpdate(guildId, toAdd, (key, old) => toAdd);
await uow.SaveChangesAsync(); await uow.SaveChangesAsync();
}
return enabled; return enabled;
} }
#region Get Enabled Status #region Get Enabled Status
public bool GetGreetDmEnabled(ulong guildId) public bool GetGreetDmEnabled(ulong guildId)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ var conf = uow.GuildConfigsForId(guildId, set => set);
var conf = uow.GuildConfigsForId(guildId, set => set); return conf.SendDmGreetMessage;
return conf.SendDmGreetMessage;
}
} }
public bool GetGreetEnabled(ulong guildId) public bool GetGreetEnabled(ulong guildId)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ var conf = uow.GuildConfigsForId(guildId, set => set);
var conf = uow.GuildConfigsForId(guildId, set => set); return conf.SendChannelGreetMessage;
return conf.SendChannelGreetMessage;
}
} }
public bool GetByeEnabled(ulong guildId) public bool GetByeEnabled(ulong guildId)
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ var conf = uow.GuildConfigsForId(guildId, set => set);
var conf = uow.GuildConfigsForId(guildId, set => set); return conf.SendChannelByeMessage;
return conf.SendChannelByeMessage;
}
} }
#endregion #endregion
@@ -481,34 +461,30 @@ public class GreetSettingsService : INService
throw new ArgumentNullException(nameof(message)); throw new ArgumentNullException(nameof(message));
bool greetMsgEnabled; bool greetMsgEnabled;
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ var conf = uow.GuildConfigsForId(guildId, set => set);
var conf = uow.GuildConfigsForId(guildId, set => set); conf.DmGreetMessageText = message;
conf.DmGreetMessageText = message; greetMsgEnabled = conf.SendDmGreetMessage;
greetMsgEnabled = conf.SendDmGreetMessage;
var toAdd = GreetSettings.Create(conf); var toAdd = GreetSettings.Create(conf);
GuildConfigsCache.AddOrUpdate(guildId, toAdd, (key, old) => toAdd); GuildConfigsCache.AddOrUpdate(guildId, toAdd, (key, old) => toAdd);
uow.SaveChanges(); uow.SaveChanges();
}
return greetMsgEnabled; return greetMsgEnabled;
} }
public async Task<bool> SetBye(ulong guildId, ulong channelId, bool? value = null) public async Task<bool> SetBye(ulong guildId, ulong channelId, bool? value = null)
{ {
bool enabled; bool enabled;
await using (var uow = _db.GetDbContext()) await using var uow = _db.GetDbContext();
{ var conf = uow.GuildConfigsForId(guildId, set => set);
var conf = uow.GuildConfigsForId(guildId, set => set); enabled = conf.SendChannelByeMessage = value ?? !conf.SendChannelByeMessage;
enabled = conf.SendChannelByeMessage = value ?? !conf.SendChannelByeMessage; conf.ByeMessageChannelId = channelId;
conf.ByeMessageChannelId = channelId;
var toAdd = GreetSettings.Create(conf); var toAdd = GreetSettings.Create(conf);
GuildConfigsCache.AddOrUpdate(guildId, toAdd, (key, old) => toAdd); GuildConfigsCache.AddOrUpdate(guildId, toAdd, (key, old) => toAdd);
await uow.SaveChangesAsync(); await uow.SaveChangesAsync();
}
return enabled; return enabled;
} }
@@ -520,17 +496,15 @@ public class GreetSettingsService : INService
throw new ArgumentNullException(nameof(message)); throw new ArgumentNullException(nameof(message));
bool byeMsgEnabled; bool byeMsgEnabled;
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ var conf = uow.GuildConfigsForId(guildId, set => set);
var conf = uow.GuildConfigsForId(guildId, set => set); conf.ChannelByeMessageText = message;
conf.ChannelByeMessageText = message; byeMsgEnabled = conf.SendChannelByeMessage;
byeMsgEnabled = conf.SendChannelByeMessage;
var toAdd = GreetSettings.Create(conf); var toAdd = GreetSettings.Create(conf);
GuildConfigsCache.AddOrUpdate(guildId, toAdd, (key, old) => toAdd); GuildConfigsCache.AddOrUpdate(guildId, toAdd, (key, old) => toAdd);
uow.SaveChanges(); uow.SaveChanges();
}
return byeMsgEnabled; return byeMsgEnabled;
} }
@@ -539,16 +513,14 @@ public class GreetSettingsService : INService
if (timer < 0 || timer > 600) if (timer < 0 || timer > 600)
return; return;
await using (var uow = _db.GetDbContext()) await using var uow = _db.GetDbContext();
{ var conf = uow.GuildConfigsForId(guildId, set => set);
var conf = uow.GuildConfigsForId(guildId, set => set); conf.AutoDeleteByeMessagesTimer = timer;
conf.AutoDeleteByeMessagesTimer = timer;
var toAdd = GreetSettings.Create(conf); var toAdd = GreetSettings.Create(conf);
GuildConfigsCache.AddOrUpdate(guildId, toAdd, (key, old) => toAdd); GuildConfigsCache.AddOrUpdate(guildId, toAdd, (key, old) => toAdd);
await uow.SaveChangesAsync(); await uow.SaveChangesAsync();
}
} }
public async Task SetGreetDel(ulong id, int timer) public async Task SetGreetDel(ulong id, int timer)
@@ -556,16 +528,14 @@ public class GreetSettingsService : INService
if (timer < 0 || timer > 600) if (timer < 0 || timer > 600)
return; return;
await using (var uow = _db.GetDbContext()) await using var uow = _db.GetDbContext();
{ var conf = uow.GuildConfigsForId(id, set => set);
var conf = uow.GuildConfigsForId(id, set => set); conf.AutoDeleteGreetMessagesTimer = timer;
conf.AutoDeleteGreetMessagesTimer = timer;
var toAdd = GreetSettings.Create(conf); var toAdd = GreetSettings.Create(conf);
GuildConfigsCache.AddOrUpdate(id, toAdd, (key, old) => toAdd); GuildConfigsCache.AddOrUpdate(id, toAdd, (key, old) => toAdd);
await uow.SaveChangesAsync(); await uow.SaveChangesAsync();
}
} }
public bool SetBoostMessage(ulong guildId, ref string message) public bool SetBoostMessage(ulong guildId, ref string message)

View File

@@ -54,11 +54,9 @@ public class CurrencyService : ICurrencyService, INService
throw new ArgumentException("You can't add negative amounts. Use RemoveAsync method for that.", nameof(amount)); throw new ArgumentException("You can't add negative amounts. Use RemoveAsync method for that.", nameof(amount));
} }
await using (var uow = _db.GetDbContext()) await using var uow = _db.GetDbContext();
{ InternalChange(userId, userName, discrim, avatar, reason, amount, gamble, uow);
InternalChange(userId, userName, discrim, avatar, reason, amount, gamble, uow); await uow.SaveChangesAsync();
await uow.SaveChangesAsync();
}
} }
public Task AddAsync(ulong userId, string reason, long amount, bool gamble = false) public Task AddAsync(ulong userId, string reason, long amount, bool gamble = false)
@@ -98,16 +96,14 @@ public class CurrencyService : ICurrencyService, INService
throw new ArgumentException("Cannot perform bulk operation. Arrays are not of equal length."); throw new ArgumentException("Cannot perform bulk operation. Arrays are not of equal length.");
var userIdHashSet = new HashSet<ulong>(idArray.Length); var userIdHashSet = new HashSet<ulong>(idArray.Length);
await using (var uow = _db.GetDbContext()) await using var uow = _db.GetDbContext();
for (var i = 0; i < idArray.Length; i++)
{ {
for (var i = 0; i < idArray.Length; i++) // i have to prevent same user changing more than once as it will cause db error
{ if (userIdHashSet.Add(idArray[i]))
// i have to prevent same user changing more than once as it will cause db error InternalChange(idArray[i], null, null, null, reasonArray[i], amountArray[i], gamble, uow);
if (userIdHashSet.Add(idArray[i]))
InternalChange(idArray[i], null, null, null, reasonArray[i], amountArray[i], gamble, uow);
}
await uow.SaveChangesAsync();
} }
await uow.SaveChangesAsync();
} }
public async Task RemoveBulkAsync(IEnumerable<ulong> userIds, IEnumerable<string> reasons, IEnumerable<long> amounts, bool gamble = false) public async Task RemoveBulkAsync(IEnumerable<ulong> userIds, IEnumerable<string> reasons, IEnumerable<long> amounts, bool gamble = false)
@@ -120,16 +116,14 @@ public class CurrencyService : ICurrencyService, INService
throw new ArgumentException("Cannot perform bulk operation. Arrays are not of equal length."); throw new ArgumentException("Cannot perform bulk operation. Arrays are not of equal length.");
var userIdHashSet = new HashSet<ulong>(idArray.Length); var userIdHashSet = new HashSet<ulong>(idArray.Length);
await using (var uow = _db.GetDbContext()) await using var uow = _db.GetDbContext();
for (var i = 0; i < idArray.Length; i++)
{ {
for (var i = 0; i < idArray.Length; i++) // i have to prevent same user changing more than once as it will cause db error
{ if (userIdHashSet.Add(idArray[i]))
// i have to prevent same user changing more than once as it will cause db error InternalChange(idArray[i], null, null, null, reasonArray[i], -amountArray[i], gamble, uow);
if (userIdHashSet.Add(idArray[i]))
InternalChange(idArray[i], null, null, null, reasonArray[i], -amountArray[i], gamble, uow);
}
await uow.SaveChangesAsync();
} }
await uow.SaveChangesAsync();
} }
private async Task<bool> InternalRemoveAsync(ulong userId, string userName, string userDiscrim, string avatar, string reason, long amount, bool gamble = false) private async Task<bool> InternalRemoveAsync(ulong userId, string userName, string userDiscrim, string avatar, string reason, long amount, bool gamble = false)
@@ -140,11 +134,9 @@ public class CurrencyService : ICurrencyService, INService
} }
bool result; bool result;
await using (var uow = _db.GetDbContext()) await using var uow = _db.GetDbContext();
{ result = InternalChange(userId, userName, userDiscrim, avatar, reason, -amount, gamble, uow);
result = InternalChange(userId, userName, userDiscrim, avatar, reason, -amount, gamble, uow); await uow.SaveChangesAsync();
await uow.SaveChangesAsync();
}
return result; return result;
} }

View File

@@ -66,12 +66,10 @@ public class Localization : ILocalization, INService
if (GuildCultureInfos.TryRemove(guildId, out var _)) if (GuildCultureInfos.TryRemove(guildId, out var _))
{ {
using (var uow = _db.GetDbContext()) using var uow = _db.GetDbContext();
{ var gc = uow.GuildConfigsForId(guildId, set => set);
var gc = uow.GuildConfigsForId(guildId, set => set); gc.Locale = null;
gc.Locale = null; uow.SaveChanges();
uow.SaveChanges();
}
} }
} }

View File

@@ -120,22 +120,18 @@ public class StatsService : IStatsService, IReadyExecutor, INService, IDisposabl
return; return;
try try
{ {
using (var http = _httpFactory.CreateClient()) using var http = _httpFactory.CreateClient();
{ using var content = new FormUrlEncodedContent(
using (var content = new FormUrlEncodedContent( new Dictionary<string, string> {
new Dictionary<string, string> { { "shard_count", _creds.TotalShards.ToString()},
{ "shard_count", _creds.TotalShards.ToString()}, { "shard_id", client.ShardId.ToString() },
{ "shard_id", client.ShardId.ToString() }, { "server_count", client.Guilds.Count().ToString() }
{ "server_count", client.Guilds.Count().ToString() } });
})) content.Headers.Clear();
{ content.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
content.Headers.Clear(); http.DefaultRequestHeaders.Add("Authorization", _creds.BotListToken);
content.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
http.DefaultRequestHeaders.Add("Authorization", _creds.BotListToken);
using (await http.PostAsync(new Uri($"https://discordbots.org/api/bots/{client.CurrentUser.Id}/stats"), content).ConfigureAwait(false)) { } using (await http.PostAsync(new Uri($"https://discordbots.org/api/bots/{client.CurrentUser.Id}/stats"), content).ConfigureAwait(false)) { }
}
}
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@@ -1,4 +1,5 @@
using NadekoBot.Db.Models; using Discord;
using NadekoBot.Db.Models;
namespace NadekoBot.Extensions; namespace NadekoBot.Extensions;
@@ -55,14 +56,12 @@ public static class IUserExtensions
public static async Task<IUserMessage> SendFileAsync(this IUser user, string filePath, string caption = null, string text = null, bool isTTS = false) public static async Task<IUserMessage> SendFileAsync(this IUser user, string filePath, string caption = null, string text = null, bool isTTS = false)
{ {
await using (var file = File.Open(filePath, FileMode.Open)) await using var file = File.Open(filePath, FileMode.Open);
{ return await UserExtensions.SendFileAsync(user, file, caption ?? "x", text, isTTS).ConfigureAwait(false);
return await user.SendFileAsync(file, caption ?? "x", text, isTTS).ConfigureAwait(false);
}
} }
public static async Task<IUserMessage> SendFileAsync(this IUser user, Stream fileStream, string fileName, string caption = null, bool isTTS = false) => public static async Task<IUserMessage> SendFileAsync(this IUser user, Stream fileStream, string fileName, string caption = null, bool isTTS = false) =>
await user.SendFileAsync(fileStream, fileName, caption, isTTS).ConfigureAwait(false); await UserExtensions.SendFileAsync(user, fileStream, fileName, caption, isTTS).ConfigureAwait(false);
// This method is used by everything that fetches the avatar from a user // This method is used by everything that fetches the avatar from a user
public static Uri RealAvatarUrl(this IUser usr, ushort size = 128) public static Uri RealAvatarUrl(this IUser usr, ushort size = 128)

View File

@@ -49,22 +49,20 @@ public static class ProcessExtensions
if (exitCode == 0 && !string.IsNullOrEmpty(stdout)) if (exitCode == 0 && !string.IsNullOrEmpty(stdout))
{ {
using (var reader = new StringReader(stdout)) using var reader = new StringReader(stdout);
while (true)
{ {
while (true) var text = reader.ReadLine();
if (text is null)
{ {
var text = reader.ReadLine(); return;
if (text is null) }
{
return;
}
if (int.TryParse(text, out var id)) if (int.TryParse(text, out var id))
{ {
children.Add(id); children.Add(id);
// Recursively get the children // Recursively get the children
GetAllChildIdsUnix(id, children, timeout); GetAllChildIdsUnix(id, children, timeout);
}
} }
} }
} }