Compare commits
4 commits
7246c982df
...
69a02e0e15
Author | SHA1 | Date | |
---|---|---|---|
69a02e0e15 | |||
8d08595a9f | |||
1cbaaed944 | |||
a583c7d763 |
11 changed files with 190 additions and 86 deletions
16
CHANGELOG.md
16
CHANGELOG.md
|
@ -2,6 +2,22 @@
|
||||||
|
|
||||||
*a,c,f,r,o*
|
*a,c,f,r,o*
|
||||||
|
|
||||||
|
## [6.0.14]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Added `.notify <channel> nicecatch <message>` event
|
||||||
|
- It will show all rare fish/trash and all max star fish caught on any server
|
||||||
|
- You can use `.notifyphs nicecatch` to see the list of placeholders you can use while setting a message
|
||||||
|
- Example: `.notify #fishfeed nicecatch %user% just caught a %event.fish.stars% %event.fish.name% %event.fish.emoji%`
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- .notify commands now require Manage Messages permission
|
||||||
|
- .notify will now let you know if you can't set a notify message due to a missing channel
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Fixed `.antispamignore` restart persistence
|
||||||
|
- Fixed `.notify` events. Only levelup used to work
|
||||||
|
|
||||||
## [6.0.13] - 23.03.2025
|
## [6.0.13] - 23.03.2025
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
|
@ -21,5 +21,6 @@ public enum NotifyType
|
||||||
Protection = 1, Prot = 1,
|
Protection = 1, Prot = 1,
|
||||||
AddRoleReward = 2,
|
AddRoleReward = 2,
|
||||||
RemoveRoleReward = 3,
|
RemoveRoleReward = 3,
|
||||||
|
NiceCatch = 4,
|
||||||
// BigWin = 4,
|
// BigWin = 4,
|
||||||
}
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
#nullable disable
|
||||||
|
using EllieBot.Db.Models;
|
||||||
|
using EllieBot.Modules.Games;
|
||||||
|
|
||||||
|
namespace EllieBot.Modules.Administration.Services;
|
||||||
|
|
||||||
|
public record struct NiceCatchNotifyModel(
|
||||||
|
ulong UserId,
|
||||||
|
FishData Fish,
|
||||||
|
string Stars
|
||||||
|
) : INotifyModel<NiceCatchNotifyModel>
|
||||||
|
{
|
||||||
|
public static string KeyName
|
||||||
|
=> "notify.nicecatch";
|
||||||
|
|
||||||
|
public static NotifyType NotifyType
|
||||||
|
=> NotifyType.NiceCatch;
|
||||||
|
|
||||||
|
public const string PH_EMOJI = "fish.emoji";
|
||||||
|
public const string PH_IMAGE = "fish.image";
|
||||||
|
public const string PH_NAME = "fish.name";
|
||||||
|
public const string PH_STARS = "fish.stars";
|
||||||
|
public const string PH_FLUFF = "fish.fluff";
|
||||||
|
|
||||||
|
public bool TryGetUserId(out ulong userId)
|
||||||
|
{
|
||||||
|
userId = UserId;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IReadOnlyList<NotifyModelPlaceholderData<NiceCatchNotifyModel>> GetReplacements()
|
||||||
|
{
|
||||||
|
return
|
||||||
|
[
|
||||||
|
new(PH_EMOJI, static (data, _) => data.Fish.Emoji),
|
||||||
|
new(PH_IMAGE, static (data, _) => data.Fish.Image),
|
||||||
|
new(PH_NAME, static (data, _) => data.Fish.Name),
|
||||||
|
new(PH_STARS, static (data, _) => data.Stars),
|
||||||
|
new(PH_FLUFF, static (data, _) => data.Fish.Fluff),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,7 +8,7 @@ public partial class Administration
|
||||||
public class NotifyCommands : EllieModule<NotifyService>
|
public class NotifyCommands : EllieModule<NotifyService>
|
||||||
{
|
{
|
||||||
[Cmd]
|
[Cmd]
|
||||||
[UserPerm(GuildPerm.Administrator)]
|
[UserPerm(GuildPerm.ManageRoles)]
|
||||||
public async Task Notify()
|
public async Task Notify()
|
||||||
{
|
{
|
||||||
await Response()
|
await Response()
|
||||||
|
@ -38,11 +38,12 @@ public partial class Administration
|
||||||
NotifyType.Protection => strs.notify_desc_protection,
|
NotifyType.Protection => strs.notify_desc_protection,
|
||||||
NotifyType.AddRoleReward => strs.notify_desc_addrolerew,
|
NotifyType.AddRoleReward => strs.notify_desc_addrolerew,
|
||||||
NotifyType.RemoveRoleReward => strs.notify_desc_removerolerew,
|
NotifyType.RemoveRoleReward => strs.notify_desc_removerolerew,
|
||||||
|
NotifyType.NiceCatch => strs.notify_desc_nicecatch,
|
||||||
_ => strs.notify_desc_not_found
|
_ => strs.notify_desc_not_found
|
||||||
};
|
};
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
[UserPerm(GuildPerm.Administrator)]
|
[UserPerm(GuildPerm.ManageRoles)]
|
||||||
public async Task Notify(NotifyType nType)
|
public async Task Notify(NotifyType nType)
|
||||||
{
|
{
|
||||||
// show msg
|
// show msg
|
||||||
|
@ -76,12 +77,12 @@ public partial class Administration
|
||||||
}
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
[UserPerm(GuildPerm.Administrator)]
|
[UserPerm(GuildPerm.ManageRoles)]
|
||||||
public async Task Notify(NotifyType nType, [Leftover] string message)
|
public async Task Notify(NotifyType nType, [Leftover] string message)
|
||||||
=> await NotifyInternalAsync(nType, null, message);
|
=> await NotifyInternalAsync(nType, null, message);
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
[UserPerm(GuildPerm.Administrator)]
|
[UserPerm(GuildPerm.ManageRoles)]
|
||||||
public async Task Notify(NotifyType nType, IMessageChannel channel, [Leftover] string message)
|
public async Task Notify(NotifyType nType, IMessageChannel channel, [Leftover] string message)
|
||||||
=> await NotifyInternalAsync(nType, channel, message);
|
=> await NotifyInternalAsync(nType, channel, message);
|
||||||
|
|
||||||
|
@ -89,6 +90,14 @@ public partial class Administration
|
||||||
{
|
{
|
||||||
var result = await _service.EnableAsync(ctx.Guild.Id, channel?.Id, nType, message);
|
var result = await _service.EnableAsync(ctx.Guild.Id, channel?.Id, nType, message);
|
||||||
|
|
||||||
|
if(!result)
|
||||||
|
{
|
||||||
|
await Response()
|
||||||
|
.Error(strs.notify_cant_set)
|
||||||
|
.SendAsync();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
var outChannel = channel is null ? "origin" : $"<#{channel.Id}>";
|
var outChannel = channel is null ? "origin" : $"<#{channel.Id}>";
|
||||||
await Response()
|
await Response()
|
||||||
.Confirm(strs.notify_on(outChannel, Format.Bold(nType.ToString())))
|
.Confirm(strs.notify_on(outChannel, Format.Bold(nType.ToString())))
|
||||||
|
@ -96,7 +105,7 @@ public partial class Administration
|
||||||
}
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
[UserPerm(GuildPerm.Administrator)]
|
[UserPerm(GuildPerm.ManageRoles)]
|
||||||
public async Task NotifyPhs(NotifyType nType)
|
public async Task NotifyPhs(NotifyType nType)
|
||||||
{
|
{
|
||||||
var data = _service.GetRegisteredModel(nType);
|
var data = _service.GetRegisteredModel(nType);
|
||||||
|
@ -111,7 +120,7 @@ public partial class Administration
|
||||||
}
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
[UserPerm(GuildPerm.Administrator)]
|
[UserPerm(GuildPerm.ManageRoles)]
|
||||||
public async Task NotifyList(int page = 1)
|
public async Task NotifyList(int page = 1)
|
||||||
{
|
{
|
||||||
if (--page < 0)
|
if (--page < 0)
|
||||||
|
@ -139,7 +148,7 @@ public partial class Administration
|
||||||
}
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
[UserPerm(GuildPerm.Administrator)]
|
[UserPerm(GuildPerm.ManageRoles)]
|
||||||
public async Task NotifyClear(NotifyType nType)
|
public async Task NotifyClear(NotifyType nType)
|
||||||
{
|
{
|
||||||
await _service.DisableAsync(ctx.Guild.Id, nType);
|
await _service.DisableAsync(ctx.Guild.Id, nType);
|
||||||
|
|
|
@ -42,12 +42,11 @@ public sealed class NotifyService : IReadyExecutor, INotifySubscriber, IEService
|
||||||
RegisterModel<ProtectionNotifyModel>();
|
RegisterModel<ProtectionNotifyModel>();
|
||||||
RegisterModel<AddRoleRewardNotifyModel>();
|
RegisterModel<AddRoleRewardNotifyModel>();
|
||||||
RegisterModel<RemoveRoleRewardNotifyModel>();
|
RegisterModel<RemoveRoleRewardNotifyModel>();
|
||||||
|
RegisterModel<NiceCatchNotifyModel>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task OnReadyAsync()
|
public async Task OnReadyAsync()
|
||||||
{
|
{
|
||||||
RegisterModels();
|
|
||||||
|
|
||||||
await using var uow = _db.GetDbContext();
|
await using var uow = _db.GetDbContext();
|
||||||
_events = (await uow.GetTable<Notify>()
|
_events = (await uow.GetTable<Notify>()
|
||||||
.Where(x => Queries.GuildOnShard(x.GuildId,
|
.Where(x => Queries.GuildOnShard(x.GuildId,
|
||||||
|
@ -57,9 +56,8 @@ public sealed class NotifyService : IReadyExecutor, INotifySubscriber, IEService
|
||||||
.GroupBy(x => x.Type)
|
.GroupBy(x => x.Type)
|
||||||
.ToDictionary(x => x.Key, x => x.ToDictionary(x => x.GuildId).ToConcurrent())
|
.ToDictionary(x => x.Key, x => x.ToDictionary(x => x.GuildId).ToConcurrent())
|
||||||
.ToConcurrent();
|
.ToConcurrent();
|
||||||
|
|
||||||
|
RegisterModels();
|
||||||
await SubscribeToEvent<LevelUpNotifyModel>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task SubscribeToEvent<T>()
|
private async Task SubscribeToEvent<T>()
|
||||||
|
@ -75,7 +73,7 @@ public sealed class NotifyService : IReadyExecutor, INotifySubscriber, IEService
|
||||||
{
|
{
|
||||||
if (isShardLocal)
|
if (isShardLocal)
|
||||||
{
|
{
|
||||||
await OnEvent(data);
|
_ = Task.Run(async () => await OnEvent(data));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -283,7 +281,10 @@ public sealed class NotifyService : IReadyExecutor, INotifySubscriber, IEService
|
||||||
var data = new NotifyModelData(T.NotifyType,
|
var data = new NotifyModelData(T.NotifyType,
|
||||||
T.SupportsOriginTarget,
|
T.SupportsOriginTarget,
|
||||||
T.GetReplacements().Map(x => x.Name));
|
T.GetReplacements().Map(x => x.Name));
|
||||||
|
|
||||||
_models[T.NotifyType] = data;
|
_models[T.NotifyType] = data;
|
||||||
|
|
||||||
|
_pubSub.Sub<T>(new(T.KeyName), async (data) => await OnEvent(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
public NotifyModelData GetRegisteredModel(NotifyType nType)
|
public NotifyModelData GetRegisteredModel(NotifyType nType)
|
||||||
|
|
|
@ -391,7 +391,7 @@ public class ProtectionService : IReadyExecutor, IEService
|
||||||
{
|
{
|
||||||
var obj = new AntiSpamIgnore
|
var obj = new AntiSpamIgnore
|
||||||
{
|
{
|
||||||
ChannelId = channelId
|
ChannelId = channelId,
|
||||||
};
|
};
|
||||||
|
|
||||||
await using var uow = _db.GetDbContext();
|
await using var uow = _db.GetDbContext();
|
||||||
|
@ -529,16 +529,18 @@ public class ProtectionService : IReadyExecutor, IEService
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
var spamConfigs = await uow.GetTable<AntiSpamSetting>()
|
var spamConfigs = await uow.Set<AntiSpamSetting>()
|
||||||
.AsNoTracking()
|
.AsNoTracking()
|
||||||
.Where(x => Queries.GuildOnShard(x.GuildId, _shardData.TotalShards, _shardData.ShardId))
|
.Where(x => gids.Contains(x.GuildId))
|
||||||
.ToListAsyncLinqToDB();
|
.Include(x => x.IgnoredChannels)
|
||||||
|
.ToListAsyncEF();
|
||||||
|
|
||||||
foreach (var config in spamConfigs)
|
foreach (var config in spamConfigs)
|
||||||
{
|
{
|
||||||
_antiSpamGuilds[config.GuildId] = new()
|
_antiSpamGuilds[config.GuildId] = new()
|
||||||
{
|
{
|
||||||
AntiSpamSettings = config,
|
AntiSpamSettings = config,
|
||||||
|
UserStats = new()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -105,7 +105,7 @@ public partial class Games
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithAuthor(ctx.User)
|
.WithAuthor(ctx.User)
|
||||||
.WithDescription(desc)
|
.WithDescription(desc)
|
||||||
.AddField(GetText(strs.fish_quality), GetStarText(res.Stars, res.Fish.Stars), true)
|
.AddField(GetText(strs.fish_quality), fs.GetStarText(res.Stars, res.Fish.Stars), true)
|
||||||
.AddField(GetText(strs.desc), res.Fish.Fluff, true)
|
.AddField(GetText(strs.desc), res.Fish.Fluff, true)
|
||||||
.WithThumbnailUrl(res.Fish.Image))
|
.WithThumbnailUrl(res.Fish.Image))
|
||||||
.SendAsync();
|
.SendAsync();
|
||||||
|
@ -150,7 +150,7 @@ public partial class Games
|
||||||
.Items(fishes)
|
.Items(fishes)
|
||||||
.PageSize(9)
|
.PageSize(9)
|
||||||
.CurrentPage(page)
|
.CurrentPage(page)
|
||||||
.Page((fs, i) =>
|
.Page((fishes, i) =>
|
||||||
{
|
{
|
||||||
var eb = CreateEmbed()
|
var eb = CreateEmbed()
|
||||||
.WithDescription($"🧠 **Skill:** {skill} / {maxSkill}")
|
.WithDescription($"🧠 **Skill:** {skill} / {maxSkill}")
|
||||||
|
@ -158,7 +158,7 @@ public partial class Games
|
||||||
.WithTitle(GetText(strs.fish_list_title))
|
.WithTitle(GetText(strs.fish_list_title))
|
||||||
.WithOkColor();
|
.WithOkColor();
|
||||||
|
|
||||||
foreach (var f in fs)
|
foreach (var f in fishes)
|
||||||
{
|
{
|
||||||
if (catchDict.TryGetValue(f.Id, out var c))
|
if (catchDict.TryGetValue(f.Id, out var c))
|
||||||
{
|
{
|
||||||
|
@ -169,14 +169,14 @@ public partial class Games
|
||||||
+ GetTodEmoji(f.Time)
|
+ GetTodEmoji(f.Time)
|
||||||
+ GetWeatherEmoji(f.Weather)
|
+ GetWeatherEmoji(f.Weather)
|
||||||
+ "\n"
|
+ "\n"
|
||||||
+ GetStarText(c.MaxStars, f.Stars)
|
+ fs.GetStarText(c.MaxStars, f.Stars)
|
||||||
+ "\n"
|
+ "\n"
|
||||||
+ Format.Italics(f.Fluff),
|
+ Format.Italics(f.Fluff),
|
||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
eb.AddField("?", GetFishEmoji(null, 0) + "\n" + GetStarText(0, f.Stars), true);
|
eb.AddField("?", GetFishEmoji(null, 0) + "\n" + fs.GetStarText(0, f.Stars), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,31 +225,8 @@ public partial class Games
|
||||||
_ => ""
|
_ => ""
|
||||||
};
|
};
|
||||||
|
|
||||||
private string GetStarText(int resStars, int fishStars)
|
|
||||||
{
|
|
||||||
if (resStars == fishStars)
|
|
||||||
{
|
|
||||||
return MultiplyStars(fcs.Data.StarEmojis[^1], fishStars);
|
|
||||||
}
|
|
||||||
|
|
||||||
var c = fcs.Data;
|
|
||||||
var starsp1 = MultiplyStars(c.StarEmojis[resStars], resStars);
|
|
||||||
var starsp2 = MultiplyStars(c.StarEmojis[0], fishStars - resStars);
|
|
||||||
|
|
||||||
return starsp1 + starsp2;
|
|
||||||
}
|
|
||||||
|
|
||||||
private string MultiplyStars(string starEmoji, int count)
|
|
||||||
{
|
|
||||||
var sb = new StringBuilder();
|
|
||||||
|
|
||||||
for (var i = 0; i < count; i++)
|
|
||||||
{
|
|
||||||
sb.Append(starEmoji);
|
|
||||||
}
|
|
||||||
|
|
||||||
return sb.ToString();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,12 @@ public sealed class FishResult
|
||||||
public bool IsSkillUp { get; set; }
|
public bool IsSkillUp { get; set; }
|
||||||
public int Skill { get; set; }
|
public int Skill { get; set; }
|
||||||
public int MaxSkill { get; set; }
|
public int MaxSkill { get; set; }
|
||||||
|
|
||||||
|
public bool IsMaxStar()
|
||||||
|
=> Stars == Fish.Stars;
|
||||||
|
|
||||||
|
public bool IsRare()
|
||||||
|
=> Fish.Chance <= 15;
|
||||||
}
|
}
|
||||||
|
|
||||||
public readonly record struct AlreadyFishing;
|
public readonly record struct AlreadyFishing;
|
|
@ -1,10 +1,19 @@
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
using LinqToDB;
|
using LinqToDB;
|
||||||
using LinqToDB.EntityFrameworkCore;
|
using LinqToDB.EntityFrameworkCore;
|
||||||
|
using EllieBot.Modules.Administration;
|
||||||
|
using EllieBot.Modules.Administration.Services;
|
||||||
|
|
||||||
namespace EllieBot.Modules.Games.Fish;
|
namespace EllieBot.Modules.Games.Fish;
|
||||||
|
|
||||||
public sealed class FishService(FishConfigService fcs, IBotCache cache, DbService db) : IEService
|
public sealed class FishService(
|
||||||
|
FishConfigService fcs,
|
||||||
|
IBotCache cache,
|
||||||
|
DbService db,
|
||||||
|
INotifySubscriber notify
|
||||||
|
)
|
||||||
|
: IEService
|
||||||
{
|
{
|
||||||
private const double MAX_SKILL = 100;
|
private const double MAX_SKILL = 100;
|
||||||
|
|
||||||
|
@ -15,7 +24,7 @@ public sealed class FishService(FishConfigService fcs, IBotCache cache, DbServic
|
||||||
|
|
||||||
public async Task<OneOf.OneOf<Task<FishResult?>, AlreadyFishing>> FishAsync(ulong userId, ulong channelId)
|
public async Task<OneOf.OneOf<Task<FishResult?>, AlreadyFishing>> FishAsync(ulong userId, ulong channelId)
|
||||||
{
|
{
|
||||||
var duration = _rng.Next(5, 9);
|
var duration = _rng.Next(3, 6);
|
||||||
|
|
||||||
if (!await cache.AddAsync(FishingKey(userId), true, TimeSpan.FromSeconds(duration), overwrite: false))
|
if (!await cache.AddAsync(FishingKey(userId), true, TimeSpan.FromSeconds(duration), overwrite: false))
|
||||||
{
|
{
|
||||||
|
@ -69,6 +78,18 @@ public sealed class FishService(FishConfigService fcs, IBotCache cache, DbServic
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// notification system
|
||||||
|
if (result is not null)
|
||||||
|
{
|
||||||
|
if (result.IsMaxStar() || result.IsRare())
|
||||||
|
{
|
||||||
|
await notify.NotifyAsync(new NiceCatchNotifyModel(
|
||||||
|
userId,
|
||||||
|
result.Fish,
|
||||||
|
GetStarText(result.Stars, result.Fish.Stars)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -85,21 +106,21 @@ public sealed class FishService(FishConfigService fcs, IBotCache cache, DbServic
|
||||||
|
|
||||||
var maxSkill = (int)MAX_SKILL;
|
var maxSkill = (int)MAX_SKILL;
|
||||||
await ctx.GetTable<UserFishStats>()
|
await ctx.GetTable<UserFishStats>()
|
||||||
.InsertOrUpdateAsync(() => new()
|
.InsertOrUpdateAsync(() => new()
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = userId,
|
||||||
Skill = 1,
|
Skill = 1,
|
||||||
},
|
},
|
||||||
(old) => new()
|
(old) => new()
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = userId,
|
||||||
Skill = old.Skill > maxSkill ? maxSkill : old.Skill + 1
|
Skill = old.Skill > maxSkill ? maxSkill : old.Skill + 1
|
||||||
},
|
},
|
||||||
() => new()
|
() => new()
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = userId,
|
||||||
Skill = playerSkill
|
Skill = playerSkill
|
||||||
});
|
});
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -123,9 +144,9 @@ public sealed class FishService(FishConfigService fcs, IBotCache cache, DbServic
|
||||||
await using var ctx = db.GetDbContext();
|
await using var ctx = db.GetDbContext();
|
||||||
|
|
||||||
var skill = await ctx.GetTable<UserFishStats>()
|
var skill = await ctx.GetTable<UserFishStats>()
|
||||||
.Where(x => x.UserId == userId)
|
.Where(x => x.UserId == userId)
|
||||||
.Select(x => x.Skill)
|
.Select(x => x.Skill)
|
||||||
.FirstOrDefaultAsyncLinqToDB();
|
.FirstOrDefaultAsyncLinqToDB();
|
||||||
|
|
||||||
return (skill, (int)MAX_SKILL);
|
return (skill, (int)MAX_SKILL);
|
||||||
}
|
}
|
||||||
|
@ -188,23 +209,23 @@ public sealed class FishService(FishConfigService fcs, IBotCache cache, DbServic
|
||||||
await using var uow = db.GetDbContext();
|
await using var uow = db.GetDbContext();
|
||||||
|
|
||||||
await uow.GetTable<FishCatch>()
|
await uow.GetTable<FishCatch>()
|
||||||
.InsertOrUpdateAsync(() => new FishCatch()
|
.InsertOrUpdateAsync(() => new FishCatch()
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = userId,
|
||||||
FishId = caught.Fish.Id,
|
FishId = caught.Fish.Id,
|
||||||
MaxStars = caught.Stars,
|
MaxStars = caught.Stars,
|
||||||
Count = 1
|
Count = 1
|
||||||
},
|
},
|
||||||
(old) => new FishCatch()
|
(old) => new FishCatch()
|
||||||
{
|
{
|
||||||
Count = old.Count + 1,
|
Count = old.Count + 1,
|
||||||
MaxStars = Math.Max(old.MaxStars, caught.Stars),
|
MaxStars = Math.Max(old.MaxStars, caught.Stars),
|
||||||
},
|
},
|
||||||
() => new()
|
() => new()
|
||||||
{
|
{
|
||||||
FishId = caught.Fish.Id,
|
FishId = caught.Fish.Id,
|
||||||
UserId = userId
|
UserId = userId
|
||||||
});
|
});
|
||||||
|
|
||||||
return caught;
|
return caught;
|
||||||
}
|
}
|
||||||
|
@ -392,9 +413,35 @@ public sealed class FishService(FishConfigService fcs, IBotCache cache, DbServic
|
||||||
await using var ctx = db.GetDbContext();
|
await using var ctx = db.GetDbContext();
|
||||||
|
|
||||||
var catches = await ctx.GetTable<FishCatch>()
|
var catches = await ctx.GetTable<FishCatch>()
|
||||||
.Where(x => x.UserId == userId)
|
.Where(x => x.UserId == userId)
|
||||||
.ToListAsyncLinqToDB();
|
.ToListAsyncLinqToDB();
|
||||||
|
|
||||||
return catches;
|
return catches;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string GetStarText(int resStars, int fishStars)
|
||||||
|
{
|
||||||
|
if (resStars == fishStars)
|
||||||
|
{
|
||||||
|
return MultiplyStars(fcs.Data.StarEmojis[^1], fishStars);
|
||||||
|
}
|
||||||
|
|
||||||
|
var c = fcs.Data;
|
||||||
|
var starsp1 = MultiplyStars(c.StarEmojis[resStars], resStars);
|
||||||
|
var starsp2 = MultiplyStars(c.StarEmojis[0], fishStars - resStars);
|
||||||
|
|
||||||
|
return starsp1 + starsp2;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string MultiplyStars(string starEmoji, int count)
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
|
||||||
|
for (var i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
sb.Append(starEmoji);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -88,6 +88,7 @@ public partial class Utility : EllieModule
|
||||||
.Text(message)
|
.Text(message)
|
||||||
.Channel(channel)
|
.Channel(channel)
|
||||||
.UserBasedMentions()
|
.UserBasedMentions()
|
||||||
|
.NoReply()
|
||||||
.SendAsync();
|
.SendAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1154,6 +1154,7 @@
|
||||||
"notify_desc_protection": "Triggers when antialt, antispam or antiraid is triggered.",
|
"notify_desc_protection": "Triggers when antialt, antispam or antiraid is triggered.",
|
||||||
"notify_desc_addrolerew": "Triggers when a user gets a role as a reward for reaching a level (xprew).",
|
"notify_desc_addrolerew": "Triggers when a user gets a role as a reward for reaching a level (xprew).",
|
||||||
"notify_desc_removerolerew": "Triggers when a user loses a role as a reward for reaching a level (xprew).",
|
"notify_desc_removerolerew": "Triggers when a user loses a role as a reward for reaching a level (xprew).",
|
||||||
|
"notify_desc_nicecatch": "Triggers when a user catches quality fish.",
|
||||||
"notify_desc_not_found": "No description found for this notify event. Please report this.",
|
"notify_desc_not_found": "No description found for this notify event. Please report this.",
|
||||||
"notify_placeholders": "Placeholders for '{0}' notify event",
|
"notify_placeholders": "Placeholders for '{0}' notify event",
|
||||||
"winlb": "Biggest Wins Leaderboard",
|
"winlb": "Biggest Wins Leaderboard",
|
||||||
|
@ -1238,5 +1239,6 @@
|
||||||
"linkfix_list_none": "No link fixes have been configured for this server.",
|
"linkfix_list_none": "No link fixes have been configured for this server.",
|
||||||
"linkfix_list_title": "Link Fixes",
|
"linkfix_list_title": "Link Fixes",
|
||||||
"linkfix_removed": "Link fix for {0} has been removed.",
|
"linkfix_removed": "Link fix for {0} has been removed.",
|
||||||
"linkfix_not_found": "No link fix found for {0}."
|
"linkfix_not_found": "No link fix found for {0}.",
|
||||||
|
"notify_cant_set": "This event doesn't support origin channel, Please specify a channel"
|
||||||
}
|
}
|
Loading…
Add table
Reference in a new issue