mirror of
https://github.com/Jetsparrow/karmabot.git
synced 2026-01-21 09:06:09 +03:00
Basic leaky bucket timeout
This commit is contained in:
parent
29af7c9183
commit
2b17d3925a
@ -23,33 +23,23 @@ namespace JetKarmaBot
|
|||||||
Me = await Client.GetMeAsync();
|
Me = await Client.GetMeAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<bool> Execute(object sender, MessageEventArgs args)
|
public Task<bool> Execute(CommandString cmd, MessageEventArgs args)
|
||||||
{
|
{
|
||||||
log.Debug("Message received");
|
log.Debug("Message received");
|
||||||
var text = args.Message.Text;
|
|
||||||
if (CommandString.TryParse(text, out var cmd))
|
|
||||||
{
|
|
||||||
if (cmd.UserName != null && cmd.UserName != Me.Username)
|
|
||||||
{
|
|
||||||
// directed not at us!
|
|
||||||
log.Debug("Message not directed at us");
|
|
||||||
return Task.FromResult(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
try
|
||||||
|
{
|
||||||
|
if (commands.ContainsKey(cmd.Command))
|
||||||
{
|
{
|
||||||
if (commands.ContainsKey(cmd.Command))
|
log.Debug($"Handling message via {commands[cmd.Command].GetType().Name}");
|
||||||
{
|
return commands[cmd.Command].Execute(cmd, args);
|
||||||
log.Debug($"Handling message via {commands[cmd.Command].GetType().Name}");
|
|
||||||
return commands[cmd.Command].Execute(cmd, args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
log.Error($"Error while handling command {cmd.Command}!");
|
|
||||||
log.Error(e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
log.Error($"Error while handling command {cmd.Command}!");
|
||||||
|
log.Error(e);
|
||||||
|
}
|
||||||
|
|
||||||
return Task.FromResult(false);
|
return Task.FromResult(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,8 +15,8 @@ namespace JetKarmaBot.Commands
|
|||||||
class AwardCommand : IChatCommand
|
class AwardCommand : IChatCommand
|
||||||
{
|
{
|
||||||
public IReadOnlyCollection<string> Names => new[] { "award", "revoke" };
|
public IReadOnlyCollection<string> Names => new[] { "award", "revoke" };
|
||||||
[Inject]
|
[Inject] private Logger log;
|
||||||
private Logger log;
|
[Inject] private TimeoutManager Timeout;
|
||||||
|
|
||||||
public async Task<bool> Execute(CommandString cmd, MessageEventArgs args)
|
public async Task<bool> Execute(CommandString cmd, MessageEventArgs args)
|
||||||
{
|
{
|
||||||
@ -24,6 +24,7 @@ namespace JetKarmaBot.Commands
|
|||||||
{
|
{
|
||||||
var currentLocale = Locale[(await db.Chats.FindAsync(args.Message.Chat.Id)).Locale];
|
var currentLocale = Locale[(await db.Chats.FindAsync(args.Message.Chat.Id)).Locale];
|
||||||
|
|
||||||
|
var awarder = args.Message.From;
|
||||||
string awardTypeText = null;
|
string awardTypeText = null;
|
||||||
int recipientId = default(int);
|
int recipientId = default(int);
|
||||||
foreach (string arg in cmd.Parameters)
|
foreach (string arg in cmd.Parameters)
|
||||||
@ -33,12 +34,14 @@ namespace JetKarmaBot.Commands
|
|||||||
if (recipientId != default(int))
|
if (recipientId != default(int))
|
||||||
{
|
{
|
||||||
await Client.SendTextMessageAsync(args.Message.Chat.Id, currentLocale["jetkarmabot.award.errdup"]);
|
await Client.SendTextMessageAsync(args.Message.Chat.Id, currentLocale["jetkarmabot.award.errdup"]);
|
||||||
|
await Timeout.ApplyCost("AwardFailure", awarder.Id, db);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
recipientId = await db.Users.Where(x => x.Username == arg).Select(x => x.UserId).FirstOrDefaultAsync();
|
recipientId = await db.Users.Where(x => x.Username == arg).Select(x => x.UserId).FirstOrDefaultAsync();
|
||||||
if (recipientId == default(int))
|
if (recipientId == default(int))
|
||||||
{
|
{
|
||||||
await Client.SendTextMessageAsync(args.Message.Chat.Id, currentLocale["jetkarmabot.award.errbadusername"]);
|
await Client.SendTextMessageAsync(args.Message.Chat.Id, currentLocale["jetkarmabot.award.errbadusername"]);
|
||||||
|
await Timeout.ApplyCost("AwardFailure", awarder.Id, db);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -49,6 +52,7 @@ namespace JetKarmaBot.Commands
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
await Client.SendTextMessageAsync(args.Message.Chat.Id, currentLocale["jetkarmabot.award.errdup"]);
|
await Client.SendTextMessageAsync(args.Message.Chat.Id, currentLocale["jetkarmabot.award.errdup"]);
|
||||||
|
await Timeout.ApplyCost("AwardFailure", awarder.Id, db);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -62,10 +66,10 @@ namespace JetKarmaBot.Commands
|
|||||||
if (recipientId == default(int))
|
if (recipientId == default(int))
|
||||||
{
|
{
|
||||||
await Client.SendTextMessageAsync(args.Message.Chat.Id, currentLocale["jetkarmabot.award.errawardnoreply"]);
|
await Client.SendTextMessageAsync(args.Message.Chat.Id, currentLocale["jetkarmabot.award.errawardnoreply"]);
|
||||||
|
await Timeout.ApplyCost("AwardFailure", awarder.Id, db);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var awarder = args.Message.From;
|
|
||||||
|
|
||||||
bool awarding = cmd.Command == "award";
|
bool awarding = cmd.Command == "award";
|
||||||
|
|
||||||
@ -75,6 +79,7 @@ namespace JetKarmaBot.Commands
|
|||||||
args.Message.Chat.Id,
|
args.Message.Chat.Id,
|
||||||
currentLocale["jetkarmabot.award.errawardself"],
|
currentLocale["jetkarmabot.award.errawardself"],
|
||||||
replyToMessageId: args.Message.MessageId);
|
replyToMessageId: args.Message.MessageId);
|
||||||
|
await Timeout.ApplyCost("AwardFailure", awarder.Id, db);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,6 +91,7 @@ namespace JetKarmaBot.Commands
|
|||||||
? currentLocale["jetkarmabot.award.errawardbot"]
|
? currentLocale["jetkarmabot.award.errawardbot"]
|
||||||
: currentLocale["jetkarmabot.award.errrevokebot"],
|
: currentLocale["jetkarmabot.award.errrevokebot"],
|
||||||
replyToMessageId: args.Message.MessageId);
|
replyToMessageId: args.Message.MessageId);
|
||||||
|
await Timeout.ApplyCost("AwardFailure", awarder.Id, db);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,15 +99,6 @@ namespace JetKarmaBot.Commands
|
|||||||
global::JetKarmaBot.Models.AwardType awardType = awardTypeText != null
|
global::JetKarmaBot.Models.AwardType awardType = awardTypeText != null
|
||||||
? await db.AwardTypes.FirstAsync(at => at.CommandName == awardTypeText)
|
? await db.AwardTypes.FirstAsync(at => at.CommandName == awardTypeText)
|
||||||
: await db.AwardTypes.FindAsync((sbyte)1);
|
: await db.AwardTypes.FindAsync((sbyte)1);
|
||||||
DateTime cutoff = DateTime.Now - TimeSpan.FromMinutes(5);
|
|
||||||
if (await db.Awards.Where(x => x.Date > cutoff && x.FromId == awarder.Id).CountAsync() >= 10)
|
|
||||||
{
|
|
||||||
await Client.SendTextMessageAsync(
|
|
||||||
args.Message.Chat.Id,
|
|
||||||
currentLocale["jetkarmabot.award.ratelimit"],
|
|
||||||
replyToMessageId: args.Message.MessageId);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
await db.Awards.AddAsync(new Models.Award()
|
await db.Awards.AddAsync(new Models.Award()
|
||||||
{
|
{
|
||||||
AwardTypeId = awardType.AwardTypeId,
|
AwardTypeId = awardType.AwardTypeId,
|
||||||
@ -130,6 +127,7 @@ namespace JetKarmaBot.Commands
|
|||||||
args.Message.Chat.Id,
|
args.Message.Chat.Id,
|
||||||
response,
|
response,
|
||||||
replyToMessageId: args.Message.MessageId);
|
replyToMessageId: args.Message.MessageId);
|
||||||
|
await Timeout.ApplyCost("AwardSuccess", awarder.Id, db);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,8 +12,8 @@ namespace JetKarmaBot.Commands
|
|||||||
class LocaleCommand : IChatCommand
|
class LocaleCommand : IChatCommand
|
||||||
{
|
{
|
||||||
public IReadOnlyCollection<string> Names => new[] { "changelocale", "locale" };
|
public IReadOnlyCollection<string> Names => new[] { "changelocale", "locale" };
|
||||||
[Inject]
|
[Inject] private Logger log;
|
||||||
private Logger log;
|
[Inject] private TimeoutManager Timeout;
|
||||||
|
|
||||||
public async Task<bool> Execute(CommandString cmd, MessageEventArgs args)
|
public async Task<bool> Execute(CommandString cmd, MessageEventArgs args)
|
||||||
{
|
{
|
||||||
@ -26,6 +26,7 @@ namespace JetKarmaBot.Commands
|
|||||||
args.Message.Chat.Id,
|
args.Message.Chat.Id,
|
||||||
currentLocale["jetkarmabot.changelocale.getlocale"],
|
currentLocale["jetkarmabot.changelocale.getlocale"],
|
||||||
replyToMessageId: args.Message.MessageId);
|
replyToMessageId: args.Message.MessageId);
|
||||||
|
await Timeout.ApplyCost("LocaleFailure", args.Message.From.Id, db);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (cmd.Parameters[0] == "list")
|
else if (cmd.Parameters[0] == "list")
|
||||||
@ -35,6 +36,7 @@ namespace JetKarmaBot.Commands
|
|||||||
currentLocale["jetkarmabot.changelocale.listalltext"] + "\n"
|
currentLocale["jetkarmabot.changelocale.listalltext"] + "\n"
|
||||||
+ string.Join("\n", Locale.Select(a => a.Key)),
|
+ string.Join("\n", Locale.Select(a => a.Key)),
|
||||||
replyToMessageId: args.Message.MessageId);
|
replyToMessageId: args.Message.MessageId);
|
||||||
|
await Timeout.ApplyCost("LocaleFailure", args.Message.From.Id, db);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (cmd.Parameters[0] == "all")
|
else if (cmd.Parameters[0] == "all")
|
||||||
@ -43,6 +45,7 @@ namespace JetKarmaBot.Commands
|
|||||||
args.Message.Chat.Id,
|
args.Message.Chat.Id,
|
||||||
currentLocale["jetkarmabot.changelocale.errorall"],
|
currentLocale["jetkarmabot.changelocale.errorall"],
|
||||||
replyToMessageId: args.Message.MessageId);
|
replyToMessageId: args.Message.MessageId);
|
||||||
|
await Timeout.ApplyCost("LocaleFailure", args.Message.From.Id, db);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
string localeId;
|
string localeId;
|
||||||
@ -56,9 +59,10 @@ namespace JetKarmaBot.Commands
|
|||||||
catch (LocalizationException e)
|
catch (LocalizationException e)
|
||||||
{
|
{
|
||||||
await Client.SendTextMessageAsync(
|
await Client.SendTextMessageAsync(
|
||||||
args.Message.Chat.Id,
|
args.Message.Chat.Id,
|
||||||
currentLocale["jetkarmabot.changelocale.toomany"] + "\n" + string.Join("\n", (e.Data["LocaleNames"] as Locale[]).Select(x => x.Name)),
|
currentLocale["jetkarmabot.changelocale.toomany"] + "\n" + string.Join("\n", (e.Data["LocaleNames"] as Locale[]).Select(x => x.Name)),
|
||||||
replyToMessageId: args.Message.MessageId);
|
replyToMessageId: args.Message.MessageId);
|
||||||
|
await Timeout.ApplyCost("LocaleFailure", args.Message.From.Id, db);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
(await db.Chats.FindAsync(args.Message.Chat.Id)).Locale = localeId;
|
(await db.Chats.FindAsync(args.Message.Chat.Id)).Locale = localeId;
|
||||||
@ -72,6 +76,7 @@ namespace JetKarmaBot.Commands
|
|||||||
(currentLocale.HasNote ? currentLocale["jetkarmabot.changelocale.beforenote"] + currentLocale.Note + "\n" : "")
|
(currentLocale.HasNote ? currentLocale["jetkarmabot.changelocale.beforenote"] + currentLocale.Note + "\n" : "")
|
||||||
+ currentLocale["jetkarmabot.changelocale.justchanged"],
|
+ currentLocale["jetkarmabot.changelocale.justchanged"],
|
||||||
replyToMessageId: args.Message.MessageId);
|
replyToMessageId: args.Message.MessageId);
|
||||||
|
await Timeout.ApplyCost("LocaleSuccess", args.Message.From.Id, db);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,6 +15,7 @@ namespace JetKarmaBot.Commands
|
|||||||
[Inject] KarmaContextFactory Db;
|
[Inject] KarmaContextFactory Db;
|
||||||
[Inject] TelegramBotClient Client { get; set; }
|
[Inject] TelegramBotClient Client { get; set; }
|
||||||
[Inject] Localization Locale { get; set; }
|
[Inject] Localization Locale { get; set; }
|
||||||
|
[Inject] TimeoutManager Timeout { get; set; }
|
||||||
public IReadOnlyCollection<string> Names => new[] { "currencies", "awardtypes" };
|
public IReadOnlyCollection<string> Names => new[] { "currencies", "awardtypes" };
|
||||||
|
|
||||||
public string Description => "Shows all award types";
|
public string Description => "Shows all award types";
|
||||||
@ -35,6 +36,7 @@ namespace JetKarmaBot.Commands
|
|||||||
resp,
|
resp,
|
||||||
replyToMessageId: args.Message.MessageId,
|
replyToMessageId: args.Message.MessageId,
|
||||||
parseMode: ParseMode.Html);
|
parseMode: ParseMode.Html);
|
||||||
|
await Timeout.ApplyCost("Currencies", args.Message.From.Id, db);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,6 +13,7 @@ namespace JetKarmaBot.Commands
|
|||||||
[Inject] KarmaContextFactory Db;
|
[Inject] KarmaContextFactory Db;
|
||||||
[Inject] TelegramBotClient Client { get; set; }
|
[Inject] TelegramBotClient Client { get; set; }
|
||||||
[Inject] Localization Locale { get; set; }
|
[Inject] Localization Locale { get; set; }
|
||||||
|
[Inject] TimeoutManager Timeout { get; set; }
|
||||||
[Inject] ChatCommandRouter Router;
|
[Inject] ChatCommandRouter Router;
|
||||||
public IReadOnlyCollection<string> Names => new[] { "help" };
|
public IReadOnlyCollection<string> Names => new[] { "help" };
|
||||||
|
|
||||||
@ -34,6 +35,7 @@ namespace JetKarmaBot.Commands
|
|||||||
using (var db = Db.GetContext())
|
using (var db = Db.GetContext())
|
||||||
{
|
{
|
||||||
var currentLocale = Locale[(await db.Chats.FindAsync(args.Message.Chat.Id)).Locale];
|
var currentLocale = Locale[(await db.Chats.FindAsync(args.Message.Chat.Id)).Locale];
|
||||||
|
await Timeout.ApplyCost("Help", args.Message.From.Id, db);
|
||||||
if (cmd.Parameters.Length < 1)
|
if (cmd.Parameters.Length < 1)
|
||||||
{
|
{
|
||||||
await Client.SendTextMessageAsync(
|
await Client.SendTextMessageAsync(
|
||||||
|
|||||||
@ -51,12 +51,14 @@ namespace JetKarmaBot.Commands
|
|||||||
args.Message.Chat.Id,
|
args.Message.Chat.Id,
|
||||||
response,
|
response,
|
||||||
replyToMessageId: args.Message.MessageId);
|
replyToMessageId: args.Message.MessageId);
|
||||||
|
await Timeout.ApplyCost("Leaderboard", args.Message.From.Id, db);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Inject] KarmaContextFactory Db { get; set; }
|
[Inject] KarmaContextFactory Db { get; set; }
|
||||||
[Inject] TelegramBotClient Client { get; set; }
|
[Inject] TelegramBotClient Client { get; set; }
|
||||||
|
[Inject] TimeoutManager Timeout { get; set; }
|
||||||
[Inject] Localization Locale { get; set; }
|
[Inject] Localization Locale { get; set; }
|
||||||
|
|
||||||
public string Description => "Shows the people with the most of a specific award.";
|
public string Description => "Shows the people with the most of a specific award.";
|
||||||
|
|||||||
@ -71,12 +71,14 @@ namespace JetKarmaBot.Commands
|
|||||||
args.Message.Chat.Id,
|
args.Message.Chat.Id,
|
||||||
response,
|
response,
|
||||||
replyToMessageId: args.Message.MessageId);
|
replyToMessageId: args.Message.MessageId);
|
||||||
|
await Timeout.ApplyCost("Status", args.Message.From.Id, db);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Inject] KarmaContextFactory Db { get; set; }
|
[Inject] KarmaContextFactory Db { get; set; }
|
||||||
[Inject] TelegramBotClient Client { get; set; }
|
[Inject] TelegramBotClient Client { get; set; }
|
||||||
|
[Inject] TimeoutManager Timeout { get; set; }
|
||||||
[Inject] Localization Locale { get; set; }
|
[Inject] Localization Locale { get; set; }
|
||||||
|
|
||||||
public string Description => "Shows the amount of awards that you have";
|
public string Description => "Shows the amount of awards that you have";
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using JsonNet.PrivateSettersContractResolvers;
|
using JsonNet.PrivateSettersContractResolvers;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace JetKarmaBot
|
namespace JetKarmaBot
|
||||||
{
|
{
|
||||||
@ -21,7 +22,19 @@ namespace JetKarmaBot
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ProxySettings Proxy { get; private set; }
|
public ProxySettings Proxy { get; private set; }
|
||||||
public bool SqlDebug { get; private set; }
|
public class TimeoutConfig
|
||||||
|
{
|
||||||
|
public int DebtLimitSeconds { get; private set; } = 60 * 60 * 2;
|
||||||
|
public Dictionary<string, int> CommandCostsSeconds { get; private set; } = new Dictionary<string, int>()
|
||||||
|
{
|
||||||
|
{"AwardSuccessful", 60*15},
|
||||||
|
{"AwardFailed", 60*5},
|
||||||
|
{"Default", 60*5}
|
||||||
|
};
|
||||||
|
public int SaveIntervalSeconds { get; private set; } = 60 * 5;
|
||||||
|
}
|
||||||
|
public TimeoutConfig Timeout { get; private set; } = new TimeoutConfig();
|
||||||
|
public bool SqlDebug { get; private set; } = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class ConfigBase
|
public abstract class ConfigBase
|
||||||
|
|||||||
@ -5,6 +5,7 @@ using Perfusion;
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
using Telegram.Bot;
|
using Telegram.Bot;
|
||||||
@ -19,9 +20,13 @@ namespace JetKarmaBot
|
|||||||
[Inject] Config Config { get; set; }
|
[Inject] Config Config { get; set; }
|
||||||
[Inject] IContainer Container { get; set; }
|
[Inject] IContainer Container { get; set; }
|
||||||
[Inject] KarmaContextFactory Db { get; set; }
|
[Inject] KarmaContextFactory Db { get; set; }
|
||||||
|
[Inject] TimeoutManager Timeout { get; set; }
|
||||||
|
[Inject] Localization Locale { get; set; }
|
||||||
|
|
||||||
TelegramBotClient Client { get; set; }
|
TelegramBotClient Client { get; set; }
|
||||||
ChatCommandRouter Commands;
|
ChatCommandRouter Commands;
|
||||||
|
Task timeoutWaitTask;
|
||||||
|
CancellationTokenSource timeoutWaitTaskToken;
|
||||||
|
|
||||||
public async Task Init()
|
public async Task Init()
|
||||||
{
|
{
|
||||||
@ -35,6 +40,9 @@ namespace JetKarmaBot
|
|||||||
Client = new TelegramBotClient(Config.ApiKey, httpProxy);
|
Client = new TelegramBotClient(Config.ApiKey, httpProxy);
|
||||||
Container.AddInstance(Client);
|
Container.AddInstance(Client);
|
||||||
|
|
||||||
|
timeoutWaitTaskToken = new CancellationTokenSource();
|
||||||
|
timeoutWaitTask = Timeout.SaveLoop(timeoutWaitTaskToken.Token);
|
||||||
|
|
||||||
await InitCommands(Container);
|
await InitCommands(Container);
|
||||||
|
|
||||||
Client.OnMessage += BotOnMessageReceived;
|
Client.OnMessage += BotOnMessageReceived;
|
||||||
@ -43,29 +51,59 @@ namespace JetKarmaBot
|
|||||||
|
|
||||||
public async Task Stop()
|
public async Task Stop()
|
||||||
{
|
{
|
||||||
|
Client.StopReceiving();
|
||||||
|
timeoutWaitTaskToken.Cancel();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await timeoutWaitTask;
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException) { }
|
||||||
|
await Timeout.Save();
|
||||||
Dispose();
|
Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
#region service
|
#region service
|
||||||
|
|
||||||
void BotOnMessageReceived(object sender, MessageEventArgs messageEventArgs)
|
void BotOnMessageReceived(object sender, MessageEventArgs args)
|
||||||
{
|
{
|
||||||
var message = messageEventArgs.Message;
|
var message = args.Message;
|
||||||
if (message == null || message.Type != MessageType.Text)
|
if (message == null || message.Type != MessageType.Text)
|
||||||
return;
|
return;
|
||||||
|
if (!CommandString.TryParse(args.Message.Text, out var cmd))
|
||||||
|
return;
|
||||||
|
if (cmd.UserName != null && cmd.UserName != Commands.Me.Username)
|
||||||
|
return;
|
||||||
|
|
||||||
Task.Run(async () =>
|
Task.Run(async () =>
|
||||||
{
|
{
|
||||||
using (KarmaContext db = Db.GetContext())
|
using (KarmaContext db = Db.GetContext())
|
||||||
{
|
{
|
||||||
await AddUserToDatabase(db, messageEventArgs.Message.From);
|
await AddUserToDatabase(db, args.Message.From);
|
||||||
if (messageEventArgs.Message.ReplyToMessage != null)
|
var checkResult = await Timeout.Check(args.Message.From.Id, db);
|
||||||
await AddUserToDatabase(db, messageEventArgs.Message.ReplyToMessage.From);
|
if (checkResult == TimeoutManager.CheckResult.Limited)
|
||||||
if (!db.Chats.Any(x => x.ChatId == messageEventArgs.Message.Chat.Id))
|
{
|
||||||
db.Chats.Add(new Models.Chat { ChatId = messageEventArgs.Message.Chat.Id });
|
Locale currentLocale = Locale[(await db.Chats.FindAsync(args.Message.Chat.Id)).Locale];
|
||||||
|
await Client.SendTextMessageAsync(
|
||||||
|
args.Message.Chat.Id,
|
||||||
|
currentLocale["jetkarmabot.ratelimit"],
|
||||||
|
replyToMessageId: args.Message.MessageId);
|
||||||
|
await Timeout.SetMessaged(args.Message.From.Id, db);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (checkResult != TimeoutManager.CheckResult.NonLimited)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (args.Message.ReplyToMessage != null)
|
||||||
|
await AddUserToDatabase(db, args.Message.ReplyToMessage.From);
|
||||||
|
if (!db.Chats.Any(x => x.ChatId == args.Message.Chat.Id))
|
||||||
|
db.Chats.Add(new Models.Chat
|
||||||
|
{
|
||||||
|
ChatId = args.Message.Chat.Id
|
||||||
|
});
|
||||||
await db.SaveChangesAsync();
|
await db.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
await Commands.Execute(sender, messageEventArgs);
|
await Commands.Execute(cmd, args);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,7 +142,8 @@ namespace JetKarmaBot
|
|||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
Client.StopReceiving();
|
timeoutWaitTaskToken.Dispose();
|
||||||
|
timeoutWaitTask.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@ -172,6 +172,10 @@ namespace JetKarmaBot.Models
|
|||||||
entity.Property(e => e.Username)
|
entity.Property(e => e.Username)
|
||||||
.HasColumnName("username")
|
.HasColumnName("username")
|
||||||
.HasColumnType("varchar(45)");
|
.HasColumnType("varchar(45)");
|
||||||
|
|
||||||
|
entity.Property(e => e.CooldownDate)
|
||||||
|
.HasColumnName("cooldowndate")
|
||||||
|
.HasColumnType("datetime");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,6 +14,7 @@ namespace JetKarmaBot.Models
|
|||||||
|
|
||||||
public int UserId { get; set; }
|
public int UserId { get; set; }
|
||||||
public string Username { get; set; }
|
public string Username { get; set; }
|
||||||
|
public DateTime CooldownDate { get; set; }
|
||||||
[InverseProperty("From")]
|
[InverseProperty("From")]
|
||||||
public virtual ICollection<Award> AwardsFrom { get; set; }
|
public virtual ICollection<Award> AwardsFrom { get; set; }
|
||||||
[InverseProperty("To")]
|
[InverseProperty("To")]
|
||||||
|
|||||||
87
JetKarmaBot/Services/TimeoutManager.cs
Normal file
87
JetKarmaBot/Services/TimeoutManager.cs
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
using Perfusion;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using JetKarmaBot.Models;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
|
namespace JetKarmaBot.Services
|
||||||
|
{
|
||||||
|
[Singleton]
|
||||||
|
public class TimeoutManager
|
||||||
|
{
|
||||||
|
public struct TimeoutStats
|
||||||
|
{
|
||||||
|
public DateTime CooldownDate;
|
||||||
|
public bool TimeoutMessaged;
|
||||||
|
}
|
||||||
|
[Inject] private KarmaContextFactory Db;
|
||||||
|
[Inject] private Config cfg;
|
||||||
|
public Dictionary<int, TimeoutStats> TimeoutCache = new Dictionary<int, TimeoutStats>();
|
||||||
|
public async Task ApplyCost(string name, int uid, KarmaContext db)
|
||||||
|
{
|
||||||
|
if (!cfg.Timeout.CommandCostsSeconds.TryGetValue(name, out var costSeconds))
|
||||||
|
if (!cfg.Timeout.CommandCostsSeconds.TryGetValue("Default", out costSeconds))
|
||||||
|
{
|
||||||
|
throw new LocalizationException("Default key not present");
|
||||||
|
}
|
||||||
|
await PopulateStats(uid, db);
|
||||||
|
DateTime debtLimit = DateTime.Now.AddSeconds(cfg.Timeout.DebtLimitSeconds);
|
||||||
|
if (TimeoutCache[uid].CooldownDate >= debtLimit)
|
||||||
|
//Programming error
|
||||||
|
throw new NotImplementedException();
|
||||||
|
TimeoutCache[uid] = new TimeoutStats()
|
||||||
|
{
|
||||||
|
CooldownDate = (TimeoutCache[uid].CooldownDate <= DateTime.Now ? DateTime.Now : TimeoutCache[uid].CooldownDate).AddSeconds(costSeconds),
|
||||||
|
TimeoutMessaged = false
|
||||||
|
};
|
||||||
|
TimeoutCache[uid] = TimeoutCache[uid];
|
||||||
|
}
|
||||||
|
public enum CheckResult
|
||||||
|
{
|
||||||
|
NonLimited, Limited, LimitedSent
|
||||||
|
}
|
||||||
|
public async Task<CheckResult> Check(int uid, KarmaContext db)
|
||||||
|
{
|
||||||
|
await PopulateStats(uid, db);
|
||||||
|
DateTime debtLimit = DateTime.Now.AddSeconds(cfg.Timeout.DebtLimitSeconds);
|
||||||
|
return TimeoutCache[uid].CooldownDate < debtLimit
|
||||||
|
? CheckResult.NonLimited
|
||||||
|
: (TimeoutCache[uid].TimeoutMessaged ? CheckResult.LimitedSent : CheckResult.Limited);
|
||||||
|
}
|
||||||
|
public async Task SetMessaged(int uid, KarmaContext db)
|
||||||
|
{
|
||||||
|
await PopulateStats(uid, db);
|
||||||
|
TimeoutCache[uid] = new TimeoutStats() { TimeoutMessaged = true, CooldownDate = TimeoutCache[uid].CooldownDate };
|
||||||
|
}
|
||||||
|
private async Task PopulateStats(int uid, KarmaContext db)
|
||||||
|
{
|
||||||
|
if (!TimeoutCache.ContainsKey(uid))
|
||||||
|
{
|
||||||
|
TimeoutCache[uid] = new TimeoutStats()
|
||||||
|
{
|
||||||
|
CooldownDate = (await db.Users.FindAsync(uid)).CooldownDate
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public async Task Save(CancellationToken ct = default(CancellationToken))
|
||||||
|
{
|
||||||
|
using (KarmaContext db = Db.GetContext())
|
||||||
|
{
|
||||||
|
foreach (int i in TimeoutCache.Keys)
|
||||||
|
{
|
||||||
|
(await db.Users.FindAsync(new object[] { i }, ct)).CooldownDate = TimeoutCache[i].CooldownDate;
|
||||||
|
}
|
||||||
|
await db.SaveChangesAsync(ct);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public async Task SaveLoop(CancellationToken ct = default(CancellationToken))
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
await Task.Delay(cfg.Timeout.SaveIntervalSeconds * 1000, ct);
|
||||||
|
await Save(ct);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -6,6 +6,7 @@
|
|||||||
],
|
],
|
||||||
"note": "This is a joke. And made with google translate.",
|
"note": "This is a joke. And made with google translate.",
|
||||||
"strings": {
|
"strings": {
|
||||||
|
"jetkarmabot.ratelimit": "Павольны, чувак!",
|
||||||
"jetkarmabot.award.errawardnoreply": "Пра каго ты кажаш?",
|
"jetkarmabot.award.errawardnoreply": "Пра каго ты кажаш?",
|
||||||
"jetkarmabot.award.errbadusername": "Хто гэта?",
|
"jetkarmabot.award.errbadusername": "Хто гэта?",
|
||||||
"jetkarmabot.award.errdup": "Калі ласка, спыніце батчіць ўзнагароды.",
|
"jetkarmabot.award.errdup": "Калі ласка, спыніце батчіць ўзнагароды.",
|
||||||
@ -15,7 +16,6 @@
|
|||||||
"jetkarmabot.award.awardmessage": "Ўручыў \"{0}\" {1}!",
|
"jetkarmabot.award.awardmessage": "Ўручыў \"{0}\" {1}!",
|
||||||
"jetkarmabot.award.revokemessage": "Адабраў \"{0}\" у {1}!",
|
"jetkarmabot.award.revokemessage": "Адабраў \"{0}\" у {1}!",
|
||||||
"jetkarmabot.award.statustext": "У {0} цяпер {1}{2}.",
|
"jetkarmabot.award.statustext": "У {0} цяпер {1}{2}.",
|
||||||
"jetkarmabot.award.ratelimit": "Павольны, чувак!",
|
|
||||||
"jetkarmabot.award.help": "Уручае ачко карыстачу (або адымае)",
|
"jetkarmabot.award.help": "Уручае ачко карыстачу (або адымае)",
|
||||||
"jetkarmabot.award.awardtypehelp": "Тып ачкі",
|
"jetkarmabot.award.awardtypehelp": "Тып ачкі",
|
||||||
"jetkarmabot.award.tohelp": "Карыстальнік, якога ўзнагародзіць",
|
"jetkarmabot.award.tohelp": "Карыстальнік, якога ўзнагародзіць",
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
"англійская"
|
"англійская"
|
||||||
],
|
],
|
||||||
"strings": {
|
"strings": {
|
||||||
|
"jetkarmabot.ratelimit": "Slow down there, turbo!",
|
||||||
"jetkarmabot.award.errawardnoreply": "Who are you talking about?",
|
"jetkarmabot.award.errawardnoreply": "Who are you talking about?",
|
||||||
"jetkarmabot.award.errbadusername": "I don't know who that is.",
|
"jetkarmabot.award.errbadusername": "I don't know who that is.",
|
||||||
"jetkarmabot.award.errdup": "Please stop batching awards.",
|
"jetkarmabot.award.errdup": "Please stop batching awards.",
|
||||||
@ -14,7 +15,6 @@
|
|||||||
"jetkarmabot.award.awardmessage": "Awarded a {0} to {1}!",
|
"jetkarmabot.award.awardmessage": "Awarded a {0} to {1}!",
|
||||||
"jetkarmabot.award.revokemessage": "Revoked a {0} from {1}!",
|
"jetkarmabot.award.revokemessage": "Revoked a {0} from {1}!",
|
||||||
"jetkarmabot.award.statustext": "{0} is at {1}{2} now.",
|
"jetkarmabot.award.statustext": "{0} is at {1}{2} now.",
|
||||||
"jetkarmabot.award.ratelimit": "Slow down there, turbo!",
|
|
||||||
"jetkarmabot.award.help": "Awards/revokes an award to a user.",
|
"jetkarmabot.award.help": "Awards/revokes an award to a user.",
|
||||||
"jetkarmabot.award.awardtypehelp": "The award to grant to/strip of the specified user",
|
"jetkarmabot.award.awardtypehelp": "The award to grant to/strip of the specified user",
|
||||||
"jetkarmabot.award.tohelp": "The user to award",
|
"jetkarmabot.award.tohelp": "The user to award",
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
"руская"
|
"руская"
|
||||||
],
|
],
|
||||||
"strings": {
|
"strings": {
|
||||||
|
"jetkarmabot.ratelimit": "Помедленней, чувак!",
|
||||||
"jetkarmabot.award.errawardnoreply": "О ком ты говоришь?",
|
"jetkarmabot.award.errawardnoreply": "О ком ты говоришь?",
|
||||||
"jetkarmabot.award.errbadusername": "Кто это?",
|
"jetkarmabot.award.errbadusername": "Кто это?",
|
||||||
"jetkarmabot.award.errdup": "Пожалуйста, не батчайте награды.",
|
"jetkarmabot.award.errdup": "Пожалуйста, не батчайте награды.",
|
||||||
@ -14,7 +15,6 @@
|
|||||||
"jetkarmabot.award.awardmessage": "Вручил \"{0}\" {1}!",
|
"jetkarmabot.award.awardmessage": "Вручил \"{0}\" {1}!",
|
||||||
"jetkarmabot.award.revokemessage": "Отнял \"{0}\" у {1}!",
|
"jetkarmabot.award.revokemessage": "Отнял \"{0}\" у {1}!",
|
||||||
"jetkarmabot.award.statustext": "У {0} теперь {1}{2}.",
|
"jetkarmabot.award.statustext": "У {0} теперь {1}{2}.",
|
||||||
"jetkarmabot.award.ratelimit": "Помедленней, чувак!",
|
|
||||||
"jetkarmabot.award.help": "Вручает очко пользователю (или отнимает)",
|
"jetkarmabot.award.help": "Вручает очко пользователю (или отнимает)",
|
||||||
"jetkarmabot.award.awardtypehelp": "Тип очка",
|
"jetkarmabot.award.awardtypehelp": "Тип очка",
|
||||||
"jetkarmabot.award.tohelp": "Пользователь, которого наградить",
|
"jetkarmabot.award.tohelp": "Пользователь, которого наградить",
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user