commit 90e2e27a39f66b0fee8d4ced7f8abb4db166546a Author: mathias Date: Mon Aug 6 03:36:30 2018 +0300 First version diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d7eca3b --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.gradle/ +target/ \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..6bb8a29 --- /dev/null +++ b/LICENSE @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +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 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. + +For more information, please refer to \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..ca2f33e --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# icontrolu + +Source code for the iControlU plugin on the Kaboom.pw server diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..628a9f5 --- /dev/null +++ b/build.sh @@ -0,0 +1,2 @@ +#!/bin/bash +mvn package \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..80653a1 --- /dev/null +++ b/pom.xml @@ -0,0 +1,27 @@ + + 4.0.0 + pw.kaboom + iControlU + master + + + + com.destroystokyo.paper + paper-api + 1.12.2-R0.1-SNAPSHOT + provided + + + + + + destroystokyo-repo + https://repo.destroystokyo.com/repository/maven-public/ + + + + + ${project.artifactId} + + + diff --git a/src/main/java/pw/kaboom/icontrolu/Commands.java b/src/main/java/pw/kaboom/icontrolu/Commands.java new file mode 100644 index 0000000..f97bdab --- /dev/null +++ b/src/main/java/pw/kaboom/icontrolu/Commands.java @@ -0,0 +1,87 @@ +package pw.kaboom.icontrolu; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; + +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; + +import org.bukkit.entity.Player; + +import org.bukkit.potion.PotionEffectType; + +import org.bukkit.scoreboard.Scoreboard; +import org.bukkit.scoreboard.Team; + +class CommandIcu implements CommandExecutor { + Main main; + CommandIcu(Main main) { + this.main = main; + } + + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + Player controller = (Player)sender; + if (args.length == 0) { + controller.sendMessage(ChatColor.RED + "Usage: /" + label + " "); + } else if (args[0].equalsIgnoreCase("control")) { + if (args.length == 1) { + controller.sendMessage(ChatColor.RED + "Usage: /" + label + " control "); + } else { + Player target = Bukkit.getPlayer(args[1]); + if (target != null) { + if (target == controller) { + controller.sendMessage("You are already controlling yourself"); + } else if (main.targetFor.containsKey(controller.getUniqueId())) { + controller.sendMessage("You are already controlling \"" + target.getName() + "\""); + } else if (main.controllerFor.containsKey(target.getUniqueId())) { + controller.sendMessage("Player \"" + target.getName() + "\" is already being controlled"); + } else if (main.targetFor.containsKey(target.getUniqueId())) { + controller.sendMessage("Player \"" + target.getName() + "\" is already controlling another player"); + } else { + controller.teleport(target); + + controller.getInventory().setContents(target.getInventory().getContents()); + + main.targetFor.put(controller.getUniqueId(), target); + main.controllerFor.put(target.getUniqueId(), controller); + + controller.sendMessage("You are now controlling \"" + target.getName() + "\""); + } + } else { + controller.sendMessage("Player \"" + args[1] + "\" not found"); + } + } + } else if (args[0].equalsIgnoreCase("stop")) { + Player target = main.targetFor.get(controller.getUniqueId()); + if (target != null) { + main.targetFor.remove(controller.getUniqueId()); + main.controllerFor.remove(target.getUniqueId()); + + final Player controllerRun = controller; + + Bukkit.getScheduler().scheduleSyncDelayedTask(main, new Runnable() { + public void run() { + for (Player player: Bukkit.getOnlinePlayers()) { + player.showPlayer(controllerRun); + } + + Scoreboard scoreboard = Bukkit.getScoreboardManager().getMainScoreboard(); + Team team = scoreboard.getTeam("iControlU_List"); + if (team != null && team.hasPlayer(controllerRun) == true) { + team.removePlayer(controllerRun); + } + + controllerRun.removePotionEffect(PotionEffectType.INVISIBILITY); + controllerRun.sendMessage("You are now visible"); + } + }, 200L); + + controller.sendMessage("You are no longer controlling \"" + target.getName() + "\". You are invisible for 10 seconds."); + } else { + controller.sendMessage("You are not controlling anyone at the moment"); + } + } + return true; + } +} diff --git a/src/main/java/pw/kaboom/icontrolu/Events.java b/src/main/java/pw/kaboom/icontrolu/Events.java new file mode 100644 index 0000000..b9e6896 --- /dev/null +++ b/src/main/java/pw/kaboom/icontrolu/Events.java @@ -0,0 +1,207 @@ +package pw.kaboom.icontrolu; + +import org.bukkit.Bukkit; + +import org.bukkit.entity.Player; +import org.bukkit.entity.Entity; + +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +import org.bukkit.event.entity.EntityDamageEvent; + +import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.player.PlayerDropItemEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.player.PlayerRespawnEvent; + +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import org.bukkit.scoreboard.Scoreboard; +import org.bukkit.scoreboard.Team; +import org.bukkit.scoreboard.Team.Option; +import org.bukkit.scoreboard.Team.OptionStatus; + +import org.bukkit.scheduler.BukkitRunnable; + +class Tick extends BukkitRunnable { + Main main; + Tick(Main main) { + this.main = main; + } + + public void run() { + for (Player target: Bukkit.getOnlinePlayers()) { + Player controller = main.controllerFor.get(target.getUniqueId()); + if (controller != null) { + for (int i = 0; i < 40; ++i) { + if (controller.getInventory().getItem(i) != target.getInventory().getItem(i)) { + target.getInventory().setItem(i, controller.getInventory().getItem(i)); + } + } + + if (target.getHealth() > 0) { + target.teleport(controller); + } + + target.setExhaustion(controller.getExhaustion()); + target.setFlying(controller.isFlying()); + target.setFoodLevel(controller.getFoodLevel()); + target.setHealth(controller.getHealth()); + target.setLevel(controller.getLevel()); + target.setSneaking(controller.isSneaking()); + target.setSprinting(controller.isSprinting()); + + for (Player player: Bukkit.getOnlinePlayers()) { + player.hidePlayer(controller); + } + + Scoreboard scoreboard = Bukkit.getScoreboardManager().getMainScoreboard(); + Team team = scoreboard.getTeam("iControlU_List"); + if (team == null) { + team = scoreboard.registerNewTeam("iControlU_List"); + } + + team.setCanSeeFriendlyInvisibles​(false); + team.setOption(Team.Option.COLLISION_RULE, Team.OptionStatus.NEVER); + + if (team.hasPlayer(controller) == false) { + team.addPlayer(controller); + } + + controller.addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY, 99999, 0)); + } + } + } +} + +class Events implements Listener { + Main main; + Events(Main main) { + this.main = main; + } + + @EventHandler + void onAsyncPlayerChat(AsyncPlayerChatEvent event) { + Player player = event.getPlayer(); + + if (main.controllerFor.containsKey(player.getUniqueId())) { + event.setCancelled(true); + } + + if (main.targetFor.containsKey(player.getUniqueId())) { + Player target = main.targetFor.get(player.getUniqueId()); + target.chat(event.getMessage()); + event.setCancelled(true); + } + } + + @EventHandler + void onEntityDamage(EntityDamageEvent event) { + Entity player = event.getEntity(); + + if (main.targetFor.containsKey(player.getUniqueId())) { + event.setCancelled(true); + } + } + + /*@EventHandler + void onPlayerAnimation(PlayerAnimationEvent event) { + Player controller = event.getPlayer(); + Player target = main.targetFor.get(controller.getUniqueId()); + + if (target != null) { + event.setCancelled(true); + } + }*/ + + @EventHandler + void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) { + Player player = event.getPlayer(); + + if (main.controllerFor.containsKey(player.getUniqueId())) { + event.setCancelled(true); + } + } + + @EventHandler + void onPlayerDropItem(PlayerDropItemEvent event) { + Player player = event.getPlayer(); + + if (main.controllerFor.containsKey(player.getUniqueId())) { + event.setCancelled(true); + } + } + + @EventHandler + void onPlayerInteract(PlayerInteractEvent event) { + Player player = event.getPlayer(); + + if (main.controllerFor.containsKey(player.getUniqueId())) { + event.setCancelled(true); + } + } + + @EventHandler + void onPlayerMove(PlayerMoveEvent event) { + Player player = event.getPlayer(); + + if (main.controllerFor.containsKey(player.getUniqueId())) { + event.setCancelled(true); + } + } + + @EventHandler + void onPlayerQuit(PlayerQuitEvent event) { + Player player = event.getPlayer(); + + for (Player otherPlayer: Bukkit.getOnlinePlayers()) { + /* Target disconnects */ + if (main.controllerFor.get(player.getUniqueId()).equals(otherPlayer)) { + main.targetFor.remove(otherPlayer.getUniqueId()); + main.controllerFor.remove(player.getUniqueId()); + + final Player controller = otherPlayer; + + Bukkit.getScheduler().scheduleSyncDelayedTask(main, new Runnable() { + public void run() { + for (Player allPlayers: Bukkit.getOnlinePlayers()) { + allPlayers.showPlayer(controller); + } + + Scoreboard scoreboard = Bukkit.getScoreboardManager().getMainScoreboard(); + Team team = scoreboard.getTeam("iControlU_List"); + if (team != null && team.hasPlayer(controller) == true) { + team.removePlayer(controller); + } + + controller.removePotionEffect(PotionEffectType.INVISIBILITY); + controller.sendMessage("You are now visible"); + } + }, 200L); + + otherPlayer.sendMessage("The player you were controlling has disconnected. You are invisible for 10 seconds."); + } + + /* Controller disconnects */ + if (main.targetFor.get(player.getUniqueId()).equals(otherPlayer)) { + main.targetFor.remove(player.getUniqueId()); + main.controllerFor.remove(otherPlayer.getUniqueId()); + } + } + } + + @EventHandler + void onPlayerRespawn(PlayerRespawnEvent event) { + Player player = event.getPlayer(); + + if (main.controllerFor.containsKey(player.getUniqueId())) { + Player controller = main.controllerFor.get(player.getUniqueId()); + controller.teleport(player); + } + } +} diff --git a/src/main/java/pw/kaboom/icontrolu/Main.java b/src/main/java/pw/kaboom/icontrolu/Main.java new file mode 100644 index 0000000..2ed7245 --- /dev/null +++ b/src/main/java/pw/kaboom/icontrolu/Main.java @@ -0,0 +1,53 @@ +package pw.kaboom.icontrolu; + +import java.util.HashMap; +import java.util.UUID; + +import org.bukkit.Bukkit; + +import org.bukkit.entity.Player; + +import org.bukkit.potion.PotionEffectType; + +import org.bukkit.plugin.java.JavaPlugin; + +import org.bukkit.scoreboard.Scoreboard; +import org.bukkit.scoreboard.Team; + +public class Main extends JavaPlugin { + static HashMap controllerFor = new HashMap(); + static HashMap targetFor = new HashMap(); + + public void onEnable() { + Scoreboard scoreboard = Bukkit.getScoreboardManager().getMainScoreboard(); + Team team = scoreboard.getTeam("iControlU_List"); + if (team != null) { + team.unregister(); + } + + this.getCommand("icu").setExecutor(new CommandIcu(this)); + + new Tick(this).runTaskTimer(this, 0, 1); + this.getServer().getPluginManager().registerEvents(new Events(this), this); + } + + public void onDisable() { + for (Player controller: Bukkit.getOnlinePlayers()) { + Player target = Main.targetFor.get(controller.getUniqueId()); + if (target != null) { + for (Player player: Bukkit.getOnlinePlayers()) { + player.showPlayer(controller); + } + + Scoreboard scoreboard = Bukkit.getScoreboardManager().getMainScoreboard(); + Team team = scoreboard.getTeam("iControlU_List"); + if (team != null) { + team.unregister(); + } + + controller.removePotionEffect(PotionEffectType.INVISIBILITY); + controller.sendMessage("You are no longer controlling \"" + target.getName() + "\" due to server reload"); + } + } + } +} diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml new file mode 100644 index 0000000..8185718 --- /dev/null +++ b/src/main/resources/plugin.yml @@ -0,0 +1,9 @@ +name: iControlU +main: pw.kaboom.icontrolu.Main +description: Plugin that allows players to control other players. +version: master + +commands: + icu: + description: Control another player's movements, inventory and chat + permission: icu.command