From de8932b764572d6defff7526a2bc786576c08ee8 Mon Sep 17 00:00:00 2001 From: Lezenn Date: Sun, 17 Jan 2021 21:08:44 +0100 Subject: [PATCH 01/19] Warn module added --- module_warn.lua | 292 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 292 insertions(+) create mode 100644 module_warn.lua diff --git a/module_warn.lua b/module_warn.lua new file mode 100644 index 0000000..c6d3835 --- /dev/null +++ b/module_warn.lua @@ -0,0 +1,292 @@ +-- Copyright (C) 2021 Lezenn +-- This file is part of the "Not a Bot" application +-- For conditions of distribution and use, see copyright notice in LICENSE + +local client = Client +local config = Config +local discordia = Discordia +local bot = Bot +local enums = discordia.enums + +Module.Name = "warn" + +-- Storage Model +-- +-- [ +-- { +-- UserId: memberId, +-- Warns: { +-- {From: moderatorId, Reason: "...."}, +-- ... +-- } +-- }, +-- ... +-- ] + +function FindMember(history, memberId) + local result = nil + for _idx, userHistory in ipairs(history) do + if userHistory.UserId == memberId then + result = userHistory + break + end + end + return result +end + +function AddWarn(history, memberId, moderatorId, reason) + local member = FindMember(history, memberId) + if (not member) then + table.insert(history, { + UserId = memberId, + Warns = { + { + From = moderatorId, + Reason = reason, + } + } + }) + else + table.insert(member.Warns, { + From = moderatorId, + Reason = reason, + }) + end +end + +function GetWarnAmount(history, memberId) + local member = FindMember(history, memberId) + return table.length(member.Warns) +end + +function SendWarnMessage(commandMessage, targetMember, reason) + if not reason then + commandMessage:reply(string.format("**%s** has warned **%s**.", commandMessage.member.name, targetMember.name)) + else + commandMessage:reply(string.format("**%s** has warned **%s** for the following reason:\n**%s**.", commandMessage.member.name, targetMember.name, reason)) + end +end + +-------------------------------- + +function Module:CheckPermissions(member) + return member:hasPermission(enums.permission.banMembers) +end + +function Module:GetConfigTable() + + return { + { + Name = "Sactions", + Description = "Enable sanctions over members.", + Type = bot.ConfigType.Boolean, + Default = true + }, + { + Name = "WarnAmountToMute", + Description = "Number of warns needed to mute the member.", + Type = bot.ConfigType.Integer, + Default = 3 + }, + { + Name = "WarnAmountToBan", + Description = "Number of warns needed to tempban the member.", + Type = bot.ConfigType.Integer, + Default = 9, + }, + { + Name = "DefaultMuteDuration", + Description = "Default mute duration when reached enough warns.", + Type = bot.ConfigType.Duration, + Default = 60 * 60 + }, + { + Name = "MuteRole", + Description = "Mute role to be applied (no need to configure its permissions)", + Type = bot.ConfigType.Role, + Default = "" + }, + { + Name = "BanInformationChannel", + Description = "Default channel where all the ban-able members are listed.", + Type = bot.ConfigType.Channel, + Default = "" + }, + { + Name = "SendPrivateMessage", + Description = "Sends the warning to the user in private message.", + Type = bot.ConfigType.Boolean, + Default = true + } + } + +end + +function Module:OnEnable(guild) + local data = self:GetPersistentData(guild) + data = data or {} + + return true +end + +function Module:OnLoaded() + + -- + -- warn command + -- + self:RegisterCommand({ + Name = "warn", + Args = { + {Name = "target", Type = bot.ConfigType.User}, + {Name = "reason", Type = bot.ConfigType.String, Optional = true} + }, + PrivilegeCheck = function (member) return self:CheckPermissions(member) end, + + Help = "Warns a member", + Silent = true, + Func = function (commandMessage, targetUser, reason) + local guild = commandMessage.guild + local config = self:GetConfig(guild) + local history = self:GetPersistentData(guild) + history = history or {} + + local targetMember = guild:getMember(targetUser) + local moderator = commandMessage.member + + -- Permission check + if targetMember then + local bannedByRole = moderator.highestRole + local targetRole = targetMember.highestRole + if targetRole.position >= bannedByRole.position then + commandMessage:reply("You cannot warn this user due to your lower permissions.") + return + end + end + + -- Adding warn to the user + local targetId = targetUser.id + local moderatorId = commandMessage.member.id + + AddWarn(history, targetId, moderatorId, reason) + + + if config.SendPrivateMessage then + local privateChannel = targetUser:getPrivateChannel() + if privateChannel then + privateChannel:send(string.format("You have been warned for the following reason:\n **%s**", reason)) + end + end + + -- Updating member state + SendWarnMessage(commandMessage, targetMember, reason) + + if config.Sactions then + local banAmount = config.WarnAmountToBan + local muteAmount = config.WarnAmountToMute + local warnAmount = GetWarnAmount(history, targetId) + + if warnAmount % banAmount == 0 then + -- BAN + local channel = config.BanInformationChannel + if channel then + channel:send(string.format("The member **%s** ( %d ) has enough warns to be banned (%d).", + targetMember.tag, + targetMember.id, + warnAmount + )) + end + + + elseif warnAmount % muteAmount == 0 then + -- MUTE + local duration = config.DefaultMuteDuration * (warnAmount / muteAmount) + local durationStr = util.FormatTime(duration, 3) + commandMessage:reply(string.format("**%s** has been muted for **%s** for the reason: having too many warns.", + targetMember.name, + durationStr + )) + + if config.SendPrivateMessage then + local privateChannel = targetMember:getPrivateChannel() + if privateChannel then + local durationText + if (duration > 0) then + durationText = "You will be unmuted in " .. durationStr + else + durationText = "" + end + privateChannel:send(string.format("You have been muted from **%s** by having too many warns.", + commandMessage.guild.name + )) + end + end + + local success, err = self:Mute(guild, targetMember.id, duration) + if success then + commandMessage:reply(string.format("%s has been muted for having too many warns.", targetMember.name)) + else + commandMessage:reply(string.format("Failed to mute %s: %s", targetMember.name, err)) + end + end + end + end + }) + + -- + -- warnlist command + -- + self:RegisterCommand({ + Name = "warnlist", + Args = { + {Name = "targetUser", Type = bot.ConfigType.User} + }, + PrivilegeCheck = function (member) return self:CheckPermissions(member) end, + + Help = "Shows all the warns of a member.", + Silent = true, + Func = function(commandMessage, targetUser) + local guild = commandMessage.guild + local history = self:GetPersistentData(guild) + local targetMember = guild:getMember(targetUser) + + local memberHistory = FindMember(history, targetMember.id) + if not memberHistory then + commandMessage:reply(string.format("The member **%s** doesn't have any warns.", targetMember.name)) + else + local message = string.format("Warns of **%s**\n", targetMember.name) + local warns = memberHistory.Warns + for _idx, warn in ipairs(warns) do + local moderator = guild:getMember(warn.From) + local reason = warn.Reason or "No reason provided" + message = message .. string.format("Warned by : **%s** for the reason:\n\t**%s**\n", moderator.name, reason) + end + commandMessage:reply(message) + end + end + }) + + return true +end + +-- FROM module_mute.lua +function Module:Mute(guild, userId, duration) + local config = self:GetConfig(guild) + local member = guild:getMember(userId) + if (not member) then + return false, "not part of guild" + end + + local success, err = member:addRole(config.MuteRole) + if (not success) then + self:LogError(guild, "Failed to mute %s: %s", member.tag, err) + return false, "failed to mute user: " .. err + end + + local persistentData = self:GetPersistentData(guild) + local unmuteTimestamp = duration > 0 and os.time() + duration or 0 + + persistentData.MutedUsers[userId] = unmuteTimestamp + self:RegisterUnmute(guild, userId, unmuteTimestamp) + + return true +end \ No newline at end of file From 118c1ebeb70b1aba22e47c89c731e42d355c0cff Mon Sep 17 00:00:00 2001 From: Lezenn Date: Sun, 17 Jan 2021 21:38:29 +0100 Subject: [PATCH 02/19] Changed mute and ban behaviour --- module_warn.lua | 82 +++++++++++++++++-------------------------------- 1 file changed, 28 insertions(+), 54 deletions(-) diff --git a/module_warn.lua b/module_warn.lua index c6d3835..0e620b4 100644 --- a/module_warn.lua +++ b/module_warn.lua @@ -61,9 +61,9 @@ end function SendWarnMessage(commandMessage, targetMember, reason) if not reason then - commandMessage:reply(string.format("**%s** has warned **%s**.", commandMessage.member.name, targetMember.name)) + commandMessage:reply(string.format("**%s** has warned **%s**.", commandMessage.member.tag, targetMember.tag)) else - commandMessage:reply(string.format("**%s** has warned **%s** for the following reason:\n**%s**.", commandMessage.member.name, targetMember.name, reason)) + commandMessage:reply(string.format("**%s** has warned **%s** for the following reason:\n**%s**.", commandMessage.member.tag, targetMember.tag, reason)) end end @@ -102,7 +102,7 @@ function Module:GetConfigTable() }, { Name = "MuteRole", - Description = "Mute role to be applied (no need to configure its permissions)", + Description = "(MUTE NOT YET IMPLEMENTED) Mute role to be applied (no need to configure its permissions)\n /!\\ The role must be the same as the role used in the Mute module. The Mute module must be enabled too.", Type = bot.ConfigType.Role, Default = "" }, @@ -126,6 +126,19 @@ function Module:OnEnable(guild) local data = self:GetPersistentData(guild) data = data or {} + local config = self:GetConfig(guild) + + local banInfo = config.BanInformationChannel and guild:getChannel(config.BanInformationChannel) or nil + if not banInfo then + return false, "Invalid ban information channel, check your configuration." + end + + local muteRole = config.MuteRole and guild:getRole(config.MuteRole) or nil + if not muteRole then + return false, "Invalid mute role, check your configuration." + end + + return true end @@ -187,7 +200,7 @@ function Module:OnLoaded() if warnAmount % banAmount == 0 then -- BAN - local channel = config.BanInformationChannel + local channel = guild:getChannel(config.BanInformationChannel) if channel then channel:send(string.format("The member **%s** ( %d ) has enough warns to be banned (%d).", targetMember.tag, @@ -201,31 +214,15 @@ function Module:OnLoaded() -- MUTE local duration = config.DefaultMuteDuration * (warnAmount / muteAmount) local durationStr = util.FormatTime(duration, 3) - commandMessage:reply(string.format("**%s** has been muted for **%s** for the reason: having too many warns.", - targetMember.name, - durationStr - )) - if config.SendPrivateMessage then - local privateChannel = targetMember:getPrivateChannel() - if privateChannel then - local durationText - if (duration > 0) then - durationText = "You will be unmuted in " .. durationStr - else - durationText = "" - end - privateChannel:send(string.format("You have been muted from **%s** by having too many warns.", - commandMessage.guild.name - )) - end - end - - local success, err = self:Mute(guild, targetMember.id, duration) - if success then - commandMessage:reply(string.format("%s has been muted for having too many warns.", targetMember.name)) - else - commandMessage:reply(string.format("Failed to mute %s: %s", targetMember.name, err)) + local channel = guild:getChannel(config.BanInformationChannel) + if channel then + channel:send(string.format("The member **%s** ( %d ) has enough warns to be muted (%d) for %s.", + targetMember.tag, + targetMember.id, + warnAmount, + durationStr + )) end end end @@ -251,14 +248,14 @@ function Module:OnLoaded() local memberHistory = FindMember(history, targetMember.id) if not memberHistory then - commandMessage:reply(string.format("The member **%s** doesn't have any warns.", targetMember.name)) + commandMessage:reply(string.format("The member **%s** (%d) doesn't have any warns.", targetMember.tag, targetMember.id)) else - local message = string.format("Warns of **%s**\n", targetMember.name) + local message = string.format("Warns of **%s** (%d)\n", targetMember.tag, targetMember.id) local warns = memberHistory.Warns for _idx, warn in ipairs(warns) do local moderator = guild:getMember(warn.From) local reason = warn.Reason or "No reason provided" - message = message .. string.format("Warned by : **%s** for the reason:\n\t**%s**\n", moderator.name, reason) + message = message .. string.format("Warned by : **%s** for the reason:\n\t**%s**\n", moderator.tag, reason) end commandMessage:reply(message) end @@ -266,27 +263,4 @@ function Module:OnLoaded() }) return true -end - --- FROM module_mute.lua -function Module:Mute(guild, userId, duration) - local config = self:GetConfig(guild) - local member = guild:getMember(userId) - if (not member) then - return false, "not part of guild" - end - - local success, err = member:addRole(config.MuteRole) - if (not success) then - self:LogError(guild, "Failed to mute %s: %s", member.tag, err) - return false, "failed to mute user: " .. err - end - - local persistentData = self:GetPersistentData(guild) - local unmuteTimestamp = duration > 0 and os.time() + duration or 0 - - persistentData.MutedUsers[userId] = unmuteTimestamp - self:RegisterUnmute(guild, userId, unmuteTimestamp) - - return true end \ No newline at end of file From 8f64ef95234a9777a865eb50c6f38932a836a406 Mon Sep 17 00:00:00 2001 From: Lezenn Date: Sun, 17 Jan 2021 21:57:55 +0100 Subject: [PATCH 03/19] Fixed mute and phrases --- module_warn.lua | 51 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 10 deletions(-) diff --git a/module_warn.lua b/module_warn.lua index 0e620b4..e2b81a4 100644 --- a/module_warn.lua +++ b/module_warn.lua @@ -202,27 +202,30 @@ function Module:OnLoaded() -- BAN local channel = guild:getChannel(config.BanInformationChannel) if channel then - channel:send(string.format("The member **%s** ( %d ) has enough warns to be banned (%d).", + channel:send(string.format("The member **%s** ( %d ) has enough warns to be banned (%d warns).", targetMember.tag, targetMember.id, warnAmount )) end - elseif warnAmount % muteAmount == 0 then -- MUTE local duration = config.DefaultMuteDuration * (warnAmount / muteAmount) local durationStr = util.FormatTime(duration, 3) + local mute_module = bot:GetModuleForGuild(guild, "mute") - local channel = guild:getChannel(config.BanInformationChannel) - if channel then - channel:send(string.format("The member **%s** ( %d ) has enough warns to be muted (%d) for %s.", - targetMember.tag, - targetMember.id, - warnAmount, - durationStr - )) + if mute_module:IsEnabledForGuild(guild) then + local channel = guild:getChannel(config.BanInformationChannel) + if channel then + channel:send(string.format("The member **%s** ( %d ) has enough warns to be muted (%d warns) for %s.", + targetMember.tag, + targetMember.id, + warnAmount, + durationStr + )) + end + bot:CallModuleFunction(mute_module, "Mute", guild, targetMember.id, duration) end end end @@ -262,5 +265,33 @@ function Module:OnLoaded() end }) + -- + -- clearwarns command + -- + self:RegisterCommand({ + Name = "clearwarns", + Args = { + {Name = "targetUser", Type = bot.ConfigType.User} + }, + PrivilegeCheck = function (member) return self:CheckPermissions(member) end, + + Help = "Clears all the warns of a specified user.", + Silent = true, + Func = function (commandMessage, targetUser) + local guild = commandMessage.guild + local history = self:GetPersistentData(guild) + local targetMember = guild:getMember(targetUser) + + local memberHistory = FindMember(history, targetMember.id) + if not memberHistory then + commandMessage:reply(string.format("The member **%s** (%d) already have zero warns.", targetMember.tag, targetMember.id)) + else + memberHistory.Warns = {} + commandMessage:reply(string.format("Cleared **%s** (%d) warns, saving.", targetMember.tag, targetMember.id)) + bot:Save() + end + end + }) + return true end \ No newline at end of file From dfbb84137abbc6b50f688e661423f51d2a2b8416 Mon Sep 17 00:00:00 2001 From: Lezenn Date: Mon, 18 Jan 2021 16:29:35 +0100 Subject: [PATCH 04/19] fixed global functions, nil in private messages, added origin of the warn in PM --- module_warn.lua | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/module_warn.lua b/module_warn.lua index e2b81a4..aab5a7b 100644 --- a/module_warn.lua +++ b/module_warn.lua @@ -23,7 +23,7 @@ Module.Name = "warn" -- ... -- ] -function FindMember(history, memberId) +local function FindMember(history, memberId) local result = nil for _idx, userHistory in ipairs(history) do if userHistory.UserId == memberId then @@ -34,7 +34,7 @@ function FindMember(history, memberId) return result end -function AddWarn(history, memberId, moderatorId, reason) +local function AddWarn(history, memberId, moderatorId, reason) local member = FindMember(history, memberId) if (not member) then table.insert(history, { @@ -54,12 +54,12 @@ function AddWarn(history, memberId, moderatorId, reason) end end -function GetWarnAmount(history, memberId) +local function GetWarnAmount(history, memberId) local member = FindMember(history, memberId) return table.length(member.Warns) end -function SendWarnMessage(commandMessage, targetMember, reason) +local function SendWarnMessage(commandMessage, targetMember, reason) if not reason then commandMessage:reply(string.format("**%s** has warned **%s**.", commandMessage.member.tag, targetMember.tag)) else @@ -186,7 +186,11 @@ function Module:OnLoaded() if config.SendPrivateMessage then local privateChannel = targetUser:getPrivateChannel() if privateChannel then - privateChannel:send(string.format("You have been warned for the following reason:\n **%s**", reason)) + if reason then + privateChannel:send(string.format("You have been warned on %s for the following reason:\n **%s**", guild.name, reason)) + else + privateChannel:send(string.format("You have been warned on %s", guild.name)) + end end end From 13e8facec1a86c276f88b9bd049ebce91bed4334 Mon Sep 17 00:00:00 2001 From: Lezenn Date: Mon, 18 Jan 2021 18:21:40 +0100 Subject: [PATCH 05/19] Cleanup --- module_warn.lua | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/module_warn.lua b/module_warn.lua index aab5a7b..470fec9 100644 --- a/module_warn.lua +++ b/module_warn.lua @@ -77,7 +77,7 @@ function Module:GetConfigTable() return { { - Name = "Sactions", + Name = "Sanctions", Description = "Enable sanctions over members.", Type = bot.ConfigType.Boolean, Default = true @@ -100,12 +100,6 @@ function Module:GetConfigTable() Type = bot.ConfigType.Duration, Default = 60 * 60 }, - { - Name = "MuteRole", - Description = "(MUTE NOT YET IMPLEMENTED) Mute role to be applied (no need to configure its permissions)\n /!\\ The role must be the same as the role used in the Mute module. The Mute module must be enabled too.", - Type = bot.ConfigType.Role, - Default = "" - }, { Name = "BanInformationChannel", Description = "Default channel where all the ban-able members are listed.", @@ -133,12 +127,6 @@ function Module:OnEnable(guild) return false, "Invalid ban information channel, check your configuration." end - local muteRole = config.MuteRole and guild:getRole(config.MuteRole) or nil - if not muteRole then - return false, "Invalid mute role, check your configuration." - end - - return true end From 6ffd656ca7881fb1b575a03f3624cd5278ab46c7 Mon Sep 17 00:00:00 2001 From: Lezenn Date: Mon, 18 Jan 2021 18:28:55 +0100 Subject: [PATCH 06/19] Refactor --- module_warn.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module_warn.lua b/module_warn.lua index 470fec9..2a4b2d6 100644 --- a/module_warn.lua +++ b/module_warn.lua @@ -207,7 +207,7 @@ function Module:OnLoaded() local durationStr = util.FormatTime(duration, 3) local mute_module = bot:GetModuleForGuild(guild, "mute") - if mute_module:IsEnabledForGuild(guild) then + if mute_module then local channel = guild:getChannel(config.BanInformationChannel) if channel then channel:send(string.format("The member **%s** ( %d ) has enough warns to be muted (%d warns) for %s.", From 1ff4aa63fc6f0ac2aa985e81e7fa2ca1df20c158 Mon Sep 17 00:00:00 2001 From: Lezenn Date: Mon, 18 Jan 2021 18:32:02 +0100 Subject: [PATCH 07/19] Refactor --- module_warn.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module_warn.lua b/module_warn.lua index 2a4b2d6..665de05 100644 --- a/module_warn.lua +++ b/module_warn.lua @@ -185,7 +185,7 @@ function Module:OnLoaded() -- Updating member state SendWarnMessage(commandMessage, targetMember, reason) - if config.Sactions then + if config.Sanctions then local banAmount = config.WarnAmountToBan local muteAmount = config.WarnAmountToMute local warnAmount = GetWarnAmount(history, targetId) From f4a129c98a1f89be95ac0e636428c90261a85536 Mon Sep 17 00:00:00 2001 From: Lezenn Date: Mon, 18 Jan 2021 21:39:43 +0100 Subject: [PATCH 08/19] Started documentation --- doc/index.md | 39 +++++++++++++++++++++++++++++ doc/modules/warn_module.md | 50 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 doc/index.md create mode 100644 doc/modules/warn_module.md diff --git a/doc/index.md b/doc/index.md new file mode 100644 index 0000000..c10c92e --- /dev/null +++ b/doc/index.md @@ -0,0 +1,39 @@ +# Not a Bot - Discord Bot + +Not a Bot is a french moderation bot designed for the [Not a Name](https://discord.gg/zcWp9sC). + +It is based on multiple configurable modules where each ones have their own task. + +The bot is made in Lua, with a custom wrapper around the Discordia library. + +## Summary + +### Modules + +- [Ban]() : Ban management module +- [Channel]() : Channel management module +- [Game]() : +- [Kick]() : Kick management +- [Mention]() : Mention reaction module +- [Message]() : Message handler module (includes custom commands) +- [Modmail]() : Modmail and tickets module +- [Modo]() : Alert and flags module +- [Mute]() : Mute management module +- [Pin]() : Message pinning module +- [Poll]() : Polling module +- [Purge]() : Purge management module +- [Quote]() : Message quoting module +- [Raid]() : Anti-raid module +- [RoleInfo]() : Infos about roles +- [Stats]() : Guild stat module +- [Twitch]() : Twitch notification module +- [Warn](modules/warn_module.md) : Warning module +- [Welcome]() : Welcome message module + +### API + + + +### External Resources + +- [Discordia Library](https://github.com/SinisterRectus/Discordia) \ No newline at end of file diff --git a/doc/modules/warn_module.md b/doc/modules/warn_module.md new file mode 100644 index 0000000..c11fbee --- /dev/null +++ b/doc/modules/warn_module.md @@ -0,0 +1,50 @@ +# Warn Module + +Back to the *[Summary](../index.md)*. + +*[Sources of the module](../../module_warn.lua)* + +The warn module is used to give members warnings about their behaviour in the guild. + +After a given amount of warns, the member gets muted __if the mute module is enabled__ + +## Config + + +- Sanctions (Boolean) (default = true) + - Enables sanctions (mute and ban alert) when a member receives a warning. + +- WarnAmountToMute (Integer) (default = 3) + - Number of warns needed to mute a member. + +- WarnAmountToBan (Integer) (default = 9) + - Numbed of warns needed to send the ban alert to the moderators. + +- DefaultMuteDuration (Duration) (default = 1 hour) + - Default mute duration when a member gets enough warnings. + - The duration increases as the warning amount increases: `duration = default_duration * (warnings / WarnAmountToMute)` + +- BanInformationChannel (Channel) (default = nothing) + - Channel where all the ban notifications are sent when a player has enough warnings + - This setting is required to enable the module + - You still have to manually ban the member, the last choice remains to the moderation team. + +- SendPrivateMessage (Boolean) (default = true) + - Enable private messages to inform the member of his warning. + +## Commands + +Assuming the bot prefix is `!` + +- `!warn [reason]` + - This command gives a warning to the target with the given reason. It also checks if the member should receive a mute or more (only if the option is enabled). + - If enabled, the member will receive a private message resuming the warning and where it comes from. + - Example : `!warn @SomePlayer You are a terrible liar` + +- `!warnlist ` + - Shows all the warnings that the given user received. + - Example : `!warnlist @SomePlayer` + +- `!clearwarns ` + - Clears all the history of the given member. + - Example : `!clearwarns @SomePlayer` \ No newline at end of file From f1e61f18316d4ccb0c4f88f901176da3ce7f1046 Mon Sep 17 00:00:00 2001 From: Lezenn Date: Mon, 18 Jan 2021 21:42:40 +0100 Subject: [PATCH 09/19] Added doc link to readme --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 4993204..eb07403 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ # Not a Bot Source code of the bot of the french programming discord server NaN (Not a Name). https://discord.gg/zcWp9sC + +[Documentation (WIP)](doc/index.md) \ No newline at end of file From c5defdb26ccb6bddf4592210cde77d09e0e6b7fd Mon Sep 17 00:00:00 2001 From: Lezenn Date: Wed, 20 Jan 2021 06:50:34 +0100 Subject: [PATCH 10/19] Added per-server privilege check (optional) --- bot_commands.lua | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/bot_commands.lua b/bot_commands.lua index 1a2eda0..3051d63 100644 --- a/bot_commands.lua +++ b/bot_commands.lua @@ -61,12 +61,21 @@ function Bot:RegisterCommand(values) error("Command \"" .. name .. " already exists") end + if (values.PrivilegeCheck and not values.GuildAwarePrivilegeCheck) then + values.GuildAwarePrivilegeCheck = function (member, guild) return true end + end + + if (values.GuildAwarePrivilegeCheck and not values.PrivilegeCheck) then + values.PrivilegeCheck = function (member) return true end + end + local command = { Args = values.Args, Function = values.Func, Help = values.Help, Name = name, PrivilegeCheck = values.PrivilegeCheck, + GuildAwarePrivilegeCheck = values.GuildAwarePrivilegeCheck, Silent = values.Silent ~= nil and values.Silent, BotAware = values.BotAware ~= nil and values.BotAware } @@ -124,12 +133,14 @@ client:on('messageCreate', function(message) if (commandTable.PrivilegeCheck) then local success, ret = Bot:ProtectedCall("Command " .. commandName .. " privilege check", commandTable.PrivilegeCheck, message.member) - if (not success) then + local guildAwareSuccess, guildAwareRet = Bot:ProtectedCall("Command " .. commandName .. " guild aware privilege check", commandTable.GuildAwarePrivilegeCheck, message.member, message.guild) + + if (not success or not guildAwareSuccess) then message:reply("An error occurred") return end - if (not ret) then + if (not ret and not guildAwareRet) then print(string.format("%s tried to use command %s on guild %s", message.author.tag, commandName, message.guild.name)) return end From 7520a3a5a4f4c1f97a94b057e1090fa73fc09c3c Mon Sep 17 00:00:00 2001 From: Lezenn Date: Wed, 20 Jan 2021 06:51:13 +0100 Subject: [PATCH 11/19] Added logging, popwarn command --- module_warn.lua | 197 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 183 insertions(+), 14 deletions(-) diff --git a/module_warn.lua b/module_warn.lua index 665de05..7240092 100644 --- a/module_warn.lua +++ b/module_warn.lua @@ -54,11 +54,6 @@ local function AddWarn(history, memberId, moderatorId, reason) end end -local function GetWarnAmount(history, memberId) - local member = FindMember(history, memberId) - return table.length(member.Warns) -end - local function SendWarnMessage(commandMessage, targetMember, reason) if not reason then commandMessage:reply(string.format("**%s** has warned **%s**.", commandMessage.member.tag, targetMember.tag)) @@ -67,10 +62,75 @@ local function SendWarnMessage(commandMessage, targetMember, reason) end end +local function generateLogEmbed(title, moderator, target, message, timestamp) + local result = { + content = "", + embed = { + title = title, + author = { + name = target.tag, + icon_url = target.avatarURL + }, + fields = { + { + name = "Reason", + value = message, + inline = false + } + }, + timestamp = timestamp + } + } + p(result) + return result +end + -------------------------------- -function Module:CheckPermissions(member) - return member:hasPermission(enums.permission.banMembers) +function Module:LogWarn(guild, moderator, target, message, timestamp) + local config = self:GetConfig(guild) + local logChannel = guild:getChannel(config.WarnLogChannel) + logChannel:send(generateLogEmbed( + string.format("**%s** warned **%s**", moderator.tag, target.tag), + moderator, + target, + message, + timestamp + )) +end + +function Module:LogWarnModification(guild, moderator, target, message, timestamp) + local config = self:getConfig(guild) + local logChannel = guild:getChannel(config.WarnLogChannel) + + logChannel:send(generateLogEmbed( + string.format("**%s** made a modification upon **%s** warns"), + moderator, + target, + message, + timestamp + )) +end + +function Module:GetWarnAmount(history, memberId) + local member = FindMember(history, memberId) + return table.length(member.Warns) +end + +function Module:HasWarnRole(guild, member) + local config = self:GetConfig(guild) + local warnRole = guild:getRole(config.MinimalWarnRole) + local memberRole = member.highestRole + + return memberRole.position >= warnRole.position +end + +function Module:HasUnwarnRole(guild, member) + local config = self:GetConfig(guild) + local unwarnRole = guild:getRole(config.MinimalUnwarnRole) + local memberRole = member.highestRole + + return memberRole.position >= unwarnRole.position end function Module:GetConfigTable() @@ -82,6 +142,18 @@ function Module:GetConfigTable() Type = bot.ConfigType.Boolean, Default = true }, + { + Name = "MinimalWarnRole", + Description = "Minimal role to warn members and see history", + Type = bot.ConfigType.Role, + Default = "" + }, + { + Name = "MinimalUnwarnRole", + Description = "Minimal role to unwarn (remove last warn) of a member", + Type = bot.ConfigType.Role, + Default = "", + }, { Name = "WarnAmountToMute", Description = "Number of warns needed to mute the member.", @@ -102,7 +174,13 @@ function Module:GetConfigTable() }, { Name = "BanInformationChannel", - Description = "Default channel where all the ban-able members are listed.", + Description = "Channel where all the ban-able members are listed.", + Type = bot.ConfigType.Channel, + Default = "" + }, + { + Name = "WarnLogChannel", + Description = "Channel where all the warns, unwarns, ... are logged.", Type = bot.ConfigType.Channel, Default = "" }, @@ -124,7 +202,22 @@ function Module:OnEnable(guild) local banInfo = config.BanInformationChannel and guild:getChannel(config.BanInformationChannel) or nil if not banInfo then - return false, "Invalid ban information channel, check your configuration." + return false, "Invalid BanInformationChannel, check your configuration." + end + + local logChan = config.WarnLogChannel and guild:getChannel(config.WarnLogChannel) or nil + if not logChan then + return false, "Invalid WarnLogChannel, check your configuration." + end + + local warnRole = config.MinimalWarnRole and guild:getRole(config.MinimalWarnRole) or nil + if not warnRole then + return false, "Invalid MinimalWarnRole setting, check your configuration." + end + + local unwarnRole = config.MinimalUnwarnRole and guild:getRole(config.MinimalUnwarnRole) or nil + if not unwarnRole then + return false, "Invalid MinimalUnwarnRole setting, check your configuration." end return true @@ -141,7 +234,9 @@ function Module:OnLoaded() {Name = "target", Type = bot.ConfigType.User}, {Name = "reason", Type = bot.ConfigType.String, Optional = true} }, - PrivilegeCheck = function (member) return self:CheckPermissions(member) end, + GuildAwarePrivilegeCheck = function (member, guild) + return self:HasWarnRole(guild, member) + end, Help = "Warns a member", Silent = true, @@ -169,7 +264,7 @@ function Module:OnLoaded() local moderatorId = commandMessage.member.id AddWarn(history, targetId, moderatorId, reason) - + self:LogWarn(guild, moderator, targetMember, reason, commandMessage.timestamp) if config.SendPrivateMessage then local privateChannel = targetUser:getPrivateChannel() @@ -188,7 +283,7 @@ function Module:OnLoaded() if config.Sanctions then local banAmount = config.WarnAmountToBan local muteAmount = config.WarnAmountToMute - local warnAmount = GetWarnAmount(history, targetId) + local warnAmount = self:GetWarnAmount(history, targetId) if warnAmount % banAmount == 0 then -- BAN @@ -232,7 +327,9 @@ function Module:OnLoaded() Args = { {Name = "targetUser", Type = bot.ConfigType.User} }, - PrivilegeCheck = function (member) return self:CheckPermissions(member) end, + GuildAwarePrivilegeCheck = function (member, guild) + return self:HasWarnRole(guild, member) + end, Help = "Shows all the warns of a member.", Silent = true, @@ -265,7 +362,9 @@ function Module:OnLoaded() Args = { {Name = "targetUser", Type = bot.ConfigType.User} }, - PrivilegeCheck = function (member) return self:CheckPermissions(member) end, + GuildAwarePrivilegeCheck = function (member, guild) + return self:HasUnwarnRole(guild, member) + end, Help = "Clears all the warns of a specified user.", Silent = true, @@ -273,17 +372,87 @@ function Module:OnLoaded() local guild = commandMessage.guild local history = self:GetPersistentData(guild) local targetMember = guild:getMember(targetUser) + local moderator = commandMessage.author local memberHistory = FindMember(history, targetMember.id) if not memberHistory then commandMessage:reply(string.format("The member **%s** (%d) already have zero warns.", targetMember.tag, targetMember.id)) else + for _i, warn in ipairs(memberHistory.Warns) do + self:LogWarnModification( + guild, + moderator, + targetMember, + string.format("**%s** cleared the following warn of **%s** (%d).\nIt was: **%s**\n\t*From: %s*", + moderator.tag, + targetMember.tag, + targetMember.id, + warn.Reason, + guild:getMember(warn.From).tag + ) + ) + end + + self:LogWarnModification( + guild, + moderator, + targetMember, + string.format("**%s** cleared %d warns of **%s** (%d).", + moderator.tag, + #memberHistory.Warns, + targetMember.tag, + targetMember.id + ) + ) + memberHistory.Warns = {} + commandMessage:reply(string.format("Cleared **%s** (%d) warns, saving.", targetMember.tag, targetMember.id)) bot:Save() end end }) + -- + -- popwarn command + -- + self:RegisterCommand({ + Name = "popwarn", + Args = { + {Name = "targetUser", Type = bot.ConfigType.User} + }, + GuildAwarePrivilegeCheck = function (member, guild) + return self:HasUnwarnRole(guild, member) + end, + + Help = "Removes the last warn of the given user.", + Silent = true, + Func = function (commandMessage, targetUser) + local guild = commandMessage.guild + local history = self:GetPersistentData(guild) + local targetMember = guild:getMember(targetUser) + local moderator = commandMessage.author + + local memberHistory = FindMember(history, targetMember.id) + if not memberHistory then + commandMessage:reply(string.format("The member **%s** (%d) already have zero warns.", targetMember.tag, targetMember.id)) + else + local lastWarn = memberHistory.Warns.remove(#memberHistory.Warns) + self:LogWarnModification( + guild, + moderator, + targetMember, + string.format("**%s** removed the last warn of **%s** (%d).\nIt was: **%s**\n\t*From: %s*", + moderator.tag, + targetMember.tag, + targetMember.id, + lastWarn.Reason, + guild:getMember(lastWarn.From).tag + ) + ) + end + end + }) + return true end \ No newline at end of file From 86a487ebbf5719364ed38c642de1da594a7a5893 Mon Sep 17 00:00:00 2001 From: Lezenn Date: Sat, 23 Jan 2021 19:09:52 +0100 Subject: [PATCH 12/19] added logs --- module_warn.lua | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/module_warn.lua b/module_warn.lua index 7240092..c248001 100644 --- a/module_warn.lua +++ b/module_warn.lua @@ -62,7 +62,7 @@ local function SendWarnMessage(commandMessage, targetMember, reason) end end -local function generateLogEmbed(title, moderator, target, message, timestamp) +local function generateLogEmbed(title, target, message, timestamp) local result = { content = "", embed = { @@ -81,7 +81,6 @@ local function generateLogEmbed(title, moderator, target, message, timestamp) timestamp = timestamp } } - p(result) return result end @@ -90,13 +89,15 @@ end function Module:LogWarn(guild, moderator, target, message, timestamp) local config = self:GetConfig(guild) local logChannel = guild:getChannel(config.WarnLogChannel) - logChannel:send(generateLogEmbed( + local success, errMessage = logChannel:send(generateLogEmbed( string.format("**%s** warned **%s**", moderator.tag, target.tag), - moderator, target, message, timestamp )) + if not success then + self:LogInfo(errMessage) + end end function Module:LogWarnModification(guild, moderator, target, message, timestamp) @@ -104,8 +105,7 @@ function Module:LogWarnModification(guild, moderator, target, message, timestamp local logChannel = guild:getChannel(config.WarnLogChannel) logChannel:send(generateLogEmbed( - string.format("**%s** made a modification upon **%s** warns"), - moderator, + string.format("**%s** made a modification upon **%s** warns", moderator.tag, target.tag), target, message, timestamp @@ -264,7 +264,17 @@ function Module:OnLoaded() local moderatorId = commandMessage.member.id AddWarn(history, targetId, moderatorId, reason) - self:LogWarn(guild, moderator, targetMember, reason, commandMessage.timestamp) + + if reason then + self:LogWarn(guild, moderator, targetMember, reason, commandMessage.timestamp) + else + self:LogWarn( + guild, + moderator, + targetMember, + string.format("**%s** has warned **%s**, no reason provided.", moderator.tag, targetMember.tag), + commandMessage.timestamp) + end if config.SendPrivateMessage then local privateChannel = targetUser:getPrivateChannel() @@ -272,7 +282,7 @@ function Module:OnLoaded() if reason then privateChannel:send(string.format("You have been warned on %s for the following reason:\n **%s**", guild.name, reason)) else - privateChannel:send(string.format("You have been warned on %s", guild.name)) + privateChannel:send(string.format("You have been warned on %s, no reason provided.", guild.name)) end end end From 8ec46408bf71d60ae94205a4d89af629b166f199 Mon Sep 17 00:00:00 2001 From: Lezenn Date: Sat, 23 Jan 2021 19:20:42 +0100 Subject: [PATCH 13/19] Cleanup and bug fixing --- module_warn.lua | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/module_warn.lua b/module_warn.lua index c248001..e1f5e02 100644 --- a/module_warn.lua +++ b/module_warn.lua @@ -101,7 +101,7 @@ function Module:LogWarn(guild, moderator, target, message, timestamp) end function Module:LogWarnModification(guild, moderator, target, message, timestamp) - local config = self:getConfig(guild) + local config = self:GetConfig(guild) local logChannel = guild:getChannel(config.WarnLogChannel) logChannel:send(generateLogEmbed( @@ -272,7 +272,7 @@ function Module:OnLoaded() guild, moderator, targetMember, - string.format("**%s** has warned **%s**, no reason provided.", moderator.tag, targetMember.tag), + "No reason provided.", commandMessage.timestamp) end @@ -447,7 +447,11 @@ function Module:OnLoaded() if not memberHistory then commandMessage:reply(string.format("The member **%s** (%d) already have zero warns.", targetMember.tag, targetMember.id)) else - local lastWarn = memberHistory.Warns.remove(#memberHistory.Warns) + local lastWarn = table.remove(memberHistory.Warns, #memberHistory.Warns) + local lastWarnReason = lastWarn.Reason + if not lastWarnReason then + lastWarnReason = "No reason provided." + end self:LogWarnModification( guild, moderator, @@ -456,7 +460,7 @@ function Module:OnLoaded() moderator.tag, targetMember.tag, targetMember.id, - lastWarn.Reason, + lastWarnReason, guild:getMember(lastWarn.From).tag ) ) From e1b118f462b9ebe7bf3691710fd52791f9e8bba1 Mon Sep 17 00:00:00 2001 From: Lezenn Date: Sat, 23 Jan 2021 21:36:55 +0100 Subject: [PATCH 14/19] Updated module doc --- doc/modules/warn_module.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/doc/modules/warn_module.md b/doc/modules/warn_module.md index c11fbee..2772727 100644 --- a/doc/modules/warn_module.md +++ b/doc/modules/warn_module.md @@ -14,6 +14,14 @@ After a given amount of warns, the member gets muted __if the mute module is ena - Sanctions (Boolean) (default = true) - Enables sanctions (mute and ban alert) when a member receives a warning. +- MinimalWarnRole (Role) (default = nothing) + - Minimal role to be able to warn members and see their histories + - Unlocks `warn` and `warnlist` + +- MinimalUnwarnRole (Role) (default = nothing) + - Minimal role to be able to unwarn a member. + - Unlocks `popwarn` and `clearwarn` + - WarnAmountToMute (Integer) (default = 3) - Number of warns needed to mute a member. @@ -29,6 +37,9 @@ After a given amount of warns, the member gets muted __if the mute module is ena - This setting is required to enable the module - You still have to manually ban the member, the last choice remains to the moderation team. +- WarnLogChannel (Channel) (default = nothing) + - Channel where all the notifications about warns and unwarns are logged. + - SendPrivateMessage (Boolean) (default = true) - Enable private messages to inform the member of his warning. @@ -47,4 +58,7 @@ Assuming the bot prefix is `!` - `!clearwarns ` - Clears all the history of the given member. - - Example : `!clearwarns @SomePlayer` \ No newline at end of file + - Example : `!clearwarns @SomePlayer` + +- `!popwarns ` + - Removes the last warn of the targeted member \ No newline at end of file From 972a567456b83cd87f05aa84faadc8a9a2e557f0 Mon Sep 17 00:00:00 2001 From: Lezenn Date: Sat, 23 Jan 2021 22:41:02 +0100 Subject: [PATCH 15/19] Removed GuildAwarePrivilegeCheck --- module_warn.lua | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/module_warn.lua b/module_warn.lua index e1f5e02..de64f09 100644 --- a/module_warn.lua +++ b/module_warn.lua @@ -117,17 +117,17 @@ function Module:GetWarnAmount(history, memberId) return table.length(member.Warns) end -function Module:HasWarnRole(guild, member) - local config = self:GetConfig(guild) - local warnRole = guild:getRole(config.MinimalWarnRole) +function Module:HasWarnRole(member) + local config = self:GetConfig(member.guild) + local warnRole = (member.guild):getRole(config.MinimalWarnRole) local memberRole = member.highestRole return memberRole.position >= warnRole.position end -function Module:HasUnwarnRole(guild, member) - local config = self:GetConfig(guild) - local unwarnRole = guild:getRole(config.MinimalUnwarnRole) +function Module:HasUnwarnRole(member) + local config = self:GetConfig(member.guild) + local unwarnRole = (member.guild):getRole(config.MinimalUnwarnRole) local memberRole = member.highestRole return memberRole.position >= unwarnRole.position @@ -234,8 +234,8 @@ function Module:OnLoaded() {Name = "target", Type = bot.ConfigType.User}, {Name = "reason", Type = bot.ConfigType.String, Optional = true} }, - GuildAwarePrivilegeCheck = function (member, guild) - return self:HasWarnRole(guild, member) + PrivilegeCheck = function (member) + return self:HasWarnRole(member) end, Help = "Warns a member", @@ -337,8 +337,8 @@ function Module:OnLoaded() Args = { {Name = "targetUser", Type = bot.ConfigType.User} }, - GuildAwarePrivilegeCheck = function (member, guild) - return self:HasWarnRole(guild, member) + PrivilegeCheck = function (member) + return self:HasWarnRole(member) end, Help = "Shows all the warns of a member.", @@ -372,8 +372,8 @@ function Module:OnLoaded() Args = { {Name = "targetUser", Type = bot.ConfigType.User} }, - GuildAwarePrivilegeCheck = function (member, guild) - return self:HasUnwarnRole(guild, member) + PrivilegeCheck = function (member) + return self:HasUnwarnRole(member) end, Help = "Clears all the warns of a specified user.", @@ -431,8 +431,8 @@ function Module:OnLoaded() Args = { {Name = "targetUser", Type = bot.ConfigType.User} }, - GuildAwarePrivilegeCheck = function (member, guild) - return self:HasUnwarnRole(guild, member) + PrivilegeCheck = function (member) + return self:HasUnwarnRole(member) end, Help = "Removes the last warn of the given user.", From 5b753e8d3d7840f3da0508564eea5a87b859b9be Mon Sep 17 00:00:00 2001 From: Lezenn Date: Sat, 23 Jan 2021 22:45:52 +0100 Subject: [PATCH 16/19] Removed PrivilegeCheck (finally useless lol) --- bot_commands.lua | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/bot_commands.lua b/bot_commands.lua index 3051d63..6a077b2 100644 --- a/bot_commands.lua +++ b/bot_commands.lua @@ -61,21 +61,12 @@ function Bot:RegisterCommand(values) error("Command \"" .. name .. " already exists") end - if (values.PrivilegeCheck and not values.GuildAwarePrivilegeCheck) then - values.GuildAwarePrivilegeCheck = function (member, guild) return true end - end - - if (values.GuildAwarePrivilegeCheck and not values.PrivilegeCheck) then - values.PrivilegeCheck = function (member) return true end - end - local command = { Args = values.Args, Function = values.Func, Help = values.Help, Name = name, PrivilegeCheck = values.PrivilegeCheck, - GuildAwarePrivilegeCheck = values.GuildAwarePrivilegeCheck, Silent = values.Silent ~= nil and values.Silent, BotAware = values.BotAware ~= nil and values.BotAware } @@ -133,14 +124,13 @@ client:on('messageCreate', function(message) if (commandTable.PrivilegeCheck) then local success, ret = Bot:ProtectedCall("Command " .. commandName .. " privilege check", commandTable.PrivilegeCheck, message.member) - local guildAwareSuccess, guildAwareRet = Bot:ProtectedCall("Command " .. commandName .. " guild aware privilege check", commandTable.GuildAwarePrivilegeCheck, message.member, message.guild) - if (not success or not guildAwareSuccess) then + if (not success) then message:reply("An error occurred") return end - if (not ret and not guildAwareRet) then + if (not ret) then print(string.format("%s tried to use command %s on guild %s", message.author.tag, commandName, message.guild.name)) return end From c36d456683fdc4ff647efd118918594689ebe500 Mon Sep 17 00:00:00 2001 From: Lezenn Date: Sat, 23 Jan 2021 23:07:41 +0100 Subject: [PATCH 17/19] Updating doc --- doc/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/index.md b/doc/index.md index c10c92e..a4d20f8 100644 --- a/doc/index.md +++ b/doc/index.md @@ -12,7 +12,7 @@ The bot is made in Lua, with a custom wrapper around the Discordia library. - [Ban]() : Ban management module - [Channel]() : Channel management module -- [Game]() : +- [Game]() : Global mudule handling bot status - [Kick]() : Kick management - [Mention]() : Mention reaction module - [Message]() : Message handler module (includes custom commands) From 0d0b5e694e6d4dc92de8a96131aa6ff3d42ff1e7 Mon Sep 17 00:00:00 2001 From: Lezenn Date: Sun, 24 Jan 2021 00:29:17 +0100 Subject: [PATCH 18/19] added getMember Failure check --- module_warn.lua | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/module_warn.lua b/module_warn.lua index ef555e6..1468db8 100644 --- a/module_warn.lua +++ b/module_warn.lua @@ -249,16 +249,19 @@ function Module:OnLoaded() local targetMember = guild:getMember(targetUser) local moderator = commandMessage.member - -- Permission check - if targetMember then - local bannedByRole = moderator.highestRole - local targetRole = targetMember.highestRole - if targetRole.position >= bannedByRole.position then - commandMessage:reply("You cannot warn this user due to your lower permissions.") - return - end + if not targetMember then + commandMessage:reply("The given member does not exists or is invalid.") + return end + -- Permission check + local bannedByRole = moderator.highestRole + local targetRole = targetMember.highestRole + if targetRole.position >= bannedByRole.position then + commandMessage:reply("You cannot warn this user due to your lower permissions.") + return + end + -- Adding warn to the user local targetId = targetUser.id local moderatorId = commandMessage.member.id @@ -348,6 +351,11 @@ function Module:OnLoaded() local history = self:GetPersistentData(guild) local targetMember = guild:getMember(targetUser) + if not targetMember then + commandMessage:reply("The given member does not exists or is invalid.") + return + end + local memberHistory = FindMember(history, targetMember.id) if not memberHistory then commandMessage:reply(string.format("The member **%s** (%d) doesn't have any warns.", targetMember.tag, targetMember.id)) @@ -384,6 +392,11 @@ function Module:OnLoaded() local targetMember = guild:getMember(targetUser) local moderator = commandMessage.author + if not targetMember then + commandMessage:reply("The given member does not exists or is invalid.") + return + end + local memberHistory = FindMember(history, targetMember.id) if not memberHistory then commandMessage:reply(string.format("The member **%s** (%d) already have zero warns.", targetMember.tag, targetMember.id)) @@ -442,6 +455,11 @@ function Module:OnLoaded() local history = self:GetPersistentData(guild) local targetMember = guild:getMember(targetUser) local moderator = commandMessage.author + + if not targetMember then + commandMessage:reply("The given member does not exists or is invalid.") + return + end local memberHistory = FindMember(history, targetMember.id) if not memberHistory then From 3c555927241b23e59725b84a4dc46aae216191f5 Mon Sep 17 00:00:00 2001 From: Lezenn Date: Sun, 24 Jan 2021 00:31:12 +0100 Subject: [PATCH 19/19] Refactoring --- module_warn.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/module_warn.lua b/module_warn.lua index 1468db8..2444336 100644 --- a/module_warn.lua +++ b/module_warn.lua @@ -96,7 +96,7 @@ function Module:LogWarn(guild, moderator, target, message, timestamp) timestamp )) if not success then - self:LogInfo(errMessage) + self:LogError(errMessage) end end @@ -114,7 +114,7 @@ end function Module:GetWarnAmount(history, memberId) local member = FindMember(history, memberId) - return table.length(member.Warns) + return #member.Warns end function Module:HasWarnRole(member) @@ -465,7 +465,7 @@ function Module:OnLoaded() if not memberHistory then commandMessage:reply(string.format("The member **%s** (%d) already have zero warns.", targetMember.tag, targetMember.id)) else - local lastWarn = table.remove(memberHistory.Warns, #memberHistory.Warns) + local lastWarn = table.remove(memberHistory.Warns) local lastWarnReason = lastWarn.Reason if not lastWarnReason then lastWarnReason = "No reason provided."