diff --git a/pom.xml b/pom.xml
index 669c64f..a067c7c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -22,7 +22,7 @@
com.destroystokyo.paper
- paper-api
+ paper
1.16.1-R0.1-SNAPSHOT
provided
@@ -32,6 +32,24 @@
1.16-SNAPSHOT
provided
+
+ de.cubeside
+ globalconnectionbukkit
+ 0.0.1-SNAPSHOT
+ provided
+
+
+ de.fanta.challenges
+ Challenges
+ 1.16.1.2-DEV
+ provided
+
+
+ de.iani.cubeside
+ GlobalPort
+ 0.0.1-SNAPSHOT
+ provided
+
diff --git a/src/main/java/de/fanta/challengesjoinentities/ChallengesGlobalDataHelper.java b/src/main/java/de/fanta/challengesjoinentities/ChallengesGlobalDataHelper.java
new file mode 100644
index 0000000..341165a
--- /dev/null
+++ b/src/main/java/de/fanta/challengesjoinentities/ChallengesGlobalDataHelper.java
@@ -0,0 +1,59 @@
+package de.fanta.challengesjoinentities;
+
+import de.fanta.challengesjoinentities.ChallengesGlobalDataHelper.ChallengeMessageType;
+import de.iani.cubesideutils.bukkit.plugin.api.GlobalDataHelperBukkit;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+
+public class ChallengesGlobalDataHelper extends GlobalDataHelperBukkit {
+
+ public static final String CHANNEL = "ChallengesJoinEntities";
+
+ private final ChallengesJoinEntities plugin;
+
+ public ChallengesGlobalDataHelper(ChallengesJoinEntities plugin) {
+ super(ChallengeMessageType.class, CHANNEL, plugin);
+ this.plugin = plugin;
+ }
+
+ @Override
+ protected void handleMessage(ChallengeMessageType challengeMessageType, DataInputStream data) throws IOException {
+ String serverName = data.readUTF();
+ switch (challengeMessageType) {
+ case TIMER:
+ boolean running = data.readBoolean();
+ plugin.setTimerStatus(serverName, running);
+ break;
+
+ case SERVER_STATUS:
+ boolean online = data.readBoolean();
+ plugin.setServerStatus(serverName, online);
+ break;
+
+ case PLAYER_COUNT:
+ int count = data.readInt();
+ plugin.setPlayerCount(serverName, count);
+ break;
+
+ default:
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ public void sendTimerUpdate(boolean running) {
+ sendData(ChallengeMessageType.TIMER, getThisServerName(), running);
+ }
+
+ public void sendServerStatusUpdate(boolean online) {
+ sendData(ChallengeMessageType.SERVER_STATUS, getThisServerName(), online);
+ }
+
+ public void sendPlayerCountUpdate(int count) {
+ sendData(ChallengeMessageType.PLAYER_COUNT, getThisServerName(), count);
+ }
+
+ public enum ChallengeMessageType {
+ TIMER, SERVER_STATUS, PLAYER_COUNT
+ }
+}
diff --git a/src/main/java/de/fanta/challengesjoinentities/ChallengesJoinEntities.java b/src/main/java/de/fanta/challengesjoinentities/ChallengesJoinEntities.java
new file mode 100644
index 0000000..fe956ab
--- /dev/null
+++ b/src/main/java/de/fanta/challengesjoinentities/ChallengesJoinEntities.java
@@ -0,0 +1,125 @@
+package de.fanta.challengesjoinentities;
+
+import de.fanta.challengesjoinentities.commands.AddEntityCommand;
+import de.fanta.challengesjoinentities.commands.RemoveEntityCommand;
+import de.fanta.challengesjoinentities.listeners.ChallengesEventListener;
+import de.fanta.challengesjoinentities.listeners.EntityListener;
+import de.iani.cubesideutils.bukkit.commands.CommandRouter;
+import net.md_5.bungee.api.ChatColor;
+import org.bukkit.Bukkit;
+import org.bukkit.Location;
+import org.bukkit.craftbukkit.v1_16_R1.entity.CraftPiglin;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.EntityType;
+import org.bukkit.plugin.java.JavaPlugin;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+public class ChallengesJoinEntities extends JavaPlugin {
+
+ public static final String PREFIX = ChatColor.of("#455aad") + "[" + ChatColor.of("#1FFF00") + "Challenge" + ChatColor.of("#455aad") + "]";
+
+ private Config config;
+ private ChallengesGlobalDataHelper globalDataHelper;
+ private Map entities;
+ private Map entityPortLocations;
+
+ @Override
+ public void onEnable() {
+ this.globalDataHelper = new ChallengesGlobalDataHelper(this);
+ this.entities = new HashMap<>();
+ this.entityPortLocations = new HashMap<>();
+
+ if (Bukkit.getPluginManager().getPlugin("Challenges") != null) {
+ Bukkit.getPluginManager().registerEvents(new ChallengesEventListener(this), this);
+ }
+ Bukkit.getPluginManager().registerEvents(new EntityListener(this), this);
+
+ CommandRouter router = new CommandRouter(getCommand("challengepiglins"));
+ router.addCommandMapping(new AddEntityCommand(this), "spawn");
+ router.addCommandMapping(new RemoveEntityCommand(this), "remove");
+ }
+
+ public void spawnPiglin(Location location, String serverName, String gpLocationName) {
+ if (entities.containsKey(serverName)) {
+ despawnPiglin(entities.get(serverName), serverName);
+ }
+
+ CraftPiglin piglin = (CraftPiglin) location.getWorld().spawnEntity(location, EntityType.PIGLIN);
+ piglin.setAI(false);
+ piglin.setSilent(true);
+ piglin.getEquipment().clear();
+ piglin.setRemoveWhenFarAway(false);
+ piglin.setCustomNameVisible(true);
+
+ addPiglin(piglin.getUniqueId(), serverName, gpLocationName);
+ }
+
+ public void despawnPiglin(UUID piglinUUID, String serverName) {
+ Entity piglin = Bukkit.getEntity(piglinUUID);
+ if (piglin != null) {
+ piglin.remove();
+ removePiglin(serverName);
+ }
+ }
+
+ public void addPiglin(UUID piglinUUID, String serverName, String gpLocationName) {
+ this.entities.put(serverName, piglinUUID);
+ this.entityPortLocations.put(piglinUUID, gpLocationName);
+
+ this.config.savePiglin(piglinUUID, serverName, gpLocationName);
+ }
+
+ public void removePiglin(String serverName) {
+ this.entityPortLocations.remove(this.entities.get(serverName));
+ this.entities.remove(serverName);
+
+ this.config.removePiglin(serverName);
+ }
+
+ public void setTimerStatus(String serverName, boolean running) {
+ CraftPiglin piglin = getPiglinForServerName(serverName);
+ if (piglin != null) {
+ piglin.getHandle().u(!running);
+ }
+ }
+
+ public void setServerStatus(String serverName, boolean online) {
+ CraftPiglin piglin = getPiglinForServerName(serverName);
+ if (piglin != null) {
+ // TODO trading dingsdings + paper in hand
+ }
+ }
+
+ public void setPlayerCount(String serverName, int count) {
+ CraftPiglin piglin = getPiglinForServerName(serverName);
+ if (piglin != null) {
+ // TODO displayname etc
+ }
+ }
+
+ public CraftPiglin getPiglinForServerName(String serverName) {
+ UUID entityUUID = entities.get(serverName);
+ if (entityUUID != null) {
+ Entity piglin = Bukkit.getEntity(entityUUID);
+
+ if (piglin instanceof CraftPiglin) {
+ return (CraftPiglin) piglin;
+ }
+ }
+ return null;
+ }
+
+ // TODO bounce player back when too close to piglin
+
+
+ public Config getPluginConfig() {
+ return config;
+ }
+
+ public ChallengesGlobalDataHelper getGlobalDataHelper() {
+ return globalDataHelper;
+ }
+}
diff --git a/src/main/java/de/fanta/challengesjoinentities/ChatUtil.java b/src/main/java/de/fanta/challengesjoinentities/ChatUtil.java
new file mode 100644
index 0000000..6e100a0
--- /dev/null
+++ b/src/main/java/de/fanta/challengesjoinentities/ChatUtil.java
@@ -0,0 +1,29 @@
+package de.fanta.challengesjoinentities;
+
+import de.iani.cubesideutils.bukkit.ChatUtilBukkit;
+import net.md_5.bungee.api.ChatColor;
+import org.bukkit.command.CommandSender;
+
+public class ChatUtil {
+
+ private ChatUtil() {
+ // prevent instances
+ }
+
+ public static void sendMessage(CommandSender sender, String colors, Object message, Object... messageParts) {
+ ChatUtilBukkit.sendMessage(sender, ChallengesJoinEntities.PREFIX, colors, message, messageParts);
+ }
+
+ public static void sendNormalMessage(CommandSender sender, Object message, Object... messageParts) {
+ sendMessage(sender, ChatColor.of("#1FFF00").toString(), message, messageParts);
+ }
+
+ public static void sendWarningMessage(CommandSender sender, Object message, Object... messageParts) {
+ sendMessage(sender, ChatColor.of("#ffe100").toString(), message, messageParts);
+ }
+
+ public static void sendErrorMessage(CommandSender sender, Object message, Object... messageParts) {
+ sendMessage(sender, ChatColor.of("#a30202").toString(), message, messageParts);
+ }
+}
+
diff --git a/src/main/java/de/fanta/challengesjoinentities/Config.java b/src/main/java/de/fanta/challengesjoinentities/Config.java
new file mode 100644
index 0000000..ebf4a33
--- /dev/null
+++ b/src/main/java/de/fanta/challengesjoinentities/Config.java
@@ -0,0 +1,50 @@
+package de.fanta.challengesjoinentities;
+
+import org.bukkit.configuration.ConfigurationSection;
+import org.bukkit.configuration.file.FileConfiguration;
+
+import java.util.UUID;
+
+public class Config {
+
+ private ChallengesJoinEntities plugin;
+
+ public Config(ChallengesJoinEntities plugin) {
+ this.plugin = plugin;
+ plugin.saveDefaultConfig();
+ reloadConfig();
+ }
+
+ private void reloadConfig() {
+ plugin.reloadConfig();
+ FileConfiguration config = plugin.getConfig();
+
+ ConfigurationSection piglinsSection = config.getConfigurationSection("piglins");
+
+ for (String serverName : piglinsSection.getKeys(false)) {
+ ConfigurationSection piglin = piglinsSection.getConfigurationSection(serverName);
+ plugin.addPiglin(UUID.fromString(piglin.getString("uuid")), serverName, piglin.getString("gpLocation"));
+ }
+ }
+
+ public void savePiglin(UUID piglinUUID, String serverName, String gpLocation) {
+ FileConfiguration config = plugin.getConfig();
+ ConfigurationSection piglinsSection = config.getConfigurationSection("piglins");
+
+ ConfigurationSection piglin = piglinsSection.createSection(serverName);
+ piglin.set("uuid", piglinUUID.toString());
+ piglin.set("gpLocation", gpLocation);
+
+ plugin.saveConfig();
+ }
+
+ public void removePiglin(String serverName) {
+ FileConfiguration config = plugin.getConfig();
+ ConfigurationSection piglinsSection = config.getConfigurationSection("piglins");
+
+ piglinsSection.set(serverName, null);
+
+ plugin.saveConfig();
+ }
+}
+
diff --git a/src/main/java/de/fanta/challengesjoinentities/commands/AddEntityCommand.java b/src/main/java/de/fanta/challengesjoinentities/commands/AddEntityCommand.java
new file mode 100644
index 0000000..1c121a4
--- /dev/null
+++ b/src/main/java/de/fanta/challengesjoinentities/commands/AddEntityCommand.java
@@ -0,0 +1,74 @@
+package de.fanta.challengesjoinentities.commands;
+
+import de.cubeside.connection.GlobalServer;
+import de.fanta.challengesjoinentities.ChallengesJoinEntities;
+import de.fanta.challengesjoinentities.ChatUtil;
+import de.iani.cubesideutils.bukkit.commands.SubCommand;
+import de.iani.cubesideutils.commands.ArgsParser;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.stream.Collectors;
+
+public class AddEntityCommand extends SubCommand {
+
+ private final ChallengesJoinEntities plugin;
+
+ public AddEntityCommand(ChallengesJoinEntities plugin) {
+ this.plugin = plugin;
+ }
+
+ @Override
+ public boolean onCommand(CommandSender sender, Command command, String alias, String commandString, ArgsParser args) {
+ if (!(sender instanceof Player)) {
+ ChatUtil.sendErrorMessage(sender, "Du musst ein Spieler sein!");
+ return true;
+ }
+
+ if (!sender.hasPermission("challenges.spawn.teleporter")) {
+ ChatUtil.sendErrorMessage(sender, "Keine Berechtigung!");
+ return true;
+ }
+
+ if (!args.hasNext()) {
+ return false;
+ }
+ String serverName = args.getNext();
+
+ if (!args.hasNext()) {
+ return false;
+ }
+ String locationName = args.getNext();
+
+ if (plugin.getGlobalDataHelper().getServer(serverName) != null) {
+ plugin.spawnPiglin(((Player) sender).getLocation(), serverName, locationName);
+ ChatUtil.sendNormalMessage(sender, "Piglin hinzugefügt! *grunz*");
+ } else {
+ ChatUtil.sendErrorMessage(sender, "Server nicht gefunden!");
+ }
+ return true;
+ }
+
+ @Override
+ public Collection onTabComplete(CommandSender sender, Command command, String alias, ArgsParser args) {
+ args.next();
+ if (!args.hasNext()) {
+ return plugin.getGlobalDataHelper().getServers().stream().map(GlobalServer::getName).collect(Collectors.toList());
+ }
+
+ return Collections.emptyList();
+ }
+
+ @Override
+ public String getUsage() {
+ return " ";
+ }
+
+ @Override
+ public String getRequiredPermission() {
+ return "challenges.spawn.teleporter";
+ }
+}
diff --git a/src/main/java/de/fanta/challengesjoinentities/commands/RemoveEntityCommand.java b/src/main/java/de/fanta/challengesjoinentities/commands/RemoveEntityCommand.java
new file mode 100644
index 0000000..c8df3a1
--- /dev/null
+++ b/src/main/java/de/fanta/challengesjoinentities/commands/RemoveEntityCommand.java
@@ -0,0 +1,65 @@
+package de.fanta.challengesjoinentities.commands;
+
+import de.cubeside.connection.GlobalServer;
+import de.fanta.challengesjoinentities.ChallengesJoinEntities;
+import de.fanta.challengesjoinentities.ChatUtil;
+import de.iani.cubesideutils.bukkit.commands.SubCommand;
+import de.iani.cubesideutils.commands.ArgsParser;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandSender;
+import org.bukkit.craftbukkit.v1_16_R1.entity.CraftPiglin;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.stream.Collectors;
+
+public class RemoveEntityCommand extends SubCommand {
+
+ private final ChallengesJoinEntities plugin;
+
+ public RemoveEntityCommand(ChallengesJoinEntities plugin) {
+ this.plugin = plugin;
+ }
+
+ @Override
+ public boolean onCommand(CommandSender sender, Command command, String alias, String commandString, ArgsParser args) {
+ if (!sender.hasPermission("challenges.spawn.teleporter")) {
+ ChatUtil.sendErrorMessage(sender, "Keine Berechtigung!");
+ return true;
+ }
+
+ if (args.hasNext()) {
+ String serverName = args.getNext();
+
+ CraftPiglin piglin = plugin.getPiglinForServerName(serverName);
+ if (piglin != null) {
+ plugin.despawnPiglin(piglin.getUniqueId(), serverName);
+ ChatUtil.sendNormalMessage(sender, "Piglin entfernt.");
+ } else {
+ ChatUtil.sendErrorMessage(sender, "Kein Piglin für diesen Server gefunden!");
+ }
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public Collection onTabComplete(CommandSender sender, Command command, String alias, ArgsParser args) {
+ args.next();
+ if (!args.hasNext()) {
+ return plugin.getGlobalDataHelper().getServers().stream().map(GlobalServer::getName).collect(Collectors.toList());
+ }
+
+ return Collections.emptyList();
+ }
+
+ @Override
+ public String getUsage() {
+ return "";
+ }
+
+ @Override
+ public String getRequiredPermission() {
+ return "challenges.spawn.teleporter";
+ }
+}
diff --git a/src/main/java/de/fanta/challengesjoinentities/listeners/ChallengesEventListener.java b/src/main/java/de/fanta/challengesjoinentities/listeners/ChallengesEventListener.java
new file mode 100644
index 0000000..a573276
--- /dev/null
+++ b/src/main/java/de/fanta/challengesjoinentities/listeners/ChallengesEventListener.java
@@ -0,0 +1,32 @@
+package de.fanta.challengesjoinentities.listeners;
+
+import de.fanta.challenges.events.PlayerCountChangedEvent;
+import de.fanta.challenges.events.ServerStatusChangedEvent;
+import de.fanta.challenges.events.TimerChangedEvent;
+import de.fanta.challengesjoinentities.ChallengesJoinEntities;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+
+public class ChallengesEventListener implements Listener {
+
+ private final ChallengesJoinEntities plugin;
+
+ public ChallengesEventListener(ChallengesJoinEntities plugin) {
+ this.plugin = plugin;
+ }
+
+ @EventHandler
+ public void onTimerChanged(TimerChangedEvent event) {
+ plugin.getGlobalDataHelper().sendTimerUpdate(event.isRunning());
+ }
+
+ @EventHandler
+ public void onServerStatusChanged(ServerStatusChangedEvent event) {
+ plugin.getGlobalDataHelper().sendServerStatusUpdate(event.isOnline());
+ }
+
+ @EventHandler
+ public void onPlayerCountChanged(PlayerCountChangedEvent event) {
+ plugin.getGlobalDataHelper().sendPlayerCountUpdate(event.getCount());
+ }
+}
diff --git a/src/main/java/de/fanta/challengesjoinentities/listeners/EntityListener.java b/src/main/java/de/fanta/challengesjoinentities/listeners/EntityListener.java
new file mode 100644
index 0000000..1268905
--- /dev/null
+++ b/src/main/java/de/fanta/challengesjoinentities/listeners/EntityListener.java
@@ -0,0 +1,15 @@
+package de.fanta.challengesjoinentities.listeners;
+
+import de.fanta.challengesjoinentities.ChallengesJoinEntities;
+import org.bukkit.event.Listener;
+
+public class EntityListener implements Listener {
+
+ private ChallengesJoinEntities plugin;
+
+ public EntityListener(ChallengesJoinEntities plugin) {
+ this.plugin = plugin;
+ }
+
+
+}
diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml
new file mode 100644
index 0000000..5731b8b
--- /dev/null
+++ b/src/main/resources/config.yml
@@ -0,0 +1,4 @@
+piglins:
+ SERVERNAME:
+ uuid:
+ gpLocation:
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
new file mode 100644
index 0000000..093b16b
--- /dev/null
+++ b/src/main/resources/plugin.yml
@@ -0,0 +1,13 @@
+name: ${project.artifactId}
+main: de.fanta.challengesjoinentities.ChallengesJoinEntities
+version: ${project.version}
+authors: ${project.author}
+
+depend: [GlobalClient, CubesideUtils]
+softdepend: [Challenges]
+
+commands:
+ challengepiglins:
+ permission: challenges.spawn.teleporter
+ aliases: [piglin]
+ description: asdf
\ No newline at end of file