diff options
| author | LMBishop <13875753+LMBishop@users.noreply.github.com> | 2021-06-21 01:02:06 +0100 |
|---|---|---|
| committer | LMBishop <13875753+LMBishop@users.noreply.github.com> | 2021-06-21 01:02:06 +0100 |
| commit | a835e7b48765f3b3fe1bc1c35adff0e867181e91 (patch) | |
| tree | ec6b3c0a83aaf0a5639a2adc58c3943458a3c63e /bungee/src/main/java/com/leonardobishop | |
| parent | af7e1e435f577bbf9742bb526ac00a71a21c219c (diff) | |
Start BungeeCord synchronisation with plugin messaging channelfix/sync
- See #180
Diffstat (limited to 'bungee/src/main/java/com/leonardobishop')
4 files changed, 183 insertions, 0 deletions
diff --git a/bungee/src/main/java/com/leonardobishop/quests/bungee/BungeeQuestsPlugin.java b/bungee/src/main/java/com/leonardobishop/quests/bungee/BungeeQuestsPlugin.java new file mode 100644 index 00000000..b6769f2c --- /dev/null +++ b/bungee/src/main/java/com/leonardobishop/quests/bungee/BungeeQuestsPlugin.java @@ -0,0 +1,26 @@ +package com.leonardobishop.quests.bungee; + +import com.leonardobishop.quests.bungee.listener.PluginMessageListener; +import com.leonardobishop.quests.bungee.lock.DataLockManager; +import com.leonardobishop.quests.common.enums.PluginMessagingChannels; +import net.md_5.bungee.api.plugin.Plugin; + +public class BungeeQuestsPlugin extends Plugin { + + private DataLockManager dataLockManager; + + @Override + public void onEnable() { + this.dataLockManager = new DataLockManager(); + + //TODO: https://github.com/LMBishop/Quests/issues/180 + +// super.getProxy().registerChannel(PluginMessagingChannels.QUESTS_LOCKS_CHANNEL); +// super.getProxy().getPluginManager().registerListener(this, new PluginMessageListener(this)); + } + + public DataLockManager getDataLockManager() { + return dataLockManager; + } + +} diff --git a/bungee/src/main/java/com/leonardobishop/quests/bungee/listener/PluginMessageListener.java b/bungee/src/main/java/com/leonardobishop/quests/bungee/listener/PluginMessageListener.java new file mode 100644 index 00000000..e54d094c --- /dev/null +++ b/bungee/src/main/java/com/leonardobishop/quests/bungee/listener/PluginMessageListener.java @@ -0,0 +1,69 @@ +package com.leonardobishop.quests.bungee.listener; + +import com.leonardobishop.quests.bungee.BungeeQuestsPlugin; +import com.leonardobishop.quests.common.enums.PluginMessagingChannels; +import net.md_5.bungee.api.config.ServerInfo; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.connection.Server; +import net.md_5.bungee.api.event.PluginMessageEvent; +import net.md_5.bungee.api.plugin.Listener; +import net.md_5.bungee.event.EventHandler; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.UUID; + +public class PluginMessageListener implements Listener { + + private final BungeeQuestsPlugin plugin; + + public PluginMessageListener(BungeeQuestsPlugin plugin) { + this.plugin = plugin; + } + + @EventHandler + public void onPluginMessage(PluginMessageEvent e) { + if (!e.getTag().equals(PluginMessagingChannels.QUESTS_LOCKS_CHANNEL)) { + return; + } + e.setCancelled(true); + if (!(e.getSender() instanceof Server) || !(e.getReceiver() instanceof ProxiedPlayer)) { + return; + } + Server sender = (Server) e.getSender(); + + ByteArrayInputStream stream = new ByteArrayInputStream(e.getData()); + DataInputStream in = new DataInputStream(stream); + try { + String request = in.readUTF(); + UUID uuid = UUID.fromString(in.readUTF()); + + if (request.equals("acquireLock")) { + plugin.getDataLockManager().acquireLock(sender.getInfo().getName(), uuid, + () -> sendMessage(sender.getInfo().getName(), "lockAcquired", uuid)); + } + } catch (Exception ex) { + plugin.getLogger().warning("Could not parse plugin message:"); + ex.printStackTrace(); + } + } + + public void sendMessage(String server, String request, UUID who) { + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + DataOutputStream out = new DataOutputStream(stream); + try { + out.writeUTF(request); + out.writeUTF(who.toString()); + } catch (IOException ex) { + plugin.getLogger().warning("Could not write plugin message:"); + ex.printStackTrace(); + } + + ServerInfo serverInfo = plugin.getProxy().getServerInfo(server); + if (serverInfo != null) serverInfo.sendData(PluginMessagingChannels.QUESTS_LOCKS_CHANNEL, stream.toByteArray()); + } + +} diff --git a/bungee/src/main/java/com/leonardobishop/quests/bungee/lock/DataLockManager.java b/bungee/src/main/java/com/leonardobishop/quests/bungee/lock/DataLockManager.java new file mode 100644 index 00000000..ed80fd94 --- /dev/null +++ b/bungee/src/main/java/com/leonardobishop/quests/bungee/lock/DataLockManager.java @@ -0,0 +1,67 @@ +package com.leonardobishop.quests.bungee.lock; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; + +//TODO https://github.com/LMBishop/Quests/issues/180 +public class DataLockManager { + + private final Map<UUID, String> locks = new HashMap<>(); + private final Map<UUID, LinkedList<QueuedServer>> queue = new HashMap<>(); + + public synchronized boolean hasLock(String server, UUID who) { + String lockedServer = locks.get(who); + if (lockedServer == null) { + return false; + } else { + return lockedServer.equals(server); + } + } + + public synchronized void acquireLock(String server, UUID who, Runnable callback) { + String lockedServer = locks.get(who); + if (lockedServer == null) { + locks.put(who, server); + callback.run(); + } else if (lockedServer.equals(server)) { + callback.run(); + } + CompletableFuture<Void> future = new CompletableFuture<>(); + QueuedServer queuedServer = new QueuedServer(callback, server); + queue.compute(who, (uuid, list) -> { + if (list == null) { + LinkedList<QueuedServer> newList = new LinkedList<>(); + newList.add(queuedServer); + return newList; + } else { + list.add(queuedServer); + } + return list; + }); + } + + public synchronized void releaseLock(String server, UUID who) { + String lockedServer = locks.get(who); + if (lockedServer == null || lockedServer.equals(server)) { + LinkedList<QueuedServer> queuedServers = queue.get(who); + QueuedServer nextServer = queuedServers.poll(); + if (nextServer != null) { + locks.put(who, nextServer.getServer()); + nextServer.getCallback().run(); + } else { + locks.remove(who); + } + } else { + LinkedList<QueuedServer> queuedServers = queue.get(who); + QueuedServer queuedServer = null; + for (QueuedServer qs : queuedServers) { + if (qs.getServer().equals(server)) queuedServer = qs; + } + if (queuedServer != null) queuedServers.remove(queuedServer); + } + } + +} diff --git a/bungee/src/main/java/com/leonardobishop/quests/bungee/lock/QueuedServer.java b/bungee/src/main/java/com/leonardobishop/quests/bungee/lock/QueuedServer.java new file mode 100644 index 00000000..90a68987 --- /dev/null +++ b/bungee/src/main/java/com/leonardobishop/quests/bungee/lock/QueuedServer.java @@ -0,0 +1,21 @@ +package com.leonardobishop.quests.bungee.lock; + +public class QueuedServer { + + private Runnable callback; + private String server; + + public QueuedServer(Runnable callback, String server) { + this.callback = callback; + this.server = server; + } + + public Runnable getCallback() { + return callback; + } + + public String getServer() { + return server; + } + +} |
