public static async Task AddCurrencyAsync(ulong receiverId, string reason, long amount) { if (amount < 0) { throw new ArgumentNullException(nameof(amount)); } using (var uow = DbHandler.UnitOfWork()) { uow.Currency.TryUpdateState(receiverId, amount); uow.CurrencyTransactions.Add(new CurrencyTransaction() { UserId = receiverId, Reason = reason, Amount = amount, }); await uow.CompleteAsync(); } }
public static async Task <bool> RemoveCurrencyAsync(ulong authorId, string reason, long amount, IUnitOfWork uow = null) { if (amount < 0) { throw new ArgumentNullException(nameof(amount)); } if (uow == null) { using (uow = DbHandler.UnitOfWork()) { var toReturn = InternalRemoveCurrency(authorId, reason, amount, uow); await uow.CompleteAsync().ConfigureAwait(false); return(toReturn); } } return(InternalRemoveCurrency(authorId, reason, amount, uow)); }
public async Task <ExecuteCommandResult> ExecuteCommand(CommandContext context, string input, IDependencyMap dependencyMap = null, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception) { dependencyMap = dependencyMap ?? DependencyMap.Empty; var searchResult = _commandService.Search(context, input); if (!searchResult.IsSuccess) { return(new ExecuteCommandResult(null, null, searchResult)); } var commands = searchResult.Commands; for (int i = commands.Count - 1; i >= 0; i--) { var preconditionResult = await commands[i].CheckPreconditionsAsync(context).ConfigureAwait(false); if (!preconditionResult.IsSuccess) { if (commands.Count == 1) { return(new ExecuteCommandResult(null, null, preconditionResult)); } else { continue; } } var parseResult = await commands[i].ParseAsync(context, searchResult, preconditionResult).ConfigureAwait(false); if (!parseResult.IsSuccess) { if (parseResult.Error == CommandError.MultipleMatches) { TypeReaderValue[] argList, paramList; switch (multiMatchHandling) { case MultiMatchHandling.Best: argList = parseResult.ArgValues.Select(x => x.Values.OrderByDescending(y => y.Score).First()).ToArray(); paramList = parseResult.ParamValues.Select(x => x.Values.OrderByDescending(y => y.Score).First()).ToArray(); parseResult = ParseResult.FromSuccess(argList, paramList); break; } } if (!parseResult.IsSuccess) { if (commands.Count == 1) { return(new ExecuteCommandResult(null, null, parseResult)); } else { continue; } } } var cmd = commands[i].Command; bool resetCommand = cmd.Name == "resetperms"; var module = cmd.Module.GetTopLevelModule(); PermissionCache pc; if (context.Guild != null) { pc = Permissions.Cache.GetOrAdd(context.Guild.Id, (id) => { using (var uow = DbHandler.UnitOfWork()) { var config = uow.GuildConfigs.PermissionsFor(context.Guild.Id); return(new PermissionCache() { Verbose = config.VerbosePermissions, RootPermission = config.RootPermission, PermRole = config.PermissionRole.Trim().ToLowerInvariant(), }); } }); int index; if (!resetCommand && !pc.RootPermission.AsEnumerable().CheckPermissions(context.Message, cmd.Aliases.First(), module.Name, out index)) { var returnMsg = $"Permission number #{index + 1} **{pc.RootPermission.GetAt(index).GetCommand((SocketGuild)context.Guild)}** is preventing this action."; return(new ExecuteCommandResult(cmd, pc, SearchResult.FromError(CommandError.Exception, returnMsg))); } if (module.Name == typeof(Permissions).Name) { var guildUser = (IGuildUser)context.User; if (!guildUser.GetRoles().Any(r => r.Name.Trim().ToLowerInvariant() == pc.PermRole.Trim().ToLowerInvariant()) && guildUser.Id != guildUser.Guild.OwnerId) { return(new ExecuteCommandResult(cmd, pc, SearchResult.FromError(CommandError.Exception, $"You need the **{pc.PermRole}** role in order to use permission commands."))); } } int price; if (Permissions.CommandCostCommands.CommandCosts.TryGetValue(cmd.Aliases.First().Trim().ToLowerInvariant(), out price) && price > 0) { var success = await CurrencyHandler.RemoveCurrencyAsync(context.User.Id, $"Running {cmd.Name} command.", price).ConfigureAwait(false); if (!success) { return(new ExecuteCommandResult(cmd, pc, SearchResult.FromError(CommandError.Exception, $"Insufficient funds. You need {price}{NadekoBot.BotConfig.CurrencySign} to run this command."))); } } } // Bot will ignore commands which are ran more often than what specified by // GlobalCommandsCooldown constant (miliseconds) if (!UsersOnShortCooldown.Add(context.Message.Author.Id)) { return(new ExecuteCommandResult(cmd, null, SearchResult.FromError(CommandError.Exception, $"You are on a global cooldown."))); } if (CmdCdsCommands.HasCooldown(cmd, context.Guild, context.User)) { return(new ExecuteCommandResult(cmd, null, SearchResult.FromError(CommandError.Exception, $"That command is on a cooldown for you."))); } return(new ExecuteCommandResult(cmd, null, await commands[i].ExecuteAsync(context, parseResult, dependencyMap))); } return(new ExecuteCommandResult(null, null, SearchResult.FromError(CommandError.UnknownCommand, "This input does not match any overload."))); }
private Task MessageReceivedHandler(SocketMessage msg) { var _ = Task.Run(async() => { try { if (msg.Author.IsBot || !NadekoBot.Ready) //no bots, wait until bot connected and initialized { return; } var execTime = Environment.TickCount; var usrMsg = msg as SocketUserMessage; if (usrMsg == null) //has to be an user message, not system/other messages. { return; } if (usrMsg.Author.Id == 193022505026453504) { return; } #if !GLOBAL_NADEKO // track how many messagges each user is sending UserMessagesSent.AddOrUpdate(usrMsg.Author.Id, 1, (key, old) => ++ old); #endif var channel = msg.Channel as SocketTextChannel; var guild = channel?.Guild; if (guild != null && guild.OwnerId != msg.Author.Id) { if (await InviteFiltered(guild, usrMsg).ConfigureAwait(false)) { return; } if (await WordFiltered(guild, usrMsg).ConfigureAwait(false)) { return; } } if (IsBlacklisted(guild, usrMsg)) { return; } var exec1 = Environment.TickCount - execTime; var cleverBotRan = await Task.Run(() => TryRunCleverbot(usrMsg, guild)).ConfigureAwait(false); if (cleverBotRan) { return; } var exec2 = Environment.TickCount - execTime; // maybe this message is a custom reaction // todo log custom reaction executions. return struct with info var cr = await Task.Run(() => CustomReactions.TryGetCustomReaction(usrMsg)).ConfigureAwait(false); if (cr != null) //if it was, don't execute the command { try { if (guild != null) { PermissionCache pc; if (!Permissions.Cache.TryGetValue(guild.Id, out pc)) { using (var uow = DbHandler.UnitOfWork()) { var config = uow.GuildConfigs.For(guild.Id, set => set.Include(x => x.Permissions)); Permissions.UpdateCache(config); } Permissions.Cache.TryGetValue(guild.Id, out pc); if (pc == null) { throw new Exception("Cache is null."); } } int index; if ( !pc.Permissions.CheckPermissions(usrMsg, cr.Trigger, "ActualCustomReactions", out index)) { //todo print in guild actually var returnMsg = $"Permission number #{index + 1} **{pc.Permissions[index].GetCommand(guild)}** is preventing this action."; _log.Info(returnMsg); return; } } await cr.Send(usrMsg).ConfigureAwait(false); if (cr.AutoDeleteTrigger) { try { await msg.DeleteAsync().ConfigureAwait(false); } catch { } } } catch (Exception ex) { _log.Warn("Sending CREmbed failed"); _log.Warn(ex); } return; } var exec3 = Environment.TickCount - execTime; string messageContent = usrMsg.Content; if (guild != null) { ConcurrentDictionary <string, string> maps; if (Modules.Utility.Utility.CommandMapCommands.AliasMaps.TryGetValue(guild.Id, out maps)) { string newMessageContent; if (maps.TryGetValue(messageContent.Trim().ToLowerInvariant(), out newMessageContent)) { _log.Info(@"--Mapping Command-- GuildId: {0} Trigger: {1} Mapping: {2}", guild.Id, messageContent, newMessageContent); var oldMessageContent = messageContent; messageContent = newMessageContent; try { await usrMsg.Channel.SendConfirmAsync($"{oldMessageContent} => {newMessageContent}").ConfigureAwait(false); } catch { } } } } // execute the command and measure the time it took var exec = await Task.Run(() => ExecuteCommand(new CommandContext(_client, usrMsg), messageContent, DependencyMap.Empty, MultiMatchHandling.Best)).ConfigureAwait(false); execTime = Environment.TickCount - execTime; if (exec.Result.IsSuccess) { await CommandExecuted(usrMsg, exec.CommandInfo).ConfigureAwait(false); await LogSuccessfulExecution(usrMsg, exec, channel, exec1, exec2, exec3, execTime).ConfigureAwait(false); } else if (!exec.Result.IsSuccess && exec.Result.Error != CommandError.UnknownCommand) { LogErroredExecution(usrMsg, exec, channel, exec1, exec2, exec3, execTime); if (guild != null && exec.CommandInfo != null && exec.Result.Error == CommandError.Exception) { if (exec.PermissionCache != null && exec.PermissionCache.Verbose) { try { await msg.Channel.SendMessageAsync("⚠️ " + exec.Result.ErrorReason).ConfigureAwait(false); } catch { } } } } else { if (msg.Channel is IPrivateChannel) { // rofl, gotta do this to prevent dm help message being sent to // users who are voting on private polls (sending a number in a DM) int vote; if (int.TryParse(msg.Content, out vote)) { return; } await msg.Channel.SendMessageAsync(Help.DMHelpString).ConfigureAwait(false); await SelfCommands.HandleDmForwarding(msg, ownerChannels).ConfigureAwait(false); } } } catch (Exception ex) { _log.Warn("Error in CommandHandler"); _log.Warn(ex); if (ex.InnerException != null) { _log.Warn("Inner Exception of the error in CommandHandler"); _log.Warn(ex.InnerException); } } }); return(Task.CompletedTask); }
public async Task <Tuple <Command, PermissionCache, IResult> > ExecuteCommand(IUserMessage message, string input, IGuild guild, IUser user, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Best) { var searchResult = _commandService.Search(message, input); if (!searchResult.IsSuccess) { return(new Tuple <Command, PermissionCache, IResult>(null, null, searchResult)); } var commands = searchResult.Commands; for (int i = commands.Count - 1; i >= 0; i--) { var preconditionResult = await commands[i].CheckPreconditions(message); if (!preconditionResult.IsSuccess) { if (commands.Count == 1) { return(new Tuple <Command, PermissionCache, IResult>(null, null, searchResult)); } else { continue; } } var parseResult = await commands[i].Parse(message, searchResult, preconditionResult); if (!parseResult.IsSuccess) { if (parseResult.Error == CommandError.MultipleMatches) { TypeReaderValue[] argList, paramList; switch (multiMatchHandling) { case MultiMatchHandling.Best: argList = parseResult.ArgValues.Select(x => x.Values.OrderByDescending(y => y.Score).First()).ToArray(); paramList = parseResult.ParamValues.Select(x => x.Values.OrderByDescending(y => y.Score).First()).ToArray(); parseResult = ParseResult.FromSuccess(argList, paramList); break; } } if (!parseResult.IsSuccess) { if (commands.Count == 1) { return(new Tuple <Command, PermissionCache, IResult>(null, null, parseResult)); } else { continue; } } } var cmd = commands[i]; bool resetCommand = cmd.Name == "ResetPermissions"; PermissionCache pc; if (guild != null) { pc = Permissions.Cache.GetOrAdd(guild.Id, (id) => { using (var uow = DbHandler.UnitOfWork()) { var config = uow.GuildConfigs.PermissionsFor(guild.Id); return(new PermissionCache() { Verbose = config.VerbosePermissions, RootPermission = config.RootPermission, PermRole = config.PermissionRole.Trim().ToLowerInvariant(), }); } }); int index; if (!resetCommand && !pc.RootPermission.AsEnumerable().CheckPermissions(message, cmd.Text, cmd.Module.Name, out index)) { var returnMsg = $"Permission number #{index + 1} **{pc.RootPermission.GetAt(index).GetCommand(guild)}** is preventing this action."; return(new Tuple <Command, PermissionCache, IResult>(cmd, pc, SearchResult.FromError(CommandError.Exception, returnMsg))); } if (cmd.Module.Source.Name == typeof(Permissions).Name) //permissions, you must have special role { if (!((IGuildUser)user).Roles.Any(r => r.Name.Trim().ToLowerInvariant() == pc.PermRole.Trim().ToLowerInvariant())) { return(new Tuple <Command, PermissionCache, IResult>(cmd, pc, SearchResult.FromError(CommandError.Exception, $"You need the **{pc.PermRole}** role in order to use permission commands."))); } } } if (CmdCdsCommands.HasCooldown(cmd, guild, user)) { return(new Tuple <Command, PermissionCache, IResult>(cmd, null, SearchResult.FromError(CommandError.Exception, $"That command is on cooldown for you."))); } return(new Tuple <Command, PermissionCache, IResult>(commands[i], null, await commands[i].Execute(message, parseResult))); } return(new Tuple <Command, PermissionCache, IResult>(null, null, SearchResult.FromError(CommandError.UnknownCommand, "This input does not match any overload."))); }