diff --git a/.gradle/8.5/checksums/checksums.lock b/.gradle/8.5/checksums/checksums.lock index a6f97a8..8701160 100644 Binary files a/.gradle/8.5/checksums/checksums.lock and b/.gradle/8.5/checksums/checksums.lock differ diff --git a/.gradle/8.5/executionHistory/executionHistory.bin b/.gradle/8.5/executionHistory/executionHistory.bin index 5aa01aa..15eb161 100644 Binary files a/.gradle/8.5/executionHistory/executionHistory.bin and b/.gradle/8.5/executionHistory/executionHistory.bin differ diff --git a/.gradle/8.5/executionHistory/executionHistory.lock b/.gradle/8.5/executionHistory/executionHistory.lock index e361e7e..0043e31 100644 Binary files a/.gradle/8.5/executionHistory/executionHistory.lock and b/.gradle/8.5/executionHistory/executionHistory.lock differ diff --git a/.gradle/8.5/fileHashes/fileHashes.bin b/.gradle/8.5/fileHashes/fileHashes.bin index e71ef6a..1d28b80 100644 Binary files a/.gradle/8.5/fileHashes/fileHashes.bin and b/.gradle/8.5/fileHashes/fileHashes.bin differ diff --git a/.gradle/8.5/fileHashes/fileHashes.lock b/.gradle/8.5/fileHashes/fileHashes.lock index b6570bc..119178d 100644 Binary files a/.gradle/8.5/fileHashes/fileHashes.lock and b/.gradle/8.5/fileHashes/fileHashes.lock differ diff --git a/.gradle/8.5/fileHashes/resourceHashesCache.bin b/.gradle/8.5/fileHashes/resourceHashesCache.bin index fab6b69..7d61c65 100644 Binary files a/.gradle/8.5/fileHashes/resourceHashesCache.bin and b/.gradle/8.5/fileHashes/resourceHashesCache.bin differ diff --git a/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/.gradle/buildOutputCleanup/buildOutputCleanup.lock index 6239df0..95f13d5 100644 Binary files a/.gradle/buildOutputCleanup/buildOutputCleanup.lock and b/.gradle/buildOutputCleanup/buildOutputCleanup.lock differ diff --git a/.gradle/file-system.probe b/.gradle/file-system.probe index 71b7ddb..3ff40ff 100644 Binary files a/.gradle/file-system.probe and b/.gradle/file-system.probe differ diff --git a/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$AutomatedActions.class b/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$AutomatedActions.class index 11b82da..24bfef7 100644 Binary files a/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$AutomatedActions.class and b/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$AutomatedActions.class differ diff --git a/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Cooldown.class b/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Cooldown.class index 6ee93c9..157f9fa 100644 Binary files a/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Cooldown.class and b/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Cooldown.class differ diff --git a/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Permissions.class b/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Permissions.class index 57e5b97..e49806f 100644 Binary files a/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Permissions.class and b/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Permissions.class differ diff --git a/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$PlayerInteraction.class b/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$PlayerInteraction.class index 66d2c81..ce52caa 100644 Binary files a/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$PlayerInteraction.class and b/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$PlayerInteraction.class differ diff --git a/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Reports.class b/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Reports.class index 5052afd..b63b6e1 100644 Binary files a/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Reports.class and b/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Reports.class differ diff --git a/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$SocialSpy.class b/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$SocialSpy.class index baebb77..24dd849 100644 Binary files a/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$SocialSpy.class and b/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$SocialSpy.class differ diff --git a/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$Chat$Profanity.class b/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$Chat$Profanity.class index 9bc8721..d8a2596 100644 Binary files a/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$Chat$Profanity.class and b/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$Chat$Profanity.class differ diff --git a/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$Chat$Spam.class b/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$Chat$Spam.class index ce8f295..20cf89f 100644 Binary files a/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$Chat$Spam.class and b/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$Chat$Spam.class differ diff --git a/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$Chat.class b/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$Chat.class index bbc9644..d928b82 100644 Binary files a/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$Chat.class and b/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$Chat.class differ diff --git a/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$CommandBlockEdit.class b/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$CommandBlockEdit.class index 54c6eb7..efd1053 100644 Binary files a/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$CommandBlockEdit.class and b/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$CommandBlockEdit.class differ diff --git a/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$CommandBlockExecute.class b/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$CommandBlockExecute.class index 97f3421..cb0f2ff 100644 Binary files a/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$CommandBlockExecute.class and b/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$CommandBlockExecute.class differ diff --git a/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$CommandBlockMinecartPlace.class b/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$CommandBlockMinecartPlace.class index d5331e3..8aa1df6 100644 Binary files a/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$CommandBlockMinecartPlace.class and b/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$CommandBlockMinecartPlace.class differ diff --git a/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$CommandBlockMinecartUse.class b/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$CommandBlockMinecartUse.class index 684d624..f51b91f 100644 Binary files a/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$CommandBlockMinecartUse.class and b/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$CommandBlockMinecartUse.class differ diff --git a/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$CommandBlockPlace.class b/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$CommandBlockPlace.class index 4d0e704..89fa502 100644 Binary files a/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$CommandBlockPlace.class and b/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$CommandBlockPlace.class differ diff --git a/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$CommandBlockUse.class b/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$CommandBlockUse.class index 65e01e1..db908d1 100644 Binary files a/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$CommandBlockUse.class and b/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$CommandBlockUse.class differ diff --git a/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$CommandExecute.class b/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$CommandExecute.class index c30806c..05f89c1 100644 Binary files a/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$CommandExecute.class and b/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$CommandExecute.class differ diff --git a/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$CreativeHotbar.class b/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$CreativeHotbar.class index b960b70..b89fb56 100644 Binary files a/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$CreativeHotbar.class and b/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$CreativeHotbar.class differ diff --git a/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$ViolationMessages.class b/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$ViolationMessages.class index 39ed696..46b1f5f 100644 Binary files a/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$ViolationMessages.class and b/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations$ViolationMessages.class differ diff --git a/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations.class b/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations.class index 44e7678..e42fbd6 100644 Binary files a/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations.class and b/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile$Violations.class differ diff --git a/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile.class b/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile.class index af3b72f..c5cd700 100644 Binary files a/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile.class and b/build/classes/java/main/me/trouper/sentinel/data/config/lang/LanguageFile.class differ diff --git a/build/classes/java/main/me/trouper/sentinel/server/commands/CallbackCommand.class b/build/classes/java/main/me/trouper/sentinel/server/commands/CallbackCommand.class index fc43ba7..93e6a59 100644 Binary files a/build/classes/java/main/me/trouper/sentinel/server/commands/CallbackCommand.class and b/build/classes/java/main/me/trouper/sentinel/server/commands/CallbackCommand.class differ diff --git a/build/classes/java/main/me/trouper/sentinel/server/commands/MessageCommand.class b/build/classes/java/main/me/trouper/sentinel/server/commands/MessageCommand.class index 0144721..56a9113 100644 Binary files a/build/classes/java/main/me/trouper/sentinel/server/commands/MessageCommand.class and b/build/classes/java/main/me/trouper/sentinel/server/commands/MessageCommand.class differ diff --git a/build/classes/java/main/me/trouper/sentinel/server/commands/ReplyCommand.class b/build/classes/java/main/me/trouper/sentinel/server/commands/ReplyCommand.class index c847e75..780f89d 100644 Binary files a/build/classes/java/main/me/trouper/sentinel/server/commands/ReplyCommand.class and b/build/classes/java/main/me/trouper/sentinel/server/commands/ReplyCommand.class differ diff --git a/build/classes/java/main/me/trouper/sentinel/server/commands/SentinelCommand.class b/build/classes/java/main/me/trouper/sentinel/server/commands/SentinelCommand.class index c86e806..92f9051 100644 Binary files a/build/classes/java/main/me/trouper/sentinel/server/commands/SentinelCommand.class and b/build/classes/java/main/me/trouper/sentinel/server/commands/SentinelCommand.class differ diff --git a/build/classes/java/main/me/trouper/sentinel/server/commands/SocialSpyCommand.class b/build/classes/java/main/me/trouper/sentinel/server/commands/SocialSpyCommand.class deleted file mode 100644 index e27df18..0000000 Binary files a/build/classes/java/main/me/trouper/sentinel/server/commands/SocialSpyCommand.class and /dev/null differ diff --git a/build/classes/java/main/me/trouper/sentinel/server/events/ChatEvent.class b/build/classes/java/main/me/trouper/sentinel/server/events/ChatEvent.class index 44d13c7..d9fbde0 100644 Binary files a/build/classes/java/main/me/trouper/sentinel/server/events/ChatEvent.class and b/build/classes/java/main/me/trouper/sentinel/server/events/ChatEvent.class differ diff --git a/build/classes/java/main/me/trouper/sentinel/server/functions/Message.class b/build/classes/java/main/me/trouper/sentinel/server/functions/Message.class index bc38165..48d32fa 100644 Binary files a/build/classes/java/main/me/trouper/sentinel/server/functions/Message.class and b/build/classes/java/main/me/trouper/sentinel/server/functions/Message.class differ diff --git a/build/classes/java/main/me/trouper/sentinel/server/functions/chatfilter/profanity/ProfanityAction.class b/build/classes/java/main/me/trouper/sentinel/server/functions/chatfilter/profanity/ProfanityAction.class index f0ed840..3055277 100644 Binary files a/build/classes/java/main/me/trouper/sentinel/server/functions/chatfilter/profanity/ProfanityAction.class and b/build/classes/java/main/me/trouper/sentinel/server/functions/chatfilter/profanity/ProfanityAction.class differ diff --git a/build/classes/java/main/me/trouper/sentinel/server/functions/chatfilter/spam/SpamAction.class b/build/classes/java/main/me/trouper/sentinel/server/functions/chatfilter/spam/SpamAction.class index 1c7c2f1..fd94a31 100644 Binary files a/build/classes/java/main/me/trouper/sentinel/server/functions/chatfilter/spam/SpamAction.class and b/build/classes/java/main/me/trouper/sentinel/server/functions/chatfilter/spam/SpamAction.class differ diff --git a/build/classes/java/main/me/trouper/sentinel/startup/Load.class b/build/classes/java/main/me/trouper/sentinel/startup/Load.class index 2510f15..0c151f6 100644 Binary files a/build/classes/java/main/me/trouper/sentinel/startup/Load.class and b/build/classes/java/main/me/trouper/sentinel/startup/Load.class differ diff --git a/build/classes/java/main/me/trouper/sentinel/utils/PlayerUtils.class b/build/classes/java/main/me/trouper/sentinel/utils/PlayerUtils.class index 0f62709..0286292 100644 Binary files a/build/classes/java/main/me/trouper/sentinel/utils/PlayerUtils.class and b/build/classes/java/main/me/trouper/sentinel/utils/PlayerUtils.class differ diff --git a/build/resources/main/plugin.yml b/build/resources/main/plugin.yml index 5d78547..fc2faf1 100644 --- a/build/resources/main/plugin.yml +++ b/build/resources/main/plugin.yml @@ -1,7 +1,7 @@ name: SentinelAntiNuke version: '0.3.0' main: me.trouper.sentinel.Sentinel -api-version: 1.20 +api-version: 1.21 authors: [ TheTrouper ] description: Detect, Block, and Ban players who attempt to grief your server. website: https://thetrouper.github.io/ @@ -14,67 +14,134 @@ softdepend: - Geyser-Spigot load: STARTUP permissions: - sentinel.message: - description: Access to the direct messages - default: op - sentinel.reply: - description: Reply commands - sentinel.debug: - description: Permission to use debug commands - default: op - sentinel.staff: - description: Receive anti-swear and anti-spam warnings - default: op - sentinel.chat.antiswear.flags: - description: See antiSwear flags - default: op - sentinel.chat.antiswear.bypass: - description: Bypass the antiSwear - default: op - sentinel.chat.antiswear.edit: - description: Add a false positive to the config - default: op - sentinel.chat.antispam.flags: - description: See antispam flags - default: op - sentinel.chat.antispam.bypass: - description: Bypass the antispam - default: op - sentinel.chat.*: - description: bypass all chat rules and see all flags + sentinel.admin: + description: Allows access to all Sentinel admin commands. default: op children: - sentinel.chat.antiswear.flags: true - sentinel.chat.antiswear.bypass: true - sentinel.chat.antispam.flags: true - sentinel.chat.antispam.bypass: true + sentinel.reload: true + sentinel.config: true + sentinel.debug: true + sentinel.staff: + description: Allows access to Sentinel staff commands. + default: false + children: + sentinel.socialspy: true + sentinel.false-positive: true + sentinel.reload: + description: Allows the user to reload the Sentinel plugin. + default: false + sentinel.config: + description: Allows the user to modify the Sentinel configuration. + default: false + sentinel.false-positive: + description: Allows the user to manage false positives. + default: false + children: + sentinel.false-positive.add: true + sentinel.false-positive.remove: true + sentinel.false-positive.add: + description: Allows the user to add a false positive. + default: false + sentinel.false-positive.remove: + description: Allows the user to remove a false positive. + default: false + sentinel.debug: + description: Allows the user to toggle debug mode. + default: false + sentinel.commandblock: + description: Allows the user to manage command blocks. + default: false + sentinel.socialspy: + description: Allows the user to spy on social interactions. + default: false + sentinel.callbacks: + description: Allows access to all Sentinel callback commands. + default: op + children: + sentinel.callbacks.fpreport: true + sentinel.callbacks.fpreport: + description: Allows the user to report false positives. + default: false + sentinel.message: + description: Allows the user to send messages. + default: true + sentinel.reply: + description: Allows the user to reply to messages. + default: true + sentinel.chatfilter: + description: Parent permission for all chat-related features. + default: false + children: + sentinel.chatfilter.profanity: true + sentinel.chatfilter.spam: true + sentinel.chatfilter.unicode: true + sentinel.chatfilter.url: true + sentinel.chatfilter.profanity: + description: Parent permission for profanity filter features. + default: false + children: + sentinel.chatfilter.profanity.view: true + sentinel.chatfilter.profanity.bypass: true + sentinel.chatfilter.profanity.view: + description: Allows the user to view profanity filter logs. + default: false + sentinel.chatfilter.profanity.bypass: + description: Allows the user to bypass the profanity filter. + default: false + sentinel.chatfilter.spam: + description: Parent permission for spam filter features. + default: false + children: + sentinel.chatfilter.spam.view: true + sentinel.chatfilter.spam.bypass: true + sentinel.chatfilter.spam.view: + description: Allows the user to view spam filter logs. + default: false + sentinel.chatfilter.spam.bypass: + description: Allows the user to bypass the spam filter. + default: false + sentinel.chatfilter.unicode: + description: Parent permission for unicode filter features. + default: false + children: + sentinel.chatfilter.unicode.view: true + sentinel.chatfilter.unicode.bypass: true + sentinel.chatfilter.unicode.view: + description: Allows the user to view unicode filter logs. + default: false + sentinel.chatfilter.unicode.bypass: + description: Allows the user to bypass the unicode filter. + default: false + sentinel.chatfilter.url: + description: Parent permission for URL filter features. + default: false + children: + sentinel.chatfilter.url.view: true + sentinel.chatfilter.url.bypass: true + sentinel.chatfilter.url.view: + description: Allows the user to view URL filter logs. + default: false + sentinel.chatfilter.url.bypass: + description: Allows the user to bypass the URL filter. + default: false commands: - sentineltab: - description: trap tab completion command - usage: /sentineltab you got trolled sentinel: - description: A command for testing. - usage: /sentinel - permission: sentinel.info - permission-message: You do not have permission! - reop: - description: Allows trusted players to elevate their permissions - usage: /reop - socialspy: - permission: sentinel.spy - usage: /socialspy - permission-message: You do not have permission to use this command! - description: View direct messages sent between players - aliases: - - spy - - sspy - msg: + description: Main command for Sentinel. + usage: /sentinel + permission: sentinel.staff + permission-message: You do not have permission to use this command. + sentinelcallback: + description: Callback command for Sentinel. + usage: /callback + permission: sentinel.callbacks + permission-message: You do not have permission to use this command. + message: + description: Send a message to another player. + usage: /message permission: sentinel.message - usage: /msg [] - permission-message: You do not have permission to message through sentinel! - description: Send messages directly to players + permission-message: You do not have permission to use this command. aliases: - - message + - msg - etell - tell - t @@ -91,10 +158,10 @@ commands: - stell - smsg reply: - description: Reply to the last person messaging you - usage: /r [] + description: Reply to a message. + usage: /reply permission: sentinel.reply - permission-message: You do not have permission to reply through sentinel! + permission-message: You do not have permission to use this command. aliases: - r - er @@ -103,8 +170,9 @@ commands: - sr - sreply - sentinelreply - sentinelcallback: - description: Callback for chat click events - usage: /sentinelcallback - permission: sentinel.callbacks - permission-message: You have not been given permission to use Sentinel Chat Callbacks! \ No newline at end of file + sentineltab: + description: tab completion redirects for sentinel + usage: /sentineltab [] + reop: + description: Allows trusted players to elevate their permissions + usage: /reop \ No newline at end of file diff --git a/build/tmp/compileJava/previous-compilation-data.bin b/build/tmp/compileJava/previous-compilation-data.bin index 33060d6..035d474 100644 Binary files a/build/tmp/compileJava/previous-compilation-data.bin and b/build/tmp/compileJava/previous-compilation-data.bin differ diff --git a/gradle.properties b/gradle.properties index 349eda7..fbafe19 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,5 +4,5 @@ group = 'me.trouper' version = 0.3.0 # Minecraft -mc_version = 1.20 +mc_version = 1.21 diff --git a/src/main/java/me/trouper/sentinel/data/config/lang/LanguageFile.java b/src/main/java/me/trouper/sentinel/data/config/lang/LanguageFile.java index 1f2c2e1..eda4f39 100644 --- a/src/main/java/me/trouper/sentinel/data/config/lang/LanguageFile.java +++ b/src/main/java/me/trouper/sentinel/data/config/lang/LanguageFile.java @@ -2,6 +2,7 @@ package me.trouper.sentinel.data.config.lang; import io.github.itzispyder.pdk.utils.misc.config.JsonSerializable; import me.trouper.sentinel.Sentinel; +import me.trouper.sentinel.utils.Text; import java.io.File; @@ -25,6 +26,7 @@ public class LanguageFile implements JsonSerializable { public String logAlreadyOp = "The permissions of %s are already elevated! Retrying..."; public String noTrust = "You are not a trusted user!"; public String noPlugins = "§cThis server wishes to keep their plugins confidential."; + public String playersOnly = "Only players can preform this operation."; } public Cooldown cooldown = new Cooldown(); @@ -53,12 +55,46 @@ public class LanguageFile implements JsonSerializable { public String enabled = "SocialSpy is now enabled."; public String disabled = "SocialSpy is now disabled."; public String spyMessage = "§d§lSpy §8» §b§n%1$s§7 has messaged §b§n%2$s§7."; - public String spyMessageHover = "§8]==-- §d§lSocialSpy §8--==[\n§bSender: §f%1$S\n§bReceiver: §f%2$S\n§bMessage: §f%3$S"; + public String spyMessageHover = "§8]==-- §d§lSocialSpy §8--==[\n§bSender: §f%1$s\n§bReceiver: §f%2$s\n§bMessage: §f%3$s"; } public AutomatedActions automatedActions = new AutomatedActions(); public class AutomatedActions { - public String actionAutomaticReportable = "§7This action was preformed automatically \n§7by the §bSentinel Chat Filter§7 algorithm!\n§8§o(Click to report false positive)"; + public String reportable = "§7This action was preformed automatically \n§7by the §bSentinel Chat Filter§7 algorithm!\n§8§o(Click to report false positive)"; + } + + public Plugin plugin = new Plugin(); + public class Plugin { + public String invalidArgs = "Invalid arguments, please check usage."; + public String invalidSubCommand = "Invalid %1$s sub-command."; + public String reloadingConfig = "Reloading the config."; + public String reloadingConfigLite = "Reloading the config in lite mode."; + } + + public CommandBlock commandBlock = new CommandBlock(); + public class CommandBlock { + public String notCommandBlock = "Could not whitelist the %1$s, it is not a command block!"; + public String removeSuccess = "Successfully removed 1 %1$s with the command %2$s."; + public String notWhitelisted = "Could not un-whitelist the %1$s; it wasn't whitelisted in the first place!"; + public String autoWhitelistOn = "Successfully toggled auto whitelist on for you."; + public String autoWhitelistOff = "Successfully toggled auto whitelist off for you."; + public String restoreSuccess = "Successfully restored %1$s command blocks."; + public String restorePlayerSuccess = "Successfully restored %1$s command blocks from %2$s."; + public String clearSuccess = "Successfully cleared %1$s command blocks."; + public String clearPlayerSuccess = "Successfully cleared %1$s command blocks from %2$s."; + } + + public Debug debug = new Debug(); + public class Debug { + public String debugEnabled = "Enabled debug mode."; + public String debugDisabled = "Disabled debug mode."; + public String notFlagged = "Message did not get flagged."; + } + + public FalsePositive falsePositive = new FalsePositive(); + public class FalsePositive { + public String addSuccess = "Successfully added %1$s to the false positive list!"; + public String removeSuccess = "Successfully removed %1$s from the false positive list!"; } public Violations violations = new Violations(); diff --git a/src/main/java/me/trouper/sentinel/server/commands/CallbackCommand.java b/src/main/java/me/trouper/sentinel/server/commands/CallbackCommand.java index 35028c1..b4c8751 100644 --- a/src/main/java/me/trouper/sentinel/server/commands/CallbackCommand.java +++ b/src/main/java/me/trouper/sentinel/server/commands/CallbackCommand.java @@ -9,6 +9,7 @@ import io.github.itzispyder.pdk.utils.misc.Cooldown; import me.trouper.sentinel.Sentinel; import me.trouper.sentinel.server.functions.chatfilter.FalsePositiveReporting; import me.trouper.sentinel.server.functions.chatfilter.Report; +import me.trouper.sentinel.utils.PlayerUtils; import me.trouper.sentinel.utils.Text; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; @@ -26,19 +27,20 @@ public class CallbackCommand implements CustomCommand { Player p = (Player) sender; switch (args.get(0).toString()) { case "fpreport" -> { + if (!PlayerUtils.checkPermission(sender,"sentinel.callbacks.fpreport")) return; if (fpReportCooldown.isOnCooldown(p.getUniqueId()) && !p.isOp()) { p.sendMessage(Text.prefix(Sentinel.lang.cooldown.onCooldown + fpReportCooldown.getCooldown(p.getUniqueId()))); - } else { - long id = args.get(1).toLong(); - Report report = FalsePositiveReporting.reports.get(id); - if (report == null) { - p.sendMessage(Text.prefix(Sentinel.lang.reports.noReport)); - return; - } - p.sendMessage(Text.prefix(Sentinel.lang.reports.reportingFalsePositive)); - FalsePositiveReporting.sendReport(p,report); - p.sendMessage(Text.prefix(Sentinel.lang.reports.falsePositiveSuccess)); + return; } + long id = args.get(1).toLong(); + Report report = FalsePositiveReporting.reports.get(id); + if (report == null) { + p.sendMessage(Text.prefix(Sentinel.lang.reports.noReport)); + return; + } + p.sendMessage(Text.prefix(Sentinel.lang.reports.reportingFalsePositive)); + FalsePositiveReporting.sendReport(p,report); + p.sendMessage(Text.prefix(Sentinel.lang.reports.falsePositiveSuccess)); } } } diff --git a/src/main/java/me/trouper/sentinel/server/commands/MessageCommand.java b/src/main/java/me/trouper/sentinel/server/commands/MessageCommand.java index bb60e4d..3d6d63f 100644 --- a/src/main/java/me/trouper/sentinel/server/commands/MessageCommand.java +++ b/src/main/java/me/trouper/sentinel/server/commands/MessageCommand.java @@ -7,6 +7,7 @@ import io.github.itzispyder.pdk.commands.Permission; import io.github.itzispyder.pdk.commands.completions.CompletionBuilder; import me.trouper.sentinel.Sentinel; import me.trouper.sentinel.server.functions.Message; +import me.trouper.sentinel.utils.PlayerUtils; import me.trouper.sentinel.utils.Text; import org.bukkit.Bukkit; import org.bukkit.command.Command; @@ -16,7 +17,7 @@ import org.bukkit.entity.Player; import java.util.ArrayList; import java.util.List; -@CommandRegistry(value = "sentinelmessage",permission = @Permission("sentinel.message")) +@CommandRegistry(value = "sentinelmessage",permission = @Permission("sentinel.message"),printStackTrace = true) public class MessageCommand implements CustomCommand { @Override public void dispatchCommand(CommandSender sender, Command command, String s, Args args) { @@ -34,10 +35,9 @@ public class MessageCommand implements CustomCommand { String msg = args.getAll(1).toString().trim(); - if (p.hasPermission("sentinel.message") && r != null) { + if (PlayerUtils.checkPermission(sender,"sentinel.message") && r != null) { Message.messagePlayer(p,r,msg); } else if (r == null) p.sendMessage(Text.prefix((Sentinel.lang.playerInteraction.noOnlinePlayer))); - else sender.sendMessage(Text.prefix(Sentinel.lang.permissions.noPermission)); } @Override diff --git a/src/main/java/me/trouper/sentinel/server/commands/ReplyCommand.java b/src/main/java/me/trouper/sentinel/server/commands/ReplyCommand.java index 3de24e1..7866ee9 100644 --- a/src/main/java/me/trouper/sentinel/server/commands/ReplyCommand.java +++ b/src/main/java/me/trouper/sentinel/server/commands/ReplyCommand.java @@ -7,6 +7,7 @@ import io.github.itzispyder.pdk.commands.Permission; import io.github.itzispyder.pdk.commands.completions.CompletionBuilder; import me.trouper.sentinel.Sentinel; import me.trouper.sentinel.server.functions.Message; +import me.trouper.sentinel.utils.PlayerUtils; import me.trouper.sentinel.utils.Text; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; @@ -15,7 +16,7 @@ import org.bukkit.entity.Player; import java.util.Map; import java.util.UUID; -@CommandRegistry(value = "reply", permission = @Permission("sentinel.reply")) +@CommandRegistry(value = "reply", permission = @Permission("sentinel.reply"),printStackTrace = true) public class ReplyCommand implements CustomCommand { public static Map replyMap = Message.replyMap; @@ -34,11 +35,9 @@ public class ReplyCommand implements CustomCommand { p.sendMessage(Text.prefix(Sentinel.lang.playerInteraction.noMessageProvided)); } String msg = args.getAll().toString(); - if (p.hasPermission("sentinel.message")) { + if (PlayerUtils.checkPermission(sender,"sentinel.message")) { Message.messagePlayer(p,r,msg); replyMap.put(senderID,reciverID); - } else { - sender.sendMessage(Text.prefix(Sentinel.lang.permissions.noPermission)); } } diff --git a/src/main/java/me/trouper/sentinel/server/commands/SentinelCommand.java b/src/main/java/me/trouper/sentinel/server/commands/SentinelCommand.java index e44d08d..8423971 100644 --- a/src/main/java/me/trouper/sentinel/server/commands/SentinelCommand.java +++ b/src/main/java/me/trouper/sentinel/server/commands/SentinelCommand.java @@ -32,48 +32,28 @@ import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; +import java.util.HashMap; +import java.util.Map; import java.util.Set; import java.util.UUID; @CommandRegistry(value = "sentinel",permission = @Permission("sentinel.staff"),printStackTrace = true) public class SentinelCommand implements CustomCommand { - public static String liteMode = Text.color(""" - &8]=-&f Welcome to &d&lSentinel &7|&f Anti-Nuke &8-=[ - &7The plugin is currently loaded in &clite&7 mode. - - &7Your License Key is &a%s&7. - &7Your server ID is &6%s&7. - &7You are &6%s&7. - - &fIf you have just &apurchased&f the plugin: - &8- &7Join the &b&ndiscord&r&7 and open a ticket. - &8- &7https://discord.gg/Xh6BAzNtxY - &8- &7You will then receive a license key. - &fIf you have &cnot&f purchased the plugin: - &8- &7Then purchase it :D - &8- &7It wont do anything in this state! - &8- &7(Its only 5$) - &fIf you are reading this from a decompiler: - &8- &7Please stop trying to crack the plugin and purchase it! - &8- &7Your time spent trying to bypass my DRM could be spent at a minimum wage job. - &8- &7There you will make 7$ an hour! (As oppose to 5$ for multiple hours of cracking) - &fWoah! You read quite far! - &8- &7Want the plugin for cheaper, &nor even for free&r&7? - &8- &7DM &b@obvwolf&7 on discord and lets make a deal! - """.formatted(Sentinel.getInstance().license,Sentinel.getInstance().identifier, MainConfig.username)); + public static Map spyMap = new HashMap<>(); @Override public void dispatchCommand(CommandSender sender, Command command, String s, Args args) { try { safety(sender,command,s,args); } catch (IllegalArgumentException e) { - sender.sendMessage(Text.prefix("Invalid arguments, please check usage.")); + sender.sendMessage(Text.prefix(Sentinel.lang.plugin.invalidArgs)); } } @Override public void dispatchCompletions(CommandSender commandSender, Command command, String s, CompletionBuilder b) { + b.then(b.arg("socialspy")); b.then(b.arg("config")); b.then(b.arg("reload")); b.then(b.arg("false-positive").then(b.arg("add","remove"))); @@ -87,85 +67,213 @@ public class SentinelCommand implements CustomCommand { } - public void safety(CommandSender sender, Command command, String s, Args args) { + private void safety(CommandSender sender, Command command, String label, Args args) { if (Load.lite) { - handleLiteMessage(sender,args); + handleLiteMessage(sender, args); return; } - if (sender instanceof Player p && !p.hasPermission("sentinel.staff")) return; - switch (args.get(0).toString()) { - case "reload" -> { - handleReload(sender); - } - case "config" -> { - if (!(sender instanceof Player p) || !PlayerUtils.isTrusted(p)) return; - if (!MainGUI.verify(p)) return; - p.openInventory(new MainGUI().home.getInventory()); - } - case "commandblock", "cb" -> { - if (!(sender instanceof Player p) || !PlayerUtils.isTrusted(p)) return; - handleCommandBlock(p,args); - } - case "debug" -> { - if (!(sender instanceof Player p) || !PlayerUtils.isTrusted(p)) return; - handleDebugCommand(p,args); - } - case "false-positive" -> { - if (!(sender instanceof Player p)) return; - handleFalsePositive(p,args); - } + if (args.isEmpty()) { + sender.sendMessage(Text.prefix("Usage: /sentinel ")); + return; + } + + String subCommand = args.get(0).toString().toLowerCase(); + switch (subCommand) { + case "reload" -> handleReload(sender); + case "config" -> handleConfig(sender); + case "commandblock", "cb" -> handleCommandBlock(sender, args); + case "debug" -> handleDebugCommand(sender, args); + case "false-positive" -> handleFalsePositive(sender, args); + case "socialspy" -> handleSocialSpy(sender); + default -> sender.sendMessage(Text.prefix("Invalid sub-command. Usage: /sentinel ")); } } + private void handleReload(CommandSender sender) { - if (sender instanceof Player p && !PlayerUtils.isTrusted(p)) { - p.sendMessage(Text.prefix(Sentinel.lang.permissions.noTrust)); - return; + if (sender instanceof Player p) { + if (!PlayerUtils.checkPermission(sender, "sentinel.reload") || !PlayerUtils.isTrusted(p)) { + p.sendMessage(Text.prefix(Sentinel.lang.permissions.noTrust)); + return; + } } - Sentinel.log.info("Sentinel is now Reloading the config."); - sender.sendMessage(Text.prefix("Reloading the config.")); + Sentinel.log.info("Sentinel is now reloading the config."); + sender.sendMessage(Text.prefix(Sentinel.lang.plugin.reloadingConfig)); Sentinel.getInstance().loadConfig(); } - private void handleLiteMessage(CommandSender sender, Args args) { - if (!args.isEmpty() && args.get(0).toString().equals("reload")) { - if (sender instanceof Player && !PlayerUtils.isTrusted((Player) sender)) { - sender.sendMessage(Text.prefix(Sentinel.lang.permissions.noTrust)); - return; - } - Sentinel.log.info("Sentinel is now Reloading the config."); - sender.sendMessage(Text.prefix("Reloading the config.")); - Sentinel.getInstance().loadConfig(); + private void handleConfig(CommandSender sender) { + if (!PlayerUtils.playerCheck(sender)) + return; + Player p = (Player) sender; + if (!PlayerUtils.checkPermission(sender, "sentinel.config") || !PlayerUtils.isTrusted(p)) + return; + if (!MainGUI.verify(p)) + return; + p.openInventory(new MainGUI().home.getInventory()); + } - if (Load.load(Sentinel.getInstance().license, Sentinel.getInstance().identifier,false)) { - return; + private void handleCommandBlock(CommandSender sender, Args args) { + if (!PlayerUtils.isTrusted(sender)) + return; + + if (args.getSize() < 2) { + sender.sendMessage(Text.prefix("Usage: /sentinel commandblock ")); + return; + } + String sub = args.get(1).toString().toLowerCase(); + switch (sub) { + case "add" -> { + if (!PlayerUtils.playerCheck(sender)) + return; + Player p = (Player) sender; + Block target = p.getTargetBlock(Set.of(Material.AIR), 10); + if (target.getType() == Material.COMMAND_BLOCK || + target.getType() == Material.REPEATING_COMMAND_BLOCK || + target.getType() == Material.CHAIN_COMMAND_BLOCK) { + CommandBlock cb = (CommandBlock) target.getState(); + CBWhitelistManager.add(cb, p.getUniqueId()); + } else { + sender.sendMessage(Text.prefix(Sentinel.lang.commandBlock.notCommandBlock.formatted(Text.cleanName(target.getType().toString())))); + } } - Sentinel.log.info("Re-authentication Failed."); - } else { - sender.sendMessage(liteMode); + case "remove" -> { + if (!PlayerUtils.playerCheck(sender)) + return; + Player p = (Player) sender; + Block target = p.getTargetBlock(Set.of(Material.AIR), 10); + WhitelistedBlock wb = CBWhitelistManager.get(target.getLocation()); + if (wb != null) { + CBWhitelistManager.remove(target.getLocation()); + String cleanedType = Text.cleanName(WhitelistedBlock.fromSerialized(wb.loc()).getBlock().getType().toString()); + sender.sendMessage(Text.prefix(Sentinel.lang.commandBlock.removeSuccess.formatted(cleanedType, wb.command()))); + } else { + sender.sendMessage(Text.prefix(Sentinel.lang.commandBlock.notWhitelisted.formatted(Text.cleanName(target.getType().toString())))); + } + } + case "auto" -> { + if (!PlayerUtils.playerCheck(sender)) + return; + Player p = (Player) sender; + if (CBWhitelistManager.autoWhitelist.contains(p.getUniqueId())) { + CBWhitelistManager.autoWhitelist.remove(p.getUniqueId()); + sender.sendMessage(Text.prefix(Sentinel.lang.commandBlock.autoWhitelistOn)); + } else { + CBWhitelistManager.autoWhitelist.add(p.getUniqueId()); + sender.sendMessage(Text.prefix(Sentinel.lang.commandBlock.autoWhitelistOff)); + } + } + case "restore" -> { + if (args.getSize() < 3) { + sender.sendMessage(Text.prefix("Usage: /sentinel commandblock restore ")); + return; + } + String targetPlayer = args.get(2).toString(); + if (targetPlayer.equalsIgnoreCase("all")) { + int result = CBWhitelistManager.restoreAll(); + sender.sendMessage(Text.prefix(Sentinel.lang.commandBlock.restoreSuccess.formatted(result))); + } else { + UUID id = Bukkit.getOfflinePlayer(targetPlayer).getUniqueId(); + int result = CBWhitelistManager.restoreAll(id); + sender.sendMessage(Text.prefix(Sentinel.lang.commandBlock.restorePlayerSuccess.formatted(result,targetPlayer))); + } + } + case "clear" -> { + if (args.getSize() < 3) { + sender.sendMessage(Text.prefix("Usage: /sentinel commandblock clear ")); + return; + } + String targetPlayer = args.get(2).toString(); + if (targetPlayer.equalsIgnoreCase("all")) { + int result = CBWhitelistManager.clearAll(); + sender.sendMessage(Text.prefix(Sentinel.lang.commandBlock.clearSuccess.formatted(result))); + } else { + UUID id = Bukkit.getOfflinePlayer(targetPlayer).getUniqueId(); + int result = CBWhitelistManager.clearAll(id); + sender.sendMessage(Text.prefix(Sentinel.lang.commandBlock.clearPlayerSuccess.formatted(result,targetPlayer))); + } + } + default -> sender.sendMessage(Text.prefix(Sentinel.lang.plugin.invalidSubCommand.formatted("commandblock"))); } } - private void handleFalsePositive(Player p, Args args) { - if (!p.hasPermission("sentinel.chat.antiswear.edit")) { - p.sendMessage(Sentinel.lang.permissions.noPermission); + private void handleDebugCommand(CommandSender sender, Args args) { + if (!PlayerUtils.checkPermission(sender, "sentinel.debug")) + return; + if (args.getSize() < 2) { + sender.sendMessage(Text.prefix("Usage: /sentinel debug ")); return; } + String sub = args.get(1).toString().toLowerCase(); + switch (sub) { + case "lang" -> sender.sendMessage(Sentinel.lang.brokenLang); + case "toggle" -> { + Sentinel.mainConfig.debugMode = !Sentinel.mainConfig.debugMode; + Sentinel.mainConfig.debugMode = !Sentinel.mainConfig.debugMode; + String message = Sentinel.mainConfig.debugMode + ? Sentinel.lang.debug.debugEnabled + : Sentinel.lang.debug.debugDisabled; + sender.sendMessage(Text.prefix(message)); + Sentinel.mainConfig.save(); + } + case "chat" -> { + if (!PlayerUtils.playerCheck(sender)) + return; + if (args.getSize() < 3) { + sender.sendMessage(Text.prefix("Usage: /sentinel debug chat ")); + return; + } + Player p = (Player) sender; + String messageText = args.getAll(2).toString(); + AsyncChatEvent message = new AsyncChatEvent(true, + p, + Set.of(p), + ChatRenderer.defaultRenderer(), + Component.text(messageText), + Component.text(messageText), + SignedMessage.system(messageText, Component.text(messageText)) + ); + UnicodeFilter.handleUnicodeFilter(message); + UrlFilter.handleUrlFilter(message); + SpamFilter.handleSpamFilter(message); + ProfanityFilter.handleProfanityFilter(message); + if (!message.isCancelled()) { + sender.sendMessage(Text.prefix(Sentinel.lang.debug.notFlagged)); + } + } + default -> sender.sendMessage(Text.prefix(Sentinel.lang.plugin.invalidSubCommand.formatted("debug"))); + } + } + + private void handleFalsePositive(CommandSender sender, Args args) { + if (args.getSize() < 2) { + sender.sendMessage(Text.prefix("Usage: /sentinel false-positive ")); + return; + } + if (!PlayerUtils.checkPermission(sender, "sentinel.false-positive")) + return; + String sub = args.get(1).toString().toLowerCase(); String falsePositive = args.getAll(2).toString(); Node root = new Node("Sentinel"); root.addTextLine("False Positive Management Log"); Node info = new Node("Info"); - info.addKeyValue("User",p.getName()); - switch (args.get(1).toString()) { + info.addKeyValue("User", sender.getName()); + switch (sub) { case "add" -> { + if (!PlayerUtils.checkPermission(sender,"sentinel.false-positive.add")) return; Sentinel.fpConfig.swearWhitelist.add(falsePositive); - p.sendMessage(Text.prefix("&7Successfully added &a%s&7 to the false positive list!".formatted(falsePositive))); - info.addKeyValue("Action","Add"); + sender.sendMessage(Text.prefix(Sentinel.lang.falsePositive.addSuccess.formatted(falsePositive))); + info.addKeyValue("Action", "Add"); } case "remove" -> { + if (!PlayerUtils.checkPermission(sender,"sentinel.false-positive.remove")) return; Sentinel.fpConfig.swearWhitelist.remove(falsePositive); - p.sendMessage(Text.prefix("&7Successfully removed &c%s&7 from the false positive list!".formatted(falsePositive))); - info.addKeyValue("Action","Remove"); + sender.sendMessage(Text.prefix(Sentinel.lang.falsePositive.removeSuccess.formatted(falsePositive))); + info.addKeyValue("Action", "Remove"); + } + default -> { + sender.sendMessage(Text.prefix(Sentinel.lang.plugin.invalidSubCommand.formatted("false-positive"))); + return; } } info.addKeyValue("False Positive Edited", falsePositive); @@ -175,100 +283,39 @@ public class SentinelCommand implements CustomCommand { EmbedFormatter.sendEmbed(EmbedFormatter.format(root)); } - private void handleCommandBlock(CommandSender sender, Args args) { - if ((sender instanceof Player p) && !PlayerUtils.isTrusted(p)) { - p.sendMessage(Text.prefix(Sentinel.lang.permissions.noTrust)); + private void handleSocialSpy(CommandSender sender) { + if (!PlayerUtils.playerCheck(sender)) return; - } - switch (args.get(1).toString()) { - case "add" -> { - if (!(sender instanceof Player p)) return; - Block target = p.getTargetBlock(Set.of(Material.AIR),10); - if (target.getType().equals(Material.COMMAND_BLOCK) || target.getType().equals(Material.REPEATING_COMMAND_BLOCK) || target.getType().equals(Material.CHAIN_COMMAND_BLOCK)) { - CommandBlock cb = (CommandBlock) target.getState(); - CBWhitelistManager.add(cb,p.getUniqueId()); - return; - } - sender.sendMessage(Text.prefix("Could not whitelist the &b" + Text.cleanName(target.getType().toString()) + "&7 it is not a command block!")); - } - case "remove" -> { - if (!(sender instanceof Player p)) return; - Block target = p.getTargetBlock(Set.of(Material.AIR),10); - WhitelistedBlock wb = CBWhitelistManager.get(target.getLocation()); - if (wb != null) { - CBWhitelistManager.remove(target.getLocation()); - sender.sendMessage(Text.prefix("Successfully removed 1 &b" + Text.cleanName(WhitelistedBlock.fromSerialized(wb.loc()).getBlock().getType().toString()) + "&7 with the command &a" + wb.command() + "&7.")); - return; - } - sender.sendMessage(Text.prefix("Could not un-whitelist the &b" + Text.cleanName(target.getType().toString()) + "&7 it wasn't whitelisted in the first place!")); - } - case "auto" -> { - if (!(sender instanceof Player p)) return; - if (CBWhitelistManager.autoWhitelist.contains(p.getUniqueId())) { - CBWhitelistManager.autoWhitelist.remove(p.getUniqueId()); - sender.sendMessage(Text.prefix("Successfully toggled &bauto whitelist&7 off for you.")); - } else { - CBWhitelistManager.autoWhitelist.add(p.getUniqueId()); - sender.sendMessage(Text.prefix("Successfully toggled &bauto whitelist&7 on for you.")); - } - } - case "restore" -> { - if (args.get(2).toString().equals("all")) { - int result = CBWhitelistManager.restoreAll(); - sender.sendMessage(Text.prefix("Successfully restored &b%s&7 command blocks.".formatted(result))); - return; - } - String who = args.get(2).toString(); - UUID id = Bukkit.getOfflinePlayer(who).getUniqueId(); - int result = CBWhitelistManager.restoreAll(id); - sender.sendMessage(Text.prefix("Successfully restored &b%s&7 command blocks from &e%s&7.".formatted(result,who))); - } - case "clear" -> { - if (args.get(2).toString().equals("all")) { - int result = CBWhitelistManager.clearAll(); - sender.sendMessage(Text.prefix("Successfully cleared &b%s&7 command blocks.".formatted(result))); - return; - } - String who = args.get(2).toString(); - UUID id = Bukkit.getOfflinePlayer(who).getUniqueId(); - int result = CBWhitelistManager.clearAll(id); - sender.sendMessage(Text.prefix("Successfully cleared &b%s&7 command blocks from &e%s&7.".formatted(result,who))); - } + if (!PlayerUtils.checkPermission(sender, "sentinel.socialspy")) + return; + Player p = (Player) sender; + UUID senderID = p.getUniqueId(); + boolean enabled = spyMap.getOrDefault(senderID, false); + if (!enabled) { + sender.sendMessage(Text.prefix(Sentinel.lang.socialSpy.enabled)); + spyMap.put(senderID, true); + } else { + sender.sendMessage(Text.prefix(Sentinel.lang.socialSpy.disabled)); + spyMap.put(senderID, false); } } - private void handleDebugCommand(Player p, Args args) { - if (!PlayerUtils.isTrusted(p)) { - p.sendMessage(Text.prefix(Sentinel.lang.permissions.noTrust)); - return; - } - switch (args.get(1).toString()) { - case "lang" -> { - p.sendMessage(Sentinel.lang.brokenLang); + private void handleLiteMessage(CommandSender sender, Args args) { + if (!args.isEmpty() && args.get(0).toString().equalsIgnoreCase("reload")) { + if (sender instanceof Player p && !PlayerUtils.isTrusted(p)) { + sender.sendMessage(Text.prefix(Sentinel.lang.permissions.noTrust)); + return; } - case "toggle" -> { - Sentinel.mainConfig.debugMode = !Sentinel.mainConfig.debugMode ; - p.sendMessage(Text.prefix((Sentinel.mainConfig.debugMode ? "Enabled" : "Disabled") + " debug mode.")); - Sentinel.mainConfig.save(); - } - case "chat" -> { - //true,p,args.getAll(2).toString(), Set.of(p) - AsyncChatEvent message = new AsyncChatEvent(true, - p, - Set.of(p), - ChatRenderer.defaultRenderer(), - Component.text(args.getAll(2).toString()), - Component.text(args.getAll(2).toString()), - SignedMessage.system(args.getAll(2).toString(), - Component.text(args.getAll(2).toString())) - ); - UnicodeFilter.handleUnicodeFilter(message); - UrlFilter.handleUrlFilter(message); - SpamFilter.handleSpamFilter(message); - ProfanityFilter.handleProfanityFilter(message); - if (!message.isCancelled()) p.sendMessage(Text.prefix("Message did not get flagged.")); + Sentinel.log.info("Sentinel is now reloading the config in lite mode."); + sender.sendMessage(Text.prefix(Sentinel.lang.plugin.reloadingConfigLite)); + Sentinel.getInstance().loadConfig(); + + if (Load.load(Sentinel.getInstance().license, Sentinel.getInstance().identifier, false)) { + return; } + Sentinel.log.info("Re-authentication Failed."); + } else { + sender.sendMessage(Load.liteMode); } } - } diff --git a/src/main/java/me/trouper/sentinel/server/commands/SocialSpyCommand.java b/src/main/java/me/trouper/sentinel/server/commands/SocialSpyCommand.java deleted file mode 100644 index a1920a1..0000000 --- a/src/main/java/me/trouper/sentinel/server/commands/SocialSpyCommand.java +++ /dev/null @@ -1,37 +0,0 @@ -package me.trouper.sentinel.server.commands; - -import io.github.itzispyder.pdk.commands.Args; -import io.github.itzispyder.pdk.commands.CustomCommand; -import io.github.itzispyder.pdk.commands.completions.CompletionBuilder; -import me.trouper.sentinel.Sentinel; -import me.trouper.sentinel.utils.Text; -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; - -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - -public class SocialSpyCommand implements CustomCommand { - public static Map spyMap = new HashMap<>(); - - @Override - public void dispatchCommand(CommandSender sender, Command command, String s, Args args) { - String name = sender.getName(); - Player p = sender.getServer().getPlayer(name); - UUID senderID = p.getUniqueId(); - if (!spyMap.containsKey(senderID) || !spyMap.get(senderID)) { - sender.sendMessage(Text.prefix(Sentinel.lang.socialSpy.enabled)); - spyMap.put(senderID,true); - } else if (spyMap.get(senderID)) { - sender.sendMessage(Text.prefix(Sentinel.lang.socialSpy.disabled)); - spyMap.put(senderID,false); - } - } - - @Override - public void dispatchCompletions(CommandSender commandSender, Command command, String s, CompletionBuilder completionBuilder) { - - } -} diff --git a/src/main/java/me/trouper/sentinel/server/events/ChatEvent.java b/src/main/java/me/trouper/sentinel/server/events/ChatEvent.java index e663dba..9cb6b7a 100644 --- a/src/main/java/me/trouper/sentinel/server/events/ChatEvent.java +++ b/src/main/java/me/trouper/sentinel/server/events/ChatEvent.java @@ -39,24 +39,23 @@ public class ChatEvent implements CustomListener { ServerUtils.verbose("Attempting to cancel events for callback!"); e.setCancelled(true); MainGUI.awaitingCallback.remove(e.getPlayer().getUniqueId()); + ServerUtils.verbose("Handling Chat Event for callbacks"); + SchedulerUtils.later(0,()->{ + UnicodeFilterGUI.updater.invokeCallbacks(e); + UrlFilterGUI.updater.invokeCallbacks(e); + ProfanityFilterGUI.updater.invokeCallbacks(e); + SpamFilterGUI.updater.invokeCallbacks(e); + DangerousCMDGUI.updater.invokeCallbacks(e); + LoggedCMDGUI.updater.invokeCallbacks(e); + SpecificCMDGUI.updater.invokeCallbacks(e); + CBEditGUI.updater.invokeCallbacks(e); + CBMCPlaceGUI.updater.invokeCallbacks(e); + CBMCUseGUI.updater.invokeCallbacks(e); + CBPlaceGUI.updater.invokeCallbacks(e); + CBUseGUI.updater.invokeCallbacks(e); + HotbarActionGUI.updater.invokeCallbacks(e); + }); } - - ServerUtils.verbose("Handling Chat Event for callbacks"); - SchedulerUtils.later(0,()->{ - UnicodeFilterGUI.updater.invokeCallbacks(e); - UrlFilterGUI.updater.invokeCallbacks(e); - ProfanityFilterGUI.updater.invokeCallbacks(e); - SpamFilterGUI.updater.invokeCallbacks(e); - DangerousCMDGUI.updater.invokeCallbacks(e); - LoggedCMDGUI.updater.invokeCallbacks(e); - SpecificCMDGUI.updater.invokeCallbacks(e); - CBEditGUI.updater.invokeCallbacks(e); - CBMCPlaceGUI.updater.invokeCallbacks(e); - CBMCUseGUI.updater.invokeCallbacks(e); - CBPlaceGUI.updater.invokeCallbacks(e); - CBUseGUI.updater.invokeCallbacks(e); - HotbarActionGUI.updater.invokeCallbacks(e); - }); return; } @@ -65,7 +64,7 @@ public class ChatEvent implements CustomListener { ServerUtils.verbose("Chat event start after trust check:\n Canceled %s".formatted(e.isCancelled())); handle(p, - "sentinel.chat.regex.bypass", + "sentinel.chatfilter.unicode.bypass", Sentinel.mainConfig.chat.unicodeFilter.enabled, "unicode", e, UnicodeFilter::handleUnicodeFilter); @@ -73,15 +72,15 @@ public class ChatEvent implements CustomListener { ServerUtils.verbose("Chat event middle after unicode:\n Canceled %s".formatted(e.isCancelled())); handle(p, - "sentinel.chat.regex.bypass", - Sentinel.mainConfig.chat.unicodeFilter.enabled, "url", + "sentinel.chatfilter.url.bypass", + Sentinel.mainConfig.chat.urlFilter.enabled, "url", e, UrlFilter::handleUrlFilter); - ServerUtils.verbose("Chat event middle after unicode:\n Canceled %s".formatted(e.isCancelled())); + ServerUtils.verbose("Chat event middle after URL:\n Canceled %s".formatted(e.isCancelled())); handle(p, - "sentinel.chat.spam.bypass", + "sentinel.chatfilter.spam.bypass", Sentinel.mainConfig.chat.spamFilter.enabled, "spam", e, @@ -90,7 +89,7 @@ public class ChatEvent implements CustomListener { ServerUtils.verbose("Chat event middle after spam:\n Canceled %s".formatted(e.isCancelled())); handle(p, - "sentinel.chat.swear.bypass", + "sentinel.chatfilter.swear.bypass", Sentinel.mainConfig.chat.profanityFilter.enabled, "swear", e, diff --git a/src/main/java/me/trouper/sentinel/server/functions/Message.java b/src/main/java/me/trouper/sentinel/server/functions/Message.java index 3cd9b4b..812b516 100644 --- a/src/main/java/me/trouper/sentinel/server/functions/Message.java +++ b/src/main/java/me/trouper/sentinel/server/functions/Message.java @@ -4,20 +4,21 @@ import io.github.itzispyder.pdk.utils.ServerUtils; import io.papermc.paper.chat.ChatRenderer; import io.papermc.paper.event.player.AsyncChatEvent; import me.trouper.sentinel.Sentinel; -import me.trouper.sentinel.server.commands.SocialSpyCommand; +import me.trouper.sentinel.server.commands.SentinelCommand; import me.trouper.sentinel.server.events.ChatEvent; +import net.kyori.adventure.audience.Audience; import net.kyori.adventure.chat.SignedMessage; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.TextComponent; import org.bukkit.entity.Player; -import org.bukkit.event.player.AsyncPlayerChatEvent; import java.util.*; +import java.util.stream.Collectors; public class Message { public static final Map replyMap = new HashMap<>(); public static void messagePlayer(Player sender, Player receiver, String message) { - AsyncChatEvent checkEvent = new AsyncChatEvent(true,sender, Set.of(receiver,sender), ChatRenderer.defaultRenderer(),Component.text(message),Component.text(message), SignedMessage.system(message,Component.text(message))); + AsyncChatEvent checkEvent = new AsyncChatEvent(true,sender, new HashSet<>(Arrays.asList(receiver, sender)), ChatRenderer.defaultRenderer(),Component.text(message),Component.text(message), SignedMessage.system(message,Component.text(message))); if (checkEvent.isCancelled()) return; new ChatEvent().handleEvent(checkEvent); if (checkEvent.isCancelled()) return; @@ -31,7 +32,7 @@ public class Message { public static void sendSpy(Player sender, Player receiver, String message) { ServerUtils.forEachPlayer(player -> { - if (SocialSpyCommand.spyMap.getOrDefault(player.getUniqueId(),false)) { + if (SentinelCommand.spyMap.getOrDefault(player.getUniqueId(),false)) { TextComponent notification = Component .text(Sentinel.lang.socialSpy.spyMessage.formatted(sender.getName(),receiver.getName())) .hoverEvent(Component.text(Sentinel.lang.socialSpy.spyMessageHover.formatted(sender.getName(),receiver.getName(),message))); diff --git a/src/main/java/me/trouper/sentinel/server/functions/chatfilter/profanity/ProfanityAction.java b/src/main/java/me/trouper/sentinel/server/functions/chatfilter/profanity/ProfanityAction.java index 68a732b..8809b29 100644 --- a/src/main/java/me/trouper/sentinel/server/functions/chatfilter/profanity/ProfanityAction.java +++ b/src/main/java/me/trouper/sentinel/server/functions/chatfilter/profanity/ProfanityAction.java @@ -33,13 +33,15 @@ public class ProfanityAction extends AbstractActionHandler { )); String hoverText = HoverFormatter.format(tree); - ServerUtils.forEachStaff(player -> player.sendMessage(Component.text(messageText).hoverEvent(Component.text(hoverText).asHoverEvent()))); + ServerUtils.forEachPlayer(player -> { + if (player.hasPermission("sentinel.chatfilter.profanity.view")) player.sendMessage(Component.text(messageText).hoverEvent(Component.text(hoverText).asHoverEvent())); + }); } @Override public void playerWarning(ProfanityResponse response) { String message = Text.prefix(response.isPunished() ? Sentinel.lang.violations.chat.profanity.autoPunishWarning : Sentinel.lang.violations.chat.profanity.preventWarning); - String hoverText = Sentinel.lang.automatedActions.actionAutomaticReportable; + String hoverText = Sentinel.lang.automatedActions.reportable; String command = "/sentinelcallback fpreport %s".formatted(response.getReport().getId()); response.getPlayer().sendMessage(Component.text(message) .hoverEvent(Component.text(hoverText).asHoverEvent()) diff --git a/src/main/java/me/trouper/sentinel/server/functions/chatfilter/spam/SpamAction.java b/src/main/java/me/trouper/sentinel/server/functions/chatfilter/spam/SpamAction.java index 46f9b5f..6cb9398 100644 --- a/src/main/java/me/trouper/sentinel/server/functions/chatfilter/spam/SpamAction.java +++ b/src/main/java/me/trouper/sentinel/server/functions/chatfilter/spam/SpamAction.java @@ -28,13 +28,15 @@ public class SpamAction extends AbstractActionHandler { )); String hoverText = HoverFormatter.format(tree); - ServerUtils.forEachStaff(player -> player.sendMessage(Component.text(messageText).hoverEvent(Component.text(hoverText).asHoverEvent()))); + ServerUtils.forEachPlayer(player -> { + if (player.hasPermission("sentinel.chatfilter.spam.view")) player.sendMessage(Component.text(messageText).hoverEvent(Component.text(hoverText).asHoverEvent())); + }); } @Override public void playerWarning(SpamResponse response) { String message = Text.prefix(response.isPunished() ? Sentinel.lang.violations.chat.spam.autoPunishWarning : Sentinel.lang.violations.chat.spam.preventWarning) ; - String hoverText = Sentinel.lang.automatedActions.actionAutomaticReportable; + String hoverText = Sentinel.lang.automatedActions.reportable; String command = "/sentinelcallback fpreport %s".formatted(response.getReport().getId()); response.getEvent().getPlayer().sendMessage(Component.text(message) .hoverEvent(Component.text(hoverText).asHoverEvent()) diff --git a/src/main/java/me/trouper/sentinel/server/functions/chatfilter/unicode/UnicodeAction.java b/src/main/java/me/trouper/sentinel/server/functions/chatfilter/unicode/UnicodeAction.java index f9425c1..b80bc88 100644 --- a/src/main/java/me/trouper/sentinel/server/functions/chatfilter/unicode/UnicodeAction.java +++ b/src/main/java/me/trouper/sentinel/server/functions/chatfilter/unicode/UnicodeAction.java @@ -2,7 +2,6 @@ package me.trouper.sentinel.server.functions.chatfilter.unicode; import me.trouper.sentinel.Sentinel; import me.trouper.sentinel.server.functions.chatfilter.AbstractActionHandler; -import me.trouper.sentinel.server.functions.chatfilter.profanity.ProfanityFilter; import me.trouper.sentinel.utils.ServerUtils; import me.trouper.sentinel.utils.Text; import me.trouper.sentinel.utils.trees.HoverFormatter; @@ -26,13 +25,15 @@ public class UnicodeAction extends AbstractActionHandler { )); String hoverText = HoverFormatter.format(tree); - ServerUtils.forEachStaff(player -> player.sendMessage(Component.text(messageText).hoverEvent(Component.text(hoverText).asHoverEvent()))); + ServerUtils.forEachPlayer(player -> { + if (player.hasPermission("sentinel.chatfilter.unicode.view")) player.sendMessage(Component.text(messageText).hoverEvent(Component.text(hoverText).asHoverEvent())); + }); } @Override protected void playerWarning(UnicodeResponse response) { String message = Text.prefix(response.isPunished() ? Sentinel.lang.violations.chat.unicode.autoPunishWarning : Sentinel.lang.violations.chat.unicode.preventWarning); - String hoverText = Sentinel.lang.automatedActions.actionAutomaticReportable; + String hoverText = Sentinel.lang.automatedActions.reportable; String command = "/sentinelcallback fpreport %s".formatted(response.getReport().getId()); response.getPlayer().sendMessage(Component.text(message) .hoverEvent(Component.text(hoverText).asHoverEvent()) diff --git a/src/main/java/me/trouper/sentinel/server/functions/chatfilter/url/UrlAction.java b/src/main/java/me/trouper/sentinel/server/functions/chatfilter/url/UrlAction.java index fea56ac..7b2fcdb 100644 --- a/src/main/java/me/trouper/sentinel/server/functions/chatfilter/url/UrlAction.java +++ b/src/main/java/me/trouper/sentinel/server/functions/chatfilter/url/UrlAction.java @@ -25,13 +25,15 @@ public class UrlAction extends AbstractActionHandler { )); String hoverText = HoverFormatter.format(tree); - ServerUtils.forEachStaff(player -> player.sendMessage(Component.text(messageText).hoverEvent(Component.text(hoverText).asHoverEvent()))); + ServerUtils.forEachPlayer(player -> { + if (player.hasPermission("sentinel.chatfilter.url.view")) player.sendMessage(Component.text(messageText).hoverEvent(Component.text(hoverText).asHoverEvent())); + }); } @Override protected void playerWarning(UrlResponse response) { String message = Text.prefix(response.isPunished() ? Sentinel.lang.violations.chat.url.autoPunishWarning : Sentinel.lang.violations.chat.url.preventWarning); - String hoverText = Sentinel.lang.automatedActions.actionAutomaticReportable; + String hoverText = Sentinel.lang.automatedActions.reportable; String command = "/sentinelcallback fpreport %s".formatted(response.getReport().getId()); response.getPlayer().sendMessage(Component.text(message) .hoverEvent(Component.text(hoverText).asHoverEvent()) diff --git a/src/main/java/me/trouper/sentinel/startup/Load.java b/src/main/java/me/trouper/sentinel/startup/Load.java index b2f1ef0..f0f7d69 100644 --- a/src/main/java/me/trouper/sentinel/startup/Load.java +++ b/src/main/java/me/trouper/sentinel/startup/Load.java @@ -2,6 +2,7 @@ package me.trouper.sentinel.startup; import io.github.itzispyder.pdk.utils.SchedulerUtils; import me.trouper.sentinel.Sentinel; +import me.trouper.sentinel.data.config.MainConfig; import me.trouper.sentinel.server.commands.*; import me.trouper.sentinel.server.events.*; import me.trouper.sentinel.server.functions.chatfilter.profanity.ProfanityFilter; @@ -13,6 +14,31 @@ public class Load { public static boolean lite = false; + public static String liteMode = Text.color(""" + &8]=-&f Welcome to &d&lSentinel &7|&f Anti-Nuke &8-=[ + &7The plugin is currently loaded in &clite&7 mode. + + &7Your License Key is &a%s&7. + &7Your server ID is &6%s&7. + &7You are &6%s&7. + + &fIf you have just &apurchased&f the plugin: + &8- &7Join the &b&ndiscord&r&7 and open a ticket. + &8- &7https://discord.gg/Xh6BAzNtxY + &8- &7You will then receive a license key. + &fIf you have &cnot&f purchased the plugin: + &8- &7Then purchase it :D + &8- &7It wont do anything in this state! + &8- &7(Its only 5$) + &fIf you are reading this from a decompiler: + &8- &7Please stop trying to crack the plugin and purchase it! + &8- &7Your time spent trying to bypass my DRM could be spent at a minimum wage job. + &8- &7There you will make 7$ an hour! (As oppose to 5$ for multiple hours of cracking) + &fWoah! You read quite far! + &8- &7Want the plugin for cheaper, &nor even for free&r&7? + &8- &7DM &b@obvwolf&7 on discord and lets make a deal! + """.formatted(Sentinel.getInstance().license,Sentinel.getInstance().identifier, MainConfig.username)); + public static boolean load(String license, String identifier, boolean coldStart) { Sentinel.log.info("\n]====---- Requesting Authentication ----====[ \n- License Key: %s\n- Server ID: %s\n".formatted(license,identifier)); try { @@ -80,7 +106,7 @@ public class Load { SchedulerUtils.repeat(20*60,()->{ if (lite) { - Sentinel.log.info(Text.removeColors(SentinelCommand.liteMode)); + Sentinel.log.info(Text.removeColors(Load.liteMode)); } }); } diff --git a/src/main/java/me/trouper/sentinel/utils/PlayerUtils.java b/src/main/java/me/trouper/sentinel/utils/PlayerUtils.java index 080c3b7..40adc2a 100644 --- a/src/main/java/me/trouper/sentinel/utils/PlayerUtils.java +++ b/src/main/java/me/trouper/sentinel/utils/PlayerUtils.java @@ -1,6 +1,8 @@ package me.trouper.sentinel.utils; import me.trouper.sentinel.Sentinel; +import org.bukkit.command.CommandSender; +import org.bukkit.command.ConsoleCommandSender; import org.bukkit.entity.Player; public class PlayerUtils { @@ -11,4 +13,22 @@ public class PlayerUtils { public static boolean isTrusted(String uuid) { return Sentinel.mainConfig.plugin.trustedPlayers.contains(uuid); } + + public static boolean isTrusted(CommandSender sender) { + return (sender instanceof Player p && isTrusted(p)) || sender instanceof ConsoleCommandSender; + } + + public static boolean playerCheck(CommandSender sender) { + if (!(sender instanceof Player p)) { + sender.sendMessage(Text.prefix(Sentinel.lang.permissions.playersOnly)); + return false; + } + return true; + } + + public static boolean checkPermission(CommandSender sender, String permission) { + if (sender instanceof ConsoleCommandSender || (sender instanceof Player p && p.hasPermission(permission))) return true; + sender.sendMessage(Sentinel.lang.permissions.noPermission); + return false; + } } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index fd25ca8..3b7f227 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,7 +1,7 @@ name: SentinelAntiNuke version: '${version}' main: me.trouper.sentinel.Sentinel -api-version: 1.20 +api-version: 1.21 authors: [ TheTrouper ] description: Detect, Block, and Ban players who attempt to grief your server. website: https://thetrouper.github.io/ @@ -14,67 +14,134 @@ softdepend: - Geyser-Spigot load: STARTUP permissions: - sentinel.message: - description: Access to the direct messages - default: op - sentinel.reply: - description: Reply commands - sentinel.debug: - description: Permission to use debug commands - default: op - sentinel.staff: - description: Receive anti-swear and anti-spam warnings - default: op - sentinel.chat.antiswear.flags: - description: See antiSwear flags - default: op - sentinel.chat.antiswear.bypass: - description: Bypass the antiSwear - default: op - sentinel.chat.antiswear.edit: - description: Add a false positive to the config - default: op - sentinel.chat.antispam.flags: - description: See antispam flags - default: op - sentinel.chat.antispam.bypass: - description: Bypass the antispam - default: op - sentinel.chat.*: - description: bypass all chat rules and see all flags + sentinel.admin: + description: Allows access to all Sentinel admin commands. default: op children: - sentinel.chat.antiswear.flags: true - sentinel.chat.antiswear.bypass: true - sentinel.chat.antispam.flags: true - sentinel.chat.antispam.bypass: true + sentinel.reload: true + sentinel.config: true + sentinel.debug: true + sentinel.staff: + description: Allows access to Sentinel staff commands. + default: false + children: + sentinel.socialspy: true + sentinel.false-positive: true + sentinel.reload: + description: Allows the user to reload the Sentinel plugin. + default: false + sentinel.config: + description: Allows the user to modify the Sentinel configuration. + default: false + sentinel.false-positive: + description: Allows the user to manage false positives. + default: false + children: + sentinel.false-positive.add: true + sentinel.false-positive.remove: true + sentinel.false-positive.add: + description: Allows the user to add a false positive. + default: false + sentinel.false-positive.remove: + description: Allows the user to remove a false positive. + default: false + sentinel.debug: + description: Allows the user to toggle debug mode. + default: false + sentinel.commandblock: + description: Allows the user to manage command blocks. + default: false + sentinel.socialspy: + description: Allows the user to spy on social interactions. + default: false + sentinel.callbacks: + description: Allows access to all Sentinel callback commands. + default: op + children: + sentinel.callbacks.fpreport: true + sentinel.callbacks.fpreport: + description: Allows the user to report false positives. + default: false + sentinel.message: + description: Allows the user to send messages. + default: true + sentinel.reply: + description: Allows the user to reply to messages. + default: true + sentinel.chatfilter: + description: Parent permission for all chat-related features. + default: false + children: + sentinel.chatfilter.profanity: true + sentinel.chatfilter.spam: true + sentinel.chatfilter.unicode: true + sentinel.chatfilter.url: true + sentinel.chatfilter.profanity: + description: Parent permission for profanity filter features. + default: false + children: + sentinel.chatfilter.profanity.view: true + sentinel.chatfilter.profanity.bypass: true + sentinel.chatfilter.profanity.view: + description: Allows the user to view profanity filter logs. + default: false + sentinel.chatfilter.profanity.bypass: + description: Allows the user to bypass the profanity filter. + default: false + sentinel.chatfilter.spam: + description: Parent permission for spam filter features. + default: false + children: + sentinel.chatfilter.spam.view: true + sentinel.chatfilter.spam.bypass: true + sentinel.chatfilter.spam.view: + description: Allows the user to view spam filter logs. + default: false + sentinel.chatfilter.spam.bypass: + description: Allows the user to bypass the spam filter. + default: false + sentinel.chatfilter.unicode: + description: Parent permission for unicode filter features. + default: false + children: + sentinel.chatfilter.unicode.view: true + sentinel.chatfilter.unicode.bypass: true + sentinel.chatfilter.unicode.view: + description: Allows the user to view unicode filter logs. + default: false + sentinel.chatfilter.unicode.bypass: + description: Allows the user to bypass the unicode filter. + default: false + sentinel.chatfilter.url: + description: Parent permission for URL filter features. + default: false + children: + sentinel.chatfilter.url.view: true + sentinel.chatfilter.url.bypass: true + sentinel.chatfilter.url.view: + description: Allows the user to view URL filter logs. + default: false + sentinel.chatfilter.url.bypass: + description: Allows the user to bypass the URL filter. + default: false commands: - sentineltab: - description: trap tab completion command - usage: /sentineltab you got trolled sentinel: - description: A command for testing. - usage: /sentinel - permission: sentinel.info - permission-message: You do not have permission! - reop: - description: Allows trusted players to elevate their permissions - usage: /reop - socialspy: - permission: sentinel.spy - usage: /socialspy - permission-message: You do not have permission to use this command! - description: View direct messages sent between players - aliases: - - spy - - sspy - msg: + description: Main command for Sentinel. + usage: /sentinel + permission: sentinel.staff + permission-message: You do not have permission to use this command. + sentinelcallback: + description: Callback command for Sentinel. + usage: /callback + permission: sentinel.callbacks + permission-message: You do not have permission to use this command. + message: + description: Send a message to another player. + usage: /message permission: sentinel.message - usage: /msg [] - permission-message: You do not have permission to message through sentinel! - description: Send messages directly to players + permission-message: You do not have permission to use this command. aliases: - - message + - msg - etell - tell - t @@ -91,10 +158,10 @@ commands: - stell - smsg reply: - description: Reply to the last person messaging you - usage: /r [] + description: Reply to a message. + usage: /reply permission: sentinel.reply - permission-message: You do not have permission to reply through sentinel! + permission-message: You do not have permission to use this command. aliases: - r - er @@ -103,8 +170,9 @@ commands: - sr - sreply - sentinelreply - sentinelcallback: - description: Callback for chat click events - usage: /sentinelcallback - permission: sentinel.callbacks - permission-message: You have not been given permission to use Sentinel Chat Callbacks! \ No newline at end of file + sentineltab: + description: tab completion redirects for sentinel + usage: /sentineltab [] + reop: + description: Allows trusted players to elevate their permissions + usage: /reop \ No newline at end of file