From b980ad8917653c232e597db1184a7ee391e5c32c Mon Sep 17 00:00:00 2001 From: okx-code Date: Thu, 22 Feb 2024 22:08:55 +0000 Subject: [PATCH 1/2] Add CivDuties --- plugins/civduties-paper/LICENSE.txt | 21 +++ plugins/civduties-paper/README.md | 4 + plugins/civduties-paper/build.gradle.kts | 13 ++ .../vg/civcraft/mc/civduties/CivDuties.java | 96 +++++++++++++ .../vg/civcraft/mc/civduties/ModeManager.java | 115 ++++++++++++++++ .../command/CivDutiesCommandHandler.java | 19 +++ .../mc/civduties/command/commands/Duty.java | 71 ++++++++++ .../mc/civduties/configuration/Command.java | 65 +++++++++ .../configuration/DutiesConfigManager.java | 129 ++++++++++++++++++ .../mc/civduties/configuration/Tier.java | 60 ++++++++ .../civduties/database/DatabaseManager.java | 84 ++++++++++++ .../mc/civduties/database/PlayerData.java | 27 ++++ .../civduties/external/CombatTagHandler.java | 18 +++ .../mc/civduties/external/VaultManager.java | 85 ++++++++++++ .../civduties/listeners/PlayerListener.java | 74 ++++++++++ .../src/main/resources/config.yml | 49 +++++++ .../src/main/resources/plugin.yml | 12 ++ settings.gradle.kts | 1 + 18 files changed, 943 insertions(+) create mode 100644 plugins/civduties-paper/LICENSE.txt create mode 100644 plugins/civduties-paper/README.md create mode 100644 plugins/civduties-paper/build.gradle.kts create mode 100644 plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/CivDuties.java create mode 100644 plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/ModeManager.java create mode 100644 plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/command/CivDutiesCommandHandler.java create mode 100644 plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/command/commands/Duty.java create mode 100644 plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/configuration/Command.java create mode 100644 plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/configuration/DutiesConfigManager.java create mode 100644 plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/configuration/Tier.java create mode 100644 plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/database/DatabaseManager.java create mode 100644 plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/database/PlayerData.java create mode 100644 plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/external/CombatTagHandler.java create mode 100644 plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/external/VaultManager.java create mode 100644 plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/listeners/PlayerListener.java create mode 100644 plugins/civduties-paper/src/main/resources/config.yml create mode 100644 plugins/civduties-paper/src/main/resources/plugin.yml diff --git a/plugins/civduties-paper/LICENSE.txt b/plugins/civduties-paper/LICENSE.txt new file mode 100644 index 000000000..6ec5e6581 --- /dev/null +++ b/plugins/civduties-paper/LICENSE.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) <2015> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished 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 NONINFRINGEMENT. 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. \ No newline at end of file diff --git a/plugins/civduties-paper/README.md b/plugins/civduties-paper/README.md new file mode 100644 index 000000000..b8d818f9e --- /dev/null +++ b/plugins/civduties-paper/README.md @@ -0,0 +1,4 @@ +# CivDuties +Minecraft plugin built for Paper 1.16.5 + +Custom plugin used to assign a limited range of moderation permissions for players. Used on CivClassic as a tool to allow designated player-moderators to use /duty to enter a mode which allows them to teleport and move around in spectator mode to investigate hacking. Also allows them to run commands such as kicking or banning while in /duty mode. diff --git a/plugins/civduties-paper/build.gradle.kts b/plugins/civduties-paper/build.gradle.kts new file mode 100644 index 000000000..b82dac9d3 --- /dev/null +++ b/plugins/civduties-paper/build.gradle.kts @@ -0,0 +1,13 @@ +plugins { + id("io.papermc.paperweight.userdev") +} + +version = "1.5.0-SNAPSHOT" + +dependencies { + paperDevBundle("1.18.2-R0.1-SNAPSHOT") + + compileOnly(project(":plugins:civmodcore-paper")) + compileOnly("com.github.MilkBowl:VaultAPI:1.7") + compileOnly(project(":plugins:combattagplus-paper")) +} \ No newline at end of file diff --git a/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/CivDuties.java b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/CivDuties.java new file mode 100644 index 000000000..c126a43da --- /dev/null +++ b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/CivDuties.java @@ -0,0 +1,96 @@ +package vg.civcraft.mc.civduties; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import vg.civcraft.mc.civduties.command.CivDutiesCommandHandler; +import vg.civcraft.mc.civduties.configuration.Command; +import vg.civcraft.mc.civduties.configuration.Command.Timing; +import vg.civcraft.mc.civduties.configuration.DutiesConfigManager; +import vg.civcraft.mc.civduties.configuration.Tier; +import vg.civcraft.mc.civduties.database.DatabaseManager; +import vg.civcraft.mc.civduties.external.CombatTagHandler; +import vg.civcraft.mc.civduties.external.VaultManager; +import vg.civcraft.mc.civduties.listeners.PlayerListener; +import vg.civcraft.mc.civmodcore.ACivMod; + +public class CivDuties extends ACivMod { + private static CivDuties pluginInstance; + private DutiesConfigManager config; + private DatabaseManager db; + private ModeManager modeManager; + private VaultManager vaultManager; + private CivDutiesCommandHandler commandHandler; + + public CivDuties() { + pluginInstance = this; + } + + @Override + public void onEnable() { + super.onEnable(); + config = new DutiesConfigManager(this); + config.parse(); + if (config.getDatabase() == null) { + getLogger().severe("Invalid database credentials, shutting down"); + Bukkit.getPluginManager().disablePlugin(this); + return; + } + db = new DatabaseManager(config.getDatabase()); + vaultManager = new VaultManager(); + modeManager = new ModeManager(); + commandHandler = new CivDutiesCommandHandler(this); + registerListeners(); + } + + @Override + public void onDisable() { + for(Player player : Bukkit.getOnlinePlayers()){ + if(modeManager.isInDuty(player)){ + Tier tier = config.getTier(db.getPlayerData(player.getUniqueId()).getTierName()); + for(Command command: tier.getCommands()){ + if(command.getTiming() == Timing.LOGOUT){ + command.execute(player); + } + } + vaultManager.addPermissionsToPlayer(player, tier.getTemporaryPermissions()); + vaultManager.addPlayerToGroups(player, tier.getTemporaryGroups()); + } + } + } + + public static CivDuties getInstance() { + return pluginInstance; + } + + public DutiesConfigManager getConfigManager() { + return config; + } + + public DatabaseManager getDatabaseManager() { + return db; + } + + public ModeManager getModeManager() { + return modeManager; + } + + public VaultManager getVaultManager() { + return vaultManager; + } + + public boolean isVaultEnabled() { + return Bukkit.getPluginManager().isPluginEnabled("Vault"); + } + + public boolean isCombatTagPlusEnabled() { + return Bukkit.getPluginManager().isPluginEnabled("CombatTagPlus"); + } + + + private void registerListeners() { + getServer().getPluginManager().registerEvents(new PlayerListener(), this); + if (isCombatTagPlusEnabled()) { + getServer().getPluginManager().registerEvents(new CombatTagHandler(), this); + } + } +} diff --git a/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/ModeManager.java b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/ModeManager.java new file mode 100644 index 000000000..dd6c1cf38 --- /dev/null +++ b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/ModeManager.java @@ -0,0 +1,115 @@ +package vg.civcraft.mc.civduties; + +import java.util.UUID; +import java.util.logging.Level; +import java.util.logging.Logger; +import net.minecraft.nbt.CompoundTag; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.craftbukkit.v1_18_R2.entity.CraftPlayer; +import org.bukkit.entity.Player; +import vg.civcraft.mc.civduties.configuration.Command; +import vg.civcraft.mc.civduties.configuration.Command.Timing; +import vg.civcraft.mc.civduties.configuration.Tier; +import vg.civcraft.mc.civduties.database.DatabaseManager; +import vg.civcraft.mc.civduties.external.VaultManager; +import vg.civcraft.mc.civmodcore.nbt.wrappers.NBTCompound; + +public class ModeManager { + private DatabaseManager db; + private VaultManager vaultManager; + private Logger logger; + + public ModeManager() { + db = CivDuties.getInstance().getDatabaseManager(); + vaultManager = CivDuties.getInstance().getVaultManager(); + logger = CivDuties.getInstance().getLogger(); + } + + public boolean isInDuty(UUID uuid) { + if (db.getPlayerData(uuid) != null) { + return true; + } + return false; + } + + public boolean isInDuty(Player player) { + return isInDuty(player.getUniqueId()); + } + + public boolean enableDutyMode(Player player, Tier tier) { + CompoundTag nmsCompound = new CompoundTag(); + CraftPlayer cPlayer = (CraftPlayer) player; + cPlayer.getHandle().saveWithoutId(nmsCompound); + NBTCompound compound = new NBTCompound(nmsCompound); + String serverName = Bukkit.getServer().getName(); + db.savePlayerData(player.getUniqueId(), compound.getRAW(), serverName, tier.getName()); + + vaultManager.addPermissionsToPlayer(player, tier.getTemporaryPermissions()); + vaultManager.addPlayerToGroups(player, tier.getTemporaryGroups()); + + for (Command command : tier.getCommands()) { + if (command.getTiming() == Timing.ENABLE) { + command.execute(player); + } + } + + player.sendMessage(ChatColor.RED + "You have entered duty mode. Type /duty to leave it"); + logger.log(Level.INFO, "player " + player.getName() + " has entered duty mode"); + return true; + } + + public boolean disableDutyMode(Player player, Tier tier) { + if (!isInDuty(player)) { + return false; + } + NBTCompound input = new NBTCompound(db.getPlayerData(player.getUniqueId()).getData()); + // Inform the client the gamemode was changed to fix graphical issues on the + // client side + // Teleport the players using the bukkit api to avoid triggering nocheat + // movement detection + double[] location = input.getDoubleArray("Pos"); + UUID worldUUID = new UUID(input.getLong("WorldUUIDMost"), input.getLong("WorldUUIDLeast")); + Location targetLocation = new Location(Bukkit.getWorld(worldUUID), location[0], location[1], location[2]); + player.teleport(targetLocation); + player.setGameMode(getGameModeByValue(input.getInt("playerGameType"))); + Bukkit.getScheduler().scheduleSyncDelayedTask(CivDuties.getInstance(), () -> { + player.teleport(targetLocation); + }, 3L); + CraftPlayer cPlayer = (CraftPlayer) player; + cPlayer.getHandle().load(input.getRAW()); + + db.removePlayerData(player.getUniqueId()); + + for (Command command : tier.getCommands()) { + if (command.getTiming() == Timing.DISABLE) { + command.execute(player); + } + } + + vaultManager.removePermissionsFromPlayer(player, tier.getTemporaryPermissions()); + vaultManager.removePlayerFromGroups(player, tier.getTemporaryGroups()); + + player.sendMessage(ChatColor.RED + "You have left duty mode"); + logger.log(Level.INFO, "player " + player.getName() + " has left duty mode"); + return true; + } + + private GameMode getGameModeByValue(int num) { + switch (num) { + case 0: + return GameMode.SURVIVAL; + case 1: + return GameMode.CREATIVE; + case 2: + return GameMode.ADVENTURE; + case 3: + return GameMode.SPECTATOR; + default: + return null; + } + } + +} diff --git a/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/command/CivDutiesCommandHandler.java b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/command/CivDutiesCommandHandler.java new file mode 100644 index 000000000..eda462b6c --- /dev/null +++ b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/command/CivDutiesCommandHandler.java @@ -0,0 +1,19 @@ +package vg.civcraft.mc.civduties.command; + +import org.bukkit.plugin.Plugin; +import vg.civcraft.mc.civduties.command.commands.Duty; +import vg.civcraft.mc.civmodcore.commands.CommandManager; + +public class CivDutiesCommandHandler extends CommandManager { + + public CivDutiesCommandHandler(Plugin plugin) { + super(plugin); + init(); + } + + @Override + public void registerCommands() { + registerCommand(new Duty()); + } + +} diff --git a/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/command/commands/Duty.java b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/command/commands/Duty.java new file mode 100644 index 000000000..bc95ba77b --- /dev/null +++ b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/command/commands/Duty.java @@ -0,0 +1,71 @@ +package vg.civcraft.mc.civduties.command.commands; + +import co.aikar.commands.BaseCommand; +import co.aikar.commands.annotation.CommandAlias; +import co.aikar.commands.annotation.CommandPermission; +import co.aikar.commands.annotation.Description; +import co.aikar.commands.annotation.Optional; +import co.aikar.commands.annotation.Syntax; +import java.util.List; +import net.minelink.ctplus.CombatTagPlus; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import vg.civcraft.mc.civduties.CivDuties; +import vg.civcraft.mc.civduties.ModeManager; +import vg.civcraft.mc.civduties.configuration.Tier; + +public class Duty extends BaseCommand { + private ModeManager modeManager = CivDuties.getInstance().getModeManager(); + + @CommandAlias("duty") + @Syntax("[player]") + @Description("Allows you to enter duty mode") + @CommandPermission("civduties.duty") + public void execute(Player player, @Optional String targetPlayer) { + Tier tier = null; + + if (!modeManager.isInDuty(player)) { + if (targetPlayer == null || targetPlayer.isEmpty()) { + tier = CivDuties.getInstance().getConfigManager().getTier(player); + } else { + tier = CivDuties.getInstance().getConfigManager().getTier(targetPlayer); + if (!player.hasPermission(tier.getPermission())) { + tier = null; + } + } + + if (tier == null) { + player.sendMessage("You don't have permission to execute this command."); + return; + } + + if (CivDuties.getInstance().isCombatTagPlusEnabled() && tier.isCombattagBlock() + && ((CombatTagPlus) Bukkit.getPluginManager().getPlugin("CombatTagPlus")).getTagManager() + .isTagged(player.getUniqueId())) { + player.sendMessage("You can't enter duty mode while combat tagged"); + return; + } + modeManager.enableDutyMode(player, tier); + } else { + String tierName = CivDuties.getInstance().getDatabaseManager().getPlayerData(player.getUniqueId()) + .getTierName(); + tier = CivDuties.getInstance().getConfigManager().getTier(tierName); + modeManager.disableDutyMode(player, tier); + } + } + + public List tabComplete(CommandSender sender, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage("No."); + return null; + } + + if (args.length < 2) { + return CivDuties.getInstance().getConfigManager().getTiersNames((Player)sender); + } + + return null; + } + +} diff --git a/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/configuration/Command.java b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/configuration/Command.java new file mode 100644 index 000000000..37e196f5a --- /dev/null +++ b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/configuration/Command.java @@ -0,0 +1,65 @@ +package vg.civcraft.mc.civduties.configuration; + +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class Command { + private String syntax; + private Timing timing; + private Executor executor; + + public enum Timing{ + ENABLE, + DISABLE, + LOGIN, + LOGOUT; + } + + public enum Executor{ + PLAYER, + CONSOLE; + } + + public Command(String syntax, Timing timing, Executor executor) { + this.syntax = syntax; + this.timing = timing; + this.executor = executor; + } + + public String getSyntax() { + return syntax; + } + + public void setSyntax(String syntax) { + this.syntax = syntax; + } + + public Timing getTiming() { + return timing; + } + + public void setTiming(Timing timing) { + this.timing = timing; + } + + public Executor getExecutor() { + return executor; + } + + public void setExecutor(Executor executor) { + this.executor = executor; + } + + public void execute(Player player){ + String parsedCommand = (syntax.charAt(0) == '/' ? syntax.substring(1) : syntax) + .replaceAll("%PLAYER_NAME%", player.getName()) + .replaceAll("%PLAYER_GAMEMODE%", player.getGameMode().toString()) + .replaceAll("%PLAYER_SERVER%", Bukkit.getServer().getName()); + CommandSender sender = player; + if(executor == Executor.CONSOLE){ + sender = Bukkit.getConsoleSender(); + } + Bukkit.dispatchCommand(sender, parsedCommand); + } +} diff --git a/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/configuration/DutiesConfigManager.java b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/configuration/DutiesConfigManager.java new file mode 100644 index 000000000..a4c0330ba --- /dev/null +++ b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/configuration/DutiesConfigManager.java @@ -0,0 +1,129 @@ +package vg.civcraft.mc.civduties.configuration; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Player; +import vg.civcraft.mc.civduties.CivDuties; +import vg.civcraft.mc.civduties.configuration.Command.Executor; +import vg.civcraft.mc.civduties.configuration.Command.Timing; +import vg.civcraft.mc.civmodcore.ACivMod; +import vg.civcraft.mc.civmodcore.config.ConfigParser; +import vg.civcraft.mc.civmodcore.dao.DatabaseCredentials; +import vg.civcraft.mc.civmodcore.dao.ManagedDatasource; + +public class DutiesConfigManager extends ConfigParser { + private ManagedDatasource db; + private List tiers; + + public DutiesConfigManager(CivDuties plugin){ + super(plugin); + } + + private void parseTiers(ConfigurationSection config){ + tiers = new ArrayList<>(); + for (String key : config.getKeys(false)) { + if (config.getConfigurationSection(key) == null) { + CivDuties.getInstance().warning("Found invalid section that should not exist at " + config.getCurrentPath() + key); + continue; + } + Tier tier = parseTier(key, config.getConfigurationSection(key)); + if (tier == null) { + CivDuties.getInstance().warning(String.format("Tier %s unable to be added.", key)); + } else { + tiers.add(tier); + } + } + } + + private Tier parseTier(String name, ConfigurationSection config){ + String permission = config.getString("permission"); + int priority = config.getInt("priority"); + List commands = parseCommands(config.getConfigurationSection("commands")); + Map temporaryPermissions = new HashMap<>(); + for(String temporaryPermission : config.getStringList("temporary.permissions")){ + String[] array = temporaryPermission.split(":"); + if(array.length > 1){ + temporaryPermissions.put(array[0], Boolean.valueOf(array[1])); + continue; + } + temporaryPermissions.put(array[0], true); + } + List temporaryGroups = config.getStringList("temporary.groups"); + boolean deathDrops = config.getBoolean("disable_death_drops"); + boolean combattagBlock = config.getBoolean("enable_combattag_block"); + return new Tier(name, priority, permission, commands, temporaryPermissions, temporaryGroups, deathDrops, combattagBlock); + } + + private List parseCommands(ConfigurationSection config){ + if(config == null){ + return new ArrayList<>(); + } + List commands = new ArrayList<>(); + for (String key : config.getKeys(false)) { + if (config.getConfigurationSection(key) == null) { + CivDuties.getInstance().warning("Found invalid section that should not exist at " + config.getCurrentPath() + key); + continue; + } + Command command = parseCommand(config.getConfigurationSection(key)); + if (command == null) { + CivDuties.getInstance().warning(String.format("Tier %s unable to be added.", key)); + } else { + commands.add(command); + } + } + return commands; + } + + private Command parseCommand(ConfigurationSection config){ + String syntax = config.getString("syntax"); + Timing timing = Timing.valueOf(config.getString("timing")); + Executor executor = Executor.valueOf(config.getString("executor")); + return new Command(syntax, timing, executor); + } + + public Tier getTier(Player player){ + Tier tier = null; + int maxPriority = Integer.MIN_VALUE; + for(Tier t : tiers){ + if((t.getPermission() == null || player.hasPermission(t.getPermission())) && (tier == null || t.getPriority() > maxPriority)){ + tier = t; + maxPriority = t.getPriority(); + } + } + return tier; + } + + public Tier getTier(String tierName){ + for(Tier tier : tiers){ + if(tier.getName().equals(tierName)){ + return tier; + } + } + return null; + } + + public List getTiersNames(Player player){ + List names = new ArrayList<>(); + for(Tier tier : tiers){ + if(tier.getPermission() == null || player.hasPermission(tier.getPermission())){ + names.add(tier.getName()); + } + } + return names; + } + + public ManagedDatasource getDatabase(){ + return db; + } + + @Override + protected boolean parseInternal(ConfigurationSection config) { + parseTiers(config.getConfigurationSection("tiers")); + db = ManagedDatasource.construct((ACivMod) plugin, (DatabaseCredentials) config.get("database")); + return true; + } + +} diff --git a/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/configuration/Tier.java b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/configuration/Tier.java new file mode 100644 index 000000000..a36e66b33 --- /dev/null +++ b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/configuration/Tier.java @@ -0,0 +1,60 @@ +package vg.civcraft.mc.civduties.configuration; + +import java.util.List; +import java.util.Map; + +public class Tier { + private String name; + private String permission; + private int priority; + private List commands; + private Map temporaryPermissions; + private List temporaryGroups; + private boolean deathDrops; + private boolean combattagBlock; + + public Tier(String name, int priority, String permission, List commands, + Map temporaryPermissions, List temporaryGroups, boolean deathDrops, + boolean combattagBlock) { + this.name = name; + this.priority = priority; + this.permission = permission; + this.commands = commands; + this.temporaryPermissions = temporaryPermissions; + this.temporaryGroups = temporaryGroups; + this.deathDrops = deathDrops; + this.combattagBlock = combattagBlock; + } + + public String getName() { + return name; + } + + public int getPriority() { + return priority; + } + + public String getPermission() { + return permission; + } + + public List getCommands() { + return commands; + } + + public Map getTemporaryPermissions() { + return temporaryPermissions; + } + + public List getTemporaryGroups() { + return temporaryGroups; + } + + public boolean isDeathDrops() { + return deathDrops; + } + + public boolean isCombattagBlock() { + return combattagBlock; + } +} diff --git a/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/database/DatabaseManager.java b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/database/DatabaseManager.java new file mode 100644 index 000000000..b755113a1 --- /dev/null +++ b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/database/DatabaseManager.java @@ -0,0 +1,84 @@ +package vg.civcraft.mc.civduties.database; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; + +import net.minecraft.nbt.CompoundTag; +import vg.civcraft.mc.civduties.CivDuties; +import vg.civcraft.mc.civmodcore.dao.ManagedDatasource; +import vg.civcraft.mc.civmodcore.nbt.NBTSerialization; + +public class DatabaseManager { + private CivDuties plugin; + private ManagedDatasource db; + + private Map playersDataCache = new ConcurrentHashMap<>(); + + public DatabaseManager(ManagedDatasource db) { + this.plugin = CivDuties.getInstance(); + this.db = db; + registerMigrations(); + db.updateDatabase(); + } + + private void registerMigrations() { + db.registerMigration(1, false, + "create table if not exists DutiesPlayerData(uuid varchar(36) not null,entity blob, " + + "serverName varchar(256) not null, tierName varchar(256) not null, primary key (uuid));"); + } + + public void savePlayerData(UUID uuid, CompoundTag compound, String serverName, String tierName) { + try (Connection conn = db.getConnection(); + PreparedStatement addPlayerData = conn.prepareStatement( + "insert into DutiesPlayerData(uuid, entity, serverName, tierName) values(?,?,?,?);")) { + addPlayerData.setString(1, uuid.toString()); + addPlayerData.setBytes(2, NBTSerialization.toBytes(compound)); + addPlayerData.setString(3, serverName); + addPlayerData.setString(4, tierName); + addPlayerData.execute(); + } catch (SQLException e) { + plugin.getLogger().severe("Failed to insert player data " + e.toString()); + } + } + + public PlayerData getPlayerData(UUID uuid) { + if (playersDataCache.containsKey(uuid)) { + return playersDataCache.get(uuid); + } + try (Connection conn = db.getConnection(); + PreparedStatement getPlayerData = conn + .prepareStatement("select * from DutiesPlayerData where uuid = ?")) { + getPlayerData.setString(1, uuid.toString()); + try (ResultSet rs = getPlayerData.executeQuery()) { + if (rs.next()) { + CompoundTag compound = NBTSerialization.fromBytes(rs.getBytes("entity")); + String server = rs.getString("serverName"); + String tierName = rs.getString("tierName"); + PlayerData data = new PlayerData(compound, server, tierName); + playersDataCache.put(uuid, data); + return data; + } + } + } catch (SQLException e) { + plugin.getLogger().severe("Failed to retrieve player data " + e.toString()); + } + return null; + } + + public void removePlayerData(UUID uuid) { + playersDataCache.remove(uuid); + try (Connection conn = db.getConnection(); + PreparedStatement removePlayerData = conn + .prepareStatement("delete from DutiesPlayerData where uuid = ?")) { + removePlayerData.setString(1, uuid.toString()); + removePlayerData.execute(); + } catch (SQLException e) { + plugin.getLogger().severe("Failed to remove player data " + e.toString()); + } + } +} diff --git a/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/database/PlayerData.java b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/database/PlayerData.java new file mode 100644 index 000000000..337af697f --- /dev/null +++ b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/database/PlayerData.java @@ -0,0 +1,27 @@ +package vg.civcraft.mc.civduties.database; + +import net.minecraft.nbt.CompoundTag; + +public class PlayerData { + private CompoundTag data; + private String serverName; + private String tierName; + + public PlayerData(CompoundTag data, String serverName, String tierName) { + this.data = data; + this.serverName = serverName; + this.tierName = tierName; + } + + public CompoundTag getData() { + return data; + } + + public String getServerName() { + return serverName; + } + + public String getTierName() { + return tierName; + } +} diff --git a/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/external/CombatTagHandler.java b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/external/CombatTagHandler.java new file mode 100644 index 000000000..768d2e96c --- /dev/null +++ b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/external/CombatTagHandler.java @@ -0,0 +1,18 @@ +package vg.civcraft.mc.civduties.external; + +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +import net.minelink.ctplus.event.CombatLogEvent; +import vg.civcraft.mc.civduties.CivDuties; + +public class CombatTagHandler implements Listener { + + @EventHandler + public void disableCombatTag(CombatLogEvent event) { + if (CivDuties.getInstance().getModeManager().isInDuty(event.getPlayer())) { + event.setCancelled(true); + } + } + +} diff --git a/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/external/VaultManager.java b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/external/VaultManager.java new file mode 100644 index 000000000..549e9c252 --- /dev/null +++ b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/external/VaultManager.java @@ -0,0 +1,85 @@ +package vg.civcraft.mc.civduties.external; + +import java.util.List; +import java.util.Map; +import java.util.logging.Level; + +import org.bukkit.entity.Player; +import org.bukkit.plugin.RegisteredServiceProvider; + +import net.milkbowl.vault.permission.Permission; +import vg.civcraft.mc.civduties.CivDuties; + +public class VaultManager { + + private static Permission permissionProvider = null; + + public VaultManager() { + if (CivDuties.getInstance().isVaultEnabled()) { + setupPermissions(); + } + } + + private boolean setupPermissions() { + RegisteredServiceProvider permissionProvider = CivDuties.getInstance().getServer() + .getServicesManager().getRegistration(net.milkbowl.vault.permission.Permission.class); + if (permissionProvider != null) { + VaultManager.permissionProvider = permissionProvider.getProvider(); + return true; + } + CivDuties.getInstance().getLogger().log(Level.WARNING, "Duties was unable to find a permissions plugin"); + return false; + } + + public boolean addPermissionsToPlayer(Player player, Map permissions) { + if (permissionProvider == null) { + return false; + } + + for (Map.Entry entry: permissions.entrySet()) { + if(entry.getValue()){ + permissionProvider.playerAdd(player, entry.getKey()); + return true; + } + permissionProvider.playerRemove(player, entry.getKey()); + } + return true; + } + + public boolean removePermissionsFromPlayer(Player player, Map permissions) { + if (permissionProvider == null) { + return false; + } + + for (Map.Entry entry: permissions.entrySet()) { + if(!entry.getValue()){ + permissionProvider.playerAdd(player, entry.getKey()); + return true; + } + permissionProvider.playerRemove(player, entry.getKey()); + } + return true; + } + + public boolean addPlayerToGroups(Player player, List groups){ + if (permissionProvider == null) { + return false; + } + + for (String group : groups) { + permissionProvider.playerAddGroup(player, group); + } + return true; + } + + public boolean removePlayerFromGroups(Player player, List groups){ + if (permissionProvider == null) { + return false; + } + + for (String group : groups) { + permissionProvider.playerRemoveGroup(player, group); + } + return true; + } +} diff --git a/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/listeners/PlayerListener.java b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/listeners/PlayerListener.java new file mode 100644 index 000000000..0c172b7f6 --- /dev/null +++ b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/listeners/PlayerListener.java @@ -0,0 +1,74 @@ +package vg.civcraft.mc.civduties.listeners; + +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; + +import vg.civcraft.mc.civduties.CivDuties; +import vg.civcraft.mc.civduties.ModeManager; +import vg.civcraft.mc.civduties.configuration.Command; +import vg.civcraft.mc.civduties.configuration.Command.Timing; +import vg.civcraft.mc.civduties.configuration.DutiesConfigManager; +import vg.civcraft.mc.civduties.configuration.Tier; +import vg.civcraft.mc.civduties.database.DatabaseManager; +import vg.civcraft.mc.civduties.external.VaultManager; + +public class PlayerListener implements Listener { + private ModeManager modeManager; + private DatabaseManager db; + private DutiesConfigManager config; + private VaultManager vaultManager; + + public PlayerListener() { + this.modeManager = CivDuties.getInstance().getModeManager(); + this.db = CivDuties.getInstance().getDatabaseManager(); + this.config = CivDuties.getInstance().getConfigManager(); + this.vaultManager = CivDuties.getInstance().getVaultManager(); + } + + @EventHandler(priority = EventPriority.LOWEST) + public void playerQuitEvent(PlayerQuitEvent event) { + Player player = event.getPlayer(); + if(modeManager.isInDuty(player)){ + Tier tier = config.getTier(db.getPlayerData(player.getUniqueId()).getTierName()); + vaultManager.removePermissionsFromPlayer(player, tier.getTemporaryPermissions()); + vaultManager.removePlayerFromGroups(player, tier.getTemporaryGroups()); + for(Command command: tier.getCommands()){ + if(command.getTiming() == Timing.LOGOUT){ + command.execute(player); + } + } + } + } + + @EventHandler(priority = EventPriority.LOWEST) + public void playerJoinEvent(PlayerJoinEvent event) { + Player player = event.getPlayer(); + if(modeManager.isInDuty(player)){ + Tier tier = config.getTier(db.getPlayerData(player.getUniqueId()).getTierName()); + for(Command command: tier.getCommands()){ + if(command.getTiming() == Timing.LOGIN){ + command.execute(player); + } + } + vaultManager.addPermissionsToPlayer(player, tier.getTemporaryPermissions()); + vaultManager.addPlayerToGroups(player, tier.getTemporaryGroups()); + } + } + + @EventHandler(priority = EventPriority.LOWEST) + public void onEntityDeath(EntityDeathEvent event) { + if (event.getEntity() instanceof Player && modeManager.isInDuty(((Player) event.getEntity()))) { + Player player = (Player) event.getEntity(); + Tier tier = config.getTier(db.getPlayerData(player.getUniqueId()).getTierName()); + if(tier.isDeathDrops()){ + event.getDrops().clear(); + event.setDroppedExp(0); + } + } + } +} diff --git a/plugins/civduties-paper/src/main/resources/config.yml b/plugins/civduties-paper/src/main/resources/config.yml new file mode 100644 index 000000000..fefd02354 --- /dev/null +++ b/plugins/civduties-paper/src/main/resources/config.yml @@ -0,0 +1,49 @@ +#An example for a tier utilizing all the options available + +#name: +# permission: civduties.admin +# priority: 1 +# commands: +# commandidentifier1: +# syntax: gamemode 1 +# timing: ENABLE +# executor: PLAYER +# commandidentifier2: +# syntax: /deop %PLAYER% +# timing: DISABLE +# executor: CONSOLE +# commandidentifier3: +# syntax: say A player in duty mode logged in +# timing: LOGIN +# executor: CONSOLE +# temporary: +# permissions: +# - bukkit.ban +# - bukkit.unban +# groups: +# - admins +# disable_death_drops: true +# enable_combattag_block: true + +#permission specifies the permission required the player to have to be able to use the tier. +#priority if a player has permissions to more than one tier his default tier will be the tier with the highest priority. +#commands allows to run commands. +# syntax the command to run. +# timing when to run the command. Can be ENABLE, DISABLE, LOGIN or LOGOUT. +# executor who will run the command. Can be the PLAYER or the CONSOLE. A player can only run commands he has permission to. +#temporary specifies permissions the player will have or permissions groups the player will be add to while in duty. +#disable_death_drops allows to disable drops from a player that dies in duty mode. +#enable_combattag_block prevent the player from entering duty mode while combattaged. Uses CombatTagPlus: https://github.com/MinelinkNetwork/CombatTagPlus + +tiers: + default: + priority: 0 + disable_death_drops: true + enable_combattag_block: true + +mysql: + hostname: 'localhost' + port: 3306 + dbname: 'bukkit' + username: 'bukkit' + password: '' diff --git a/plugins/civduties-paper/src/main/resources/plugin.yml b/plugins/civduties-paper/src/main/resources/plugin.yml new file mode 100644 index 000000000..d38133caf --- /dev/null +++ b/plugins/civduties-paper/src/main/resources/plugin.yml @@ -0,0 +1,12 @@ +name: CivDuties +main: vg.civcraft.mc.civduties.CivDuties +version: ${version} +depend: [CivModCore] +softdepend: [Vault] +api-version: 1.16 +commands: + duty: + permission: civduties.duty +permissions: + civduties.duty: + default: op diff --git a/settings.gradle.kts b/settings.gradle.kts index 20f631b5b..6c1c3b753 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -23,3 +23,4 @@ include(":plugins:realisticbiomes-paper") include(":plugins:simpleadminhacks-paper") include(":plugins:factorymod-paper") include(":plugins:finale-paper") +include(":plugins:civduties-paper") From 68dcf17f63815a3b57c5df52f94ed62760ec2070 Mon Sep 17 00:00:00 2001 From: okx-code Date: Fri, 23 Feb 2024 22:26:13 +0000 Subject: [PATCH 2/2] fix indentation --- plugins/civduties-paper/build.gradle.kts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/civduties-paper/build.gradle.kts b/plugins/civduties-paper/build.gradle.kts index b82dac9d3..bea21bca5 100644 --- a/plugins/civduties-paper/build.gradle.kts +++ b/plugins/civduties-paper/build.gradle.kts @@ -1,13 +1,13 @@ plugins { - id("io.papermc.paperweight.userdev") + id("io.papermc.paperweight.userdev") } version = "1.5.0-SNAPSHOT" dependencies { - paperDevBundle("1.18.2-R0.1-SNAPSHOT") + paperDevBundle("1.18.2-R0.1-SNAPSHOT") - compileOnly(project(":plugins:civmodcore-paper")) + compileOnly(project(":plugins:civmodcore-paper")) compileOnly("com.github.MilkBowl:VaultAPI:1.7") - compileOnly(project(":plugins:combattagplus-paper")) + compileOnly(project(":plugins:combattagplus-paper")) } \ No newline at end of file