mirror of
https://gitlab.com/Kwoth/nadekobot.git
synced 2025-09-13 18:58:27 -04:00
Added many more braces for multiline if's, Improved .crypto command quite a bit and applied locale-specific format
This commit is contained in:
@@ -349,7 +349,7 @@ resharper_csharp_place_type_constraints_on_same_line = false
|
|||||||
resharper_csharp_wrap_before_extends_colon = true
|
resharper_csharp_wrap_before_extends_colon = true
|
||||||
resharper_csharp_place_constructor_initializer_on_same_line = false
|
resharper_csharp_place_constructor_initializer_on_same_line = false
|
||||||
resharper_force_attribute_style = separate
|
resharper_force_attribute_style = separate
|
||||||
resharper_csharp_braces_for_ifelse = required_for_complex
|
resharper_csharp_braces_for_ifelse = required_for_multiline_statement
|
||||||
resharper_csharp_braces_for_foreach = required_for_multiline
|
resharper_csharp_braces_for_foreach = required_for_multiline
|
||||||
resharper_csharp_braces_for_while = required_for_multiline
|
resharper_csharp_braces_for_while = required_for_multiline
|
||||||
resharper_csharp_braces_for_for = required_for_multiline
|
resharper_csharp_braces_for_for = required_for_multiline
|
||||||
|
@@ -123,9 +123,11 @@ public sealed class Bot
|
|||||||
if (Environment.GetEnvironmentVariable("NADEKOBOT_IS_COORDINATED") != "1")
|
if (Environment.GetEnvironmentVariable("NADEKOBOT_IS_COORDINATED") != "1")
|
||||||
svcs.AddSingleton<ICoordinator, SingleProcessCoordinator>();
|
svcs.AddSingleton<ICoordinator, SingleProcessCoordinator>();
|
||||||
else
|
else
|
||||||
|
{
|
||||||
svcs.AddSingleton<RemoteGrpcCoordinator>()
|
svcs.AddSingleton<RemoteGrpcCoordinator>()
|
||||||
.AddSingleton<ICoordinator>(x => x.GetRequiredService<RemoteGrpcCoordinator>())
|
.AddSingleton<ICoordinator>(x => x.GetRequiredService<RemoteGrpcCoordinator>())
|
||||||
.AddSingleton<IReadyExecutor>(x => x.GetRequiredService<RemoteGrpcCoordinator>());
|
.AddSingleton<IReadyExecutor>(x => x.GetRequiredService<RemoteGrpcCoordinator>());
|
||||||
|
}
|
||||||
|
|
||||||
svcs.AddSingleton<RedisLocalDataCache>()
|
svcs.AddSingleton<RedisLocalDataCache>()
|
||||||
.AddSingleton<ILocalDataCache>(x => x.GetRequiredService<RedisLocalDataCache>())
|
.AddSingleton<ILocalDataCache>(x => x.GetRequiredService<RedisLocalDataCache>())
|
||||||
|
@@ -385,8 +385,10 @@ public sealed class ConcurrentHashSet<T> : IReadOnlyCollection<T>, ICollection<T
|
|||||||
count += tables.CountPerLock[i];
|
count += tables.CountPerLock[i];
|
||||||
|
|
||||||
if (array.Length - count < arrayIndex || count < 0) //"count" itself or "count + arrayIndex" can overflow
|
if (array.Length - count < arrayIndex || count < 0) //"count" itself or "count + arrayIndex" can overflow
|
||||||
|
{
|
||||||
throw new ArgumentException(
|
throw new ArgumentException(
|
||||||
"The index is equal to or greater than the length of the array, or the number of elements in the set is greater than the available space from index to the end of the destination array.");
|
"The index is equal to or greater than the length of the array, or the number of elements in the set is greater than the available space from index to the end of the destination array.");
|
||||||
|
}
|
||||||
|
|
||||||
CopyToItems(array, arrayIndex);
|
CopyToItems(array, arrayIndex);
|
||||||
}
|
}
|
||||||
|
@@ -53,6 +53,7 @@ public class EventPubSub : IPubSub
|
|||||||
// get subscriptions which have the same action hash code
|
// get subscriptions which have the same action hash code
|
||||||
// note: having this as a list allows for multiple subscriptions of
|
// note: having this as a list allows for multiple subscriptions of
|
||||||
// the same insance's/static method
|
// the same insance's/static method
|
||||||
|
{
|
||||||
if (actions.TryGetValue(action, out var sameActions))
|
if (actions.TryGetValue(action, out var sameActions))
|
||||||
{
|
{
|
||||||
// remove last subscription
|
// remove last subscription
|
||||||
@@ -71,6 +72,7 @@ public class EventPubSub : IPubSub
|
|||||||
_actions.Remove(key.Key);
|
_actions.Remove(key.Key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
@@ -36,9 +36,11 @@ public sealed class RedisPubSub : IPubSub
|
|||||||
if (dataObj is not null)
|
if (dataObj is not null)
|
||||||
await action(dataObj);
|
await action(dataObj);
|
||||||
else
|
else
|
||||||
|
{
|
||||||
Log.Warning("Publishing event {EventName} with a null value. This is not allowed",
|
Log.Warning("Publishing event {EventName} with a null value. This is not allowed",
|
||||||
eventName);
|
eventName);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error("Error handling the event {EventName}: {ErrorMessage}", eventName, ex.Message);
|
Log.Error("Error handling the event {EventName}: {ErrorMessage}", eventName, ex.Message);
|
||||||
|
@@ -63,8 +63,10 @@ public class ReplacementBuilder
|
|||||||
{
|
{
|
||||||
var to = TimeZoneInfo.Local;
|
var to = TimeZoneInfo.Local;
|
||||||
if (g is not null)
|
if (g is not null)
|
||||||
|
{
|
||||||
if (GuildTimezoneService.AllServices.TryGetValue(client.CurrentUser.Id, out var tz))
|
if (GuildTimezoneService.AllServices.TryGetValue(client.CurrentUser.Id, out var tz))
|
||||||
to = tz.GetTimeZoneOrDefault(g.Id) ?? TimeZoneInfo.Local;
|
to = tz.GetTimeZoneOrDefault(g.Id) ?? TimeZoneInfo.Local;
|
||||||
|
}
|
||||||
|
|
||||||
return TimeZoneInfo.ConvertTime(DateTime.UtcNow, TimeZoneInfo.Utc, to).ToString("HH:mm ")
|
return TimeZoneInfo.ConvertTime(DateTime.UtcNow, TimeZoneInfo.Utc, to).ToString("HH:mm ")
|
||||||
+ to.StandardName.GetInitials();
|
+ to.StandardName.GetInitials();
|
||||||
|
@@ -54,11 +54,13 @@ public class Replacer
|
|||||||
Url = Replace(embedData.Url)
|
Url = Replace(embedData.Url)
|
||||||
};
|
};
|
||||||
if (embedData.Author is not null)
|
if (embedData.Author is not null)
|
||||||
|
{
|
||||||
newEmbedData.Author = new()
|
newEmbedData.Author = new()
|
||||||
{
|
{
|
||||||
Name = Replace(embedData.Author.Name),
|
Name = Replace(embedData.Author.Name),
|
||||||
IconUrl = Replace(embedData.Author.IconUrl)
|
IconUrl = Replace(embedData.Author.IconUrl)
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if (embedData.Fields is not null)
|
if (embedData.Fields is not null)
|
||||||
{
|
{
|
||||||
@@ -78,11 +80,13 @@ public class Replacer
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (embedData.Footer is not null)
|
if (embedData.Footer is not null)
|
||||||
|
{
|
||||||
newEmbedData.Footer = new()
|
newEmbedData.Footer = new()
|
||||||
{
|
{
|
||||||
Text = Replace(embedData.Footer.Text),
|
Text = Replace(embedData.Footer.Text),
|
||||||
IconUrl = Replace(embedData.Footer.IconUrl)
|
IconUrl = Replace(embedData.Footer.IconUrl)
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
newEmbedData.Color = embedData.Color;
|
newEmbedData.Color = embedData.Color;
|
||||||
|
|
||||||
|
@@ -54,6 +54,7 @@ public sealed record SmartEmbedText : SmartText
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (eb.Fields.Length > 0)
|
if (eb.Fields.Length > 0)
|
||||||
|
{
|
||||||
set.Fields = eb.Fields.Select(field
|
set.Fields = eb.Fields.Select(field
|
||||||
=> new SmartTextEmbedField
|
=> new SmartTextEmbedField
|
||||||
{
|
{
|
||||||
@@ -62,6 +63,7 @@ public sealed record SmartEmbedText : SmartText
|
|||||||
Value = field.Value
|
Value = field.Value
|
||||||
})
|
})
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
set.Color = eb.Color?.RawValue ?? 0;
|
set.Color = eb.Color?.RawValue ?? 0;
|
||||||
return set;
|
return set;
|
||||||
@@ -81,12 +83,14 @@ public sealed record SmartEmbedText : SmartText
|
|||||||
embed.WithUrl(Url);
|
embed.WithUrl(Url);
|
||||||
|
|
||||||
if (Footer is not null)
|
if (Footer is not null)
|
||||||
|
{
|
||||||
embed.WithFooter(efb =>
|
embed.WithFooter(efb =>
|
||||||
{
|
{
|
||||||
efb.WithText(Footer.Text);
|
efb.WithText(Footer.Text);
|
||||||
if (Uri.IsWellFormedUriString(Footer.IconUrl, UriKind.Absolute))
|
if (Uri.IsWellFormedUriString(Footer.IconUrl, UriKind.Absolute))
|
||||||
efb.WithIconUrl(Footer.IconUrl);
|
efb.WithIconUrl(Footer.IconUrl);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (Thumbnail is not null && Uri.IsWellFormedUriString(Thumbnail, UriKind.Absolute))
|
if (Thumbnail is not null && Uri.IsWellFormedUriString(Thumbnail, UriKind.Absolute))
|
||||||
embed.WithThumbnailUrl(Thumbnail);
|
embed.WithThumbnailUrl(Thumbnail);
|
||||||
@@ -105,11 +109,13 @@ public sealed record SmartEmbedText : SmartText
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (Fields is not null)
|
if (Fields is not null)
|
||||||
|
{
|
||||||
foreach (var f in Fields)
|
foreach (var f in Fields)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrWhiteSpace(f.Name) && !string.IsNullOrWhiteSpace(f.Value))
|
if (!string.IsNullOrWhiteSpace(f.Name) && !string.IsNullOrWhiteSpace(f.Value))
|
||||||
embed.AddField(f.Name, f.Value, f.Inline);
|
embed.AddField(f.Name, f.Value, f.Inline);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return embed;
|
return embed;
|
||||||
}
|
}
|
||||||
@@ -117,10 +123,12 @@ public sealed record SmartEmbedText : SmartText
|
|||||||
public void NormalizeFields()
|
public void NormalizeFields()
|
||||||
{
|
{
|
||||||
if (Fields is { Length: > 0 })
|
if (Fields is { Length: > 0 })
|
||||||
|
{
|
||||||
foreach (var f in Fields)
|
foreach (var f in Fields)
|
||||||
{
|
{
|
||||||
f.Name = f.Name.TrimTo(256);
|
f.Name = f.Name.TrimTo(256);
|
||||||
f.Value = f.Value.TrimTo(1024);
|
f.Value = f.Value.TrimTo(1024);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@@ -53,8 +53,10 @@ public sealed class CommandOrCrTypeReader : NadekoTypeReader<CommandOrCrInfo>
|
|||||||
|
|
||||||
var cmd = await new CommandTypeReader(_commandHandler, _cmds).ReadAsync(ctx, input);
|
var cmd = await new CommandTypeReader(_commandHandler, _cmds).ReadAsync(ctx, input);
|
||||||
if (cmd.IsSuccess)
|
if (cmd.IsSuccess)
|
||||||
|
{
|
||||||
return TypeReaderResult.FromSuccess(new CommandOrCrInfo(((CommandInfo)cmd.Values.First().Value).Name,
|
return TypeReaderResult.FromSuccess(new CommandOrCrInfo(((CommandInfo)cmd.Values.First().Value).Name,
|
||||||
CommandOrCrInfo.Type.Normal));
|
CommandOrCrInfo.Type.Normal));
|
||||||
|
}
|
||||||
|
|
||||||
return TypeReaderResult.FromError<CommandOrCrInfo>(CommandError.ParseFailed, "No such command or cr found.");
|
return TypeReaderResult.FromError<CommandOrCrInfo>(CommandError.ParseFailed, "No such command or cr found.");
|
||||||
}
|
}
|
||||||
|
@@ -14,8 +14,10 @@ public sealed class GuildDateTimeTypeReader : NadekoTypeReader<GuildDateTime>
|
|||||||
{
|
{
|
||||||
var gdt = Parse(context.Guild.Id, input);
|
var gdt = Parse(context.Guild.Id, input);
|
||||||
if (gdt is null)
|
if (gdt is null)
|
||||||
|
{
|
||||||
return new(TypeReaderResult.FromError<GuildDateTime>(CommandError.ParseFailed,
|
return new(TypeReaderResult.FromError<GuildDateTime>(CommandError.ParseFailed,
|
||||||
"Input string is in an incorrect format."));
|
"Input string is in an incorrect format."));
|
||||||
|
}
|
||||||
|
|
||||||
return new(TypeReaderResult.FromSuccess(gdt));
|
return new(TypeReaderResult.FromSuccess(gdt));
|
||||||
}
|
}
|
||||||
|
@@ -21,10 +21,8 @@ public class CommentsObjectGraphVisitor : ChainedObjectGraphVisitor
|
|||||||
var parts = commentsDescriptor.Comment.Split('\n');
|
var parts = commentsDescriptor.Comment.Split('\n');
|
||||||
|
|
||||||
foreach (var part in parts)
|
foreach (var part in parts)
|
||||||
{
|
|
||||||
context.Emit(new Comment(part.Trim(), false));
|
context.Emit(new Comment(part.Trim(), false));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return base.EnterMapping(key, value, context);
|
return base.EnterMapping(key, value, context);
|
||||||
}
|
}
|
||||||
|
@@ -21,12 +21,14 @@ public class MultilineScalarFlowStyleEmitter : ChainedEventEmitter
|
|||||||
{
|
{
|
||||||
var isMultiLine = value.IndexOfAny(new[] { '\r', '\n', '\x85', '\x2028', '\x2029' }) >= 0;
|
var isMultiLine = value.IndexOfAny(new[] { '\r', '\n', '\x85', '\x2028', '\x2029' }) >= 0;
|
||||||
if (isMultiLine)
|
if (isMultiLine)
|
||||||
|
{
|
||||||
eventInfo = new(eventInfo.Source)
|
eventInfo = new(eventInfo.Source)
|
||||||
{
|
{
|
||||||
Style = ScalarStyle.Literal
|
Style = ScalarStyle.Literal
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
nextEmitter.Emit(eventInfo, emitter);
|
nextEmitter.Emit(eventInfo, emitter);
|
||||||
}
|
}
|
||||||
|
@@ -127,6 +127,7 @@ WHERE UserId={userId};");
|
|||||||
|
|
||||||
// just update the amount, there is no new user data
|
// just update the amount, there is no new user data
|
||||||
if (!updatedUserData)
|
if (!updatedUserData)
|
||||||
|
{
|
||||||
ctx.Database.ExecuteSqlInterpolated($@"
|
ctx.Database.ExecuteSqlInterpolated($@"
|
||||||
UPDATE OR IGNORE DiscordUser
|
UPDATE OR IGNORE DiscordUser
|
||||||
SET CurrencyAmount=CurrencyAmount+{amount}
|
SET CurrencyAmount=CurrencyAmount+{amount}
|
||||||
@@ -135,7 +136,9 @@ WHERE UserId={userId};
|
|||||||
INSERT OR IGNORE INTO DiscordUser (UserId, Username, Discriminator, AvatarId, CurrencyAmount, TotalXp)
|
INSERT OR IGNORE INTO DiscordUser (UserId, Username, Discriminator, AvatarId, CurrencyAmount, TotalXp)
|
||||||
VALUES ({userId}, {name}, {discrim}, {avatarId}, {amount}, 0);
|
VALUES ({userId}, {name}, {discrim}, {avatarId}, {amount}, 0);
|
||||||
");
|
");
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
ctx.Database.ExecuteSqlInterpolated($@"
|
ctx.Database.ExecuteSqlInterpolated($@"
|
||||||
UPDATE OR IGNORE DiscordUser
|
UPDATE OR IGNORE DiscordUser
|
||||||
SET CurrencyAmount=CurrencyAmount+{amount},
|
SET CurrencyAmount=CurrencyAmount+{amount},
|
||||||
@@ -147,6 +150,7 @@ WHERE UserId={userId};
|
|||||||
INSERT OR IGNORE INTO DiscordUser (UserId, Username, Discriminator, AvatarId, CurrencyAmount, TotalXp)
|
INSERT OR IGNORE INTO DiscordUser (UserId, Username, Discriminator, AvatarId, CurrencyAmount, TotalXp)
|
||||||
VALUES ({userId}, {name}, {discrim}, {avatarId}, {amount}, 0);
|
VALUES ({userId}, {name}, {discrim}, {avatarId}, {amount}, 0);
|
||||||
");
|
");
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@@ -74,9 +74,7 @@ public static class GuildConfigExtensions
|
|||||||
GuildConfig config;
|
GuildConfig config;
|
||||||
|
|
||||||
if (includes is null)
|
if (includes is null)
|
||||||
{
|
|
||||||
config = ctx.GuildConfigs.IncludeEverything().FirstOrDefault(c => c.GuildId == guildId);
|
config = ctx.GuildConfigs.IncludeEverything().FirstOrDefault(c => c.GuildId == guildId);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var set = includes(ctx.GuildConfigs);
|
var set = includes(ctx.GuildConfigs);
|
||||||
|
@@ -13,6 +13,7 @@ public static class UserXpExtensions
|
|||||||
var usr = ctx.UserXpStats.FirstOrDefault(x => x.UserId == userId && x.GuildId == guildId);
|
var usr = ctx.UserXpStats.FirstOrDefault(x => x.UserId == userId && x.GuildId == guildId);
|
||||||
|
|
||||||
if (usr is null)
|
if (usr is null)
|
||||||
|
{
|
||||||
ctx.Add(usr = new()
|
ctx.Add(usr = new()
|
||||||
{
|
{
|
||||||
Xp = 0,
|
Xp = 0,
|
||||||
@@ -20,6 +21,7 @@ public static class UserXpExtensions
|
|||||||
NotifyOnLevelUp = XpNotificationLocation.None,
|
NotifyOnLevelUp = XpNotificationLocation.None,
|
||||||
GuildId = guildId
|
GuildId = guildId
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return usr;
|
return usr;
|
||||||
}
|
}
|
||||||
@@ -42,12 +44,6 @@ public static class UserXpExtensions
|
|||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
public static int GetUserGuildRanking(this DbSet<UserXpStats> xps, ulong userId, ulong guildId)
|
public static int GetUserGuildRanking(this DbSet<UserXpStats> xps, ulong userId, ulong guildId)
|
||||||
// @"SELECT COUNT(*) + 1
|
|
||||||
//FROM UserXpStats
|
|
||||||
//WHERE GuildId = @p1 AND ((Xp + AwardedXp) > (SELECT Xp + AwardedXp
|
|
||||||
// FROM UserXpStats
|
|
||||||
// WHERE UserId = @p2 AND GuildId = @p1
|
|
||||||
// LIMIT 1));";
|
|
||||||
=> xps.AsQueryable()
|
=> xps.AsQueryable()
|
||||||
.AsNoTracking()
|
.AsNoTracking()
|
||||||
.Where(x => x.GuildId == guildId
|
.Where(x => x.GuildId == guildId
|
||||||
|
@@ -28,11 +28,13 @@ public static class WaifuExtensions
|
|||||||
Func<DbSet<WaifuInfo>, IQueryable<WaifuInfo>> includes = null)
|
Func<DbSet<WaifuInfo>, IQueryable<WaifuInfo>> includes = null)
|
||||||
{
|
{
|
||||||
if (includes is null)
|
if (includes is null)
|
||||||
|
{
|
||||||
return waifus.Include(wi => wi.Waifu)
|
return waifus.Include(wi => wi.Waifu)
|
||||||
.Include(wi => wi.Affinity)
|
.Include(wi => wi.Affinity)
|
||||||
.Include(wi => wi.Claimer)
|
.Include(wi => wi.Claimer)
|
||||||
.Include(wi => wi.Items)
|
.Include(wi => wi.Items)
|
||||||
.FirstOrDefault(wi => wi.Waifu.UserId == userId);
|
.FirstOrDefault(wi => wi.Waifu.UserId == userId);
|
||||||
|
}
|
||||||
|
|
||||||
return includes(waifus).AsQueryable().FirstOrDefault(wi => wi.Waifu.UserId == userId);
|
return includes(waifus).AsQueryable().FirstOrDefault(wi => wi.Waifu.UserId == userId);
|
||||||
}
|
}
|
||||||
|
@@ -32,8 +32,11 @@ public class WaifuInfo : DbEntity
|
|||||||
else if (AffinityId == ClaimerId)
|
else if (AffinityId == ClaimerId)
|
||||||
status = $"... and {waifuUsername} likes {claimerUsername} too <3";
|
status = $"... and {waifuUsername} likes {claimerUsername} too <3";
|
||||||
else
|
else
|
||||||
|
{
|
||||||
status =
|
status =
|
||||||
$"... but {waifuUsername}'s heart belongs to {Affinity.Username.TrimTo(20)}#{Affinity.Discriminator}";
|
$"... but {waifuUsername}'s heart belongs to {Affinity.Username.TrimTo(20)}#{Affinity.Discriminator}";
|
||||||
|
}
|
||||||
|
|
||||||
return $"**{waifuUsername}#{Waifu.Discriminator}** - claimed by **{claimer}**\n\t{status}";
|
return $"**{waifuUsername}#{Waifu.Discriminator}** - claimed by **{claimer}**\n\t{status}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -314,9 +314,7 @@ public partial class Administration : NadekoModule<AdministrationService>
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (time is null)
|
if (time is null)
|
||||||
{
|
|
||||||
await msg.DeleteAsync();
|
await msg.DeleteAsync();
|
||||||
}
|
|
||||||
else if (time.Time <= TimeSpan.FromDays(7))
|
else if (time.Time <= TimeSpan.FromDays(7))
|
||||||
{
|
{
|
||||||
_ = Task.Run(async () =>
|
_ = Task.Run(async () =>
|
||||||
|
@@ -115,14 +115,10 @@ public class AdministrationService : INService
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
else if (newState == Administration.State.Enable)
|
else if (newState == Administration.State.Enable)
|
||||||
{
|
|
||||||
DeleteMessagesOnCommandChannels[chId] = true;
|
DeleteMessagesOnCommandChannels[chId] = true;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
DeleteMessagesOnCommandChannels.TryRemove(chId, out _);
|
DeleteMessagesOnCommandChannels.TryRemove(chId, out _);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public async Task DeafenUsers(bool value, params IGuildUser[] users)
|
public async Task DeafenUsers(bool value, params IGuildUser[] users)
|
||||||
{
|
{
|
||||||
|
@@ -25,9 +25,7 @@ public partial class Administration
|
|||||||
var id = _service.ToggleGameVoiceChannel(ctx.Guild.Id, vch.Id);
|
var id = _service.ToggleGameVoiceChannel(ctx.Guild.Id, vch.Id);
|
||||||
|
|
||||||
if (id is null)
|
if (id is null)
|
||||||
{
|
|
||||||
await ReplyConfirmLocalizedAsync(strs.gvc_disabled);
|
await ReplyConfirmLocalizedAsync(strs.gvc_disabled);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_service.GameVoiceChannels.Add(vch.Id);
|
_service.GameVoiceChannels.Add(vch.Id);
|
||||||
|
@@ -42,10 +42,12 @@ public class GameVoiceChannelService : INService
|
|||||||
{
|
{
|
||||||
if (activity is { Type: ActivityType.Playing })
|
if (activity is { Type: ActivityType.Playing })
|
||||||
//trigger gvc
|
//trigger gvc
|
||||||
|
{
|
||||||
if (await TriggerGvc(newUser, activity.Name))
|
if (await TriggerGvc(newUser, activity.Name))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Warning(ex, "Error running GuildMemberUpdated in gvc");
|
Log.Warning(ex, "Error running GuildMemberUpdated in gvc");
|
||||||
|
@@ -141,10 +141,8 @@ public class GreetService : INService, IReadyExecutor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
await ByeUsers(conf, channel, new[] { user });
|
await ByeUsers(conf, channel, new[] { user });
|
||||||
}
|
}
|
||||||
}
|
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
// ignored
|
// ignored
|
||||||
@@ -255,10 +253,12 @@ public class GreetService : INService, IReadyExecutor
|
|||||||
text = rep.Replace(text);
|
text = rep.Replace(text);
|
||||||
|
|
||||||
if (text is SmartPlainText pt)
|
if (text is SmartPlainText pt)
|
||||||
|
{
|
||||||
text = new SmartEmbedText()
|
text = new SmartEmbedText()
|
||||||
{
|
{
|
||||||
PlainText = pt.Text
|
PlainText = pt.Text
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
((SmartEmbedText)text).Footer = new()
|
((SmartEmbedText)text).Footer = new()
|
||||||
{
|
{
|
||||||
@@ -308,11 +308,9 @@ public class GreetService : INService, IReadyExecutor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
await GreetUsers(conf, channel, new[] { user });
|
await GreetUsers(conf, channel, new[] { user });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (conf.SendDmGreetMessage)
|
if (conf.SendDmGreetMessage)
|
||||||
await GreetDmUser(conf, user);
|
await GreetDmUser(conf, user);
|
||||||
|
@@ -75,9 +75,7 @@ public sealed class ImageOnlyChannelService : IEarlyBehavior
|
|||||||
var newState = false;
|
var newState = false;
|
||||||
using var uow = _db.GetDbContext();
|
using var uow = _db.GetDbContext();
|
||||||
if (forceDisable || (_enabledOn.TryGetValue(guildId, out var channels) && channels.TryRemove(channelId)))
|
if (forceDisable || (_enabledOn.TryGetValue(guildId, out var channels) && channels.TryRemove(channelId)))
|
||||||
{
|
|
||||||
uow.ImageOnlyChannels.Delete(x => x.ChannelId == channelId);
|
uow.ImageOnlyChannels.Delete(x => x.ChannelId == channelId);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
uow.ImageOnlyChannels.Add(new()
|
uow.ImageOnlyChannels.Add(new()
|
||||||
|
@@ -66,9 +66,7 @@ public class MuteService : INService
|
|||||||
{
|
{
|
||||||
TimeSpan after;
|
TimeSpan after;
|
||||||
if (x.UnmuteAt - TimeSpan.FromMinutes(2) <= DateTime.UtcNow)
|
if (x.UnmuteAt - TimeSpan.FromMinutes(2) <= DateTime.UtcNow)
|
||||||
{
|
|
||||||
after = TimeSpan.FromMinutes(2);
|
after = TimeSpan.FromMinutes(2);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var unmute = x.UnmuteAt - DateTime.UtcNow;
|
var unmute = x.UnmuteAt - DateTime.UtcNow;
|
||||||
@@ -82,9 +80,7 @@ public class MuteService : INService
|
|||||||
{
|
{
|
||||||
TimeSpan after;
|
TimeSpan after;
|
||||||
if (x.UnbanAt - TimeSpan.FromMinutes(2) <= DateTime.UtcNow)
|
if (x.UnbanAt - TimeSpan.FromMinutes(2) <= DateTime.UtcNow)
|
||||||
{
|
|
||||||
after = TimeSpan.FromMinutes(2);
|
after = TimeSpan.FromMinutes(2);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var unban = x.UnbanAt - DateTime.UtcNow;
|
var unban = x.UnbanAt - DateTime.UtcNow;
|
||||||
@@ -98,9 +94,7 @@ public class MuteService : INService
|
|||||||
{
|
{
|
||||||
TimeSpan after;
|
TimeSpan after;
|
||||||
if (x.UnbanAt - TimeSpan.FromMinutes(2) <= DateTime.UtcNow)
|
if (x.UnbanAt - TimeSpan.FromMinutes(2) <= DateTime.UtcNow)
|
||||||
{
|
|
||||||
after = TimeSpan.FromMinutes(2);
|
after = TimeSpan.FromMinutes(2);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var unban = x.UnbanAt - DateTime.UtcNow;
|
var unban = x.UnbanAt - DateTime.UtcNow;
|
||||||
@@ -306,6 +300,7 @@ public class MuteService : INService
|
|||||||
var muteRole = guild.Roles.FirstOrDefault(r => r.Name == muteRoleName);
|
var muteRole = guild.Roles.FirstOrDefault(r => r.Name == muteRoleName);
|
||||||
if (muteRole is null)
|
if (muteRole is null)
|
||||||
//if it doesn't exist, create it
|
//if it doesn't exist, create it
|
||||||
|
{
|
||||||
try { muteRole = await guild.CreateRoleAsync(muteRoleName, isMentionable: false); }
|
try { muteRole = await guild.CreateRoleAsync(muteRoleName, isMentionable: false); }
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
@@ -313,6 +308,7 @@ public class MuteService : INService
|
|||||||
muteRole = guild.Roles.FirstOrDefault(r => r.Name == muteRoleName)
|
muteRole = guild.Roles.FirstOrDefault(r => r.Name == muteRoleName)
|
||||||
?? await guild.CreateRoleAsync(defaultMuteRoleName, isMentionable: false);
|
?? await guild.CreateRoleAsync(defaultMuteRoleName, isMentionable: false);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var toOverwrite in await guild.GetTextChannelsAsync())
|
foreach (var toOverwrite in await guild.GetTextChannelsAsync())
|
||||||
{
|
{
|
||||||
@@ -414,6 +410,7 @@ public class MuteService : INService
|
|||||||
var toAdd = new Timer(async _ =>
|
var toAdd = new Timer(async _ =>
|
||||||
{
|
{
|
||||||
if (type == TimerType.Ban)
|
if (type == TimerType.Ban)
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
RemoveTimerFromDb(guildId, userId, type);
|
RemoveTimerFromDb(guildId, userId, type);
|
||||||
@@ -426,7 +423,9 @@ public class MuteService : INService
|
|||||||
{
|
{
|
||||||
Log.Warning(ex, "Couldn't unban user {UserId} in guild {GuildId}", userId, guildId);
|
Log.Warning(ex, "Couldn't unban user {UserId} in guild {GuildId}", userId, guildId);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (type == TimerType.AddRole)
|
else if (type == TimerType.AddRole)
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (roleId is null)
|
if (roleId is null)
|
||||||
@@ -444,7 +443,9 @@ public class MuteService : INService
|
|||||||
{
|
{
|
||||||
Log.Warning(ex, "Couldn't remove role from user {UserId} in guild {GuildId}", userId, guildId);
|
Log.Warning(ex, "Couldn't remove role from user {UserId} in guild {GuildId}", userId, guildId);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// unmute the user, this will also remove the timer from the db
|
// unmute the user, this will also remove the timer from the db
|
||||||
@@ -455,6 +456,7 @@ public class MuteService : INService
|
|||||||
RemoveTimerFromDb(guildId, userId, type); // if unmute errored, just remove unmute from db
|
RemoveTimerFromDb(guildId, userId, type); // if unmute errored, just remove unmute from db
|
||||||
Log.Warning(ex, "Couldn't unmute user {UserId} in guild {GuildId}", userId, guildId);
|
Log.Warning(ex, "Couldn't unmute user {UserId} in guild {GuildId}", userId, guildId);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
null,
|
null,
|
||||||
after,
|
after,
|
||||||
|
@@ -67,8 +67,10 @@ public partial class Administration
|
|||||||
if (thisPageOverrides.Count == 0)
|
if (thisPageOverrides.Count == 0)
|
||||||
eb.WithDescription(GetText(strs.perm_override_page_none));
|
eb.WithDescription(GetText(strs.perm_override_page_none));
|
||||||
else
|
else
|
||||||
|
{
|
||||||
eb.WithDescription(thisPageOverrides.Select(ov => $"{ov.Command} => {ov.Perm.ToString()}")
|
eb.WithDescription(thisPageOverrides.Select(ov => $"{ov.Command} => {ov.Perm.ToString()}")
|
||||||
.Join("\n"));
|
.Join("\n"));
|
||||||
|
}
|
||||||
|
|
||||||
return eb;
|
return eb;
|
||||||
},
|
},
|
||||||
|
@@ -56,6 +56,7 @@ public class DiscordPermOverrideService : INService, ILateBlocker
|
|||||||
.FirstOrDefaultAsync(x => x.GuildId == guildId && commandName == x.Command);
|
.FirstOrDefaultAsync(x => x.GuildId == guildId && commandName == x.Command);
|
||||||
|
|
||||||
if (over is null)
|
if (over is null)
|
||||||
|
{
|
||||||
uow.Set<DiscordPermOverride>()
|
uow.Set<DiscordPermOverride>()
|
||||||
.Add(over = new()
|
.Add(over = new()
|
||||||
{
|
{
|
||||||
@@ -63,6 +64,7 @@ public class DiscordPermOverrideService : INService, ILateBlocker
|
|||||||
Perm = perm,
|
Perm = perm,
|
||||||
GuildId = guildId
|
GuildId = guildId
|
||||||
});
|
});
|
||||||
|
}
|
||||||
else
|
else
|
||||||
over.Perm = perm;
|
over.Perm = perm;
|
||||||
|
|
||||||
|
@@ -34,9 +34,7 @@ public partial class Administration
|
|||||||
var statuses = _service.GetRotatingStatuses();
|
var statuses = _service.GetRotatingStatuses();
|
||||||
|
|
||||||
if (!statuses.Any())
|
if (!statuses.Any())
|
||||||
{
|
|
||||||
await ReplyErrorLocalizedAsync(strs.ropl_not_set);
|
await ReplyErrorLocalizedAsync(strs.ropl_not_set);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var i = 1;
|
var i = 1;
|
||||||
|
@@ -114,8 +114,10 @@ public partial class Administration
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (punishTime is not null)
|
if (punishTime is not null)
|
||||||
|
{
|
||||||
if (!_service.IsDurationAllowed(action))
|
if (!_service.IsDurationAllowed(action))
|
||||||
await ReplyErrorLocalizedAsync(strs.prot_cant_use_time);
|
await ReplyErrorLocalizedAsync(strs.prot_cant_use_time);
|
||||||
|
}
|
||||||
|
|
||||||
var time = (int?)punishTime?.Time.TotalMinutes ?? 0;
|
var time = (int?)punishTime?.Time.TotalMinutes ?? 0;
|
||||||
if (time is < 0 or > 60 * 24)
|
if (time is < 0 or > 60 * 24)
|
||||||
@@ -176,8 +178,10 @@ public partial class Administration
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (timeData is not null)
|
if (timeData is not null)
|
||||||
|
{
|
||||||
if (!_service.IsDurationAllowed(action))
|
if (!_service.IsDurationAllowed(action))
|
||||||
await ReplyErrorLocalizedAsync(strs.prot_cant_use_time);
|
await ReplyErrorLocalizedAsync(strs.prot_cant_use_time);
|
||||||
|
}
|
||||||
|
|
||||||
var time = (int?)timeData?.Time.TotalMinutes ?? 0;
|
var time = (int?)timeData?.Time.TotalMinutes ?? 0;
|
||||||
if (time is < 0 or > 60 * 24)
|
if (time is < 0 or > 60 * 24)
|
||||||
|
@@ -136,10 +136,12 @@ public class ProtectionService : INService
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (spam is not null)
|
if (spam is not null)
|
||||||
|
{
|
||||||
_antiSpamGuilds[gc.GuildId] = new()
|
_antiSpamGuilds[gc.GuildId] = new()
|
||||||
{
|
{
|
||||||
AntiSpamSettings = spam
|
AntiSpamSettings = spam
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
var alt = gc.AntiAltSetting;
|
var alt = gc.AntiAltSetting;
|
||||||
if (alt is not null)
|
if (alt is not null)
|
||||||
@@ -160,6 +162,7 @@ public class ProtectionService : INService
|
|||||||
_ = Task.Run(async () =>
|
_ = Task.Run(async () =>
|
||||||
{
|
{
|
||||||
if (maybeAlts is { } alts)
|
if (maybeAlts is { } alts)
|
||||||
|
{
|
||||||
if (user.CreatedAt != default)
|
if (user.CreatedAt != default)
|
||||||
{
|
{
|
||||||
var diff = DateTime.UtcNow - user.CreatedAt.UtcDateTime;
|
var diff = DateTime.UtcNow - user.CreatedAt.UtcDateTime;
|
||||||
@@ -176,6 +179,7 @@ public class ProtectionService : INService
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -234,6 +238,7 @@ public class ProtectionService : INService
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (stats.Count >= spamSettings.AntiSpamSettings.MessageThreshold)
|
if (stats.Count >= spamSettings.AntiSpamSettings.MessageThreshold)
|
||||||
|
{
|
||||||
if (spamSettings.UserStats.TryRemove(msg.Author.Id, out stats))
|
if (spamSettings.UserStats.TryRemove(msg.Author.Id, out stats))
|
||||||
{
|
{
|
||||||
var settings = spamSettings.AntiSpamSettings;
|
var settings = spamSettings.AntiSpamSettings;
|
||||||
@@ -244,6 +249,7 @@ public class ProtectionService : INService
|
|||||||
(IGuildUser)msg.Author);
|
(IGuildUser)msg.Author);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
// ignored
|
// ignored
|
||||||
@@ -392,9 +398,7 @@ public class ProtectionService : INService
|
|||||||
gc.AntiSpamSetting.RoleId = stats.AntiSpamSettings.RoleId;
|
gc.AntiSpamSetting.RoleId = stats.AntiSpamSettings.RoleId;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
gc.AntiSpamSetting = stats.AntiSpamSettings;
|
gc.AntiSpamSetting = stats.AntiSpamSettings;
|
||||||
}
|
|
||||||
|
|
||||||
await uow.SaveChangesAsync();
|
await uow.SaveChangesAsync();
|
||||||
return stats;
|
return stats;
|
||||||
|
@@ -71,13 +71,17 @@ public partial class Administration
|
|||||||
count = 1000;
|
count = 1000;
|
||||||
|
|
||||||
if (parameter is "-s" or "--safe")
|
if (parameter is "-s" or "--safe")
|
||||||
|
{
|
||||||
await _service.PruneWhere((ITextChannel)ctx.Channel,
|
await _service.PruneWhere((ITextChannel)ctx.Channel,
|
||||||
count,
|
count,
|
||||||
m => m.Author.Id == userId && DateTime.UtcNow - m.CreatedAt < _twoWeeks && !m.IsPinned);
|
m => m.Author.Id == userId && DateTime.UtcNow - m.CreatedAt < _twoWeeks && !m.IsPinned);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
await _service.PruneWhere((ITextChannel)ctx.Channel,
|
await _service.PruneWhere((ITextChannel)ctx.Channel,
|
||||||
count,
|
count,
|
||||||
m => m.Author.Id == userId && DateTime.UtcNow - m.CreatedAt < _twoWeeks);
|
m => m.Author.Id == userId && DateTime.UtcNow - m.CreatedAt < _twoWeeks);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@@ -52,12 +52,14 @@ public class PruneService : INService
|
|||||||
//100 messages, Maybe this needs to be reduced by msgs.Length instead of 100
|
//100 messages, Maybe this needs to be reduced by msgs.Length instead of 100
|
||||||
amount -= 50;
|
amount -= 50;
|
||||||
if (amount > 0)
|
if (amount > 0)
|
||||||
|
{
|
||||||
msgs = (await channel.GetMessagesAsync(lastMessage, Direction.Before, 50).FlattenAsync())
|
msgs = (await channel.GetMessagesAsync(lastMessage, Direction.Before, 50).FlattenAsync())
|
||||||
.Where(predicate)
|
.Where(predicate)
|
||||||
.Take(amount)
|
.Take(amount)
|
||||||
.ToArray();
|
.ToArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
//ignore
|
//ignore
|
||||||
|
@@ -143,9 +143,7 @@ public partial class Administration
|
|||||||
{
|
{
|
||||||
var embed = _eb.Create().WithOkColor();
|
var embed = _eb.Create().WithOkColor();
|
||||||
if (!_service.Get(ctx.Guild.Id, out var rrs) || !rrs.Any())
|
if (!_service.Get(ctx.Guild.Id, out var rrs) || !rrs.Any())
|
||||||
{
|
|
||||||
embed.WithDescription(GetText(strs.no_reaction_roles));
|
embed.WithDescription(GetText(strs.no_reaction_roles));
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var g = (SocketGuild)ctx.Guild;
|
var g = (SocketGuild)ctx.Guild;
|
||||||
|
@@ -101,9 +101,7 @@ public partial class Administration
|
|||||||
var scmds = _service.GetStartupCommands().Skip(page * 5).Take(5).ToList();
|
var scmds = _service.GetStartupCommands().Skip(page * 5).Take(5).ToList();
|
||||||
|
|
||||||
if (scmds.Count == 0)
|
if (scmds.Count == 0)
|
||||||
{
|
|
||||||
await ReplyErrorLocalizedAsync(strs.startcmdlist_none);
|
await ReplyErrorLocalizedAsync(strs.startcmdlist_none);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var i = 0;
|
var i = 0;
|
||||||
@@ -128,9 +126,7 @@ public partial class Administration
|
|||||||
|
|
||||||
var scmds = _service.GetAutoCommands().Skip(page * 5).Take(5).ToList();
|
var scmds = _service.GetAutoCommands().Skip(page * 5).Take(5).ToList();
|
||||||
if (!scmds.Any())
|
if (!scmds.Any())
|
||||||
{
|
|
||||||
await ReplyErrorLocalizedAsync(strs.autocmdlist_none);
|
await ReplyErrorLocalizedAsync(strs.autocmdlist_none);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var i = 0;
|
var i = 0;
|
||||||
|
@@ -190,13 +190,17 @@ public sealed class SelfService : ILateExecutor, IReadyExecutor, INService
|
|||||||
.ToImmutableDictionary();
|
.ToImmutableDictionary();
|
||||||
|
|
||||||
if (!ownerChannels.Any())
|
if (!ownerChannels.Any())
|
||||||
|
{
|
||||||
Log.Warning(
|
Log.Warning(
|
||||||
"No owner channels created! Make sure you've specified the correct OwnerId in the creds.yml file and invited the bot to a Discord server");
|
"No owner channels created! Make sure you've specified the correct OwnerId in the creds.yml file and invited the bot to a Discord server");
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
Log.Information("Created {OwnerChannelCount} out of {TotalOwnerChannelCount} owner message channels",
|
Log.Information("Created {OwnerChannelCount} out of {TotalOwnerChannelCount} owner message channels",
|
||||||
ownerChannels.Count,
|
ownerChannels.Count,
|
||||||
_creds.OwnerIds.Count);
|
_creds.OwnerIds.Count);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Task LeaveGuild(string guildStr)
|
public Task LeaveGuild(string guildStr)
|
||||||
=> _pubSub.Pub(_guildLeaveKey, guildStr);
|
=> _pubSub.Pub(_guildLeaveKey, guildStr);
|
||||||
@@ -214,8 +218,10 @@ public sealed class SelfService : ILateExecutor, IReadyExecutor, INService
|
|||||||
var toSend = msg.Content;
|
var toSend = msg.Content;
|
||||||
|
|
||||||
if (msg.Attachments.Count > 0)
|
if (msg.Attachments.Count > 0)
|
||||||
|
{
|
||||||
toSend += $"\n\n{Format.Code(attachamentsTxt)}:\n"
|
toSend += $"\n\n{Format.Code(attachamentsTxt)}:\n"
|
||||||
+ string.Join("\n", msg.Attachments.Select(a => a.ProxyUrl));
|
+ string.Join("\n", msg.Attachments.Select(a => a.ProxyUrl));
|
||||||
|
}
|
||||||
|
|
||||||
if (bs.ForwardToAllOwners)
|
if (bs.ForwardToAllOwners)
|
||||||
{
|
{
|
||||||
@@ -237,6 +243,7 @@ public sealed class SelfService : ILateExecutor, IReadyExecutor, INService
|
|||||||
{
|
{
|
||||||
var firstOwnerChannel = ownerChannels.Values.First();
|
var firstOwnerChannel = ownerChannels.Values.First();
|
||||||
if (firstOwnerChannel.Recipient.Id != msg.Author.Id)
|
if (firstOwnerChannel.Recipient.Id != msg.Author.Id)
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await firstOwnerChannel.SendConfirmAsync(_eb, title, toSend);
|
await firstOwnerChannel.SendConfirmAsync(_eb, title, toSend);
|
||||||
@@ -248,6 +255,7 @@ public sealed class SelfService : ILateExecutor, IReadyExecutor, INService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public bool RemoveStartupCommand(int index, out AutoCommand cmd)
|
public bool RemoveStartupCommand(int index, out AutoCommand cmd)
|
||||||
{
|
{
|
||||||
@@ -273,8 +281,11 @@ public sealed class SelfService : ILateExecutor, IReadyExecutor, INService
|
|||||||
{
|
{
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
@@ -45,8 +45,10 @@ public partial class Administration
|
|||||||
var succ = _service.AddNew(ctx.Guild.Id, role, group);
|
var succ = _service.AddNew(ctx.Guild.Id, role, group);
|
||||||
|
|
||||||
if (succ)
|
if (succ)
|
||||||
|
{
|
||||||
await ReplyConfirmLocalizedAsync(strs.role_added(Format.Bold(role.Name),
|
await ReplyConfirmLocalizedAsync(strs.role_added(Format.Bold(role.Name),
|
||||||
Format.Bold(group.ToString())));
|
Format.Bold(@group.ToString())));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
await ReplyErrorLocalizedAsync(strs.role_in_list(Format.Bold(role.Name)));
|
await ReplyErrorLocalizedAsync(strs.role_in_list(Format.Bold(role.Name)));
|
||||||
}
|
}
|
||||||
@@ -61,8 +63,10 @@ public partial class Administration
|
|||||||
var set = await _service.SetNameAsync(ctx.Guild.Id, group, name);
|
var set = await _service.SetNameAsync(ctx.Guild.Id, group, name);
|
||||||
|
|
||||||
if (set)
|
if (set)
|
||||||
|
{
|
||||||
await ReplyConfirmLocalizedAsync(
|
await ReplyConfirmLocalizedAsync(
|
||||||
strs.group_name_added(Format.Bold(group.ToString()), Format.Bold(name)));
|
strs.group_name_added(Format.Bold(@group.ToString()), Format.Bold(name)));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
await ReplyConfirmLocalizedAsync(strs.group_name_removed(Format.Bold(group.ToString())));
|
await ReplyConfirmLocalizedAsync(strs.group_name_removed(Format.Bold(group.ToString())));
|
||||||
}
|
}
|
||||||
|
@@ -85,6 +85,7 @@ public class SelfAssignedRolesService : INService
|
|||||||
{
|
{
|
||||||
var sameRole = guildUser.Guild.GetRole(roleId);
|
var sameRole = guildUser.Guild.GetRole(roleId);
|
||||||
if (sameRole is not null)
|
if (sameRole is not null)
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await guildUser.RemoveRoleAsync(sameRole);
|
await guildUser.RemoveRoleAsync(sameRole);
|
||||||
@@ -96,6 +97,7 @@ public class SelfAssignedRolesService : INService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -192,9 +194,7 @@ public class SelfAssignedRolesService : INService
|
|||||||
uow.SaveChanges();
|
uow.SaveChanges();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@@ -89,10 +89,8 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||||||
{
|
{
|
||||||
using var timer = new PeriodicTimer(TimeSpan.FromHours(1));
|
using var timer = new PeriodicTimer(TimeSpan.FromHours(1));
|
||||||
while (await timer.WaitForNextTickAsync())
|
while (await timer.WaitForNextTickAsync())
|
||||||
{
|
|
||||||
_ignoreMessageIds.Clear();
|
_ignoreMessageIds.Clear();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private async Task PresenceUpdateTask()
|
private async Task PresenceUpdateTask()
|
||||||
{
|
{
|
||||||
@@ -234,9 +232,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||||||
embed.WithImageUrl(aav.ToString());
|
embed.WithImageUrl(aav.ToString());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
await logChannel.EmbedAsync(embed);
|
await logChannel.EmbedAsync(embed);
|
||||||
}
|
}
|
||||||
@@ -656,14 +652,18 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||||||
var afterTextChannel = cafter as ITextChannel;
|
var afterTextChannel = cafter as ITextChannel;
|
||||||
|
|
||||||
if (before.Name != after.Name)
|
if (before.Name != after.Name)
|
||||||
|
{
|
||||||
embed.WithTitle("ℹ️ " + GetText(logChannel.Guild, strs.ch_name_change))
|
embed.WithTitle("ℹ️ " + GetText(logChannel.Guild, strs.ch_name_change))
|
||||||
.WithDescription($"{after} | {after.Id}")
|
.WithDescription($"{after} | {after.Id}")
|
||||||
.AddField(GetText(logChannel.Guild, strs.ch_old_name), before.Name);
|
.AddField(GetText(logChannel.Guild, strs.ch_old_name), before.Name);
|
||||||
|
}
|
||||||
else if (beforeTextChannel?.Topic != afterTextChannel?.Topic)
|
else if (beforeTextChannel?.Topic != afterTextChannel?.Topic)
|
||||||
|
{
|
||||||
embed.WithTitle("ℹ️ " + GetText(logChannel.Guild, strs.ch_topic_change))
|
embed.WithTitle("ℹ️ " + GetText(logChannel.Guild, strs.ch_topic_change))
|
||||||
.WithDescription($"{after} | {after.Id}")
|
.WithDescription($"{after} | {after.Id}")
|
||||||
.AddField(GetText(logChannel.Guild, strs.old_topic), beforeTextChannel?.Topic ?? "-")
|
.AddField(GetText(logChannel.Guild, strs.old_topic), beforeTextChannel?.Topic ?? "-")
|
||||||
.AddField(GetText(logChannel.Guild, strs.new_topic), afterTextChannel?.Topic ?? "-");
|
.AddField(GetText(logChannel.Guild, strs.new_topic), afterTextChannel?.Topic ?? "-");
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -778,26 +778,33 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||||||
|
|
||||||
var str = string.Empty;
|
var str = string.Empty;
|
||||||
if (beforeVch?.Guild == afterVch?.Guild)
|
if (beforeVch?.Guild == afterVch?.Guild)
|
||||||
|
{
|
||||||
str = "🎙"
|
str = "🎙"
|
||||||
+ Format.Code(PrettyCurrentTime(usr.Guild))
|
+ Format.Code(PrettyCurrentTime(usr.Guild))
|
||||||
+ GetText(logChannel.Guild,
|
+ GetText(logChannel.Guild,
|
||||||
strs.user_vmoved("👤" + Format.Bold(usr.Username + "#" + usr.Discriminator),
|
strs.user_vmoved("👤" + Format.Bold(usr.Username + "#" + usr.Discriminator),
|
||||||
Format.Bold(beforeVch?.Name ?? ""),
|
Format.Bold(beforeVch?.Name ?? ""),
|
||||||
Format.Bold(afterVch?.Name ?? "")));
|
Format.Bold(afterVch?.Name ?? "")));
|
||||||
|
}
|
||||||
else if (beforeVch is null)
|
else if (beforeVch is null)
|
||||||
|
{
|
||||||
str = "🎙"
|
str = "🎙"
|
||||||
+ Format.Code(PrettyCurrentTime(usr.Guild))
|
+ Format.Code(PrettyCurrentTime(usr.Guild))
|
||||||
+ GetText(logChannel.Guild,
|
+ GetText(logChannel.Guild,
|
||||||
strs.user_vjoined("👤" + Format.Bold(usr.Username + "#" + usr.Discriminator),
|
strs.user_vjoined("👤" + Format.Bold(usr.Username + "#" + usr.Discriminator),
|
||||||
Format.Bold(afterVch?.Name ?? "")));
|
Format.Bold(afterVch?.Name ?? "")));
|
||||||
|
}
|
||||||
else if (afterVch is null)
|
else if (afterVch is null)
|
||||||
|
{
|
||||||
str = "🎙"
|
str = "🎙"
|
||||||
+ Format.Code(PrettyCurrentTime(usr.Guild))
|
+ Format.Code(PrettyCurrentTime(usr.Guild))
|
||||||
+ GetText(logChannel.Guild,
|
+ GetText(logChannel.Guild,
|
||||||
strs.user_vleft("👤" + Format.Bold(usr.Username + "#" + usr.Discriminator),
|
strs.user_vleft("👤" + Format.Bold(usr.Username + "#" + usr.Discriminator),
|
||||||
Format.Bold(beforeVch.Name ?? "")));
|
Format.Bold(beforeVch.Name ?? "")));
|
||||||
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(str))
|
if (!string.IsNullOrWhiteSpace(str))
|
||||||
|
{
|
||||||
PresenceUpdates.AddOrUpdate(logChannel,
|
PresenceUpdates.AddOrUpdate(logChannel,
|
||||||
new List<string>
|
new List<string>
|
||||||
{
|
{
|
||||||
@@ -809,6 +816,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||||||
return list;
|
return list;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
// ignored
|
// ignored
|
||||||
@@ -1001,8 +1009,10 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||||||
.AddField("Id", msg.Id.ToString())
|
.AddField("Id", msg.Id.ToString())
|
||||||
.WithFooter(CurrentTime(channel.Guild));
|
.WithFooter(CurrentTime(channel.Guild));
|
||||||
if (msg.Attachments.Any())
|
if (msg.Attachments.Any())
|
||||||
|
{
|
||||||
embed.AddField(GetText(logChannel.Guild, strs.attachments),
|
embed.AddField(GetText(logChannel.Guild, strs.attachments),
|
||||||
string.Join(", ", msg.Attachments.Select(a => a.Url)));
|
string.Join(", ", msg.Attachments.Select(a => a.Url)));
|
||||||
|
}
|
||||||
|
|
||||||
await logChannel.EmbedAsync(embed);
|
await logChannel.EmbedAsync(embed);
|
||||||
}
|
}
|
||||||
|
@@ -58,12 +58,16 @@ public partial class Administration
|
|||||||
var removed = _service.LogIgnore(ctx.Guild.Id, target.Id, IgnoredItemType.Channel);
|
var removed = _service.LogIgnore(ctx.Guild.Id, target.Id, IgnoredItemType.Channel);
|
||||||
|
|
||||||
if (!removed)
|
if (!removed)
|
||||||
|
{
|
||||||
await ReplyConfirmLocalizedAsync(
|
await ReplyConfirmLocalizedAsync(
|
||||||
strs.log_ignore_chan(Format.Bold(target.Mention + "(" + target.Id + ")")));
|
strs.log_ignore_chan(Format.Bold(target.Mention + "(" + target.Id + ")")));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
await ReplyConfirmLocalizedAsync(
|
await ReplyConfirmLocalizedAsync(
|
||||||
strs.log_not_ignore_chan(Format.Bold(target.Mention + "(" + target.Id + ")")));
|
strs.log_not_ignore_chan(Format.Bold(target.Mention + "(" + target.Id + ")")));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
@@ -74,12 +78,16 @@ public partial class Administration
|
|||||||
var removed = _service.LogIgnore(ctx.Guild.Id, target.Id, IgnoredItemType.User);
|
var removed = _service.LogIgnore(ctx.Guild.Id, target.Id, IgnoredItemType.User);
|
||||||
|
|
||||||
if (!removed)
|
if (!removed)
|
||||||
|
{
|
||||||
await ReplyConfirmLocalizedAsync(
|
await ReplyConfirmLocalizedAsync(
|
||||||
strs.log_ignore_user(Format.Bold(target.Mention + "(" + target.Id + ")")));
|
strs.log_ignore_user(Format.Bold(target.Mention + "(" + target.Id + ")")));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
await ReplyConfirmLocalizedAsync(
|
await ReplyConfirmLocalizedAsync(
|
||||||
strs.log_not_ignore_user(Format.Bold(target.Mention + "(" + target.Id + ")")));
|
strs.log_not_ignore_user(Format.Bold(target.Mention + "(" + target.Id + ")")));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
|
@@ -100,8 +100,10 @@ public partial class Administration
|
|||||||
if (punishment is null)
|
if (punishment is null)
|
||||||
embed.WithDescription(GetText(strs.user_warned(Format.Bold(user.ToString()))));
|
embed.WithDescription(GetText(strs.user_warned(Format.Bold(user.ToString()))));
|
||||||
else
|
else
|
||||||
|
{
|
||||||
embed.WithDescription(GetText(strs.user_warned_and_punished(Format.Bold(user.ToString()),
|
embed.WithDescription(GetText(strs.user_warned_and_punished(Format.Bold(user.ToString()),
|
||||||
Format.Bold(punishment.Punishment.ToString()))));
|
Format.Bold(punishment.Punishment.ToString()))));
|
||||||
|
}
|
||||||
|
|
||||||
if (dmFailed)
|
if (dmFailed)
|
||||||
embed.WithFooter("⚠️ " + GetText(strs.unable_to_dm_user));
|
embed.WithFooter("⚠️ " + GetText(strs.unable_to_dm_user));
|
||||||
@@ -204,9 +206,7 @@ public partial class Administration
|
|||||||
var embed = _eb.Create().WithOkColor().WithTitle(GetText(strs.warnlog_for(user)));
|
var embed = _eb.Create().WithOkColor().WithTitle(GetText(strs.warnlog_for(user)));
|
||||||
|
|
||||||
if (!warnings.Any())
|
if (!warnings.Any())
|
||||||
{
|
|
||||||
embed.WithDescription(GetText(strs.warnings_none));
|
embed.WithDescription(GetText(strs.warnings_none));
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var descText = GetText(strs.warn_count(
|
var descText = GetText(strs.warn_count(
|
||||||
@@ -288,9 +288,7 @@ public partial class Administration
|
|||||||
var success = await _service.WarnClearAsync(ctx.Guild.Id, userId, index, ctx.User.ToString());
|
var success = await _service.WarnClearAsync(ctx.Guild.Id, userId, index, ctx.User.ToString());
|
||||||
var userStr = Format.Bold((ctx.Guild as SocketGuild)?.GetUser(userId)?.ToString() ?? userId.ToString());
|
var userStr = Format.Bold((ctx.Guild as SocketGuild)?.GetUser(userId)?.ToString() ?? userId.ToString());
|
||||||
if (index == 0)
|
if (index == 0)
|
||||||
{
|
|
||||||
await ReplyErrorLocalizedAsync(strs.warnings_cleared(userStr));
|
await ReplyErrorLocalizedAsync(strs.warnings_cleared(userStr));
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (success)
|
if (success)
|
||||||
@@ -325,13 +323,17 @@ public partial class Administration
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (time is null)
|
if (time is null)
|
||||||
|
{
|
||||||
await ReplyConfirmLocalizedAsync(strs.warn_punish_set(Format.Bold(punish.ToString()),
|
await ReplyConfirmLocalizedAsync(strs.warn_punish_set(Format.Bold(punish.ToString()),
|
||||||
Format.Bold(number.ToString())));
|
Format.Bold(number.ToString())));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
await ReplyConfirmLocalizedAsync(strs.warn_punish_set_timed(Format.Bold(punish.ToString()),
|
await ReplyConfirmLocalizedAsync(strs.warn_punish_set_timed(Format.Bold(punish.ToString()),
|
||||||
Format.Bold(number.ToString()),
|
Format.Bold(number.ToString()),
|
||||||
Format.Bold(time.Input)));
|
Format.Bold(time.Input)));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
@@ -348,13 +350,17 @@ public partial class Administration
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (time is null)
|
if (time is null)
|
||||||
|
{
|
||||||
await ReplyConfirmLocalizedAsync(strs.warn_punish_set(Format.Bold(punish.ToString()),
|
await ReplyConfirmLocalizedAsync(strs.warn_punish_set(Format.Bold(punish.ToString()),
|
||||||
Format.Bold(number.ToString())));
|
Format.Bold(number.ToString())));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
await ReplyConfirmLocalizedAsync(strs.warn_punish_set_timed(Format.Bold(punish.ToString()),
|
await ReplyConfirmLocalizedAsync(strs.warn_punish_set_timed(Format.Bold(punish.ToString()),
|
||||||
Format.Bold(number.ToString()),
|
Format.Bold(number.ToString()),
|
||||||
Format.Bold(time.Input)));
|
Format.Bold(time.Input)));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
@@ -375,11 +381,14 @@ public partial class Administration
|
|||||||
|
|
||||||
string list;
|
string list;
|
||||||
if (ps.Any())
|
if (ps.Any())
|
||||||
|
{
|
||||||
list = string.Join("\n",
|
list = string.Join("\n",
|
||||||
ps.Select(x
|
ps.Select(x
|
||||||
=> $"{x.Count} -> {x.Punishment} {(x.Punishment == PunishmentAction.AddRole ? $"<@&{x.RoleId}>" : "")} {(x.Time <= 0 ? "" : x.Time + "m")} "));
|
=> $"{x.Count} -> {x.Punishment} {(x.Punishment == PunishmentAction.AddRole ? $"<@&{x.RoleId}>" : "")} {(x.Time <= 0 ? "" : x.Time + "m")} "));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
list = GetText(strs.warnpl_none);
|
list = GetText(strs.warnpl_none);
|
||||||
|
|
||||||
await SendConfirmAsync(GetText(strs.warn_punish_list), list);
|
await SendConfirmAsync(GetText(strs.warn_punish_list), list);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -401,6 +410,7 @@ public partial class Administration
|
|||||||
var dmFailed = false;
|
var dmFailed = false;
|
||||||
|
|
||||||
if (guildUser is not null)
|
if (guildUser is not null)
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var defaultMessage = GetText(strs.bandm(Format.Bold(ctx.Guild.Name), msg));
|
var defaultMessage = GetText(strs.bandm(Format.Bold(ctx.Guild.Name), msg));
|
||||||
@@ -412,6 +422,7 @@ public partial class Administration
|
|||||||
{
|
{
|
||||||
dmFailed = true;
|
dmFailed = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
await _mute.TimedBan(ctx.Guild, user, time.Time, (ctx.User + " | " + msg).TrimTo(512));
|
await _mute.TimedBan(ctx.Guild, user, time.Time, (ctx.User + " | " + msg).TrimTo(512));
|
||||||
var toSend = _eb.Create()
|
var toSend = _eb.Create()
|
||||||
@@ -447,10 +458,8 @@ public partial class Administration
|
|||||||
.AddField("ID", userId.ToString(), true));
|
.AddField("ID", userId.ToString(), true));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
await Ban(user, msg);
|
await Ban(user, msg);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
@@ -545,9 +554,7 @@ public partial class Administration
|
|||||||
var embed = _service.GetBanUserDmEmbed(Context, (IGuildUser)ctx.User, defaultMessage, reason, duration);
|
var embed = _service.GetBanUserDmEmbed(Context, (IGuildUser)ctx.User, defaultMessage, reason, duration);
|
||||||
|
|
||||||
if (embed is null)
|
if (embed is null)
|
||||||
{
|
|
||||||
await ConfirmLocalizedAsync(strs.banmsg_disabled);
|
await ConfirmLocalizedAsync(strs.banmsg_disabled);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -755,10 +762,8 @@ public partial class Administration
|
|||||||
banning.Add(user);
|
banning.Add(user);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
missing.Add(userStr);
|
missing.Add(userStr);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
var missStr = string.Join("\n", missing);
|
var missStr = string.Join("\n", missing);
|
||||||
if (string.IsNullOrWhiteSpace(missStr))
|
if (string.IsNullOrWhiteSpace(missStr))
|
||||||
|
@@ -233,10 +233,12 @@ WHERE GuildId in (SELECT GuildId FROM GuildConfigs WHERE WarnExpireHours > 0 AND
|
|||||||
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 {ClearedWarnings} warnings and deleted {DeletedWarnings} warnings due to expiry",
|
Log.Information("Cleared {ClearedWarnings} warnings and deleted {DeletedWarnings} warnings due to expiry",
|
||||||
cleared,
|
cleared,
|
||||||
deleted);
|
deleted);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async Task CheckWarnExpiresAsync(ulong guildId)
|
public async Task CheckWarnExpiresAsync(ulong guildId)
|
||||||
{
|
{
|
||||||
@@ -248,16 +250,20 @@ WHERE GuildId in (SELECT GuildId FROM GuildConfigs WHERE WarnExpireHours > 0 AND
|
|||||||
|
|
||||||
var hours = $"{-config.WarnExpireHours} hours";
|
var hours = $"{-config.WarnExpireHours} hours";
|
||||||
if (config.WarnExpireAction == WarnExpireAction.Clear)
|
if (config.WarnExpireAction == WarnExpireAction.Clear)
|
||||||
|
{
|
||||||
await uow.Database.ExecuteSqlInterpolatedAsync($@"UPDATE warnings
|
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();
|
||||||
}
|
}
|
||||||
@@ -436,9 +442,7 @@ WHERE GuildId={guildId}
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
template.Text = text;
|
template.Text = text;
|
||||||
}
|
|
||||||
|
|
||||||
uow.SaveChanges();
|
uow.SaveChanges();
|
||||||
}
|
}
|
||||||
@@ -487,22 +491,26 @@ WHERE GuildId={guildId}
|
|||||||
|
|
||||||
// if template isn't set, use the old message style
|
// if template isn't set, use the old message style
|
||||||
if (string.IsNullOrWhiteSpace(template))
|
if (string.IsNullOrWhiteSpace(template))
|
||||||
|
{
|
||||||
template = JsonConvert.SerializeObject(new
|
template = JsonConvert.SerializeObject(new
|
||||||
{
|
{
|
||||||
color = _bcs.Data.Color.Error.PackedValue >> 8,
|
color = _bcs.Data.Color.Error.PackedValue >> 8,
|
||||||
description = defaultMessage
|
description = defaultMessage
|
||||||
});
|
});
|
||||||
|
}
|
||||||
// if template is set to "-" do not dm the user
|
// if template is set to "-" do not dm the user
|
||||||
else if (template == "-")
|
else if (template == "-")
|
||||||
return default;
|
return default;
|
||||||
// if template is an embed, send that embed with replacements
|
// if template is an embed, send that embed with replacements
|
||||||
// otherwise, treat template as a regular string with replacements
|
// otherwise, treat template as a regular string with replacements
|
||||||
else if (!SmartText.CreateFrom(template).IsEmbed)
|
else if (!SmartText.CreateFrom(template).IsEmbed)
|
||||||
|
{
|
||||||
template = JsonConvert.SerializeObject(new
|
template = JsonConvert.SerializeObject(new
|
||||||
{
|
{
|
||||||
color = _bcs.Data.Color.Error.PackedValue >> 8,
|
color = _bcs.Data.Color.Error.PackedValue >> 8,
|
||||||
description = template
|
description = template
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
var output = SmartText.CreateFrom(template);
|
var output = SmartText.CreateFrom(template);
|
||||||
return replacer.Replace(output);
|
return replacer.Replace(output);
|
||||||
|
@@ -59,14 +59,14 @@ public partial class Administration
|
|||||||
if (!roles.Any())
|
if (!roles.Any())
|
||||||
text = GetText(strs.no_vcroles);
|
text = GetText(strs.no_vcroles);
|
||||||
else
|
else
|
||||||
|
{
|
||||||
text = string.Join("\n",
|
text = string.Join("\n",
|
||||||
roles.Select(x
|
roles.Select(x
|
||||||
=> $"{Format.Bold(guild.GetVoiceChannel(x.Key)?.Name ?? x.Key.ToString())} => {x.Value}"));
|
=> $"{Format.Bold(guild.GetVoiceChannel(x.Key)?.Name ?? x.Key.ToString())} => {x.Value}"));
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
text = GetText(strs.no_vcroles);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
text = GetText(strs.no_vcroles);
|
||||||
|
|
||||||
await ctx.Channel.EmbedAsync(_eb.Create()
|
await ctx.Channel.EmbedAsync(_eb.Create()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
|
@@ -64,9 +64,7 @@ public static class NadekoExpressionExtensions
|
|||||||
return WordPosition.End;
|
return WordPosition.End;
|
||||||
}
|
}
|
||||||
else if (str.IsValidWordDivider(wordIndex - 1) && str.IsValidWordDivider(wordIndex + word.Length))
|
else if (str.IsValidWordDivider(wordIndex - 1) && str.IsValidWordDivider(wordIndex + word.Length))
|
||||||
{
|
|
||||||
return WordPosition.Middle;
|
return WordPosition.Middle;
|
||||||
}
|
|
||||||
|
|
||||||
return WordPosition.None;
|
return WordPosition.None;
|
||||||
}
|
}
|
||||||
|
@@ -249,12 +249,16 @@ public partial class NadekoExpressions : NadekoModule<NadekoExpressionsService>
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (newVal)
|
if (newVal)
|
||||||
|
{
|
||||||
await ReplyConfirmLocalizedAsync(strs.option_enabled(Format.Code(option.ToString()),
|
await ReplyConfirmLocalizedAsync(strs.option_enabled(Format.Code(option.ToString()),
|
||||||
Format.Code(id.ToString())));
|
Format.Code(id.ToString())));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
await ReplyConfirmLocalizedAsync(strs.option_disabled(Format.Code(option.ToString()),
|
await ReplyConfirmLocalizedAsync(strs.option_disabled(Format.Code(option.ToString()),
|
||||||
Format.Code(id.ToString())));
|
Format.Code(id.ToString())));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
|
@@ -290,6 +290,7 @@ public sealed class NadekoExpressionsService : IEarlyBehavior, IReadyExecutor
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (expr.AutoDeleteTrigger)
|
if (expr.AutoDeleteTrigger)
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await msg.DeleteAsync();
|
await msg.DeleteAsync();
|
||||||
@@ -297,6 +298,7 @@ public sealed class NadekoExpressionsService : IEarlyBehavior, IReadyExecutor
|
|||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Log.Information("s: {GuildId} c: {ChannelId} u: {UserId} | {UserName} executed expression {Expr}",
|
Log.Information("s: {GuildId} c: {ChannelId} u: {UserId} | {UserName} executed expression {Expr}",
|
||||||
guild.Id,
|
guild.Id,
|
||||||
@@ -341,6 +343,7 @@ public sealed class NadekoExpressionsService : IEarlyBehavior, IReadyExecutor
|
|||||||
private void UpdateInternal(ulong? maybeGuildId, NadekoExpression expr)
|
private void UpdateInternal(ulong? maybeGuildId, NadekoExpression expr)
|
||||||
{
|
{
|
||||||
if (maybeGuildId is { } guildId)
|
if (maybeGuildId is { } guildId)
|
||||||
|
{
|
||||||
newGuildReactions.AddOrUpdate(guildId,
|
newGuildReactions.AddOrUpdate(guildId,
|
||||||
new[] { expr },
|
new[] { expr },
|
||||||
(_, old) =>
|
(_, old) =>
|
||||||
@@ -354,7 +357,9 @@ public sealed class NadekoExpressionsService : IEarlyBehavior, IReadyExecutor
|
|||||||
|
|
||||||
return newArray;
|
return newArray;
|
||||||
});
|
});
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
lock (_gexprWriteLock)
|
lock (_gexprWriteLock)
|
||||||
{
|
{
|
||||||
var exprs = globalReactions;
|
var exprs = globalReactions;
|
||||||
@@ -365,6 +370,7 @@ public sealed class NadekoExpressionsService : IEarlyBehavior, IReadyExecutor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Task AddInternalAsync(ulong? maybeGuildId, NadekoExpression expr)
|
private Task AddInternalAsync(ulong? maybeGuildId, NadekoExpression expr)
|
||||||
{
|
{
|
||||||
|
@@ -131,9 +131,11 @@ public sealed class AnimalRace : IDisposable
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (FinishedUsers[0].Bet > 0)
|
if (FinishedUsers[0].Bet > 0)
|
||||||
|
{
|
||||||
await _currency.AddAsync(FinishedUsers[0].UserId,
|
await _currency.AddAsync(FinishedUsers[0].UserId,
|
||||||
FinishedUsers[0].Bet * (_users.Count - 1),
|
FinishedUsers[0].Bet * (_users.Count - 1),
|
||||||
new("animalrace", "win"));
|
new("animalrace", "win"));
|
||||||
|
}
|
||||||
|
|
||||||
_ = OnEnded?.Invoke(this);
|
_ = OnEnded?.Invoke(this);
|
||||||
});
|
});
|
||||||
|
@@ -53,9 +53,11 @@ public partial class Gambling
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (arg.Channel.Id == ctx.Channel.Id)
|
if (arg.Channel.Id == ctx.Channel.Id)
|
||||||
|
{
|
||||||
if (ar.CurrentPhase == AnimalRace.Phase.Running && ++count % 9 == 0)
|
if (ar.CurrentPhase == AnimalRace.Phase.Running && ++count % 9 == 0)
|
||||||
raceMessage = null;
|
raceMessage = null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
catch { }
|
catch { }
|
||||||
});
|
});
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
@@ -67,10 +69,13 @@ public partial class Gambling
|
|||||||
_service.AnimalRaces.TryRemove(ctx.Guild.Id, out _);
|
_service.AnimalRaces.TryRemove(ctx.Guild.Id, out _);
|
||||||
var winner = race.FinishedUsers[0];
|
var winner = race.FinishedUsers[0];
|
||||||
if (race.FinishedUsers[0].Bet > 0)
|
if (race.FinishedUsers[0].Bet > 0)
|
||||||
|
{
|
||||||
return SendConfirmAsync(GetText(strs.animal_race),
|
return SendConfirmAsync(GetText(strs.animal_race),
|
||||||
GetText(strs.animal_race_won_money(Format.Bold(winner.Username),
|
GetText(strs.animal_race_won_money(Format.Bold(winner.Username),
|
||||||
winner.Animal.Icon,
|
winner.Animal.Icon,
|
||||||
(race.FinishedUsers[0].Bet * (race.Users.Count - 1)) + CurrencySign)));
|
(race.FinishedUsers[0].Bet * (race.Users.Count - 1)) + CurrencySign)));
|
||||||
|
}
|
||||||
|
|
||||||
return SendConfirmAsync(GetText(strs.animal_race),
|
return SendConfirmAsync(GetText(strs.animal_race),
|
||||||
GetText(strs.animal_race_won(Format.Bold(winner.Username), winner.Animal.Icon)));
|
GetText(strs.animal_race_won(Format.Bold(winner.Username), winner.Animal.Icon)));
|
||||||
}
|
}
|
||||||
@@ -110,12 +115,14 @@ public partial class Gambling
|
|||||||
if (msg is null)
|
if (msg is null)
|
||||||
raceMessage = await SendConfirmAsync(text);
|
raceMessage = await SendConfirmAsync(text);
|
||||||
else
|
else
|
||||||
|
{
|
||||||
await msg.ModifyAsync(x => x.Embed = _eb.Create()
|
await msg.ModifyAsync(x => x.Embed = _eb.Create()
|
||||||
.WithTitle(GetText(strs.animal_race))
|
.WithTitle(GetText(strs.animal_race))
|
||||||
.WithDescription(text)
|
.WithDescription(text)
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.Build());
|
.Build());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Task Ar_OnStartingFailed(AnimalRace race)
|
private Task Ar_OnStartingFailed(AnimalRace race)
|
||||||
{
|
{
|
||||||
@@ -140,9 +147,11 @@ public partial class Gambling
|
|||||||
{
|
{
|
||||||
var user = await ar.JoinRace(ctx.User.Id, ctx.User.ToString(), amount);
|
var user = await ar.JoinRace(ctx.User.Id, ctx.User.ToString(), amount);
|
||||||
if (amount > 0)
|
if (amount > 0)
|
||||||
|
{
|
||||||
await SendConfirmAsync(GetText(strs.animal_race_join_bet(ctx.User.Mention,
|
await SendConfirmAsync(GetText(strs.animal_race_join_bet(ctx.User.Mention,
|
||||||
user.Animal.Icon,
|
user.Animal.Icon,
|
||||||
amount + CurrencySign)));
|
amount + CurrencySign)));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
await SendConfirmAsync(GetText(strs.animal_race_join(ctx.User.Mention, user.Animal.Icon)));
|
await SendConfirmAsync(GetText(strs.animal_race_join(ctx.User.Mention, user.Animal.Icon)));
|
||||||
}
|
}
|
||||||
|
@@ -56,10 +56,12 @@ public partial class Gambling
|
|||||||
if (await bj.Join(ctx.User, amount))
|
if (await bj.Join(ctx.User, amount))
|
||||||
await ReplyConfirmLocalizedAsync(strs.bj_joined);
|
await ReplyConfirmLocalizedAsync(strs.bj_joined);
|
||||||
else
|
else
|
||||||
|
{
|
||||||
Log.Information("{User} can't join a blackjack game as it's in {BlackjackState} state already",
|
Log.Information("{User} can't join a blackjack game as it's in {BlackjackState} state already",
|
||||||
ctx.User,
|
ctx.User,
|
||||||
bj.State);
|
bj.State);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
await ctx.Message.DeleteAsync();
|
await ctx.Message.DeleteAsync();
|
||||||
}
|
}
|
||||||
@@ -114,21 +116,13 @@ public partial class Gambling
|
|||||||
full = "✅ " + full;
|
full = "✅ " + full;
|
||||||
}
|
}
|
||||||
else if (p == bj.CurrentUser)
|
else if (p == bj.CurrentUser)
|
||||||
{
|
|
||||||
full = "▶ " + full;
|
full = "▶ " + full;
|
||||||
}
|
|
||||||
else if (p.State == User.UserState.Stand)
|
else if (p.State == User.UserState.Stand)
|
||||||
{
|
|
||||||
full = "⏹ " + full;
|
full = "⏹ " + full;
|
||||||
}
|
|
||||||
else if (p.State == User.UserState.Bust)
|
else if (p.State == User.UserState.Bust)
|
||||||
{
|
|
||||||
full = "💥 " + full;
|
full = "💥 " + full;
|
||||||
}
|
|
||||||
else if (p.State == User.UserState.Blackjack)
|
else if (p.State == User.UserState.Blackjack)
|
||||||
{
|
|
||||||
full = "💰 " + full;
|
full = "💰 " + full;
|
||||||
}
|
|
||||||
|
|
||||||
embed.AddField(full, cStr);
|
embed.AddField(full, cStr);
|
||||||
}
|
}
|
||||||
@@ -177,8 +171,10 @@ public partial class Gambling
|
|||||||
else if (a == BjAction.Stand)
|
else if (a == BjAction.Stand)
|
||||||
await bj.Stand(ctx.User);
|
await bj.Stand(ctx.User);
|
||||||
else if (a == BjAction.Double)
|
else if (a == BjAction.Double)
|
||||||
|
{
|
||||||
if (!await bj.Double(ctx.User))
|
if (!await bj.Double(ctx.User))
|
||||||
await ReplyErrorLocalizedAsync(strs.not_enough(CurrencySign));
|
await ReplyErrorLocalizedAsync(strs.not_enough(CurrencySign));
|
||||||
|
}
|
||||||
|
|
||||||
await ctx.Message.DeleteAsync();
|
await ctx.Message.DeleteAsync();
|
||||||
}
|
}
|
||||||
|
@@ -202,6 +202,7 @@ public class Blackjack
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (hw > 21)
|
if (hw > 21)
|
||||||
|
{
|
||||||
foreach (var usr in Players)
|
foreach (var usr in Players)
|
||||||
{
|
{
|
||||||
if (usr.State is User.UserState.Stand or User.UserState.Blackjack)
|
if (usr.State is User.UserState.Stand or User.UserState.Blackjack)
|
||||||
@@ -209,7 +210,9 @@ public class Blackjack
|
|||||||
else
|
else
|
||||||
usr.State = User.UserState.Lost;
|
usr.State = User.UserState.Lost;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
foreach (var usr in Players)
|
foreach (var usr in Players)
|
||||||
{
|
{
|
||||||
if (usr.State == User.UserState.Blackjack)
|
if (usr.State == User.UserState.Blackjack)
|
||||||
@@ -219,6 +222,7 @@ public class Blackjack
|
|||||||
else
|
else
|
||||||
usr.State = User.UserState.Lost;
|
usr.State = User.UserState.Lost;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var usr in Players)
|
foreach (var usr in Players)
|
||||||
{
|
{
|
||||||
|
@@ -129,9 +129,7 @@ public sealed class Connect4Game : IDisposable
|
|||||||
_players[0] = (userId, userName);
|
_players[0] = (userId, userName);
|
||||||
}
|
}
|
||||||
else //else join as a second player
|
else //else join as a second player
|
||||||
{
|
|
||||||
_players[1] = (userId, userName);
|
_players[1] = (userId, userName);
|
||||||
}
|
|
||||||
|
|
||||||
CurrentPhase = Phase.P1Move; //start the game
|
CurrentPhase = Phase.P1Move; //start the game
|
||||||
playerTimeoutTimer = new(async _ =>
|
playerTimeoutTimer = new(async _ =>
|
||||||
@@ -197,6 +195,7 @@ public sealed class Connect4Game : IDisposable
|
|||||||
|
|
||||||
var first = _gameState[i + (j * NUMBER_OF_ROWS)];
|
var first = _gameState[i + (j * NUMBER_OF_ROWS)];
|
||||||
if (first != Field.Empty)
|
if (first != Field.Empty)
|
||||||
|
{
|
||||||
for (var k = 1; k < 4; k++)
|
for (var k = 1; k < 4; k++)
|
||||||
{
|
{
|
||||||
var next = _gameState[i + k + (j * NUMBER_OF_ROWS)];
|
var next = _gameState[i + k + (j * NUMBER_OF_ROWS)];
|
||||||
@@ -208,7 +207,6 @@ public sealed class Connect4Game : IDisposable
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -228,19 +226,23 @@ public sealed class Connect4Game : IDisposable
|
|||||||
|
|
||||||
var first = _gameState[j + (i * NUMBER_OF_ROWS)];
|
var first = _gameState[j + (i * NUMBER_OF_ROWS)];
|
||||||
if (first != Field.Empty)
|
if (first != Field.Empty)
|
||||||
|
{
|
||||||
for (var k = 1; k < 4; k++)
|
for (var k = 1; k < 4; k++)
|
||||||
{
|
{
|
||||||
var next = _gameState[j + ((i + k) * NUMBER_OF_ROWS)];
|
var next = _gameState[j + ((i + k) * NUMBER_OF_ROWS)];
|
||||||
if (next == first)
|
if (next == first)
|
||||||
|
{
|
||||||
if (k == 3)
|
if (k == 3)
|
||||||
EndGame(Result.CurrentPlayerWon, CurrentPlayer.UserId);
|
EndGame(Result.CurrentPlayerWon, CurrentPlayer.UserId);
|
||||||
else
|
else
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//need to check diagonal now
|
//need to check diagonal now
|
||||||
for (var col = 0; col < NUMBER_OF_COLUMNS; col++)
|
for (var col = 0; col < NUMBER_OF_COLUMNS; col++)
|
||||||
|
@@ -65,6 +65,7 @@ public partial class Gambling
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (options.Bet > 0)
|
if (options.Bet > 0)
|
||||||
|
{
|
||||||
if (!await _cs.RemoveAsync(ctx.User.Id, options.Bet, new("connect4", "bet")))
|
if (!await _cs.RemoveAsync(ctx.User.Id, options.Bet, new("connect4", "bet")))
|
||||||
{
|
{
|
||||||
await ReplyErrorLocalizedAsync(strs.not_enough(CurrencySign));
|
await ReplyErrorLocalizedAsync(strs.not_enough(CurrencySign));
|
||||||
@@ -72,6 +73,7 @@ public partial class Gambling
|
|||||||
game.Dispose();
|
game.Dispose();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
game.OnGameStateUpdated += Game_OnGameStateUpdated;
|
game.OnGameStateUpdated += Game_OnGameStateUpdated;
|
||||||
game.OnGameFailedToStart += GameOnGameFailedToStart;
|
game.OnGameFailedToStart += GameOnGameFailedToStart;
|
||||||
@@ -106,9 +108,11 @@ public partial class Gambling
|
|||||||
return;
|
return;
|
||||||
RepostCounter++;
|
RepostCounter++;
|
||||||
if (RepostCounter == 0)
|
if (RepostCounter == 0)
|
||||||
|
{
|
||||||
try { msg = await ctx.Channel.SendMessageAsync("", embed: (Embed)msg.Embeds.First()); }
|
try { msg = await ctx.Channel.SendMessageAsync("", embed: (Embed)msg.Embeds.First()); }
|
||||||
catch { }
|
catch { }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
@@ -134,11 +138,15 @@ public partial class Gambling
|
|||||||
|
|
||||||
string title;
|
string title;
|
||||||
if (result == Connect4Game.Result.CurrentPlayerWon)
|
if (result == Connect4Game.Result.CurrentPlayerWon)
|
||||||
|
{
|
||||||
title = GetText(strs.connect4_won(Format.Bold(arg.CurrentPlayer.Username),
|
title = GetText(strs.connect4_won(Format.Bold(arg.CurrentPlayer.Username),
|
||||||
Format.Bold(arg.OtherPlayer.Username)));
|
Format.Bold(arg.OtherPlayer.Username)));
|
||||||
|
}
|
||||||
else if (result == Connect4Game.Result.OtherPlayerWon)
|
else if (result == Connect4Game.Result.OtherPlayerWon)
|
||||||
|
{
|
||||||
title = GetText(strs.connect4_won(Format.Bold(arg.OtherPlayer.Username),
|
title = GetText(strs.connect4_won(Format.Bold(arg.OtherPlayer.Username),
|
||||||
Format.Bold(arg.CurrentPlayer.Username)));
|
Format.Bold(arg.CurrentPlayer.Username)));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
title = GetText(strs.connect4_draw);
|
title = GetText(strs.connect4_draw);
|
||||||
|
|
||||||
|
@@ -82,6 +82,7 @@ public partial class Gambling
|
|||||||
if (randomNumber == 6 || dice.Count == 0)
|
if (randomNumber == 6 || dice.Count == 0)
|
||||||
toInsert = 0;
|
toInsert = 0;
|
||||||
else if (randomNumber != 1)
|
else if (randomNumber != 1)
|
||||||
|
{
|
||||||
for (var j = 0; j < dice.Count; j++)
|
for (var j = 0; j < dice.Count; j++)
|
||||||
{
|
{
|
||||||
if (values[j] < randomNumber)
|
if (values[j] < randomNumber)
|
||||||
@@ -91,10 +92,9 @@ public partial class Gambling
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
toInsert = dice.Count;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
toInsert = dice.Count;
|
||||||
|
|
||||||
dice.Insert(toInsert, GetDice(randomNumber));
|
dice.Insert(toInsert, GetDice(randomNumber));
|
||||||
values.Insert(toInsert, randomNumber);
|
values.Insert(toInsert, randomNumber);
|
||||||
@@ -190,9 +190,7 @@ public partial class Gambling
|
|||||||
rolled = new NadekoRandom().Next(arr[0], arr[1] + 1);
|
rolled = new NadekoRandom().Next(arr[0], arr[1] + 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
rolled = new NadekoRandom().Next(0, int.Parse(range) + 1);
|
rolled = new NadekoRandom().Next(0, int.Parse(range) + 1);
|
||||||
}
|
|
||||||
|
|
||||||
await ReplyConfirmLocalizedAsync(strs.dice_rolled(Format.Bold(rolled.ToString())));
|
await ReplyConfirmLocalizedAsync(strs.dice_rolled(Format.Bold(rolled.ToString())));
|
||||||
}
|
}
|
||||||
|
@@ -43,6 +43,7 @@ public class CurrencyEventsService : INService
|
|||||||
|
|
||||||
var added = _events.TryAdd(guildId, ce);
|
var added = _events.TryAdd(guildId, ce);
|
||||||
if (added)
|
if (added)
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ce.OnEnded += OnEventEnded;
|
ce.OnEnded += OnEventEnded;
|
||||||
@@ -54,6 +55,7 @@ public class CurrencyEventsService : INService
|
|||||||
_events.TryRemove(guildId, out ce);
|
_events.TryRemove(guildId, out ce);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return added;
|
return added;
|
||||||
}
|
}
|
||||||
|
@@ -82,6 +82,7 @@ public class GameStatusEvent : ICurrencyEvent
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (_isPotLimited)
|
if (_isPotLimited)
|
||||||
|
{
|
||||||
await msg.ModifyAsync(m =>
|
await msg.ModifyAsync(m =>
|
||||||
{
|
{
|
||||||
m.Embed = GetEmbed(PotSize).Build();
|
m.Embed = GetEmbed(PotSize).Build();
|
||||||
@@ -90,6 +91,7 @@ public class GameStatusEvent : ICurrencyEvent
|
|||||||
{
|
{
|
||||||
RetryMode = RetryMode.AlwaysRetry
|
RetryMode = RetryMode.AlwaysRetry
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Log.Information("Awarded {Count} users {Amount} currency.{Remaining}",
|
Log.Information("Awarded {Count} users {Amount} currency.{Remaining}",
|
||||||
toAward.Count,
|
toAward.Count,
|
||||||
@@ -179,6 +181,7 @@ public class GameStatusEvent : ICurrencyEvent
|
|||||||
private bool TryTakeFromPot()
|
private bool TryTakeFromPot()
|
||||||
{
|
{
|
||||||
if (_isPotLimited)
|
if (_isPotLimited)
|
||||||
|
{
|
||||||
lock (_potLock)
|
lock (_potLock)
|
||||||
{
|
{
|
||||||
if (PotSize < _amount)
|
if (PotSize < _amount)
|
||||||
@@ -187,6 +190,7 @@ public class GameStatusEvent : ICurrencyEvent
|
|||||||
PotSize -= _amount;
|
PotSize -= _amount;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@@ -75,6 +75,7 @@ public class ReactionEvent : ICurrencyEvent
|
|||||||
await _cs.AddBulkAsync(toAward, _amount, new("event", "reaction"));
|
await _cs.AddBulkAsync(toAward, _amount, new("event", "reaction"));
|
||||||
|
|
||||||
if (_isPotLimited)
|
if (_isPotLimited)
|
||||||
|
{
|
||||||
await msg.ModifyAsync(m =>
|
await msg.ModifyAsync(m =>
|
||||||
{
|
{
|
||||||
m.Embed = GetEmbed(PotSize).Build();
|
m.Embed = GetEmbed(PotSize).Build();
|
||||||
@@ -83,6 +84,7 @@ public class ReactionEvent : ICurrencyEvent
|
|||||||
{
|
{
|
||||||
RetryMode = RetryMode.AlwaysRetry
|
RetryMode = RetryMode.AlwaysRetry
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Log.Information("Awarded {Count} users {Amount} currency.{Remaining}",
|
Log.Information("Awarded {Count} users {Amount} currency.{Remaining}",
|
||||||
toAward.Count,
|
toAward.Count,
|
||||||
@@ -178,6 +180,7 @@ public class ReactionEvent : ICurrencyEvent
|
|||||||
private bool TryTakeFromPot()
|
private bool TryTakeFromPot()
|
||||||
{
|
{
|
||||||
if (_isPotLimited)
|
if (_isPotLimited)
|
||||||
|
{
|
||||||
lock (_potLock)
|
lock (_potLock)
|
||||||
{
|
{
|
||||||
if (PotSize < _amount)
|
if (PotSize < _amount)
|
||||||
@@ -186,6 +189,7 @@ public class ReactionEvent : ICurrencyEvent
|
|||||||
PotSize -= _amount;
|
PotSize -= _amount;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@@ -114,9 +114,7 @@ public partial class Gambling
|
|||||||
await _cs.AddAsync(ctx.User, toWin, new("betflip", "win"));
|
await _cs.AddAsync(ctx.User, toWin, new("betflip", "win"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
str = Format.Bold(ctx.User.ToString()) + " " + GetText(strs.better_luck);
|
str = Format.Bold(ctx.User.ToString()) + " " + GetText(strs.better_luck);
|
||||||
}
|
|
||||||
|
|
||||||
await ctx.Channel.EmbedAsync(_eb.Create()
|
await ctx.Channel.EmbedAsync(_eb.Create()
|
||||||
.WithDescription(str)
|
.WithDescription(str)
|
||||||
|
@@ -8,7 +8,6 @@ using NadekoBot.Modules.Gambling.Services;
|
|||||||
using NadekoBot.Services.Currency;
|
using NadekoBot.Services.Currency;
|
||||||
using NadekoBot.Services.Database.Models;
|
using NadekoBot.Services.Database.Models;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Numerics;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace NadekoBot.Modules.Gambling;
|
namespace NadekoBot.Modules.Gambling;
|
||||||
@@ -79,13 +78,15 @@ public partial class Gambling : GamblingModule<GamblingService>
|
|||||||
|
|
||||||
// This stops the top 1% from owning more than 100% of the money
|
// This stops the top 1% from owning more than 100% of the money
|
||||||
if (ec.Cash > 0)
|
if (ec.Cash > 0)
|
||||||
|
{
|
||||||
onePercent = ec.OnePercent / (ec.Cash - ec.Bot);
|
onePercent = ec.OnePercent / (ec.Cash - ec.Bot);
|
||||||
|
}
|
||||||
|
|
||||||
// [21:03] Bob Page: Kinda remids me of US economy
|
// [21:03] Bob Page: Kinda remids me of US economy
|
||||||
var embed = _eb.Create()
|
var embed = _eb.Create()
|
||||||
.WithTitle(GetText(strs.economy_state))
|
.WithTitle(GetText(strs.economy_state))
|
||||||
.AddField(GetText(strs.currency_owned),
|
.AddField(GetText(strs.currency_owned),
|
||||||
N((ec.Cash - ec.Bot)))
|
N(ec.Cash - ec.Bot))
|
||||||
.AddField(GetText(strs.currency_one_percent), (onePercent * 100).ToString("F2") + "%")
|
.AddField(GetText(strs.currency_one_percent), (onePercent * 100).ToString("F2") + "%")
|
||||||
.AddField(GetText(strs.currency_planted), N(ec.Planted))
|
.AddField(GetText(strs.currency_planted), N(ec.Planted))
|
||||||
.AddField(GetText(strs.owned_waifus_total), N(ec.Waifus))
|
.AddField(GetText(strs.owned_waifus_total), N(ec.Waifus))
|
||||||
@@ -132,7 +133,9 @@ public partial class Gambling : GamblingModule<GamblingService>
|
|||||||
public async partial Task TimelySet(int amount, int period = 24)
|
public async partial Task TimelySet(int amount, int period = 24)
|
||||||
{
|
{
|
||||||
if (amount < 0 || period < 0)
|
if (amount < 0 || period < 0)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_configService.ModifyConfig(gs =>
|
_configService.ModifyConfig(gs =>
|
||||||
{
|
{
|
||||||
@@ -141,10 +144,14 @@ public partial class Gambling : GamblingModule<GamblingService>
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (amount == 0)
|
if (amount == 0)
|
||||||
|
{
|
||||||
await ReplyConfirmLocalizedAsync(strs.timely_set_none);
|
await ReplyConfirmLocalizedAsync(strs.timely_set_none);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
await ReplyConfirmLocalizedAsync(strs.timely_set(Format.Bold(N(amount)), Format.Bold(period.ToString())));
|
await ReplyConfirmLocalizedAsync(strs.timely_set(Format.Bold(N(amount)), Format.Bold(period.ToString())));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
@@ -155,7 +162,10 @@ public partial class Gambling : GamblingModule<GamblingService>
|
|||||||
var members = (await role.GetMembersAsync()).Where(u => u.Status != UserStatus.Offline);
|
var members = (await role.GetMembersAsync()).Where(u => u.Status != UserStatus.Offline);
|
||||||
var membersArray = members as IUser[] ?? members.ToArray();
|
var membersArray = members as IUser[] ?? members.ToArray();
|
||||||
if (membersArray.Length == 0)
|
if (membersArray.Length == 0)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var usr = membersArray[new NadekoRandom().Next(0, membersArray.Length)];
|
var usr = membersArray[new NadekoRandom().Next(0, membersArray.Length)];
|
||||||
await SendConfirmAsync("🎟 " + GetText(strs.raffled_user),
|
await SendConfirmAsync("🎟 " + GetText(strs.raffled_user),
|
||||||
$"**{usr.Username}#{usr.Discriminator}**",
|
$"**{usr.Username}#{usr.Discriminator}**",
|
||||||
@@ -171,7 +181,10 @@ public partial class Gambling : GamblingModule<GamblingService>
|
|||||||
var members = await role.GetMembersAsync();
|
var members = await role.GetMembersAsync();
|
||||||
var membersArray = members as IUser[] ?? members.ToArray();
|
var membersArray = members as IUser[] ?? members.ToArray();
|
||||||
if (membersArray.Length == 0)
|
if (membersArray.Length == 0)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var usr = membersArray[new NadekoRandom().Next(0, membersArray.Length)];
|
var usr = membersArray[new NadekoRandom().Next(0, membersArray.Length)];
|
||||||
await SendConfirmAsync("🎟 " + GetText(strs.raffled_user),
|
await SendConfirmAsync("🎟 " + GetText(strs.raffled_user),
|
||||||
$"**{usr.Username}#{usr.Discriminator}**",
|
$"**{usr.Username}#{usr.Discriminator}**",
|
||||||
@@ -198,7 +211,9 @@ public partial class Gambling : GamblingModule<GamblingService>
|
|||||||
private async Task InternalCurrencyTransactions(ulong userId, int page)
|
private async Task InternalCurrencyTransactions(ulong userId, int page)
|
||||||
{
|
{
|
||||||
if (--page < 0)
|
if (--page < 0)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
List<CurrencyTransaction> trs;
|
List<CurrencyTransaction> trs;
|
||||||
await using (var uow = _db.GetDbContext())
|
await using (var uow = _db.GetDbContext())
|
||||||
@@ -222,11 +237,15 @@ public partial class Gambling : GamblingModule<GamblingService>
|
|||||||
sb.AppendLine($"\\{change} {date} {Format.Bold(N(tr.Amount))}");
|
sb.AppendLine($"\\{change} {date} {Format.Bold(N(tr.Amount))}");
|
||||||
var transactionString = GetHumanReadableTransaction(tr.Type, tr.Extra, tr.OtherId);
|
var transactionString = GetHumanReadableTransaction(tr.Type, tr.Extra, tr.OtherId);
|
||||||
if (transactionString is not null)
|
if (transactionString is not null)
|
||||||
|
{
|
||||||
sb.AppendLine(transactionString);
|
sb.AppendLine(transactionString);
|
||||||
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(tr.Note))
|
if (!string.IsNullOrWhiteSpace(tr.Note))
|
||||||
|
{
|
||||||
sb.AppendLine($"\t`Note:` {tr.Note.TrimTo(50)}");
|
sb.AppendLine($"\t`Note:` {tr.Note.TrimTo(50)}");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
embed.WithDescription(sb.ToString());
|
embed.WithDescription(sb.ToString());
|
||||||
embed.WithFooter(GetText(strs.page(page + 1)));
|
embed.WithFooter(GetText(strs.page(page + 1)));
|
||||||
@@ -264,10 +283,14 @@ public partial class Gambling : GamblingModule<GamblingService>
|
|||||||
eb.AddField("Extra", tr.Extra, true);
|
eb.AddField("Extra", tr.Extra, true);
|
||||||
|
|
||||||
if (tr.OtherId is ulong other)
|
if (tr.OtherId is ulong other)
|
||||||
|
{
|
||||||
eb.AddField("From Id", other);
|
eb.AddField("From Id", other);
|
||||||
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(tr.Note))
|
if (!string.IsNullOrWhiteSpace(tr.Note))
|
||||||
|
{
|
||||||
eb.AddField("Note", tr.Note);
|
eb.AddField("Note", tr.Note);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
eb.WithFooter(GetFormattedCurtrDate(tr));
|
eb.WithFooter(GetFormattedCurtrDate(tr));
|
||||||
@@ -313,7 +336,9 @@ public partial class Gambling : GamblingModule<GamblingService>
|
|||||||
public async partial Task Give(ShmartNumber amount, IGuildUser receiver, [Leftover] string msg)
|
public async partial Task Give(ShmartNumber amount, IGuildUser receiver, [Leftover] string msg)
|
||||||
{
|
{
|
||||||
if (amount <= 0 || ctx.User.Id == receiver.Id || receiver.IsBot)
|
if (amount <= 0 || ctx.User.Id == receiver.Id || receiver.IsBot)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!await _cs.TransferAsync(ctx.User.Id, receiver.Id, amount, ctx.User.ToString(), msg))
|
if (!await _cs.TransferAsync(ctx.User.Id, receiver.Id, amount, ctx.User.ToString(), msg))
|
||||||
{
|
{
|
||||||
@@ -350,7 +375,9 @@ public partial class Gambling : GamblingModule<GamblingService>
|
|||||||
public async partial Task Award(long amount, ulong usrId, [Leftover] string msg = null)
|
public async partial Task Award(long amount, ulong usrId, [Leftover] string msg = null)
|
||||||
{
|
{
|
||||||
if (amount <= 0)
|
if (amount <= 0)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var usr = await ((DiscordSocketClient)Context.Client).Rest.GetUserAsync(usrId);
|
var usr = await ((DiscordSocketClient)Context.Client).Rest.GetUserAsync(usrId);
|
||||||
|
|
||||||
@@ -414,7 +441,9 @@ public partial class Gambling : GamblingModule<GamblingService>
|
|||||||
public async partial Task Take(long amount, [Leftover] IGuildUser user)
|
public async partial Task Take(long amount, [Leftover] IGuildUser user)
|
||||||
{
|
{
|
||||||
if (amount <= 0)
|
if (amount <= 0)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var extra = new TxData("take",
|
var extra = new TxData("take",
|
||||||
ctx.User.ToString()!,
|
ctx.User.ToString()!,
|
||||||
@@ -422,10 +451,14 @@ public partial class Gambling : GamblingModule<GamblingService>
|
|||||||
ctx.User.Id);
|
ctx.User.Id);
|
||||||
|
|
||||||
if (await _cs.RemoveAsync(user.Id, amount, extra))
|
if (await _cs.RemoveAsync(user.Id, amount, extra))
|
||||||
|
{
|
||||||
await ReplyConfirmLocalizedAsync(strs.take(N(amount), Format.Bold(user.ToString())));
|
await ReplyConfirmLocalizedAsync(strs.take(N(amount), Format.Bold(user.ToString())));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
await ReplyErrorLocalizedAsync(strs.take_fail(N(amount), Format.Bold(user.ToString()), CurrencySign));
|
await ReplyErrorLocalizedAsync(strs.take_fail(N(amount), Format.Bold(user.ToString()), CurrencySign));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
@@ -433,7 +466,9 @@ public partial class Gambling : GamblingModule<GamblingService>
|
|||||||
public async partial Task Take(long amount, [Leftover] ulong usrId)
|
public async partial Task Take(long amount, [Leftover] ulong usrId)
|
||||||
{
|
{
|
||||||
if (amount <= 0)
|
if (amount <= 0)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var extra = new TxData("take",
|
var extra = new TxData("take",
|
||||||
ctx.User.ToString()!,
|
ctx.User.ToString()!,
|
||||||
@@ -441,33 +476,45 @@ public partial class Gambling : GamblingModule<GamblingService>
|
|||||||
ctx.User.Id);
|
ctx.User.Id);
|
||||||
|
|
||||||
if (await _cs.RemoveAsync(usrId, amount, extra))
|
if (await _cs.RemoveAsync(usrId, amount, extra))
|
||||||
|
{
|
||||||
await ReplyConfirmLocalizedAsync(strs.take(N(amount), $"<@{usrId}>"));
|
await ReplyConfirmLocalizedAsync(strs.take(N(amount), $"<@{usrId}>"));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
await ReplyErrorLocalizedAsync(strs.take_fail(N(amount), Format.Code(usrId.ToString()), CurrencySign));
|
await ReplyErrorLocalizedAsync(strs.take_fail(N(amount), Format.Code(usrId.ToString()), CurrencySign));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
public async partial Task RollDuel(IUser u)
|
public async partial Task RollDuel(IUser u)
|
||||||
{
|
{
|
||||||
if (ctx.User.Id == u.Id)
|
if (ctx.User.Id == u.Id)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//since the challenge is created by another user, we need to reverse the ids
|
//since the challenge is created by another user, we need to reverse the ids
|
||||||
//if it gets removed, means challenge is accepted
|
//if it gets removed, means challenge is accepted
|
||||||
if (_service.Duels.TryRemove((ctx.User.Id, u.Id), out var game))
|
if (_service.Duels.TryRemove((ctx.User.Id, u.Id), out var game))
|
||||||
|
{
|
||||||
await game.StartGame();
|
await game.StartGame();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
public async partial Task RollDuel(ShmartNumber amount, IUser u)
|
public async partial Task RollDuel(ShmartNumber amount, IUser u)
|
||||||
{
|
{
|
||||||
if (ctx.User.Id == u.Id)
|
if (ctx.User.Id == u.Id)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (amount <= 0)
|
if (amount <= 0)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var embed = _eb.Create().WithOkColor().WithTitle(GetText(strs.roll_duel));
|
var embed = _eb.Create().WithOkColor().WithTitle(GetText(strs.roll_duel));
|
||||||
|
|
||||||
@@ -478,9 +525,14 @@ public partial class Gambling : GamblingModule<GamblingService>
|
|||||||
if (_service.Duels.TryGetValue((ctx.User.Id, u.Id), out var other))
|
if (_service.Duels.TryGetValue((ctx.User.Id, u.Id), out var other))
|
||||||
{
|
{
|
||||||
if (other.Amount != amount)
|
if (other.Amount != amount)
|
||||||
|
{
|
||||||
await ReplyErrorLocalizedAsync(strs.roll_duel_already_challenged);
|
await ReplyErrorLocalizedAsync(strs.roll_duel_already_challenged);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
await RollDuel(u);
|
await RollDuel(u);
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -504,13 +556,17 @@ public partial class Gambling : GamblingModule<GamblingService>
|
|||||||
embed = embed.WithDescription(description);
|
embed = embed.WithDescription(description);
|
||||||
|
|
||||||
if (rdMsg is null)
|
if (rdMsg is null)
|
||||||
|
{
|
||||||
rdMsg = await ctx.Channel.EmbedAsync(embed);
|
rdMsg = await ctx.Channel.EmbedAsync(embed);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
await rdMsg.ModifyAsync(x =>
|
await rdMsg.ModifyAsync(x =>
|
||||||
{
|
{
|
||||||
x.Embed = embed.Build();
|
x.Embed = embed.Build();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async Task GameOnEnded(RollDuelGame rdGame, RollDuelGame.Reason reason)
|
async Task GameOnEnded(RollDuelGame rdGame, RollDuelGame.Reason reason)
|
||||||
{
|
{
|
||||||
@@ -544,7 +600,9 @@ public partial class Gambling : GamblingModule<GamblingService>
|
|||||||
private async Task InternallBetroll(long amount)
|
private async Task InternallBetroll(long amount)
|
||||||
{
|
{
|
||||||
if (!await CheckBetMandatory(amount))
|
if (!await CheckBetMandatory(amount))
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!await _cs.RemoveAsync(ctx.User, amount, new("betroll", "bet")))
|
if (!await _cs.RemoveAsync(ctx.User, amount, new("betroll", "bet")))
|
||||||
{
|
{
|
||||||
@@ -588,14 +646,18 @@ public partial class Gambling : GamblingModule<GamblingService>
|
|||||||
public async partial Task Leaderboard(int page = 1, params string[] args)
|
public async partial Task Leaderboard(int page = 1, params string[] args)
|
||||||
{
|
{
|
||||||
if (--page < 0)
|
if (--page < 0)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var (opts, _) = OptionsParser.ParseFrom(new LbOpts(), args);
|
var (opts, _) = OptionsParser.ParseFrom(new LbOpts(), args);
|
||||||
|
|
||||||
List<DiscordUser> cleanRichest;
|
List<DiscordUser> cleanRichest;
|
||||||
// it's pointless to have clean on dm context
|
// it's pointless to have clean on dm context
|
||||||
if (ctx.Guild is null)
|
if (ctx.Guild is null)
|
||||||
|
{
|
||||||
opts.Clean = false;
|
opts.Clean = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (opts.Clean)
|
if (opts.Clean)
|
||||||
{
|
{
|
||||||
@@ -658,7 +720,9 @@ public partial class Gambling : GamblingModule<GamblingService>
|
|||||||
public async partial Task Rps(RpsPick pick, ShmartNumber amount = default)
|
public async partial Task Rps(RpsPick pick, ShmartNumber amount = default)
|
||||||
{
|
{
|
||||||
if (!await CheckBetOptional(amount) || amount == 1)
|
if (!await CheckBetOptional(amount) || amount == 1)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
string GetRpsPick(RpsPick p)
|
string GetRpsPick(RpsPick p)
|
||||||
{
|
{
|
||||||
@@ -678,6 +742,7 @@ public partial class Gambling : GamblingModule<GamblingService>
|
|||||||
var nadekoPick = (RpsPick)new NadekoRandom().Next(0, 3);
|
var nadekoPick = (RpsPick)new NadekoRandom().Next(0, 3);
|
||||||
|
|
||||||
if (amount > 0)
|
if (amount > 0)
|
||||||
|
{
|
||||||
if (!await _cs.RemoveAsync(ctx.User.Id,
|
if (!await _cs.RemoveAsync(ctx.User.Id,
|
||||||
amount,
|
amount,
|
||||||
new("rps", "bet", "")))
|
new("rps", "bet", "")))
|
||||||
@@ -685,6 +750,7 @@ public partial class Gambling : GamblingModule<GamblingService>
|
|||||||
await ReplyErrorLocalizedAsync(strs.not_enough(CurrencySign));
|
await ReplyErrorLocalizedAsync(strs.not_enough(CurrencySign));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
string msg;
|
string msg;
|
||||||
if (pick == nadekoPick)
|
if (pick == nadekoPick)
|
||||||
|
@@ -14,8 +14,7 @@ public sealed class GamblingConfigService : ConfigServiceBase<GamblingConfig>
|
|||||||
|
|
||||||
private readonly IEnumerable<WaifuItemModel> _antiGiftSeed = new[]
|
private readonly IEnumerable<WaifuItemModel> _antiGiftSeed = new[]
|
||||||
{
|
{
|
||||||
new WaifuItemModel("🥀", 100, "WiltedRose", true),
|
new WaifuItemModel("🥀", 100, "WiltedRose", true), new WaifuItemModel("✂️", 1000, "Haircut", true),
|
||||||
new WaifuItemModel("✂️", 1000, "Haircut", true),
|
|
||||||
new WaifuItemModel("🧻", 10000, "ToiletPaper", true)
|
new WaifuItemModel("🧻", 10000, "ToiletPaper", true)
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -151,23 +150,29 @@ public sealed class GamblingConfigService : ConfigServiceBase<GamblingConfig>
|
|||||||
public void Migrate()
|
public void Migrate()
|
||||||
{
|
{
|
||||||
if (data.Version < 2)
|
if (data.Version < 2)
|
||||||
|
{
|
||||||
ModifyConfig(c =>
|
ModifyConfig(c =>
|
||||||
{
|
{
|
||||||
c.Waifu.Items = c.Waifu.Items.Concat(_antiGiftSeed).ToList();
|
c.Waifu.Items = c.Waifu.Items.Concat(_antiGiftSeed).ToList();
|
||||||
c.Version = 2;
|
c.Version = 2;
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (data.Version < 3)
|
if (data.Version < 3)
|
||||||
|
{
|
||||||
ModifyConfig(c =>
|
ModifyConfig(c =>
|
||||||
{
|
{
|
||||||
c.Version = 3;
|
c.Version = 3;
|
||||||
c.VoteReward = 100;
|
c.VoteReward = 100;
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if(data.Version < 5)
|
if (data.Version < 5)
|
||||||
|
{
|
||||||
ModifyConfig(c =>
|
ModifyConfig(c =>
|
||||||
{
|
{
|
||||||
c.Version = 5;
|
c.Version = 5;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@@ -131,10 +131,12 @@ WHERE CurrencyAmount > {config.Decay.MinThreshold} AND UserId!={_client.CurrentU
|
|||||||
var takeRes = await _cs.RemoveAsync(userId, amount, new("slot", "bet"));
|
var takeRes = await _cs.RemoveAsync(userId, amount, new("slot", "bet"));
|
||||||
|
|
||||||
if (!takeRes)
|
if (!takeRes)
|
||||||
|
{
|
||||||
return new()
|
return new()
|
||||||
{
|
{
|
||||||
Error = GamblingError.NotEnough
|
Error = GamblingError.NotEnough
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
var game = new SlotGame();
|
var game = new SlotGame();
|
||||||
var result = game.Spin();
|
var result = game.Spin();
|
||||||
@@ -161,11 +163,13 @@ WHERE CurrencyAmount > {config.Decay.MinThreshold} AND UserId!={_client.CurrentU
|
|||||||
public EconomyResult GetEconomy()
|
public EconomyResult GetEconomy()
|
||||||
{
|
{
|
||||||
if (_cache.TryGetEconomy(out var data))
|
if (_cache.TryGetEconomy(out var data))
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return JsonConvert.DeserializeObject<EconomyResult>(data);
|
return JsonConvert.DeserializeObject<EconomyResult>(data);
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
|
}
|
||||||
|
|
||||||
decimal cash;
|
decimal cash;
|
||||||
decimal onePercent;
|
decimal onePercent;
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
#nullable disable
|
#nullable disable
|
||||||
using NadekoBot.Modules.Gambling.Services;
|
using NadekoBot.Modules.Gambling.Services;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Runtime;
|
|
||||||
|
|
||||||
namespace NadekoBot.Modules.Gambling.Common;
|
namespace NadekoBot.Modules.Gambling.Common;
|
||||||
|
|
||||||
@@ -40,7 +39,8 @@ public abstract class GamblingModule<TService> : NadekoModule<TService>
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected string N<T>(T cur) where T : INumber<T>
|
protected string N<T>(T cur)
|
||||||
|
where T : INumber<T>
|
||||||
{
|
{
|
||||||
var flowersCi = (CultureInfo)Culture.Clone();
|
var flowersCi = (CultureInfo)Culture.Clone();
|
||||||
flowersCi.NumberFormat.CurrencySymbol = CurrencySign;
|
flowersCi.NumberFormat.CurrencySymbol = CurrencySign;
|
||||||
|
@@ -31,6 +31,7 @@ public partial class Gambling
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (((SocketGuild)ctx.Guild).CurrentUser.GuildPermissions.ManageMessages)
|
if (((SocketGuild)ctx.Guild).CurrentUser.GuildPermissions.ManageMessages)
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_logService.AddDeleteIgnore(ctx.Message.Id);
|
_logService.AddDeleteIgnore(ctx.Message.Id);
|
||||||
@@ -38,6 +39,7 @@ public partial class Gambling
|
|||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
|
@@ -52,6 +52,7 @@ public class CurrencyRaffleService : INService
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (newGame)
|
if (newGame)
|
||||||
|
{
|
||||||
_ = Task.Run(async () =>
|
_ = Task.Run(async () =>
|
||||||
{
|
{
|
||||||
await Task.Delay(60000);
|
await Task.Delay(60000);
|
||||||
@@ -68,6 +69,7 @@ public class CurrencyRaffleService : INService
|
|||||||
catch { }
|
catch { }
|
||||||
finally { _locker.Release(); }
|
finally { _locker.Release(); }
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return (crg, null);
|
return (crg, null);
|
||||||
}
|
}
|
||||||
|
@@ -182,9 +182,11 @@ public partial class Gambling
|
|||||||
.ShopEntries);
|
.ShopEntries);
|
||||||
entry = entries.ElementAtOrDefault(index);
|
entry = entries.ElementAtOrDefault(index);
|
||||||
if (entry is not null)
|
if (entry is not null)
|
||||||
|
{
|
||||||
if (entry.Items.Add(item))
|
if (entry.Items.Add(item))
|
||||||
uow.SaveChanges();
|
uow.SaveChanges();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
await ReplyErrorLocalizedAsync(strs.shop_buy_error);
|
await ReplyErrorLocalizedAsync(strs.shop_buy_error);
|
||||||
return;
|
return;
|
||||||
@@ -193,11 +195,9 @@ public partial class Gambling
|
|||||||
await ReplyConfirmLocalizedAsync(strs.shop_item_purchase);
|
await ReplyConfirmLocalizedAsync(strs.shop_item_purchase);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
await ReplyErrorLocalizedAsync(strs.not_enough(CurrencySign));
|
await ReplyErrorLocalizedAsync(strs.not_enough(CurrencySign));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private static long GetProfitAmount(int price)
|
private static long GetProfitAmount(int price)
|
||||||
=> (int)Math.Ceiling(0.90 * price);
|
=> (int)Math.Ceiling(0.90 * price);
|
||||||
@@ -291,12 +291,14 @@ public partial class Gambling
|
|||||||
.ShopEntries);
|
.ShopEntries);
|
||||||
entry = entries.ElementAtOrDefault(index);
|
entry = entries.ElementAtOrDefault(index);
|
||||||
if (entry is not null && (rightType = entry.Type == ShopEntryType.List))
|
if (entry is not null && (rightType = entry.Type == ShopEntryType.List))
|
||||||
|
{
|
||||||
if (entry.Items.Add(item))
|
if (entry.Items.Add(item))
|
||||||
{
|
{
|
||||||
added = true;
|
added = true;
|
||||||
uow.SaveChanges();
|
uow.SaveChanges();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (entry is null)
|
if (entry is null)
|
||||||
await ReplyErrorLocalizedAsync(strs.shop_item_not_found);
|
await ReplyErrorLocalizedAsync(strs.shop_item_not_found);
|
||||||
@@ -353,10 +355,8 @@ public partial class Gambling
|
|||||||
await ctx.OkAsync();
|
await ctx.OkAsync();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
await ctx.ErrorAsync();
|
await ctx.ErrorAsync();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
@@ -373,10 +373,8 @@ public partial class Gambling
|
|||||||
await ctx.OkAsync();
|
await ctx.OkAsync();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
await ctx.ErrorAsync();
|
await ctx.ErrorAsync();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
@@ -393,10 +391,8 @@ public partial class Gambling
|
|||||||
await ctx.OkAsync();
|
await ctx.OkAsync();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
await ctx.ErrorAsync();
|
await ctx.ErrorAsync();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
@@ -413,16 +409,15 @@ public partial class Gambling
|
|||||||
await ctx.OkAsync();
|
await ctx.OkAsync();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
await ctx.ErrorAsync();
|
await ctx.ErrorAsync();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public IEmbedBuilder EntryToEmbed(ShopEntry entry)
|
public IEmbedBuilder EntryToEmbed(ShopEntry entry)
|
||||||
{
|
{
|
||||||
var embed = _eb.Create().WithOkColor();
|
var embed = _eb.Create().WithOkColor();
|
||||||
|
|
||||||
if (entry.Type == ShopEntryType.Role)
|
if (entry.Type == ShopEntryType.Role)
|
||||||
|
{
|
||||||
return embed
|
return embed
|
||||||
.AddField(GetText(strs.name),
|
.AddField(GetText(strs.name),
|
||||||
GetText(strs.shop_role(Format.Bold(ctx.Guild.GetRole(entry.RoleId)?.Name
|
GetText(strs.shop_role(Format.Bold(ctx.Guild.GetRole(entry.RoleId)?.Name
|
||||||
@@ -430,11 +425,14 @@ public partial class Gambling
|
|||||||
true)
|
true)
|
||||||
.AddField(GetText(strs.price), N(entry.Price), true)
|
.AddField(GetText(strs.price), N(entry.Price), true)
|
||||||
.AddField(GetText(strs.type), entry.Type.ToString(), true);
|
.AddField(GetText(strs.type), entry.Type.ToString(), true);
|
||||||
|
}
|
||||||
|
|
||||||
if (entry.Type == ShopEntryType.List)
|
if (entry.Type == ShopEntryType.List)
|
||||||
|
{
|
||||||
return embed.AddField(GetText(strs.name), entry.Name, true)
|
return embed.AddField(GetText(strs.name), entry.Name, true)
|
||||||
.AddField(GetText(strs.price), N(entry.Price), true)
|
.AddField(GetText(strs.price), N(entry.Price), true)
|
||||||
.AddField(GetText(strs.type), GetText(strs.random_unique_item), true);
|
.AddField(GetText(strs.type), GetText(strs.random_unique_item), true);
|
||||||
|
}
|
||||||
|
|
||||||
//else if (entry.Type == ShopEntryType.Infinite_List)
|
//else if (entry.Type == ShopEntryType.Infinite_List)
|
||||||
// return embed.AddField(GetText(strs.name), GetText(strs.shop_role(Format.Bold(entry.RoleName)), true))
|
// return embed.AddField(GetText(strs.name), GetText(strs.shop_role(Format.Bold(entry.RoleName)), true))
|
||||||
|
@@ -135,17 +135,21 @@ public partial class Gambling
|
|||||||
var (w, result, amount, remaining) = await _service.DivorceWaifuAsync(ctx.User, targetId);
|
var (w, result, amount, remaining) = await _service.DivorceWaifuAsync(ctx.User, targetId);
|
||||||
|
|
||||||
if (result == DivorceResult.SucessWithPenalty)
|
if (result == DivorceResult.SucessWithPenalty)
|
||||||
|
{
|
||||||
await ReplyConfirmLocalizedAsync(strs.waifu_divorced_like(Format.Bold(w.Waifu.ToString()),
|
await ReplyConfirmLocalizedAsync(strs.waifu_divorced_like(Format.Bold(w.Waifu.ToString()),
|
||||||
N(amount)));
|
N(amount)));
|
||||||
|
}
|
||||||
else if (result == DivorceResult.Success)
|
else if (result == DivorceResult.Success)
|
||||||
await ReplyConfirmLocalizedAsync(strs.waifu_divorced_notlike(N(amount)));
|
await ReplyConfirmLocalizedAsync(strs.waifu_divorced_notlike(N(amount)));
|
||||||
else if (result == DivorceResult.NotYourWife)
|
else if (result == DivorceResult.NotYourWife)
|
||||||
await ReplyErrorLocalizedAsync(strs.waifu_not_yours);
|
await ReplyErrorLocalizedAsync(strs.waifu_not_yours);
|
||||||
else
|
else
|
||||||
|
{
|
||||||
await ReplyErrorLocalizedAsync(strs.waifu_recent_divorce(
|
await ReplyErrorLocalizedAsync(strs.waifu_recent_divorce(
|
||||||
Format.Bold(((int)remaining?.TotalHours).ToString()),
|
Format.Bold(((int)remaining?.TotalHours).ToString()),
|
||||||
Format.Bold(remaining?.Minutes.ToString())));
|
Format.Bold(remaining?.Minutes.ToString())));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
@@ -161,11 +165,14 @@ public partial class Gambling
|
|||||||
if (!sucess)
|
if (!sucess)
|
||||||
{
|
{
|
||||||
if (remaining is not null)
|
if (remaining is not null)
|
||||||
|
{
|
||||||
await ReplyErrorLocalizedAsync(strs.waifu_affinity_cooldown(
|
await ReplyErrorLocalizedAsync(strs.waifu_affinity_cooldown(
|
||||||
Format.Bold(((int)remaining?.TotalHours).ToString()),
|
Format.Bold(((int)remaining?.TotalHours).ToString()),
|
||||||
Format.Bold(remaining?.Minutes.ToString())));
|
Format.Bold(remaining?.Minutes.ToString())));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
await ReplyErrorLocalizedAsync(strs.waifu_affinity_already);
|
await ReplyErrorLocalizedAsync(strs.waifu_affinity_already);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,9 +181,11 @@ public partial class Gambling
|
|||||||
else if (oldAff is null)
|
else if (oldAff is null)
|
||||||
await ReplyConfirmLocalizedAsync(strs.waifu_affinity_set(Format.Bold(user.ToString())));
|
await ReplyConfirmLocalizedAsync(strs.waifu_affinity_set(Format.Bold(user.ToString())));
|
||||||
else
|
else
|
||||||
|
{
|
||||||
await ReplyConfirmLocalizedAsync(strs.waifu_affinity_changed(Format.Bold(oldAff.ToString()),
|
await ReplyConfirmLocalizedAsync(strs.waifu_affinity_changed(Format.Bold(oldAff.ToString()),
|
||||||
Format.Bold(user.ToString())));
|
Format.Bold(user.ToString())));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
@@ -323,8 +332,10 @@ public partial class Gambling
|
|||||||
var sucess = await _service.GiftWaifuAsync(ctx.User, waifu, item);
|
var sucess = await _service.GiftWaifuAsync(ctx.User, waifu, item);
|
||||||
|
|
||||||
if (sucess)
|
if (sucess)
|
||||||
|
{
|
||||||
await ReplyConfirmLocalizedAsync(strs.waifu_gift(Format.Bold(item + " " + item.ItemEmoji),
|
await ReplyConfirmLocalizedAsync(strs.waifu_gift(Format.Bold(item + " " + item.ItemEmoji),
|
||||||
Format.Bold(waifu.ToString())));
|
Format.Bold(waifu.ToString())));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
await ReplyErrorLocalizedAsync(strs.not_enough(CurrencySign));
|
await ReplyErrorLocalizedAsync(strs.not_enough(CurrencySign));
|
||||||
}
|
}
|
||||||
|
@@ -99,7 +99,8 @@ public class WaifuService : INService, IReadyExecutor
|
|||||||
.GroupBy(x => x.New)
|
.GroupBy(x => x.New)
|
||||||
.Count();
|
.Count();
|
||||||
|
|
||||||
return (long)Math.Ceiling(waifu.Price * 1.25f) + ((divorces + affs + 2) * settings.Waifu.Multipliers.WaifuReset);
|
return (long)Math.Ceiling(waifu.Price * 1.25f)
|
||||||
|
+ ((divorces + affs + 2) * settings.Waifu.Multipliers.WaifuReset);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<bool> TryReset(IUser user)
|
public async Task<bool> TryReset(IUser user)
|
||||||
@@ -154,9 +155,7 @@ public class WaifuService : INService, IReadyExecutor
|
|||||||
var claimer = uow.GetOrCreateUser(user);
|
var claimer = uow.GetOrCreateUser(user);
|
||||||
var waifu = uow.GetOrCreateUser(target);
|
var waifu = uow.GetOrCreateUser(target);
|
||||||
if (!await _cs.RemoveAsync(user.Id, amount, new("waifu", "claim")))
|
if (!await _cs.RemoveAsync(user.Id, amount, new("waifu", "claim")))
|
||||||
{
|
|
||||||
result = WaifuClaimResult.NotEnoughFunds;
|
result = WaifuClaimResult.NotEnoughFunds;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
uow.WaifuInfo.Add(w = new()
|
uow.WaifuInfo.Add(w = new()
|
||||||
@@ -179,9 +178,7 @@ public class WaifuService : INService, IReadyExecutor
|
|||||||
else if (isAffinity && amount > w.Price * settings.Waifu.Multipliers.CrushClaim)
|
else if (isAffinity && amount > w.Price * settings.Waifu.Multipliers.CrushClaim)
|
||||||
{
|
{
|
||||||
if (!await _cs.RemoveAsync(user.Id, amount, new("waifu", "claim")))
|
if (!await _cs.RemoveAsync(user.Id, amount, new("waifu", "claim")))
|
||||||
{
|
|
||||||
result = WaifuClaimResult.NotEnoughFunds;
|
result = WaifuClaimResult.NotEnoughFunds;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var oldClaimer = w.Claimer;
|
var oldClaimer = w.Claimer;
|
||||||
@@ -201,9 +198,7 @@ public class WaifuService : INService, IReadyExecutor
|
|||||||
else if (amount >= w.Price * settings.Waifu.Multipliers.NormalClaim) // if no affinity
|
else if (amount >= w.Price * settings.Waifu.Multipliers.NormalClaim) // if no affinity
|
||||||
{
|
{
|
||||||
if (!await _cs.RemoveAsync(user.Id, amount, new("waifu", "claim")))
|
if (!await _cs.RemoveAsync(user.Id, amount, new("waifu", "claim")))
|
||||||
{
|
|
||||||
result = WaifuClaimResult.NotEnoughFunds;
|
result = WaifuClaimResult.NotEnoughFunds;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var oldClaimer = w.Claimer;
|
var oldClaimer = w.Claimer;
|
||||||
@@ -221,9 +216,7 @@ public class WaifuService : INService, IReadyExecutor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
result = WaifuClaimResult.InsufficientAmount;
|
result = WaifuClaimResult.InsufficientAmount;
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
await uow.SaveChangesAsync();
|
await uow.SaveChangesAsync();
|
||||||
@@ -311,13 +304,9 @@ public class WaifuService : INService, IReadyExecutor
|
|||||||
{
|
{
|
||||||
w = uow.WaifuInfo.ByWaifuUserId(targetId);
|
w = uow.WaifuInfo.ByWaifuUserId(targetId);
|
||||||
if (w?.Claimer is null || w.Claimer.UserId != user.Id)
|
if (w?.Claimer is null || w.Claimer.UserId != user.Id)
|
||||||
{
|
|
||||||
result = DivorceResult.NotYourWife;
|
result = DivorceResult.NotYourWife;
|
||||||
}
|
|
||||||
else if (!_cache.TryAddDivorceCooldown(user.Id, out remaining))
|
else if (!_cache.TryAddDivorceCooldown(user.Id, out remaining))
|
||||||
{
|
|
||||||
result = DivorceResult.Cooldown;
|
result = DivorceResult.Cooldown;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
amount = w.Price / 2;
|
amount = w.Price / 2;
|
||||||
@@ -361,6 +350,7 @@ public class WaifuService : INService, IReadyExecutor
|
|||||||
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));
|
var w = uow.WaifuInfo.ByWaifuUserId(giftedWaifu.Id, set => set.Include(x => x.Items).Include(x => x.Claimer));
|
||||||
if (w is null)
|
if (w is null)
|
||||||
|
{
|
||||||
uow.WaifuInfo.Add(w = new()
|
uow.WaifuInfo.Add(w = new()
|
||||||
{
|
{
|
||||||
Affinity = null,
|
Affinity = null,
|
||||||
@@ -368,6 +358,7 @@ public class WaifuService : INService, IReadyExecutor
|
|||||||
Price = 1,
|
Price = 1,
|
||||||
Waifu = uow.GetOrCreateUser(giftedWaifu)
|
Waifu = uow.GetOrCreateUser(giftedWaifu)
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (!itemObj.Negative)
|
if (!itemObj.Negative)
|
||||||
{
|
{
|
||||||
@@ -399,6 +390,7 @@ public class WaifuService : INService, IReadyExecutor
|
|||||||
using var uow = _db.GetDbContext();
|
using var uow = _db.GetDbContext();
|
||||||
var wi = uow.GetWaifuInfo(targetId);
|
var wi = uow.GetWaifuInfo(targetId);
|
||||||
if (wi is null)
|
if (wi is null)
|
||||||
|
{
|
||||||
wi = new()
|
wi = new()
|
||||||
{
|
{
|
||||||
AffinityCount = 0,
|
AffinityCount = 0,
|
||||||
@@ -412,6 +404,7 @@ public class WaifuService : INService, IReadyExecutor
|
|||||||
Items = new(),
|
Items = new(),
|
||||||
Price = 1
|
Price = 1
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return wi;
|
return wi;
|
||||||
}
|
}
|
||||||
@@ -509,9 +502,7 @@ public class WaifuService : INService, IReadyExecutor
|
|||||||
var decayInterval = _gss.Data.Waifu.Decay.HourInterval;
|
var decayInterval = _gss.Data.Waifu.Decay.HourInterval;
|
||||||
|
|
||||||
if (multi is < 0f or > 1f || decayInterval < 0)
|
if (multi is < 0f or > 1f || decayInterval < 0)
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
var val = await _cache.Redis.GetDatabase().StringGetAsync(redisKey);
|
var val = await _cache.Redis.GetDatabase().StringGetAsync(redisKey);
|
||||||
if (val != default)
|
if (val != default)
|
||||||
@@ -520,10 +511,8 @@ public class WaifuService : INService, IReadyExecutor
|
|||||||
var toWait = decayInterval.Hours() - (DateTime.UtcNow - lastDecay);
|
var toWait = decayInterval.Hours() - (DateTime.UtcNow - lastDecay);
|
||||||
|
|
||||||
if (toWait > 0.Hours())
|
if (toWait > 0.Hours())
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
await _cache.Redis.GetDatabase().StringSetAsync(redisKey, DateTime.UtcNow.ToBinary());
|
await _cache.Redis.GetDatabase().StringSetAsync(redisKey, DateTime.UtcNow.ToBinary());
|
||||||
|
|
||||||
|
@@ -18,11 +18,13 @@ public class Betroll
|
|||||||
|
|
||||||
var pair = _thresholdPairs.FirstOrDefault(x => x.WhenAbove < roll);
|
var pair = _thresholdPairs.FirstOrDefault(x => x.WhenAbove < roll);
|
||||||
if (pair is null)
|
if (pair is null)
|
||||||
|
{
|
||||||
return new()
|
return new()
|
||||||
{
|
{
|
||||||
Multiplier = 0,
|
Multiplier = 0,
|
||||||
Roll = roll
|
Roll = roll
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return new()
|
return new()
|
||||||
{
|
{
|
||||||
|
@@ -25,6 +25,7 @@ public partial class Games
|
|||||||
|
|
||||||
var game = new AcrophobiaGame(options);
|
var game = new AcrophobiaGame(options);
|
||||||
if (_service.AcrophobiaGames.TryAdd(channel.Id, game))
|
if (_service.AcrophobiaGames.TryAdd(channel.Id, game))
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
game.OnStarted += Game_OnStarted;
|
game.OnStarted += Game_OnStarted;
|
||||||
@@ -40,6 +41,7 @@ public partial class Games
|
|||||||
_service.AcrophobiaGames.TryRemove(channel.Id, out game);
|
_service.AcrophobiaGames.TryRemove(channel.Id, out game);
|
||||||
game?.Dispose();
|
game?.Dispose();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
await ReplyErrorLocalizedAsync(strs.acro_running);
|
await ReplyErrorLocalizedAsync(strs.acro_running);
|
||||||
|
|
||||||
|
@@ -35,6 +35,7 @@ public sealed class GamesConfigService : ConfigServiceBase<GamesConfig>
|
|||||||
private void Migrate()
|
private void Migrate()
|
||||||
{
|
{
|
||||||
if (data.Version < 1)
|
if (data.Version < 1)
|
||||||
|
{
|
||||||
ModifyConfig(c =>
|
ModifyConfig(c =>
|
||||||
{
|
{
|
||||||
c.Version = 1;
|
c.Version = 1;
|
||||||
@@ -44,4 +45,5 @@ public sealed class GamesConfigService : ConfigServiceBase<GamesConfig>
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@@ -62,10 +62,8 @@ public class GamesService : INService, IReadyExecutor
|
|||||||
// reset rating once a day
|
// reset rating once a day
|
||||||
using var timer = new PeriodicTimer(TimeSpan.FromDays(1));
|
using var timer = new PeriodicTimer(TimeSpan.FromDays(1));
|
||||||
while (await timer.WaitForNextTickAsync())
|
while (await timer.WaitForNextTickAsync())
|
||||||
{
|
|
||||||
GirlRatings.Clear();
|
GirlRatings.Clear();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<RatingTexts> GetRatingTexts()
|
private async Task<RatingTexts> GetRatingTexts()
|
||||||
{
|
{
|
||||||
|
@@ -24,18 +24,23 @@ public partial class Games
|
|||||||
public static IEmbedBuilder GetEmbed(IEmbedBuilderService eb, HangmanGame.State state)
|
public static IEmbedBuilder GetEmbed(IEmbedBuilderService eb, HangmanGame.State state)
|
||||||
{
|
{
|
||||||
if (state.Phase == HangmanGame.Phase.Running)
|
if (state.Phase == HangmanGame.Phase.Running)
|
||||||
|
{
|
||||||
return eb.Create()
|
return eb.Create()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.AddField("Hangman", Draw(state))
|
.AddField("Hangman", Draw(state))
|
||||||
.AddField("Guess", Format.Code(state.Word))
|
.AddField("Guess", Format.Code(state.Word))
|
||||||
.WithFooter(state.MissedLetters.Join(' '));
|
.WithFooter(state.MissedLetters.Join(' '));
|
||||||
|
}
|
||||||
|
|
||||||
if (state.Phase == HangmanGame.Phase.Ended && state.Failed)
|
if (state.Phase == HangmanGame.Phase.Ended && state.Failed)
|
||||||
|
{
|
||||||
return eb.Create()
|
return eb.Create()
|
||||||
.WithErrorColor()
|
.WithErrorColor()
|
||||||
.AddField("Hangman", Draw(state))
|
.AddField("Hangman", Draw(state))
|
||||||
.AddField("Guess", Format.Code(state.Word))
|
.AddField("Guess", Format.Code(state.Word))
|
||||||
.WithFooter(state.MissedLetters.Join(' '));
|
.WithFooter(state.MissedLetters.Join(' '));
|
||||||
|
}
|
||||||
|
|
||||||
return eb.Create()
|
return eb.Create()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.AddField("Hangman", Draw(state))
|
.AddField("Hangman", Draw(state))
|
||||||
|
@@ -87,17 +87,21 @@ public sealed class HangmanService : IHangmanService, ILateExecutor
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (state.GuessResult is HangmanGame.GuessResult.Incorrect or HangmanGame.GuessResult.AlreadyTried)
|
if (state.GuessResult is HangmanGame.GuessResult.Incorrect or HangmanGame.GuessResult.AlreadyTried)
|
||||||
|
{
|
||||||
_cdCache.Set(msg.Author.Id,
|
_cdCache.Set(msg.Author.Id,
|
||||||
string.Empty,
|
string.Empty,
|
||||||
new MemoryCacheEntryOptions
|
new MemoryCacheEntryOptions
|
||||||
{
|
{
|
||||||
AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(3)
|
AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(3)
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (state.Phase == HangmanGame.Phase.Ended)
|
if (state.Phase == HangmanGame.Phase.Ended)
|
||||||
|
{
|
||||||
if (_hangmanGames.TryRemove(msg.Channel.Id, out _))
|
if (_hangmanGames.TryRemove(msg.Channel.Id, out _))
|
||||||
rew = _gcs.Data.Hangman.CurrencyReward;
|
rew = _gcs.Data.Hangman.CurrencyReward;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (rew > 0)
|
if (rew > 0)
|
||||||
await _cs.AddAsync(msg.Author, rew, new("hangman", "win"));
|
await _cs.AddAsync(msg.Author, rew, new("hangman", "win"));
|
||||||
|
@@ -31,6 +31,7 @@ public partial class Games
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (_service.StartPoll(poll))
|
if (_service.StartPoll(poll))
|
||||||
|
{
|
||||||
await ctx.Channel.EmbedAsync(_eb.Create()
|
await ctx.Channel.EmbedAsync(_eb.Create()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle(GetText(strs.poll_created(ctx.User.ToString())))
|
.WithTitle(GetText(strs.poll_created(ctx.User.ToString())))
|
||||||
@@ -39,6 +40,7 @@ public partial class Games
|
|||||||
+ string.Join("\n",
|
+ string.Join("\n",
|
||||||
poll.Answers.Select(x
|
poll.Answers.Select(x
|
||||||
=> $"`{x.Index + 1}.` {Format.Bold(x.Text)}"))));
|
=> $"`{x.Index + 1}.` {Format.Bold(x.Text)}"))));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
await ReplyErrorLocalizedAsync(strs.poll_already_running);
|
await ReplyErrorLocalizedAsync(strs.poll_already_running);
|
||||||
}
|
}
|
||||||
|
@@ -116,11 +116,13 @@ public class PollService : IEarlyBehavior
|
|||||||
var voted = await poll.TryVote(msg);
|
var voted = await poll.TryVote(msg);
|
||||||
|
|
||||||
if (voted)
|
if (voted)
|
||||||
|
{
|
||||||
Log.Information("User {UserName} [{UserId}] voted in a poll on {GuildName} [{GuildId}] server",
|
Log.Information("User {UserName} [{UserId}] voted in a poll on {GuildName} [{GuildId}] server",
|
||||||
msg.Author.ToString(),
|
msg.Author.ToString(),
|
||||||
msg.Author.Id,
|
msg.Author.Id,
|
||||||
guild.Name,
|
guild.Name,
|
||||||
guild.Id);
|
guild.Id);
|
||||||
|
}
|
||||||
|
|
||||||
return voted;
|
return voted;
|
||||||
}
|
}
|
||||||
|
@@ -151,11 +151,13 @@ public class TypingGame
|
|||||||
.AddField("Errors", distance.ToString(), true));
|
.AddField("Errors", distance.ToString(), true));
|
||||||
|
|
||||||
if (_finishedUserIds.Count % 4 == 0)
|
if (_finishedUserIds.Count % 4 == 0)
|
||||||
|
{
|
||||||
await Channel.SendConfirmAsync(_eb,
|
await Channel.SendConfirmAsync(_eb,
|
||||||
":exclamation: A lot of people finished, here is the text for those still typing:"
|
":exclamation: A lot of people finished, here is the text for those still typing:"
|
||||||
+ $"\n\n**{Format.Sanitize(CurrentSentence.Replace(" ", " \x200B", StringComparison.InvariantCulture)).SanitizeMentions(true)}**");
|
+ $"\n\n**{Format.Sanitize(CurrentSentence.Replace(" ", " \x200B", StringComparison.InvariantCulture)).SanitizeMentions(true)}**");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Warning(ex, "Error receiving typing game answer: {ErrorMessage}", ex.Message);
|
Log.Warning(ex, "Error receiving typing game answer: {ErrorMessage}", ex.Message);
|
||||||
|
@@ -89,9 +89,7 @@ public class TicTacToe
|
|||||||
embed.WithFooter(GetText(strs.ttt_users_move(_users[curUserIndex])));
|
embed.WithFooter(GetText(strs.ttt_users_move(_users[curUserIndex])));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
embed.WithFooter(GetText(strs.ttt_has_won(winner)));
|
embed.WithFooter(GetText(strs.ttt_has_won(winner)));
|
||||||
}
|
|
||||||
|
|
||||||
return embed;
|
return embed;
|
||||||
}
|
}
|
||||||
|
@@ -123,6 +123,7 @@ public class TriviaGame
|
|||||||
//hint
|
//hint
|
||||||
await Task.Delay(_options.QuestionTimer * 1000 / 2, triviaCancelSource.Token);
|
await Task.Delay(_options.QuestionTimer * 1000 / 2, triviaCancelSource.Token);
|
||||||
if (!_options.NoHint)
|
if (!_options.NoHint)
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await questionMessage.ModifyAsync(m
|
await questionMessage.ModifyAsync(m
|
||||||
@@ -134,6 +135,7 @@ public class TriviaGame
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
catch (Exception ex) { Log.Warning(ex, "Error editing triva message"); }
|
catch (Exception ex) { Log.Warning(ex, "Error editing triva message"); }
|
||||||
|
}
|
||||||
|
|
||||||
//timeout
|
//timeout
|
||||||
await Task.Delay(_options.QuestionTimer * 1000 / 2, triviaCancelSource.Token);
|
await Task.Delay(_options.QuestionTimer * 1000 / 2, triviaCancelSource.Token);
|
||||||
@@ -147,6 +149,7 @@ public class TriviaGame
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!triviaCancelSource.IsCancellationRequested)
|
if (!triviaCancelSource.IsCancellationRequested)
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var embed = _eb.Create()
|
var embed = _eb.Create()
|
||||||
@@ -165,6 +168,7 @@ public class TriviaGame
|
|||||||
{
|
{
|
||||||
Log.Warning(ex, "Error sending trivia time's up message");
|
Log.Warning(ex, "Error sending trivia time's up message");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
await Task.Delay(5000);
|
await Task.Delay(5000);
|
||||||
}
|
}
|
||||||
@@ -186,6 +190,7 @@ public class TriviaGame
|
|||||||
var old = ShouldStopGame;
|
var old = ShouldStopGame;
|
||||||
ShouldStopGame = true;
|
ShouldStopGame = true;
|
||||||
if (!old)
|
if (!old)
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await Channel.SendConfirmAsync(_eb, GetText(strs.trivia_game), GetText(strs.trivia_stopping));
|
await Channel.SendConfirmAsync(_eb, GetText(strs.trivia_game), GetText(strs.trivia_stopping));
|
||||||
@@ -195,6 +200,7 @@ public class TriviaGame
|
|||||||
Log.Warning(ex, "Error sending trivia stopping message");
|
Log.Warning(ex, "Error sending trivia stopping message");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Task PotentialGuess(SocketMessage imsg)
|
private Task PotentialGuess(SocketMessage imsg)
|
||||||
{
|
{
|
||||||
|
@@ -232,13 +232,17 @@ public partial class Help : NadekoModule<HelpService>
|
|||||||
{
|
{
|
||||||
//if cross is specified, and the command doesn't satisfy the requirements, cross it out
|
//if cross is specified, and the command doesn't satisfy the requirements, cross it out
|
||||||
if (opts.View == CommandsOptions.ViewType.Cross)
|
if (opts.View == CommandsOptions.ViewType.Cross)
|
||||||
|
{
|
||||||
return
|
return
|
||||||
$"{(succ.Contains(x) ? "✅" : "❌")}{prefix + x.Aliases.First(),-15} {"[" + x.Aliases.Skip(1).FirstOrDefault() + "]",-8}";
|
$"{(succ.Contains(x) ? "✅" : "❌")}{prefix + x.Aliases.First(),-15} {"[" + x.Aliases.Skip(1).FirstOrDefault() + "]",-8}";
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
$"{prefix + x.Aliases.First(),-15} {"[" + x.Aliases.Skip(1).FirstOrDefault() + "]",-8}";
|
$"{prefix + x.Aliases.First(),-15} {"[" + x.Aliases.Skip(1).FirstOrDefault() + "]",-8}";
|
||||||
});
|
});
|
||||||
|
|
||||||
if (i == last - 1 && (i + 1) % 2 != 0)
|
if (i == last - 1 && (i + 1) % 2 != 0)
|
||||||
|
{
|
||||||
transformed = transformed.Chunk(2)
|
transformed = transformed.Chunk(2)
|
||||||
.Select(x =>
|
.Select(x =>
|
||||||
{
|
{
|
||||||
@@ -246,6 +250,8 @@ public partial class Help : NadekoModule<HelpService>
|
|||||||
return $"{x.First()}";
|
return $"{x.First()}";
|
||||||
return string.Concat(x);
|
return string.Concat(x);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
embed.AddField(g.ElementAt(i).Key, "```css\n" + string.Join("\n", transformed) + "\n```", true);
|
embed.AddField(g.ElementAt(i).Key, "```css\n" + string.Join("\n", transformed) + "\n```", true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -288,9 +288,7 @@ public sealed partial class Music : NadekoModule<IMusicService>
|
|||||||
// if (mps > 0)
|
// if (mps > 0)
|
||||||
// add += Format.Bold(GetText(strs.song_skips_after(TimeSpan.FromSeconds(mps).ToString("HH\\:mm\\:ss")))) + "\n";
|
// add += Format.Bold(GetText(strs.song_skips_after(TimeSpan.FromSeconds(mps).ToString("HH\\:mm\\:ss")))) + "\n";
|
||||||
if (repeatType == PlayerRepeatType.Track)
|
if (repeatType == PlayerRepeatType.Track)
|
||||||
{
|
|
||||||
add += "🔂 " + GetText(strs.repeating_track) + "\n";
|
add += "🔂 " + GetText(strs.repeating_track) + "\n";
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// if (mp.Autoplay)
|
// if (mp.Autoplay)
|
||||||
|
@@ -69,6 +69,7 @@ public sealed partial class Music
|
|||||||
var pl = uow.MusicPlaylists.FirstOrDefault(x => x.Id == id);
|
var pl = uow.MusicPlaylists.FirstOrDefault(x => x.Id == id);
|
||||||
|
|
||||||
if (pl is not null)
|
if (pl is not 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);
|
uow.MusicPlaylists.Remove(pl);
|
||||||
@@ -76,6 +77,7 @@ public sealed partial class Music
|
|||||||
success = true;
|
success = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Warning(ex, "Error deleting playlist");
|
Log.Warning(ex, "Error deleting playlist");
|
||||||
|
@@ -219,8 +219,10 @@ public sealed class MusicService : IMusicService
|
|||||||
=> _ =>
|
=> _ =>
|
||||||
{
|
{
|
||||||
if (_settings.TryGetValue(guildId, out var settings))
|
if (_settings.TryGetValue(guildId, out var settings))
|
||||||
|
{
|
||||||
if (settings.AutoDisconnect)
|
if (settings.AutoDisconnect)
|
||||||
return LeaveVoiceChannelAsync(guildId);
|
return LeaveVoiceChannelAsync(guildId);
|
||||||
|
}
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
};
|
};
|
||||||
@@ -232,9 +234,11 @@ public sealed class MusicService : IMusicService
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (mp.IsStopped)
|
if (mp.IsStopped)
|
||||||
|
{
|
||||||
if (!_voiceStateService.TryGetProxy(guildId, out var proxy)
|
if (!_voiceStateService.TryGetProxy(guildId, out var proxy)
|
||||||
|| proxy.State == VoiceProxy.VoiceProxyState.Stopped)
|
|| proxy.State == VoiceProxy.VoiceProxyState.Stopped)
|
||||||
await JoinVoiceChannelAsync(guildId, voiceChannelId);
|
await JoinVoiceChannelAsync(guildId, voiceChannelId);
|
||||||
|
}
|
||||||
|
|
||||||
mp.Next();
|
mp.Next();
|
||||||
return true;
|
return true;
|
||||||
|
@@ -44,6 +44,7 @@ public class RadioResolver : IRadioResolver
|
|||||||
if (query.Contains(".pls"))
|
if (query.Contains(".pls"))
|
||||||
//File1=http://armitunes.com:8000/
|
//File1=http://armitunes.com:8000/
|
||||||
//Regex.Match(query)
|
//Regex.Match(query)
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var m = _plsRegex.Match(file);
|
var m = _plsRegex.Match(file);
|
||||||
@@ -55,6 +56,7 @@ public class RadioResolver : IRadioResolver
|
|||||||
Log.Warning("Failed reading .pls:\n{PlsFile}", file);
|
Log.Warning("Failed reading .pls:\n{PlsFile}", file);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (query.Contains(".m3u"))
|
if (query.Contains(".m3u"))
|
||||||
/*
|
/*
|
||||||
@@ -62,6 +64,7 @@ public class RadioResolver : IRadioResolver
|
|||||||
C:\xxx4xx\xxxxxx3x\xx2xxxx\xx.mp3
|
C:\xxx4xx\xxxxxx3x\xx2xxxx\xx.mp3
|
||||||
C:\xxx5xx\x6xxxxxx\x7xxxxx\xx.mp3
|
C:\xxx5xx\x6xxxxxx\x7xxxxx\xx.mp3
|
||||||
*/
|
*/
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var m = _m3URegex.Match(file);
|
var m = _m3URegex.Match(file);
|
||||||
@@ -73,9 +76,11 @@ public class RadioResolver : IRadioResolver
|
|||||||
Log.Warning("Failed reading .m3u:\n{M3uFile}", file);
|
Log.Warning("Failed reading .m3u:\n{M3uFile}", file);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (query.Contains(".asx"))
|
if (query.Contains(".asx"))
|
||||||
//<ref href="http://armitunes.com:8000"/>
|
//<ref href="http://armitunes.com:8000"/>
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var m = _asxRegex.Match(file);
|
var m = _asxRegex.Match(file);
|
||||||
@@ -87,6 +92,7 @@ public class RadioResolver : IRadioResolver
|
|||||||
Log.Warning("Failed reading .asx:\n{AsxFile}", file);
|
Log.Warning("Failed reading .asx:\n{AsxFile}", file);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (query.Contains(".xspf"))
|
if (query.Contains(".xspf"))
|
||||||
/*
|
/*
|
||||||
@@ -95,6 +101,7 @@ public class RadioResolver : IRadioResolver
|
|||||||
<trackList>
|
<trackList>
|
||||||
<track><location>file:///mp3s/song_1.mp3</location></track>
|
<track><location>file:///mp3s/song_1.mp3</location></track>
|
||||||
*/
|
*/
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var m = _xspfRegex.Match(file);
|
var m = _xspfRegex.Match(file);
|
||||||
@@ -106,6 +113,7 @@ public class RadioResolver : IRadioResolver
|
|||||||
Log.Warning("Failed reading .xspf:\n{XspfFile}", file);
|
Log.Warning("Failed reading .xspf:\n{XspfFile}", file);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
|
@@ -205,10 +205,8 @@ public sealed class YtdlYoutubeResolver : IYoutubeResolver
|
|||||||
yield return info;
|
yield return info;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
data += Environment.NewLine;
|
data += Environment.NewLine;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
await _trackCacher.CachePlaylistTrackIdsAsync(playlistId, MusicPlatform.Youtube, trackIds);
|
await _trackCacher.CachePlaylistTrackIdsAsync(playlistId, MusicPlatform.Youtube, trackIds);
|
||||||
}
|
}
|
||||||
|
@@ -81,9 +81,7 @@ public partial class NSFW : NadekoModule<ISearchImagesService>
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (tags is null || tags.Length == 0)
|
if (tags is null || tags.Length == 0)
|
||||||
{
|
|
||||||
await InternalDapiCommand(null, true, _service.Hentai);
|
await InternalDapiCommand(null, true, _service.Hentai);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var groups = tags.Split('|');
|
var groups = tags.Split('|');
|
||||||
|
@@ -245,9 +245,7 @@ public class SearchImageCacher : INService
|
|||||||
page = _rng.Next(0, maxPage);
|
page = _rng.Next(0, maxPage);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
page = _rng.Next(0, 11);
|
page = _rng.Next(0, 11);
|
||||||
}
|
|
||||||
|
|
||||||
var result = await DownloadImagesAsync(tags, isExplicit, type, page, cancel);
|
var result = await DownloadImagesAsync(tags, isExplicit, type, page, cancel);
|
||||||
|
|
||||||
|
@@ -75,11 +75,13 @@ public class SearchImagesService : ISearchImagesService, INService
|
|||||||
CancellationToken cancel)
|
CancellationToken cancel)
|
||||||
{
|
{
|
||||||
if (!tags.All(x => IsValidTag(x)))
|
if (!tags.All(x => IsValidTag(x)))
|
||||||
|
{
|
||||||
return new()
|
return new()
|
||||||
{
|
{
|
||||||
Error = "One or more tags are invalid.",
|
Error = "One or more tags are invalid.",
|
||||||
Url = ""
|
Url = ""
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
Log.Information("Getting {V} image for Guild: {GuildId}...", dapi.ToString(), guildId);
|
Log.Information("Getting {V} image for Guild: {GuildId}...", dapi.ToString(), guildId);
|
||||||
try
|
try
|
||||||
@@ -87,27 +89,33 @@ public class SearchImagesService : ISearchImagesService, INService
|
|||||||
BlacklistedTags.TryGetValue(guildId, out var blTags);
|
BlacklistedTags.TryGetValue(guildId, out var blTags);
|
||||||
|
|
||||||
if (dapi == Booru.E621)
|
if (dapi == Booru.E621)
|
||||||
|
{
|
||||||
for (var i = 0; i < tags.Length; ++i)
|
for (var i = 0; i < tags.Length; ++i)
|
||||||
{
|
{
|
||||||
if (tags[i] == "yuri")
|
if (tags[i] == "yuri")
|
||||||
tags[i] = "female/female";
|
tags[i] = "female/female";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (dapi == Booru.Derpibooru)
|
if (dapi == Booru.Derpibooru)
|
||||||
|
{
|
||||||
for (var i = 0; i < tags.Length; ++i)
|
for (var i = 0; i < tags.Length; ++i)
|
||||||
{
|
{
|
||||||
if (tags[i] == "yuri")
|
if (tags[i] == "yuri")
|
||||||
tags[i] = "lesbian";
|
tags[i] = "lesbian";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var result = await _cache.GetImageNew(tags, forceExplicit, dapi, blTags ?? new HashSet<string>(), cancel);
|
var result = await _cache.GetImageNew(tags, forceExplicit, dapi, blTags ?? new HashSet<string>(), cancel);
|
||||||
|
|
||||||
if (result is null)
|
if (result is null)
|
||||||
|
{
|
||||||
return new()
|
return new()
|
||||||
{
|
{
|
||||||
Error = "Image not found.",
|
Error = "Image not found.",
|
||||||
Url = ""
|
Url = ""
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
var reply = new UrlReply
|
var reply = new UrlReply
|
||||||
{
|
{
|
||||||
|
@@ -129,11 +129,15 @@ public partial class Permissions
|
|||||||
_service.UnBlacklist(type, id);
|
_service.UnBlacklist(type, id);
|
||||||
|
|
||||||
if (action == AddRemove.Add)
|
if (action == AddRemove.Add)
|
||||||
|
{
|
||||||
await ReplyConfirmLocalizedAsync(strs.blacklisted(Format.Code(type.ToString()),
|
await ReplyConfirmLocalizedAsync(strs.blacklisted(Format.Code(type.ToString()),
|
||||||
Format.Code(id.ToString())));
|
Format.Code(id.ToString())));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
await ReplyConfirmLocalizedAsync(strs.unblacklisted(Format.Code(type.ToString()),
|
await ReplyConfirmLocalizedAsync(strs.unblacklisted(Format.Code(type.ToString()),
|
||||||
Format.Code(id.ToString())));
|
Format.Code(id.ToString())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@@ -69,10 +69,8 @@ public partial class Permissions
|
|||||||
await ReplyConfirmLocalizedAsync(strs.cmdcd_cleared(Format.Bold(name)));
|
await ReplyConfirmLocalizedAsync(strs.cmdcd_cleared(Format.Bold(name)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
await ReplyConfirmLocalizedAsync(strs.cmdcd_add(Format.Bold(name), Format.Bold(secs.ToString())));
|
await ReplyConfirmLocalizedAsync(strs.cmdcd_add(Format.Bold(name), Format.Bold(secs.ToString())));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
@@ -84,10 +82,12 @@ public partial class Permissions
|
|||||||
if (!localSet.Any())
|
if (!localSet.Any())
|
||||||
await ReplyConfirmLocalizedAsync(strs.cmdcd_none);
|
await ReplyConfirmLocalizedAsync(strs.cmdcd_none);
|
||||||
else
|
else
|
||||||
|
{
|
||||||
await channel.SendTableAsync("",
|
await channel.SendTableAsync("",
|
||||||
localSet.Select(c => c.CommandName + ": " + c.Seconds + GetText(strs.sec)),
|
localSet.Select(c => c.CommandName + ": " + c.Seconds + GetText(strs.sec)),
|
||||||
s => $"{s,-30}",
|
s => $"{s,-30}",
|
||||||
2);
|
2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@@ -230,10 +230,12 @@ public partial class Permissions
|
|||||||
removed = config.FilteredWords.FirstOrDefault(fw => fw.Word.Trim().ToLowerInvariant() == word);
|
removed = config.FilteredWords.FirstOrDefault(fw => fw.Word.Trim().ToLowerInvariant() == word);
|
||||||
|
|
||||||
if (removed is null)
|
if (removed is null)
|
||||||
|
{
|
||||||
config.FilteredWords.Add(new()
|
config.FilteredWords.Add(new()
|
||||||
{
|
{
|
||||||
Word = word
|
Word = word
|
||||||
});
|
});
|
||||||
|
}
|
||||||
else
|
else
|
||||||
uow.Remove(removed);
|
uow.Remove(removed);
|
||||||
|
|
||||||
|
@@ -132,6 +132,7 @@ public sealed class FilterService : IEarlyBehavior
|
|||||||
var filteredServerWords = FilteredWordsForServer(guild.Id) ?? new ConcurrentHashSet<string>();
|
var filteredServerWords = FilteredWordsForServer(guild.Id) ?? new ConcurrentHashSet<string>();
|
||||||
var wordsInMessage = usrMsg.Content.ToLowerInvariant().Split(' ');
|
var wordsInMessage = usrMsg.Content.ToLowerInvariant().Split(' ');
|
||||||
if (filteredChannelWords.Count != 0 || filteredServerWords.Count != 0)
|
if (filteredChannelWords.Count != 0 || filteredServerWords.Count != 0)
|
||||||
|
{
|
||||||
foreach (var word in wordsInMessage)
|
foreach (var word in wordsInMessage)
|
||||||
{
|
{
|
||||||
if (filteredChannelWords.Contains(word) || filteredServerWords.Contains(word))
|
if (filteredChannelWords.Contains(word) || filteredServerWords.Contains(word))
|
||||||
@@ -155,6 +156,7 @@ public sealed class FilterService : IEarlyBehavior
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@@ -43,9 +43,7 @@ public class GlobalPermissionService : ILateBlocker, INService
|
|||||||
_bss.ModifyConfig(bs =>
|
_bss.ModifyConfig(bs =>
|
||||||
{
|
{
|
||||||
if (bs.Blocked.Modules.Add(moduleName))
|
if (bs.Blocked.Modules.Add(moduleName))
|
||||||
{
|
|
||||||
added = true;
|
added = true;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bs.Blocked.Modules.Remove(moduleName);
|
bs.Blocked.Modules.Remove(moduleName);
|
||||||
@@ -67,9 +65,7 @@ public class GlobalPermissionService : ILateBlocker, INService
|
|||||||
_bss.ModifyConfig(bs =>
|
_bss.ModifyConfig(bs =>
|
||||||
{
|
{
|
||||||
if (bs.Blocked.Commands.Add(commandName))
|
if (bs.Blocked.Commands.Add(commandName))
|
||||||
{
|
|
||||||
added = true;
|
added = true;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bs.Blocked.Commands.Remove(commandName);
|
bs.Blocked.Commands.Remove(commandName);
|
||||||
|
@@ -155,6 +155,7 @@ public partial class Permissions : NadekoModule<PermissionService>
|
|||||||
from -= 1;
|
from -= 1;
|
||||||
to -= 1;
|
to -= 1;
|
||||||
if (!(from == to || from < 0 || to < 0))
|
if (!(from == to || from < 0 || to < 0))
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Permissionv2 fromPerm;
|
Permissionv2 fromPerm;
|
||||||
@@ -163,12 +164,12 @@ public partial class Permissions : NadekoModule<PermissionService>
|
|||||||
var config = uow.GcWithPermissionsFor(ctx.Guild.Id);
|
var config = uow.GcWithPermissionsFor(ctx.Guild.Id);
|
||||||
var permsCol = new PermissionsCollection<Permissionv2>(config.Permissions);
|
var permsCol = new PermissionsCollection<Permissionv2>(config.Permissions);
|
||||||
|
|
||||||
var fromFound = from < permsCol.Count;
|
var fromFound = @from < permsCol.Count;
|
||||||
var toFound = to < permsCol.Count;
|
var toFound = to < permsCol.Count;
|
||||||
|
|
||||||
if (!fromFound)
|
if (!fromFound)
|
||||||
{
|
{
|
||||||
await ReplyErrorLocalizedAsync(strs.perm_not_found(++from));
|
await ReplyErrorLocalizedAsync(strs.perm_not_found(++@from));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,9 +179,9 @@ public partial class Permissions : NadekoModule<PermissionService>
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fromPerm = permsCol[from];
|
fromPerm = permsCol[@from];
|
||||||
|
|
||||||
permsCol.RemoveAt(from);
|
permsCol.RemoveAt(@from);
|
||||||
permsCol.Insert(to, fromPerm);
|
permsCol.Insert(to, fromPerm);
|
||||||
await uow.SaveChangesAsync();
|
await uow.SaveChangesAsync();
|
||||||
_service.UpdateCache(config);
|
_service.UpdateCache(config);
|
||||||
@@ -188,7 +189,7 @@ public partial class Permissions : NadekoModule<PermissionService>
|
|||||||
|
|
||||||
await ReplyConfirmLocalizedAsync(strs.moved_permission(
|
await ReplyConfirmLocalizedAsync(strs.moved_permission(
|
||||||
Format.Code(fromPerm.GetCommand(prefix, (SocketGuild)ctx.Guild)),
|
Format.Code(fromPerm.GetCommand(prefix, (SocketGuild)ctx.Guild)),
|
||||||
++from,
|
++@from,
|
||||||
++to));
|
++to));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -196,6 +197,7 @@ public partial class Permissions : NadekoModule<PermissionService>
|
|||||||
catch (Exception e) when (e is ArgumentOutOfRangeException or IndexOutOfRangeException)
|
catch (Exception e) when (e is ArgumentOutOfRangeException or IndexOutOfRangeException)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
await ReplyConfirmLocalizedAsync(strs.perm_out_of_range);
|
await ReplyConfirmLocalizedAsync(strs.perm_out_of_range);
|
||||||
}
|
}
|
||||||
@@ -257,14 +259,18 @@ public partial class Permissions : NadekoModule<PermissionService>
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (action.Value)
|
if (action.Value)
|
||||||
|
{
|
||||||
await ReplyConfirmLocalizedAsync(strs.ux_enable(Format.Code(command.Name),
|
await ReplyConfirmLocalizedAsync(strs.ux_enable(Format.Code(command.Name),
|
||||||
GetText(strs.of_command),
|
GetText(strs.of_command),
|
||||||
Format.Code(user.ToString())));
|
Format.Code(user.ToString())));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
await ReplyConfirmLocalizedAsync(strs.ux_disable(Format.Code(command.Name),
|
await ReplyConfirmLocalizedAsync(strs.ux_disable(Format.Code(command.Name),
|
||||||
GetText(strs.of_command),
|
GetText(strs.of_command),
|
||||||
Format.Code(user.ToString())));
|
Format.Code(user.ToString())));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
@@ -281,14 +287,18 @@ public partial class Permissions : NadekoModule<PermissionService>
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (action.Value)
|
if (action.Value)
|
||||||
|
{
|
||||||
await ReplyConfirmLocalizedAsync(strs.ux_enable(Format.Code(module.Name),
|
await ReplyConfirmLocalizedAsync(strs.ux_enable(Format.Code(module.Name),
|
||||||
GetText(strs.of_module),
|
GetText(strs.of_module),
|
||||||
Format.Code(user.ToString())));
|
Format.Code(user.ToString())));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
await ReplyConfirmLocalizedAsync(strs.ux_disable(Format.Code(module.Name),
|
await ReplyConfirmLocalizedAsync(strs.ux_disable(Format.Code(module.Name),
|
||||||
GetText(strs.of_module),
|
GetText(strs.of_module),
|
||||||
Format.Code(user.ToString())));
|
Format.Code(user.ToString())));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
@@ -309,14 +319,18 @@ public partial class Permissions : NadekoModule<PermissionService>
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (action.Value)
|
if (action.Value)
|
||||||
|
{
|
||||||
await ReplyConfirmLocalizedAsync(strs.rx_enable(Format.Code(command.Name),
|
await ReplyConfirmLocalizedAsync(strs.rx_enable(Format.Code(command.Name),
|
||||||
GetText(strs.of_command),
|
GetText(strs.of_command),
|
||||||
Format.Code(role.Name)));
|
Format.Code(role.Name)));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
await ReplyConfirmLocalizedAsync(strs.rx_disable(Format.Code(command.Name),
|
await ReplyConfirmLocalizedAsync(strs.rx_disable(Format.Code(command.Name),
|
||||||
GetText(strs.of_command),
|
GetText(strs.of_command),
|
||||||
Format.Code(role.Name)));
|
Format.Code(role.Name)));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
@@ -337,14 +351,18 @@ public partial class Permissions : NadekoModule<PermissionService>
|
|||||||
|
|
||||||
|
|
||||||
if (action.Value)
|
if (action.Value)
|
||||||
|
{
|
||||||
await ReplyConfirmLocalizedAsync(strs.rx_enable(Format.Code(module.Name),
|
await ReplyConfirmLocalizedAsync(strs.rx_enable(Format.Code(module.Name),
|
||||||
GetText(strs.of_module),
|
GetText(strs.of_module),
|
||||||
Format.Code(role.Name)));
|
Format.Code(role.Name)));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
await ReplyConfirmLocalizedAsync(strs.rx_disable(Format.Code(module.Name),
|
await ReplyConfirmLocalizedAsync(strs.rx_disable(Format.Code(module.Name),
|
||||||
GetText(strs.of_module),
|
GetText(strs.of_module),
|
||||||
Format.Code(role.Name)));
|
Format.Code(role.Name)));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
@@ -362,14 +380,18 @@ public partial class Permissions : NadekoModule<PermissionService>
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (action.Value)
|
if (action.Value)
|
||||||
|
{
|
||||||
await ReplyConfirmLocalizedAsync(strs.cx_enable(Format.Code(command.Name),
|
await ReplyConfirmLocalizedAsync(strs.cx_enable(Format.Code(command.Name),
|
||||||
GetText(strs.of_command),
|
GetText(strs.of_command),
|
||||||
Format.Code(chnl.Name)));
|
Format.Code(chnl.Name)));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
await ReplyConfirmLocalizedAsync(strs.cx_disable(Format.Code(command.Name),
|
await ReplyConfirmLocalizedAsync(strs.cx_disable(Format.Code(command.Name),
|
||||||
GetText(strs.of_command),
|
GetText(strs.of_command),
|
||||||
Format.Code(chnl.Name)));
|
Format.Code(chnl.Name)));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
@@ -386,14 +408,18 @@ public partial class Permissions : NadekoModule<PermissionService>
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (action.Value)
|
if (action.Value)
|
||||||
|
{
|
||||||
await ReplyConfirmLocalizedAsync(strs.cx_enable(Format.Code(module.Name),
|
await ReplyConfirmLocalizedAsync(strs.cx_enable(Format.Code(module.Name),
|
||||||
GetText(strs.of_module),
|
GetText(strs.of_module),
|
||||||
Format.Code(chnl.Name)));
|
Format.Code(chnl.Name)));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
await ReplyConfirmLocalizedAsync(strs.cx_disable(Format.Code(module.Name),
|
await ReplyConfirmLocalizedAsync(strs.cx_disable(Format.Code(module.Name),
|
||||||
GetText(strs.of_module),
|
GetText(strs.of_module),
|
||||||
Format.Code(chnl.Name)));
|
Format.Code(chnl.Name)));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
|
@@ -112,6 +112,7 @@ public class PermissionService : ILateBlocker, INService
|
|||||||
if (!resetCommand && !pc.Permissions.CheckPermissions(msg, commandName, moduleName, out var index))
|
if (!resetCommand && !pc.Permissions.CheckPermissions(msg, commandName, moduleName, out var index))
|
||||||
{
|
{
|
||||||
if (pc.Verbose)
|
if (pc.Verbose)
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await channel.SendErrorAsync(_eb,
|
await channel.SendErrorAsync(_eb,
|
||||||
@@ -123,6 +124,7 @@ public class PermissionService : ILateBlocker, INService
|
|||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -145,8 +147,10 @@ public class PermissionService : ILateBlocker, INService
|
|||||||
{
|
{
|
||||||
returnMsg = "You need Admin permissions in order to use permission commands.";
|
returnMsg = "You need Admin permissions in order to use permission commands.";
|
||||||
if (pc.Verbose)
|
if (pc.Verbose)
|
||||||
|
{
|
||||||
try { await channel.SendErrorAsync(_eb, returnMsg); }
|
try { await channel.SendErrorAsync(_eb, returnMsg); }
|
||||||
catch { }
|
catch { }
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -155,8 +159,10 @@ public class PermissionService : ILateBlocker, INService
|
|||||||
{
|
{
|
||||||
returnMsg = $"You need the {Format.Bold(role.Name)} role in order to use permission commands.";
|
returnMsg = $"You need the {Format.Bold(role.Name)} role in order to use permission commands.";
|
||||||
if (pc.Verbose)
|
if (pc.Verbose)
|
||||||
|
{
|
||||||
try { await channel.SendErrorAsync(_eb, returnMsg); }
|
try { await channel.SendErrorAsync(_eb, returnMsg); }
|
||||||
catch { }
|
catch { }
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@@ -65,6 +65,7 @@ public partial class Searches
|
|||||||
|
|
||||||
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",
|
favAnime = string.Join("\n",
|
||||||
favorites[0]
|
favorites[0]
|
||||||
.QuerySelectorAll("ul > li > div.di-tc.va-t > a")
|
.QuerySelectorAll("ul > li > div.di-tc.va-t > a")
|
||||||
@@ -75,6 +76,7 @@ public partial class Searches
|
|||||||
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))
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
#nullable disable
|
#nullable disable
|
||||||
using NadekoBot.Modules.Searches.Services;
|
using NadekoBot.Modules.Searches.Services;
|
||||||
|
using System.Globalization;
|
||||||
|
|
||||||
namespace NadekoBot.Modules.Searches;
|
namespace NadekoBot.Modules.Searches;
|
||||||
|
|
||||||
@@ -36,30 +37,50 @@ public partial class Searches
|
|||||||
|
|
||||||
var usd = crypto.Quote["USD"];
|
var usd = crypto.Quote["USD"];
|
||||||
|
|
||||||
var sevenDay = usd.PercentChange7d.ToString("F2", Culture);
|
var localCulture = (CultureInfo)Culture.Clone();
|
||||||
var lastDay = usd.PercentChange24h.ToString("F2", Culture);
|
localCulture.NumberFormat.CurrencySymbol = "$";
|
||||||
|
|
||||||
|
var sevenDay = (usd.PercentChange7d / 100).ToString("P2", localCulture);
|
||||||
|
var lastDay = (usd.PercentChange24h / 100).ToString("P2", localCulture);
|
||||||
var price = usd.Price < 0.01
|
var price = usd.Price < 0.01
|
||||||
? usd.Price.ToString(Culture)
|
? usd.Price.ToString(localCulture)
|
||||||
: usd.Price.ToString("F2", Culture);
|
: usd.Price.ToString("C2", localCulture);
|
||||||
|
|
||||||
var volume = usd.Volume24h.ToString("n0", Culture);
|
var volume = usd.Volume24h.ToString("C0", localCulture);
|
||||||
var marketCap = usd.MarketCap.ToString("n0", Culture);
|
var marketCap = usd.MarketCap.ToString("C0", localCulture);
|
||||||
|
var dominance = (usd.MarketCapDominance / 100).ToString("P2", localCulture);
|
||||||
|
|
||||||
await ctx.Channel.EmbedAsync(_eb.Create()
|
var toSend = _eb.Create()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithAuthor($"#{crypto.CmcRank}")
|
.WithAuthor($"#{crypto.CmcRank}")
|
||||||
.WithTitle($"{crypto.Name} ({crypto.Symbol})")
|
.WithTitle($"{crypto.Name} ({crypto.Symbol})")
|
||||||
.WithUrl($"https://coinmarketcap.com/currencies/{crypto.Slug}/")
|
.WithUrl($"https://coinmarketcap.com/currencies/{crypto.Slug}/")
|
||||||
.WithThumbnailUrl(
|
.WithThumbnailUrl( $"https://s3.coinmarketcap.com/static/img/coins/128x128/{crypto.Id}.png")
|
||||||
$"https://s3.coinmarketcap.com/static/img/coins/128x128/{crypto.Id}.png")
|
.AddField(GetText(strs.market_cap), marketCap, true)
|
||||||
.AddField(GetText(strs.market_cap),
|
.AddField(GetText(strs.price), price, true)
|
||||||
$"${marketCap}",
|
.AddField(GetText(strs.volume_24h), volume, true)
|
||||||
true)
|
.AddField(GetText(strs.change_7d_24h), $"{sevenDay} / {lastDay}", true)
|
||||||
.AddField(GetText(strs.price), $"${price}", true)
|
.AddField(GetText(strs.market_cap_dominance), dominance, true)
|
||||||
.AddField(GetText(strs.volume_24h), $"${volume}", true)
|
.WithImageUrl($"https://s3.coinmarketcap.com/generated/sparklines/web/7d/usd/{crypto.Id}.png");
|
||||||
.AddField(GetText(strs.change_7d_24h), $"{sevenDay}% / {lastDay}%", true)
|
|
||||||
.WithImageUrl(
|
if (crypto.CirculatingSupply is double cs)
|
||||||
$"https://s3.coinmarketcap.com/generated/sparklines/web/7d/usd/{crypto.Id}.png"));
|
{
|
||||||
|
var csStr = cs.ToString("N0", localCulture);
|
||||||
|
|
||||||
|
if (crypto.MaxSupply is double ms)
|
||||||
|
{
|
||||||
|
var perc = (cs / ms).ToString("P1", localCulture);
|
||||||
|
|
||||||
|
toSend.AddField(GetText(strs.circulating_supply), $"{csStr} ({perc})", true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
toSend.AddField(GetText(strs.circulating_supply), csStr, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
await ctx.Channel.EmbedAsync(toSend);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -69,8 +69,10 @@ public class FeedsService : INService
|
|||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
if (!_lastPosts.TryGetValue(kvp.Key, out var lastFeedUpdate))
|
if (!_lastPosts.TryGetValue(kvp.Key, out var lastFeedUpdate))
|
||||||
|
{
|
||||||
lastFeedUpdate = _lastPosts[kvp.Key] =
|
lastFeedUpdate = _lastPosts[kvp.Key] =
|
||||||
items.Any() ? items[items.Count - 1].LastUpdate : DateTime.UtcNow;
|
items.Any() ? items[items.Count - 1].LastUpdate : DateTime.UtcNow;
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var (feedItem, itemUpdateDate) in items)
|
foreach (var (feedItem, itemUpdateDate) in items)
|
||||||
{
|
{
|
||||||
@@ -106,8 +108,10 @@ public class FeedsService : INService
|
|||||||
.FirstOrDefault(x => x.Name.LocalName == "preview");
|
.FirstOrDefault(x => x.Name.LocalName == "preview");
|
||||||
|
|
||||||
if (previewElement is null)
|
if (previewElement is null)
|
||||||
|
{
|
||||||
previewElement = afi.Element.Elements()
|
previewElement = afi.Element.Elements()
|
||||||
.FirstOrDefault(x => x.Name.LocalName == "thumbnail");
|
.FirstOrDefault(x => x.Name.LocalName == "thumbnail");
|
||||||
|
}
|
||||||
|
|
||||||
if (previewElement is not null)
|
if (previewElement is not null)
|
||||||
{
|
{
|
||||||
|
@@ -251,9 +251,7 @@ public partial class Searches
|
|||||||
|
|
||||||
// poe.ninja API does not include a "chaosEquivalent" property for Chaos Orbs.
|
// poe.ninja API does not include a "chaosEquivalent" property for Chaos Orbs.
|
||||||
if (cleanCurrency == "Chaos Orb")
|
if (cleanCurrency == "Chaos Orb")
|
||||||
{
|
|
||||||
chaosEquivalent = 1.0F;
|
chaosEquivalent = 1.0F;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var currencyInput = obj["lines"]
|
var currencyInput = obj["lines"]
|
||||||
@@ -265,9 +263,7 @@ public partial class Searches
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cleanConvert == "Chaos Orb")
|
if (cleanConvert == "Chaos Orb")
|
||||||
{
|
|
||||||
conversionEquivalent = 1.0F;
|
conversionEquivalent = 1.0F;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var currencyOutput = obj["lines"]
|
var currencyOutput = obj["lines"]
|
||||||
|
@@ -60,9 +60,7 @@ public partial class Searches : NadekoModule<SearchesService>
|
|||||||
var data = await _service.GetWeatherDataAsync(query);
|
var data = await _service.GetWeatherDataAsync(query);
|
||||||
|
|
||||||
if (data is null)
|
if (data is null)
|
||||||
{
|
|
||||||
embed.WithDescription(GetText(strs.city_not_found)).WithErrorColor();
|
embed.WithDescription(GetText(strs.city_not_found)).WithErrorColor();
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var f = StandardConversions.CelsiusToFahrenheit;
|
var f = StandardConversions.CelsiusToFahrenheit;
|
||||||
@@ -284,6 +282,7 @@ public partial class Searches : NadekoModule<SearchesService>
|
|||||||
|
|
||||||
query = query.Trim();
|
query = query.Trim();
|
||||||
if (!_cachedShortenedLinks.TryGetValue(query, out var shortLink))
|
if (!_cachedShortenedLinks.TryGetValue(query, out var shortLink))
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using var http = _httpFactory.CreateClient();
|
using var http = _httpFactory.CreateClient();
|
||||||
@@ -310,6 +309,7 @@ public partial class Searches : NadekoModule<SearchesService>
|
|||||||
Log.Error(ex, "Error shortening a link: {Message}", ex.Message);
|
Log.Error(ex, "Error shortening a link: {Message}", ex.Message);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
await ctx.Channel.EmbedAsync(_eb.Create()
|
await ctx.Channel.EmbedAsync(_eb.Create()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
@@ -693,9 +693,7 @@ public partial class Searches : NadekoModule<SearchesService>
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (obj.Error is not null || obj.Verses is null || obj.Verses.Length == 0)
|
if (obj.Error is not null || obj.Verses is null || obj.Verses.Length == 0)
|
||||||
{
|
|
||||||
await SendErrorAsync(obj.Error ?? "No verse found.");
|
await SendErrorAsync(obj.Error ?? "No verse found.");
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var v = obj.Verses[0];
|
var v = obj.Verses[0];
|
||||||
|
@@ -76,9 +76,7 @@ public class SearchesService : INService
|
|||||||
Log.Warning("data/magicitems.json is missing. Magic items are not loaded");
|
Log.Warning("data/magicitems.json is missing. Magic items are not loaded");
|
||||||
|
|
||||||
if (File.Exists("data/yomama.txt"))
|
if (File.Exists("data/yomama.txt"))
|
||||||
{
|
|
||||||
_yomamaJokes = File.ReadAllLines("data/yomama.txt").Shuffle().ToList();
|
_yomamaJokes = File.ReadAllLines("data/yomama.txt").Shuffle().ToList();
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_yomamaJokes = new();
|
_yomamaJokes = new();
|
||||||
|
@@ -172,8 +172,10 @@ public partial class Searches
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (data.IsLive)
|
if (data.IsLive)
|
||||||
|
{
|
||||||
await ReplyConfirmLocalizedAsync(strs.streamer_online(Format.Bold(data.Name),
|
await ReplyConfirmLocalizedAsync(strs.streamer_online(Format.Bold(data.Name),
|
||||||
Format.Bold(data.Viewers.ToString())));
|
Format.Bold(data.Viewers.ToString())));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
await ReplyConfirmLocalizedAsync(strs.streamer_offline(data.Name));
|
await ReplyConfirmLocalizedAsync(strs.streamer_offline(data.Name));
|
||||||
}
|
}
|
||||||
|
@@ -185,11 +185,13 @@ public sealed class StreamNotificationService : INService, IReadyExecutor
|
|||||||
if (_trackCounter.ContainsKey(key))
|
if (_trackCounter.ContainsKey(key))
|
||||||
_trackCounter[key].Add(info.GuildId);
|
_trackCounter[key].Add(info.GuildId);
|
||||||
else
|
else
|
||||||
|
{
|
||||||
_trackCounter[key] = new()
|
_trackCounter[key] = new()
|
||||||
{
|
{
|
||||||
info.GuildId
|
info.GuildId
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return default;
|
return default;
|
||||||
}
|
}
|
||||||
@@ -230,6 +232,7 @@ public sealed class StreamNotificationService : INService, IReadyExecutor
|
|||||||
{
|
{
|
||||||
var key = stream.CreateKey();
|
var key = stream.CreateKey();
|
||||||
if (_shardTrackedStreams.TryGetValue(key, out var fss))
|
if (_shardTrackedStreams.TryGetValue(key, out var fss))
|
||||||
|
{
|
||||||
await fss
|
await fss
|
||||||
// send offline stream notifications only to guilds which enable it with .stoff
|
// send offline stream notifications only to guilds which enable it with .stoff
|
||||||
.SelectMany(x => x.Value)
|
.SelectMany(x => x.Value)
|
||||||
@@ -240,6 +243,7 @@ public sealed class StreamNotificationService : INService, IReadyExecutor
|
|||||||
.WhenAll();
|
.WhenAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async ValueTask HandleStreamsOnline(List<StreamData> onlineStreams)
|
private async ValueTask HandleStreamsOnline(List<StreamData> onlineStreams)
|
||||||
{
|
{
|
||||||
@@ -247,6 +251,7 @@ public sealed class StreamNotificationService : INService, IReadyExecutor
|
|||||||
{
|
{
|
||||||
var key = stream.CreateKey();
|
var key = stream.CreateKey();
|
||||||
if (_shardTrackedStreams.TryGetValue(key, out var fss))
|
if (_shardTrackedStreams.TryGetValue(key, out var fss))
|
||||||
|
{
|
||||||
await fss.SelectMany(x => x.Value)
|
await fss.SelectMany(x => x.Value)
|
||||||
.Select(fs =>
|
.Select(fs =>
|
||||||
{
|
{
|
||||||
@@ -266,6 +271,7 @@ public sealed class StreamNotificationService : INService, IReadyExecutor
|
|||||||
.WhenAll();
|
.WhenAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Task OnStreamsOnline(List<StreamData> data)
|
private Task OnStreamsOnline(List<StreamData> data)
|
||||||
=> _pubSub.Pub(_streamsOnlineKey, data);
|
=> _pubSub.Pub(_streamsOnlineKey, data);
|
||||||
|
@@ -15,9 +15,12 @@ public class ImageCacherObject : IComparable<ImageCacherObject>
|
|||||||
if (type == Booru.Danbooru && !Uri.IsWellFormedUriString(obj.FileUrl, UriKind.Absolute))
|
if (type == Booru.Danbooru && !Uri.IsWellFormedUriString(obj.FileUrl, UriKind.Absolute))
|
||||||
FileUrl = "https://danbooru.donmai.us" + obj.FileUrl;
|
FileUrl = "https://danbooru.donmai.us" + obj.FileUrl;
|
||||||
else
|
else
|
||||||
|
{
|
||||||
FileUrl = obj.FileUrl.StartsWith("http", StringComparison.InvariantCulture)
|
FileUrl = obj.FileUrl.StartsWith("http", StringComparison.InvariantCulture)
|
||||||
? obj.FileUrl
|
? obj.FileUrl
|
||||||
: "https:" + obj.FileUrl;
|
: "https:" + obj.FileUrl;
|
||||||
|
}
|
||||||
|
|
||||||
SearchType = type;
|
SearchType = type;
|
||||||
Rating = obj.Rating;
|
Rating = obj.Rating;
|
||||||
Tags = new((obj.Tags ?? obj.TagString).Split(' '));
|
Tags = new((obj.Tags ?? obj.TagString).Split(' '));
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user