diff --git a/spigot/src/main/java/com/turikhay/mc/mapmodcompanion/spigot/CompanionSpigot.java b/spigot/src/main/java/com/turikhay/mc/mapmodcompanion/spigot/CompanionSpigot.java index feb309f..d810300 100644 --- a/spigot/src/main/java/com/turikhay/mc/mapmodcompanion/spigot/CompanionSpigot.java +++ b/spigot/src/main/java/com/turikhay/mc/mapmodcompanion/spigot/CompanionSpigot.java @@ -1,23 +1,39 @@ package com.turikhay.mc.mapmodcompanion.spigot; +import org.bukkit.World; import org.bukkit.event.Listener; import org.bukkit.plugin.java.JavaPlugin; -import java.util.Arrays; -import java.util.List; +import java.util.*; public class CompanionSpigot extends JavaPlugin implements Listener { public static final boolean ENABLE_LOGGING = Boolean.parseBoolean( System.getProperty(CompanionSpigot.class.getPackage().getName() + ".debug", "false") ); + public static final boolean DISABLE_DEFAULT_WORLD_ID = Boolean.parseBoolean( + System.getProperty(CompanionSpigot.class.getPackage().getName() + ".defaultId", "false") + ); + List> handlers = Arrays.asList( new XaerosHandler(this), new WorldIdHandler(this) ); + DefaultWorld defaultWorld; + @Override public void onEnable() { + if (DISABLE_DEFAULT_WORLD_ID) { + getLogger().info("Plugin will not use default world ID for every world"); + defaultWorld = DefaultWorld.empty(); + } else { + defaultWorld = DefaultWorld.detectDefaultWorld(this); + } handlers.forEach(Handler::init); } + + Optional getDefaultWorld() { + return defaultWorld.optional(); + } } diff --git a/spigot/src/main/java/com/turikhay/mc/mapmodcompanion/spigot/DefaultWorld.java b/spigot/src/main/java/com/turikhay/mc/mapmodcompanion/spigot/DefaultWorld.java new file mode 100644 index 0000000..aac86c4 --- /dev/null +++ b/spigot/src/main/java/com/turikhay/mc/mapmodcompanion/spigot/DefaultWorld.java @@ -0,0 +1,67 @@ +package com.turikhay.mc.mapmodcompanion.spigot; + +import org.bukkit.World; + +import java.util.*; + +interface DefaultWorld { + Optional optional(); + + static Empty empty() { + return new Empty(); + } + + static DefaultWorld detectDefaultWorld(CompanionSpigot plugin) { + List worlds = plugin.getServer().getWorlds(); + if (worlds.isEmpty()) { + throw new RuntimeException("world list is empty"); + } + Set expectedEnv = new HashSet<>(Arrays.asList( + World.Environment.NORMAL, + World.Environment.NETHER, + World.Environment.THE_END + )); + for (World world : worlds) { + World.Environment env = world.getEnvironment(); + boolean isExpected = expectedEnv.remove(env); + if (!isExpected) { + // Non-default server configuration + plugin.getLogger().severe("Unexpected world: " + world); + plugin.getLogger().severe("For every world plugin will now send their unique IDs"); + return new Empty(); + } + } + World defaultWorld = worlds.get(0); + if (CompanionSpigot.ENABLE_LOGGING) { + plugin.getLogger().info("Selected default world: " + defaultWorld + " (" + defaultWorld.getUID() + ")"); + } + return new ByUUID(plugin, defaultWorld.getUID()); + } + + class ByUUID implements DefaultWorld { + private final CompanionSpigot plugin; + private final UUID uuid; + + public ByUUID(CompanionSpigot plugin, UUID uuid) { + this.plugin = plugin; + this.uuid = uuid; + } + + @Override + public Optional optional() { + World world = plugin.getServer().getWorld(uuid); + if (world == null) { + plugin.getLogger().warning("Couldn't find world " + uuid); + return Optional.empty(); + } + return Optional.of(world); + } + } + + class Empty implements DefaultWorld { + @Override + public Optional optional() { + return Optional.empty(); + } + } +} diff --git a/spigot/src/main/java/com/turikhay/mc/mapmodcompanion/spigot/Handler.java b/spigot/src/main/java/com/turikhay/mc/mapmodcompanion/spigot/Handler.java index 8baba35..3ad2c76 100644 --- a/spigot/src/main/java/com/turikhay/mc/mapmodcompanion/spigot/Handler.java +++ b/spigot/src/main/java/com/turikhay/mc/mapmodcompanion/spigot/Handler.java @@ -16,6 +16,8 @@ public abstract class Handler> implements Listener private final String channelName; protected final CompanionSpigot plugin; + private IdRef defaultId; + public Handler(String channelName, CompanionSpigot plugin) { this.channelName = channelName; this.plugin = plugin; @@ -24,6 +26,7 @@ public Handler(String channelName, CompanionSpigot plugin) { public void init() { plugin.getServer().getMessenger().registerOutgoingPluginChannel(plugin, channelName); plugin.getServer().getPluginManager().registerEvents(this, plugin); + defaultId = plugin.getDefaultWorld().map(world -> IdRef.of(getId(world))).orElse(null); } @EventHandler(priority = EventPriority.MONITOR) @@ -39,15 +42,20 @@ public void onWorldChanged(PlayerChangedWorldEvent event) { public void sendLevelId(Player player, EventSource source) { scheduleLevelIdPacket( () -> { - Id id = getId(player.getWorld()); - byte[] data = IdMessagePacket.bytesPacket(id); + IdRef idRef; + if (defaultId == null) { + idRef = IdRef.of(getId(player.getWorld())); + } else { + idRef = defaultId; + } if (CompanionSpigot.ENABLE_LOGGING) { plugin.getLogger().info(String.format(Locale.ROOT, "Sending world id to %s (channel: %s): %s. Data: %s", - player.getName(), channelName, id, Arrays.toString(data) + player.getName(), channelName, idRef.id, + Arrays.toString(idRef.data) )); } - player.sendPluginMessage(plugin, channelName, data); + player.sendPluginMessage(plugin, channelName, idRef.data); }, source ); @@ -61,4 +69,26 @@ public enum EventSource { WORLD_CHANGE, PLUGIN_MESSAGE } + + private static class IdRef> { + private final Id id; + private final byte[] data; + + private IdRef(Id id, byte[] data) { + this.id = id; + this.data = data; + } + + @Override + public String toString() { + return "DefaultId{" + + "id=" + id + + ", data=" + Arrays.toString(data) + + '}'; + } + + private static > IdRef of(Id id) { + return new IdRef<>(id, IdMessagePacket.bytesPacket(id)); + } + } }