diff --git a/src/de/steamwar/bungeecore/BungeeCore.java b/src/de/steamwar/bungeecore/BungeeCore.java index ec819830..54da2a20 100644 --- a/src/de/steamwar/bungeecore/BungeeCore.java +++ b/src/de/steamwar/bungeecore/BungeeCore.java @@ -24,6 +24,7 @@ import de.steamwar.bungeecore.bot.config.SteamwarDiscordBotConfig; import de.steamwar.bungeecore.commands.*; import de.steamwar.bungeecore.listeners.*; import de.steamwar.bungeecore.listeners.mods.*; +import de.steamwar.bungeecore.listeners.mods.lunar.Lunar; import de.steamwar.bungeecore.listeners.ping.PingListener; import de.steamwar.bungeecore.network.BungeeNetworkHandler; import de.steamwar.bungeecore.network.NetworkReceiver; @@ -122,6 +123,7 @@ public class BungeeCore extends Plugin { new Fabric(); new SubserverProtocolFixer(); new PingListener(); + new Lunar(); local = new Node.LocalNode(); if(MAIN_SERVER) { diff --git a/src/de/steamwar/bungeecore/listeners/mods/lunar/ByteBufWrapper.java b/src/de/steamwar/bungeecore/listeners/mods/lunar/ByteBufWrapper.java new file mode 100644 index 00000000..343e2a25 --- /dev/null +++ b/src/de/steamwar/bungeecore/listeners/mods/lunar/ByteBufWrapper.java @@ -0,0 +1,74 @@ +package de.steamwar.bungeecore.listeners.mods.lunar; + +import io.netty.buffer.ByteBuf; + +import java.nio.charset.StandardCharsets; +import java.util.UUID; + +public class ByteBufWrapper { + + private final ByteBuf buf; + + public ByteBufWrapper(ByteBuf buf) { + this.buf = buf; + } + + public void writeVarInt(int b) { + while ((b & -128) != 0) { + this.buf.writeByte(b & 127 | 128); + b >>>= 7; + } + + this.buf.writeByte(b); + } + + public int readVarInt() { + int i = 0; + int chunk = 0; + byte b; + + do { + b = this.buf.readByte(); + i |= (b & 127) << chunk++ * 7; + + if (chunk > 5) { + throw new RuntimeException("VarInt too big"); + } + } while ((b & 128) == 128); + + return i; + } + + public void writeString(String s) { + byte[] arr = s.getBytes(StandardCharsets.UTF_8); + + this.writeVarInt(arr.length); + this.buf.writeBytes(arr); + } + + public String readString() { + int len = readVarInt(); + + byte[] buffer = new byte[len]; + buf.readBytes(buffer); + + return new String(buffer, StandardCharsets.UTF_8); + } + + public void writeUUID(UUID uuid) { + this.buf.writeLong(uuid.getMostSignificantBits()); + this.buf.writeLong(uuid.getLeastSignificantBits()); + } + + public UUID readUUID() { + long mostSigBits = this.buf.readLong(); + long leastSigBits = this.buf.readLong(); + + return new UUID(mostSigBits, leastSigBits); + } + + public ByteBuf buf() { + return buf; + } + +} diff --git a/src/de/steamwar/bungeecore/listeners/mods/lunar/LCPacket.java b/src/de/steamwar/bungeecore/listeners/mods/lunar/LCPacket.java new file mode 100644 index 00000000..ab16b164 --- /dev/null +++ b/src/de/steamwar/bungeecore/listeners/mods/lunar/LCPacket.java @@ -0,0 +1,44 @@ +package de.steamwar.bungeecore.listeners.mods.lunar; + +import de.steamwar.bungeecore.listeners.mods.lunar.packets.LCPacketModSettings; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +public abstract class LCPacket { + + private static final Map, Integer> classToId = new HashMap<>(); + + static { + addPacket(31, LCPacketModSettings.class); + } + + public static byte[] getPacketData(LCPacket packet) { + return getPacketBuf(packet).array(); + } + + public abstract void write(ByteBufWrapper buf) throws IOException; + + public static ByteBuf getPacketBuf(LCPacket packet) { + ByteBufWrapper wrappedBuffer = new ByteBufWrapper(Unpooled.buffer()); + wrappedBuffer.writeVarInt(classToId.get(packet.getClass())); + + try { + packet.write(wrappedBuffer); + } catch (IOException ex) { + ex.printStackTrace(); + } + + return wrappedBuffer.buf(); + } + + private static void addPacket(int id, Class clazz) { + if (classToId.containsKey(clazz)) { + throw new IllegalArgumentException("Duplicate packet class (" + clazz.getSimpleName() + "), already used by " + classToId.get(clazz)); + } + classToId.put(clazz, id); + } +} diff --git a/src/de/steamwar/bungeecore/listeners/mods/lunar/Lunar.java b/src/de/steamwar/bungeecore/listeners/mods/lunar/Lunar.java new file mode 100644 index 00000000..a51a26e9 --- /dev/null +++ b/src/de/steamwar/bungeecore/listeners/mods/lunar/Lunar.java @@ -0,0 +1,33 @@ +package de.steamwar.bungeecore.listeners.mods.lunar; + +import de.steamwar.bungeecore.BungeeCore; +import de.steamwar.bungeecore.listeners.BasicListener; +import de.steamwar.bungeecore.listeners.mods.lunar.packets.LCPacketModSettings; +import de.steamwar.sql.SteamwarUser; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.event.PluginMessageEvent; +import net.md_5.bungee.api.event.PostLoginEvent; +import net.md_5.bungee.event.EventHandler; + +import java.util.HashMap; + +public class Lunar extends BasicListener { + + public static final String MESSAGE_CHANNEL = "lunarclient:pm"; + + @EventHandler + public void onPostLogin(PostLoginEvent e) { + BungeeCore.get().getProxy().registerChannel(MESSAGE_CHANNEL); + + ProxiedPlayer player = e.getPlayer(); + SteamwarUser user = SteamwarUser.get(player.getUniqueId()); + + LCPacketModSettings modSettingsPacket = new LCPacketModSettings(); + + ModSettings modSettings = new ModSettings(); + + modSettings.addModSetting("freelook", new ModSettings.ModSetting(false, new HashMap<>())); + + player.getServer().sendData(MESSAGE_CHANNEL, LCPacket.getPacketData(modSettingsPacket)); + } +} diff --git a/src/de/steamwar/bungeecore/listeners/mods/lunar/ModSettings.java b/src/de/steamwar/bungeecore/listeners/mods/lunar/ModSettings.java new file mode 100644 index 00000000..cddbe77b --- /dev/null +++ b/src/de/steamwar/bungeecore/listeners/mods/lunar/ModSettings.java @@ -0,0 +1,71 @@ +package de.steamwar.bungeecore.listeners.mods.lunar; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +public class ModSettings { + + public static final Gson GSON = new GsonBuilder().registerTypeHierarchyAdapter(ModSettings.class, new ModSettingsAdapter()).create(); + + private Map modSettings = new HashMap<>(); + + public ModSettings addModSetting(String modId, ModSetting setting) { + modSettings.put(modId, setting); + return this; + } + + public ModSetting getModSetting(String modId) { + return this.modSettings.get(modId); + } + + public Map getModSettings() { + return modSettings; + } + + public static class ModSetting { + private boolean enabled; + private Map properties; + + public ModSetting() { } // for serialization + + public ModSetting(boolean enabled, Map properties) { + this.enabled = enabled; + this.properties = properties; + } + + public boolean isEnabled() { + return enabled; + } + + public Map getProperties() { + return properties; + } + + @Override + public String toString() { + return "ModSetting{" + + "enabled=" + enabled + + ", properties=" + properties + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ModSetting that = (ModSetting) o; + return enabled == that.enabled && + Objects.equals(properties, that.properties); + } + + @Override + public int hashCode() { + return Objects.hash(enabled, properties); + } + } + +} diff --git a/src/de/steamwar/bungeecore/listeners/mods/lunar/ModSettingsAdapter.java b/src/de/steamwar/bungeecore/listeners/mods/lunar/ModSettingsAdapter.java new file mode 100644 index 00000000..030ed05f --- /dev/null +++ b/src/de/steamwar/bungeecore/listeners/mods/lunar/ModSettingsAdapter.java @@ -0,0 +1,64 @@ +package de.steamwar.bungeecore.listeners.mods.lunar; + +import com.google.gson.*; + +import java.lang.reflect.Type; +import java.util.Map; + +public class ModSettingsAdapter implements JsonSerializer { + + @Override + public JsonElement serialize(ModSettings modSettings, Type type, JsonSerializationContext jsonSerializationContext) { + JsonObject object = new JsonObject(); + for (Map.Entry entry : modSettings.getModSettings().entrySet()) { + object.add(entry.getKey(), serializeModSetting(entry.getValue())); + } + return object; + } + + private JsonObject serializeModSetting(ModSettings.ModSetting setting) { + JsonObject object = new JsonObject(); + JsonObject properties = new JsonObject(); + object.addProperty("enabled", setting.isEnabled()); + for (Map.Entry entry : setting.getProperties().entrySet()) { + + JsonPrimitive primitive; + if (entry.getValue() instanceof Boolean) { + primitive = new JsonPrimitive((Boolean) entry.getValue()); + } else if (entry.getValue() instanceof String) { + primitive = new JsonPrimitive((String) entry.getValue()); + } else if (entry.getValue() instanceof Number) { + primitive = new JsonPrimitive((Number) entry.getValue()); + } else { + continue; + } + properties.add(entry.getKey(), primitive); + } + object.add("properties", properties); + return object; + } + + private ModSettings.ModSetting deserializeModSetting(JsonObject object) { + JsonObject propertiesObject = object.get("properties").getAsJsonObject(); + Map properties = new HashMap<>(); + for (Map.Entry entry : propertiesObject.entrySet()) { + if (!entry.getValue().isJsonPrimitive()) { + continue; + } + JsonPrimitive primitive = entry.getValue().getAsJsonPrimitive(); + Object toSet; + if (primitive.isString()) { + toSet = primitive.getAsString(); + } else if (primitive.isNumber()) { + toSet = primitive.getAsNumber(); + } else if (primitive.isBoolean()) { + toSet = primitive.getAsBoolean(); + } else { + continue; + } + properties.put(entry.getKey(), toSet); + } + return new ModSettings.ModSetting(object.get("enabled").getAsBoolean(), properties); + } + +} diff --git a/src/de/steamwar/bungeecore/listeners/mods/lunar/packets/LCPacketModSettings.java b/src/de/steamwar/bungeecore/listeners/mods/lunar/packets/LCPacketModSettings.java new file mode 100644 index 00000000..7b140b80 --- /dev/null +++ b/src/de/steamwar/bungeecore/listeners/mods/lunar/packets/LCPacketModSettings.java @@ -0,0 +1,26 @@ +package de.steamwar.bungeecore.listeners.mods.lunar.packets; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import de.steamwar.bungeecore.listeners.mods.lunar.ByteBufWrapper; +import de.steamwar.bungeecore.listeners.mods.lunar.LCPacket; +import de.steamwar.bungeecore.listeners.mods.lunar.ModSettings; + +import java.io.IOException; + +public final class LCPacketModSettings extends LCPacket { + + private ModSettings settings; + + public LCPacketModSettings() {} + + public LCPacketModSettings(ModSettings modSettings) { + this.settings = modSettings; + } + + + @Override + public void write(ByteBufWrapper buf) throws IOException { + buf.writeString(ModSettings.GSON.toJson(this.settings)); + } +}