From 8641d9d64c86be4a6769edb643df9649d5be58db Mon Sep 17 00:00:00 2001 From: Jacob Gillespie Date: Mon, 9 Nov 2015 16:05:27 -0600 Subject: [PATCH] Initial commit --- .gitignore | 3 + .travis.yml | 13 ++ LICENSE | 21 +++ README.md | 54 ++++++++ pom.xml | 128 ++++++++++++++++++ .../gg/obsidian/modtools/CommandHandler.kt | 38 ++++++ .../gg/obsidian/modtools/Configuration.kt | 18 +++ .../gg/obsidian/modtools/EventListener.kt | 56 ++++++++ .../kotlin/gg/obsidian/modtools/ModTools.kt | 49 +++++++ .../kotlin/gg/obsidian/modtools/MsgHistory.kt | 21 +++ .../gg/obsidian/modtools/Permissions.kt | 13 ++ src/main/kotlin/gg/obsidian/modtools/Utils.kt | 37 +++++ src/main/resources/config.yml | 15 ++ src/main/resources/plugin.yml | 23 ++++ 14 files changed, 489 insertions(+) create mode 100644 .gitignore create mode 100644 .travis.yml create mode 100644 LICENSE create mode 100644 README.md create mode 100644 pom.xml create mode 100644 src/main/kotlin/gg/obsidian/modtools/CommandHandler.kt create mode 100644 src/main/kotlin/gg/obsidian/modtools/Configuration.kt create mode 100644 src/main/kotlin/gg/obsidian/modtools/EventListener.kt create mode 100644 src/main/kotlin/gg/obsidian/modtools/ModTools.kt create mode 100644 src/main/kotlin/gg/obsidian/modtools/MsgHistory.kt create mode 100644 src/main/kotlin/gg/obsidian/modtools/Permissions.kt create mode 100644 src/main/kotlin/gg/obsidian/modtools/Utils.kt create mode 100644 src/main/resources/config.yml create mode 100644 src/main/resources/plugin.yml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4bfa550 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.idea/ +*.iml +target/ diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..43c3aec --- /dev/null +++ b/.travis.yml @@ -0,0 +1,13 @@ +language: java +jdk: +- oraclejdk8 + +deploy: + provider: releases + api_key: + secure: i69Ci149qroyjyvq86Za2d99eXLdvDJkQUxPFld1HTwq3/KAMzeTMvXwePhzNinlI6tL8gz+sCqbVc7a+c9WxzQ9uyFjx56nalbXkpKHS+g8P6U3JiK+807XhoSn3YPB0bHMHjDZaGUjd435NQ7RPzbgRluWJFO0XLiJ1DhkDPYzYoN9T4S18USeVQPVIe8XW0r5/7oGLQbdGjH39LKpfpYXVrEMddwnqrjs4jjYUmNVOABiW+lMCkWi71aR4xE6MOvwaTKlmXZoX6YA3atUVBJtIDQfLoo4ubgFWKzOs0Azmt9Vn8p9tnxEQCNNhsuZfj6J1Rauat94VLrmgfRNFYFhT0aUr87TkE5l1nJuX8mUSSX4zj+5AFaR6NB7OsEfVrzZHE5grd7YJL3eks5CflLQVx8NIuhLAKU+fRxp26+ckQVNcLuB2xKIIZtFO8FYDItl2A2nCyvA6KZXFu/5OR1wUI/QoKroYNjpQhgfFp8Cn2+Zy5FLUMk18DWcb1ljrk4lr41lAfnbkcZ6DP3aQw1IQZWekhbKmYN2LzLJr889EPvdL5nyxXutR1kjpJOw3K0kafFQHNTSdivhV6hSgY8ns8sIZGQslwMcwgUpSYOVANRAz1lIRXNkAOfVeJfbth/my9/X6eb4gtD0o5FkHus3Y30enOddu1eYIdCZRuY= + file: target/ModTools-*.jar + file_glob: true + on: + repo: the-obsidian/ModTools + tags: true diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..9bca104 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +Copyright (c) 2015 Jacob Gillespie + +Permission is hereby granted, free of charge, to any person ob- +taining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without restric- +tion, including without limitation the rights to use, copy, modi- +fy, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is fur- +nished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONIN- +FRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..554c552 --- /dev/null +++ b/README.md @@ -0,0 +1,54 @@ +# ModTools [![Build Status](https://travis-ci.org/the-obsidian/ModTools.svg?branch=master)](https://travis-ci.org/the-obsidian/ModTools) + +Tools to enable moderation of our Minecraft servers + +## Dependencies + +* none + +## Installation + +1. Download the [latest release](https://github.com/the-obsidian/ModTools/releases) from GitHub +1. Add it to your `plugins` folder +1. Either run Bukkit/Spigot once to generate `ModTools/config.yml` or create it using the guide below. +1. All done! + +## Configuration + +ModTools has several options that can be configured in the `config.yml` file: + +```yaml +# Prefix for plugin message +prefix: '&8[&7ModTools&8] &7' + +# Format for spied private message +spy-format: '&8[&7%from% &8-> &7%to%&8] &7%msg%' + +# Commands watched by spy +watched-commands: + - m + - msg + - r + - reply + - t + - tell + - whisper +``` + +## Permissions + +* `modtools.use` - use modtools +* `modtools.spy` - use message spy +* `modtools.spy.auto` - automatically enable message spy on join + +## Commands + +* `/spy` - toggles message spy + +## Features + +* Message spy for listening into private messages + +## Upcoming Features + +* More mod tools diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..773ca39 --- /dev/null +++ b/pom.xml @@ -0,0 +1,128 @@ + + + 4.0.0 + + gg.obsidian + ModTools + 1.0.0 + Basic moderator toolkit + https://github.com/the-obsidian/ModTools + + + scm:git:https://github.com/the-obsidian/ModTools.git + scm:git:https://github.com/the-obsidian/ModTools.git + https://github.com/the-obsidian/ModTools + + + jar + + + UTF-8 + 1.0.0-beta-1103 + + + + + spigot-repo + https://hub.spigotmc.org/nexus/content/groups/public/ + + + vault-repo + http://nexus.theyeticave.net/content/repositories/pub_releases + + + jitpack.io + https://jitpack.io + + + + + + org.spigotmc + spigot-api + 1.8.8-R0.1-SNAPSHOT + + + org.jetbrains.kotlin + kotlin-stdlib + ${kotlin.version} + + + + com.squareup.okhttp + okhttp + 2.5.0 + + + + net.milkbowl.vault + VaultAPI + 1.5 + compile + + + + + ${project.basedir}/src/main/kotlin + clean install + + + + . + true + ${basedir}/src/main/resources + + *.yml + + + + + + + kotlin-maven-plugin + org.jetbrains.kotlin + ${kotlin.version} + + + + compile + compile + + compile + + + + test-compile + test-compile + + test-compile + + + + + + org.apache.maven.plugins + maven-shade-plugin + 2.3 + + + package + + shade + + + true + false + + + org.spigotmc:* + + + + + + + + + diff --git a/src/main/kotlin/gg/obsidian/modtools/CommandHandler.kt b/src/main/kotlin/gg/obsidian/modtools/CommandHandler.kt new file mode 100644 index 0000000..7afdf0a --- /dev/null +++ b/src/main/kotlin/gg/obsidian/modtools/CommandHandler.kt @@ -0,0 +1,38 @@ +package gg.obsidian.modtools + +import org.bukkit.command.Command +import org.bukkit.command.CommandExecutor +import org.bukkit.command.CommandSender +import org.bukkit.entity.Player + +class CommandHandler(val plugin: ModTools): CommandExecutor { + + override fun onCommand(player: CommandSender, cmd: Command, alias: String?, args: Array?): Boolean { + if (player !is Player) { + plugin.utils.sendPrefixedMessage(player, "This command only works in-game") + return true + } + + if (!Permissions.modtools.has(player)) { + plugin.utils.sendPrefixedMessage(player, "You do not have permission") + return true + } + + if (cmd.name == "spy") { + if (!Permissions.spy.has(player)) { + plugin.utils.sendPrefixedMessage(player, "You do not have permission") + return true + } + + if (plugin.hasSpyEnabled(player)) { + plugin.disableSpy(player) + plugin.utils.sendPrefixedMessage(player, "Spy disabled") + } else { + plugin.enableSpy(player) + plugin.utils.sendPrefixedMessage(player, "Spy enabled") + } + } + + return true + } +} \ No newline at end of file diff --git a/src/main/kotlin/gg/obsidian/modtools/Configuration.kt b/src/main/kotlin/gg/obsidian/modtools/Configuration.kt new file mode 100644 index 0000000..e118e3c --- /dev/null +++ b/src/main/kotlin/gg/obsidian/modtools/Configuration.kt @@ -0,0 +1,18 @@ +package gg.obsidian.modtools + +import java.util.* + +class Configuration(val plugin: ModTools) { + + var PREFIX = "" + var SPY_FORMAT = "" + var WATCHED_COMMANDS = ArrayList() + + fun load() { + plugin.reloadConfig() + + SPY_FORMAT = plugin.getConfig().getString("spy-format") + PREFIX = plugin.getConfig().getString("prefix") + WATCHED_COMMANDS = plugin.getConfig().getStringList("watched-commands") as ArrayList + } +} diff --git a/src/main/kotlin/gg/obsidian/modtools/EventListener.kt b/src/main/kotlin/gg/obsidian/modtools/EventListener.kt new file mode 100644 index 0000000..14a26a7 --- /dev/null +++ b/src/main/kotlin/gg/obsidian/modtools/EventListener.kt @@ -0,0 +1,56 @@ +package gg.obsidian.modtools + +import org.bukkit.Bukkit +import org.bukkit.event.EventHandler +import org.bukkit.event.Listener +import org.bukkit.event.player.PlayerCommandPreprocessEvent +import org.bukkit.event.player.PlayerJoinEvent + +class EventListener(val plugin: ModTools): Listener { + + @EventHandler + fun onPlayerJoin(e: PlayerJoinEvent) { + if (Permissions.spyAuto.has(e.player)) { + plugin.enableSpy(e.player) + } + } + + @EventHandler + fun onCommandPreprocess(e: PlayerCommandPreprocessEvent) { + plugin.logger.info("Got a command event") + try { + var message = e.message + if (message.startsWith("/")) { + message = message.substring(1) + } + message = message.replace("([ ]+)", "$1") + + val args = message.split(" ") + + plugin.logger.info("command was " + args) + + if (!plugin.config.WATCHED_COMMANDS.contains(args[0].toLowerCase())) { + return + } + + if (args[0].equals("r", ignoreCase = true) || args[0].equals("reply", ignoreCase = true)) { + if (args.size <= 1) return + + val from = e.player + val to = Bukkit.getPlayer(MsgHistory.getTo(from)) + + MsgHistory.reportMessage(from, to) + plugin.utils.sendSpyMessage(from, to, args.subList(1, args.size).joinToString(" ")) + } else if (args.size > 2) { + val from = e.player + val to = from.server.getPlayer(args[1]) + + MsgHistory.reportMessage(from, to) + plugin.utils.sendSpyMessage(from, to, args.subList(2, args.size).joinToString(" ")) + } + } catch (e: Exception) { + plugin.logger.severe(e.message) + // Ignore errors + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/gg/obsidian/modtools/ModTools.kt b/src/main/kotlin/gg/obsidian/modtools/ModTools.kt new file mode 100644 index 0000000..ffe6f83 --- /dev/null +++ b/src/main/kotlin/gg/obsidian/modtools/ModTools.kt @@ -0,0 +1,49 @@ +package gg.obsidian.modtools + +import org.bukkit.entity.Player +import org.bukkit.metadata.FixedMetadataValue +import org.bukkit.plugin.java.JavaPlugin +import java.io.File + +val SPY_METADATA_KEY = "MODTOOLS_SPY_ENABLED" + +class ModTools : JavaPlugin() { + + val config = Configuration(this) + val utils = Utils(this) + + override fun onEnable() { + val configFile = File(dataFolder, "config.yml") + if (!configFile.exists()) { + getConfig().options().copyDefaults(true) + saveConfig() + } + + config.load() + + server.pluginManager.registerEvents(EventListener(this), this) + getCommand("spy").executor = CommandHandler(this) + } + + fun enableSpy(player: Player) { + player.setMetadata(SPY_METADATA_KEY, FixedMetadataValue(this, true)) + } + + fun disableSpy(player: Player) { + player.setMetadata(SPY_METADATA_KEY, FixedMetadataValue(this, false)) + } + + fun hasSpyEnabled(player: Player): Boolean { + logger.info("checking spy for player " + player.name) + if (!player.hasMetadata(SPY_METADATA_KEY)) { + return false + } + + val meta = player.getMetadata(SPY_METADATA_KEY) + if (meta.size == 0) { + return false + } + + return meta[0].asBoolean() + } +} diff --git a/src/main/kotlin/gg/obsidian/modtools/MsgHistory.kt b/src/main/kotlin/gg/obsidian/modtools/MsgHistory.kt new file mode 100644 index 0000000..c644eb5 --- /dev/null +++ b/src/main/kotlin/gg/obsidian/modtools/MsgHistory.kt @@ -0,0 +1,21 @@ +package gg.obsidian.modtools + +import org.bukkit.entity.Player +import java.util.* + +object MsgHistory { + val history = HashMap() + + fun getTo(player: Player): UUID? { + if (history.containsKey(player.uniqueId)) { + return history[player.uniqueId] + } + + return null + } + + fun reportMessage(from: Player, to: Player) { + history.put(from.uniqueId, to.uniqueId) + history.put(to.uniqueId, from.uniqueId) + } +} \ No newline at end of file diff --git a/src/main/kotlin/gg/obsidian/modtools/Permissions.kt b/src/main/kotlin/gg/obsidian/modtools/Permissions.kt new file mode 100644 index 0000000..165c293 --- /dev/null +++ b/src/main/kotlin/gg/obsidian/modtools/Permissions.kt @@ -0,0 +1,13 @@ +package gg.obsidian.modtools + +import org.bukkit.entity.Player + +enum class Permissions(val node: String) { + modtools("modtools.use"), + spy("modtools.spy"), + spyAuto("modtools.spy.auto"); + + fun has(player: Player): Boolean { + return player.hasPermission(node) + } +} diff --git a/src/main/kotlin/gg/obsidian/modtools/Utils.kt b/src/main/kotlin/gg/obsidian/modtools/Utils.kt new file mode 100644 index 0000000..33b45ff --- /dev/null +++ b/src/main/kotlin/gg/obsidian/modtools/Utils.kt @@ -0,0 +1,37 @@ +package gg.obsidian.modtools + +import org.bukkit.Bukkit +import org.bukkit.ChatColor +import org.bukkit.command.CommandSender +import org.bukkit.entity.Player + +class Utils(val plugin: ModTools) { + + fun getPrefix(): String { + return "[ModTools] " + } + + fun sendSpyMessage(from: Player, to: Player, msg: String) { + plugin.logger.info("sending spy message") + plugin.server.scheduler.runTaskAsynchronously(plugin, { + plugin.logger.info("running spy message") + for (player in Bukkit.getOnlinePlayers()) { + if (plugin.hasSpyEnabled(player)) { + val formattedMessage = plugin.config.SPY_FORMAT. + replace("%from%", from.name). + replace("%to%", to.name). + replace("%msg%", msg) + sendMsg(player, formattedMessage) + } + } + }) + } + + fun sendPrefixedMessage(player: CommandSender, msg: String) { + sendMsg(player, getPrefix() + msg) + } + + fun sendMsg(player: CommandSender, msg: String) { + player.sendMessage(ChatColor.translateAlternateColorCodes('&', msg)) + } +} \ No newline at end of file diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml new file mode 100644 index 0000000..eff46c1 --- /dev/null +++ b/src/main/resources/config.yml @@ -0,0 +1,15 @@ +# Prefix for plugin message +prefix: '&8[&7ModTools&8] &7' + +# Format for spied private message +spy-format: '&8[&7%from% &8-> &7%to%&8] &7%msg%' + +# Commands watched by spy +watched-commands: + - m + - msg + - r + - reply + - t + - tell + - whisper diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml new file mode 100644 index 0000000..a33d7ad --- /dev/null +++ b/src/main/resources/plugin.yml @@ -0,0 +1,23 @@ +name: ModTools +version: ${project.version} +description: ${project.description} + +author: Jacob Gillespie +website: ${project.url} + +main: gg.obsidian.modtools.ModTools + +commands: + spy: + description: Toggles the ability to spy on PMs + +permissions: + modtools.use: + description: Allows the use of ModTools + default: op + modtools.spy: + description: Allows the use of ModTools spy + default: op + modtools.spy.auto: + description: Automatically enables spy on join + default: false \ No newline at end of file