]> git.lizzy.rs Git - BoundingBoxOutlineReloaded.git/commitdiff
Add proper server support that works
authorIrtimaled <irtimaled@gmail.com>
Sat, 9 Mar 2019 06:37:31 +0000 (22:37 -0800)
committerIrtimaled <irtimaled@gmail.com>
Sun, 10 Mar 2019 01:43:25 +0000 (17:43 -0800)
19 files changed:
build.gradle
src/main/java/com/irtimaled/bbor/Main.java [new file with mode: 0644]
src/main/java/com/irtimaled/bbor/client/ClientProxy.java
src/main/java/com/irtimaled/bbor/client/ClientRenderer.java
src/main/java/com/irtimaled/bbor/common/CommonProxy.java
src/main/java/com/irtimaled/bbor/common/EventBus.java
src/main/java/com/irtimaled/bbor/common/chunkProcessors/OverworldChunkProcessor.java
src/main/java/com/irtimaled/bbor/common/events/PlayerChangedDimension.java [deleted file]
src/main/java/com/irtimaled/bbor/common/messages/AddBoundingBox.java
src/main/java/com/irtimaled/bbor/common/messages/BoundingBoxDeserializer.java
src/main/java/com/irtimaled/bbor/common/messages/BoundingBoxSerializer.java
src/main/java/com/irtimaled/bbor/common/messages/RemoveBoundingBox.java
src/main/java/com/irtimaled/bbor/install/Installer.java [new file with mode: 0644]
src/main/java/com/irtimaled/bbor/install/Main.java [deleted file]
src/main/java/com/irtimaled/bbor/mixin/entity/player/MixinEntityPlayerMP.java [deleted file]
src/main/java/com/irtimaled/bbor/mixin/server/management/MixinPlayerList.java
src/main/java/com/irtimaled/bbor/server/ServerRunner.java [new file with mode: 0644]
src/main/java/com/irtimaled/bbor/server/ThrowableConsumer.java [new file with mode: 0644]
src/main/resources/mixins.bbor.json

index d07f1b6ce8f7fa4412d6a9b7e9fca0cbe2d539e8..6edcb3dd157588b7093d440549e6e6cf49511f8d 100644 (file)
@@ -43,10 +43,10 @@ minecraft {
     makeObfSourceJar = false
 
     replace "@VERSION@", project.version
-    replaceIn "com/irtimaled/bbor/install/Main.java"
+    replaceIn "com/irtimaled/bbor/Main.java"
 
     replace "@MC_VERSION@", project.mcVersion
-    replaceIn "com/irtimaled/bbor/install/Main.java"
+    replaceIn "com/irtimaled/bbor/Main.java"
 }
 
 mixin {
@@ -78,7 +78,7 @@ processResources {
 jar {
     finalizedBy reobfJar
     manifest.attributes(
-            'Main-Class': 'com.irtimaled.bbor.install.Main'
+            'Main-Class': 'com.irtimaled.bbor.Main'
     )
  
     classifier = 'vanilla'
diff --git a/src/main/java/com/irtimaled/bbor/Main.java b/src/main/java/com/irtimaled/bbor/Main.java
new file mode 100644 (file)
index 0000000..66294b1
--- /dev/null
@@ -0,0 +1,18 @@
+package com.irtimaled.bbor;
+
+import com.irtimaled.bbor.install.Installer;
+import com.irtimaled.bbor.server.ServerRunner;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+public class Main {
+    public static void main(String... args) throws IOException {
+        if (args.length > 0 && args[0].equals("--server")) {
+            ServerRunner.run("@MC_VERSION@", Arrays.asList(args).subList(1, args.length));
+        } else {
+            Installer.install("@VERSION@", "@MC_VERSION@");
+
+        }
+    }
+}
\ No newline at end of file
index 70d95be661a40fae7d0a44d1f8c465e22cf8e6fa..165493a48a818ee5808aa0897e7af3d3848957e8 100644 (file)
@@ -88,38 +88,8 @@ public class ClientProxy extends CommonProxy {
     @Override
     protected void setWorldData(long seed, int spawnX, int spawnZ) {
         super.setWorldData(seed, spawnX, spawnZ);
-        addSpawnChunkBoundingBoxes(spawnX, spawnZ);
+        renderer.setWorldData(seed, spawnX, spawnZ);
     }
 
-    private void addSpawnChunkBoundingBoxes(int spawnX, int spawnZ) {
-        BoundingBox worldSpawnBoundingBox = getWorldSpawnBoundingBox(spawnX, spawnZ);
-        BoundingBox spawnChunksBoundingBox = buildSpawnChunksBoundingBox(spawnX, spawnZ, 12, BoundingBoxType.SpawnChunks);
-        BoundingBox lazySpawnChunksBoundingBox = buildSpawnChunksBoundingBox(spawnX, spawnZ, 16, BoundingBoxType.LazySpawnChunks);
 
-        runOnCache(DimensionType.OVERWORLD, cache -> {
-            cache.addBoundingBox(worldSpawnBoundingBox);
-            cache.addBoundingBox(spawnChunksBoundingBox);
-            cache.addBoundingBox(lazySpawnChunksBoundingBox);
-        });
-    }
-
-    private BoundingBox getWorldSpawnBoundingBox(int spawnX, int spawnZ) {
-        BlockPos minBlockPos = new BlockPos(spawnX - 10, 0, spawnZ - 10);
-        BlockPos maxBlockPos = new BlockPos(spawnX + 10, 0, spawnZ + 10);
-
-        return BoundingBoxWorldSpawn.from(minBlockPos, maxBlockPos, BoundingBoxType.WorldSpawn);
-    }
-
-    private BoundingBox buildSpawnChunksBoundingBox(int spawnX, int spawnZ, int size, BoundingBoxType type) {
-        double midOffset = CHUNK_SIZE * (size / 2.0);
-        double midX = Math.round((float) (spawnX / (double) CHUNK_SIZE)) * (double) CHUNK_SIZE;
-        double midZ = Math.round((float) (spawnZ / (double) CHUNK_SIZE)) * (double) CHUNK_SIZE;
-        BlockPos minBlockPos = new BlockPos(midX - midOffset, 0, midZ - midOffset);
-        if (spawnX / (double) CHUNK_SIZE % 0.5D == 0.0D && spawnZ / (double) CHUNK_SIZE % 0.5D == 0.0D) {
-            midX += (double) CHUNK_SIZE;
-            midZ += (double) CHUNK_SIZE;
-        }
-        BlockPos maxBlockPos = new BlockPos(midX + midOffset, 0, midZ + midOffset);
-        return BoundingBoxWorldSpawn.from(minBlockPos, maxBlockPos, type);
-    }
 }
index af0d8792e32bcf671e3a8155982f130a16efc408..7dc48f5e3bd270039985c74f5df5c79a6310fd8c 100644 (file)
@@ -2,23 +2,25 @@ package com.irtimaled.bbor.client;
 
 import com.irtimaled.bbor.client.renderers.*;
 import com.irtimaled.bbor.common.BoundingBoxCache;
+import com.irtimaled.bbor.common.BoundingBoxType;
 import com.irtimaled.bbor.common.models.*;
 import com.irtimaled.bbor.config.ConfigManager;
 import net.minecraft.client.Minecraft;
 import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.ChunkPos;
 import net.minecraft.util.math.MathHelper;
 import net.minecraft.world.dimension.DimensionType;
 import org.lwjgl.opengl.GL11;
 
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
 
 import static com.irtimaled.bbor.client.Constants.CHUNK_SIZE;
 
 public class ClientRenderer {
     private final GetCache getCache;
     private static final Map<Class<? extends BoundingBox>, Renderer> boundingBoxRendererMap = new HashMap<>();
+    private long seed;
+    private Set<BoundingBox> spawnChunkBoundingBoxes = new HashSet<>();
 
     ClientRenderer(GetCache getCache) {
         this.getCache = getCache;
@@ -42,9 +44,12 @@ public class ClientRenderer {
                 minBlockPos.getZ() <= maxZ;
     }
 
+    private boolean isWithinRenderDistance(BoundingBox boundingBox) {
+        return isWithinRenderDistance(boundingBox.getMinBlockPos(), boundingBox.getMaxBlockPos());
+    }
+
     public void render(DimensionType dimensionType, Boolean outerBoxesOnly) {
-        BoundingBoxCache cache = getCache.apply(dimensionType);
-        if (cache == null) return;
+        Map<BoundingBox, Set<BoundingBox>> boundingBoxes = getBoundingBoxes(dimensionType);
 
         GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
         GL11.glLineWidth(2.0f);
@@ -54,17 +59,17 @@ public class ClientRenderer {
         if (ConfigManager.alwaysVisible.get()) {
             GL11.glClear(GL11.GL_DEPTH_BUFFER_BIT);
         }
-        for (Map.Entry<BoundingBox, Set<BoundingBox>> entry : cache.getBoundingBoxes().entrySet()) {
+        for (Map.Entry<BoundingBox, Set<BoundingBox>> entry : boundingBoxes.entrySet()) {
             BoundingBox key = entry.getKey();
-            if (!key.shouldRender() || !isWithinRenderDistance(key.getMinBlockPos(), key.getMaxBlockPos())) continue;
+            if (!key.shouldRender()) continue;
 
             Renderer renderer = boundingBoxRendererMap.get(key.getClass());
             if (renderer == null) continue;
 
             if (!outerBoxesOnly) {
-                Set<BoundingBox> boundingBoxes = entry.getValue();
-                if (boundingBoxes != null) {
-                    boundingBoxes.forEach(renderer::render);
+                Set<BoundingBox> children = entry.getValue();
+                if (children != null) {
+                    children.forEach(renderer::render);
                     continue;
                 }
             }
@@ -75,4 +80,89 @@ public class ClientRenderer {
         GL11.glEnable(GL11.GL_CULL_FACE);
         GL11.glEnable(GL11.GL_TEXTURE_2D);
     }
+
+    private Map<BoundingBox, Set<BoundingBox>> getBoundingBoxes(DimensionType dimensionType) {
+        Map<BoundingBox, Set<BoundingBox>> boundingBoxes = new HashMap<>();
+        if (dimensionType == DimensionType.OVERWORLD) {
+            if (BoundingBoxType.SlimeChunks.shouldRender()) {
+                addSlimeChunks(boundingBoxes);
+            }
+
+            for (BoundingBox boundingBox : spawnChunkBoundingBoxes) {
+                if (boundingBox.shouldRender() && isWithinRenderDistance(boundingBox)) {
+                    boundingBoxes.put(boundingBox, null);
+                }
+            }
+        }
+
+        BoundingBoxCache cache = getCache.apply(dimensionType);
+        if (cache != null) {
+            for (Map.Entry<BoundingBox, Set<BoundingBox>> entry : cache.getBoundingBoxes().entrySet()) {
+                BoundingBox key = entry.getKey();
+                if (key.shouldRender() && isWithinRenderDistance(key)) {
+                    boundingBoxes.put(key, entry.getValue());
+                }
+            }
+        }
+        return boundingBoxes;
+    }
+
+    private void addSlimeChunks(Map<BoundingBox, Set<BoundingBox>> boundingBoxes) {
+        Minecraft minecraft = Minecraft.getInstance();
+        int renderDistanceChunks = minecraft.gameSettings.renderDistanceChunks;
+        int playerChunkX = MathHelper.floor(PlayerData.getX() / 16.0D);
+        int playerChunkZ = MathHelper.floor(PlayerData.getZ() / 16.0D);
+        for (int chunkX = playerChunkX - renderDistanceChunks; chunkX <= playerChunkX + renderDistanceChunks; ++chunkX) {
+            for (int chunkZ = playerChunkZ - renderDistanceChunks; chunkZ <= playerChunkZ + renderDistanceChunks; ++chunkZ) {
+                if (isSlimeChunk(chunkX, chunkZ)) {
+                    ChunkPos chunk = new ChunkPos(chunkX, chunkZ);
+                    BlockPos minBlockPos = new BlockPos(chunk.getXStart(), 1, chunk.getZStart());
+                    BlockPos maxBlockPos = new BlockPos(chunk.getXEnd(), 38, chunk.getZEnd());
+                    boundingBoxes.put(BoundingBoxSlimeChunk.from(minBlockPos, maxBlockPos), null);
+                }
+            }
+        }
+    }
+
+    private boolean isSlimeChunk(int chunkX, int chunkZ) {
+        Random r = new Random(seed +
+                (long) (chunkX * chunkX * 4987142) +
+                (long) (chunkX * 5947611) +
+                (long) (chunkZ * chunkZ) * 4392871L +
+                (long) (chunkZ * 389711) ^ 987234911L);
+        return r.nextInt(10) == 0;
+    }
+
+    void setWorldData(long seed, int spawnX, int spawnZ) {
+        this.seed = seed;
+        spawnChunkBoundingBoxes = getSpawnChunkBoundingBoxes(spawnX, spawnZ);
+    }
+
+    private Set<BoundingBox> getSpawnChunkBoundingBoxes(int spawnX, int spawnZ) {
+        Set<BoundingBox> boundingBoxes = new HashSet<>();
+        boundingBoxes.add(getWorldSpawnBoundingBox(spawnX, spawnZ));
+        boundingBoxes.add(buildSpawnChunksBoundingBox(spawnX, spawnZ, 12, BoundingBoxType.SpawnChunks));
+        boundingBoxes.add(buildSpawnChunksBoundingBox(spawnX, spawnZ, 16, BoundingBoxType.LazySpawnChunks));
+        return boundingBoxes;
+    }
+
+    private BoundingBox getWorldSpawnBoundingBox(int spawnX, int spawnZ) {
+        BlockPos minBlockPos = new BlockPos(spawnX - 10, 0, spawnZ - 10);
+        BlockPos maxBlockPos = new BlockPos(spawnX + 10, 0, spawnZ + 10);
+
+        return BoundingBoxWorldSpawn.from(minBlockPos, maxBlockPos, BoundingBoxType.WorldSpawn);
+    }
+
+    private BoundingBox buildSpawnChunksBoundingBox(int spawnX, int spawnZ, int size, BoundingBoxType type) {
+        double midOffset = CHUNK_SIZE * (size / 2.0);
+        double midX = Math.round((float) (spawnX / (double) CHUNK_SIZE)) * (double) CHUNK_SIZE;
+        double midZ = Math.round((float) (spawnZ / (double) CHUNK_SIZE)) * (double) CHUNK_SIZE;
+        BlockPos minBlockPos = new BlockPos(midX - midOffset, 0, midZ - midOffset);
+        if (spawnX / (double) CHUNK_SIZE % 0.5D == 0.0D && spawnZ / (double) CHUNK_SIZE % 0.5D == 0.0D) {
+            midX += (double) CHUNK_SIZE;
+            midZ += (double) CHUNK_SIZE;
+        }
+        BlockPos maxBlockPos = new BlockPos(midX + midOffset, 0, midZ + midOffset);
+        return BoundingBoxWorldSpawn.from(minBlockPos, maxBlockPos, type);
+    }
 }
index e2de4405e21a6b2fcc8f6f41525a0bae64283f68..88d44c41126d140d89b7c1e6c35750716c156cc2 100644 (file)
@@ -14,6 +14,7 @@ import com.irtimaled.bbor.common.models.BoundingBoxMobSpawner;
 import com.irtimaled.bbor.common.models.BoundingBoxVillage;
 import com.irtimaled.bbor.common.models.WorldData;
 import com.irtimaled.bbor.config.ConfigManager;
+import io.netty.channel.local.LocalAddress;
 import net.minecraft.entity.player.EntityPlayerMP;
 import net.minecraft.network.play.server.SPacketCustomPayload;
 import net.minecraft.util.math.BlockPos;
@@ -32,7 +33,7 @@ import java.util.concurrent.ConcurrentHashMap;
 import java.util.function.Consumer;
 
 public class CommonProxy {
-    private Map<EntityPlayerMP, DimensionType> playerDimensions = new ConcurrentHashMap<>();
+    private Set<EntityPlayerMP> players = new HashSet<>();
     private Map<EntityPlayerMP, Set<BoundingBox>> playerBoundingBoxesCache = new HashMap<>();
     private Map<Integer, BoundingBoxVillage> villageCache = new HashMap<>();
     private Map<DimensionType, ChunkProcessor> chunkProcessors = new HashMap<>();
@@ -43,7 +44,6 @@ public class CommonProxy {
         EventBus.subscribe(WorldLoaded.class, e -> worldLoaded(e.getWorld()));
         EventBus.subscribe(ChunkLoaded.class, e -> chunkLoaded(e.getChunk()));
         EventBus.subscribe(MobSpawnerBroken.class, e -> mobSpawnerBroken(e.getDimensionType(), e.getPos()));
-        EventBus.subscribe(PlayerChangedDimension.class, e -> playerChangedDimension(e.getPlayer()));
         EventBus.subscribe(PlayerLoggedIn.class, e -> playerLoggedIn(e.getPlayer()));
         EventBus.subscribe(PlayerLoggedOut.class, e -> playerLoggedOut(e.getPlayer()));
         EventBus.subscribe(PlayerSubscribed.class, e -> sendBoundingBoxes(e.getPlayer()));
@@ -65,7 +65,7 @@ public class CommonProxy {
             ChunkProcessor chunkProcessor = null;
             if (dimensionType == DimensionType.OVERWORLD) {
                 setWorldData(world.getSeed(), world.getWorldInfo().getSpawnX(), world.getWorldInfo().getSpawnZ());
-                chunkProcessor = new OverworldChunkProcessor(boundingBoxCache, world.getSeed());
+                chunkProcessor = new OverworldChunkProcessor(boundingBoxCache);
             }
             if (dimensionType == DimensionType.NETHER) {
                 chunkProcessor = new NetherChunkProcessor(boundingBoxCache);
@@ -86,26 +86,22 @@ public class CommonProxy {
         }
     }
 
-    private void playerChangedDimension(EntityPlayerMP player) {
-        if (playerDimensions.containsKey(player)) {
-            sendBoundingBoxes(player);
-        }
-    }
-
     private void playerLoggedIn(EntityPlayerMP player) {
+        if (player.connection.netManager.getRemoteAddress() instanceof LocalAddress) return;
         player.connection.sendPacket(InitializeClient.getPayload(worldData));
     }
 
     private void playerLoggedOut(EntityPlayerMP player) {
-        playerDimensions.remove(player);
+        players.remove(player);
         playerBoundingBoxesCache.remove(player);
     }
 
     private void sendRemoveBoundingBox(DimensionType dimensionType, BoundingBox boundingBox) {
         SPacketCustomPayload payload = RemoveBoundingBox.getPayload(dimensionType, boundingBox);
-        for (EntityPlayerMP player : playerDimensions.keySet()) {
+        if (payload == null) return;
+
+        for (EntityPlayerMP player : players) {
             if (DimensionType.getById(player.dimension) == dimensionType) {
-                Logger.info("remove 1 entry from %s (%s)", player.getScoreboardName(), dimensionType);
                 player.connection.sendPacket(payload);
 
                 if (playerBoundingBoxesCache.containsKey(player)) {
@@ -117,7 +113,7 @@ public class CommonProxy {
 
     private void sendBoundingBoxes(EntityPlayerMP player) {
         DimensionType dimensionType = DimensionType.getById(player.dimension);
-        playerDimensions.put(player, dimensionType);
+        players.add(player);
         sendToPlayer(player, getCache(dimensionType));
     }
 
@@ -127,13 +123,12 @@ public class CommonProxy {
         Map<BoundingBox, Set<BoundingBox>> cacheSubset = getBoundingBoxMap(player, boundingBoxCache.getBoundingBoxes());
 
         DimensionType dimensionType = DimensionType.getById(player.dimension);
-        if (cacheSubset.keySet().size() > 0) {
-            Logger.info("send %d entries to %s (%s)", cacheSubset.keySet().size(), player.getScoreboardName(), dimensionType);
-        }
 
         for (BoundingBox key : cacheSubset.keySet()) {
             Set<BoundingBox> boundingBoxes = cacheSubset.get(key);
-            player.connection.sendPacket(AddBoundingBox.getPayload(dimensionType, key, boundingBoxes));
+            SPacketCustomPayload payload = AddBoundingBox.getPayload(dimensionType, key, boundingBoxes);
+            if (payload != null)
+                player.connection.sendPacket(payload);
 
             if (!playerBoundingBoxesCache.containsKey(player)) {
                 playerBoundingBoxesCache.put(player, new HashSet<>());
@@ -166,8 +161,8 @@ public class CommonProxy {
     }
 
     private void tick() {
-        for (EntityPlayerMP player : playerDimensions.keySet()) {
-            DimensionType dimensionType = playerDimensions.get(player);
+        for (EntityPlayerMP player : players) {
+            DimensionType dimensionType = DimensionType.getById(player.dimension);
             sendToPlayer(player, getCache(dimensionType));
         }
     }
@@ -196,8 +191,7 @@ public class CommonProxy {
         return dimensionCache.get(dimensionType);
     }
 
-    protected BoundingBoxCache getOrCreateCache(DimensionType dimensionType)
-    {
+    protected BoundingBoxCache getOrCreateCache(DimensionType dimensionType) {
         return dimensionCache.computeIfAbsent(dimensionType, dt -> new BoundingBoxCache());
     }
 
index b5d20c60d1809b93ccaf8d9c7fe9fe4dd33dba9c..bc41db1224289aa6b83113573d0d91bdd2060721 100644 (file)
@@ -8,6 +8,8 @@ public class EventBus {
     private static Map<Class<?>, Consumer<?>> handlers = new HashMap<>();
 
     public static <evt> void publish(evt event) {
+        if (event == null) return;
+
         Class clazz = event.getClass();
         Consumer<?> handler = handlers.get(clazz);
         if (handler == null) return;
index 468e8dd6aae2d7b6915b8db181e67678b64f9c44..819a362f94c727246dd71403c89e9b54e6518759 100644 (file)
@@ -2,19 +2,10 @@ package com.irtimaled.bbor.common.chunkProcessors;
 
 import com.irtimaled.bbor.common.BoundingBoxCache;
 import com.irtimaled.bbor.common.BoundingBoxType;
-import com.irtimaled.bbor.common.models.BoundingBoxSlimeChunk;
-import net.minecraft.util.math.BlockPos;
-import net.minecraft.util.math.ChunkPos;
-import net.minecraft.world.chunk.Chunk;
-
-import java.util.Random;
 
 public class OverworldChunkProcessor extends ChunkProcessor {
-    private final long seed;
-
-    public OverworldChunkProcessor(BoundingBoxCache boundingBoxCache, long seed) {
+    public OverworldChunkProcessor(BoundingBoxCache boundingBoxCache) {
         super(boundingBoxCache);
-        this.seed = seed;
         supportedStructures.add(BoundingBoxType.DesertTemple);
         supportedStructures.add(BoundingBoxType.JungleTemple);
         supportedStructures.add(BoundingBoxType.WitchHut);
@@ -29,25 +20,4 @@ public class OverworldChunkProcessor extends ChunkProcessor {
         supportedStructures.add(BoundingBoxType.PillagerOutpost);
     }
 
-    private boolean isSlimeChunk(int chunkX, int chunkZ) {
-        Random r = new Random(seed +
-                (long) (chunkX * chunkX * 4987142) +
-                (long) (chunkX * 5947611) +
-                (long) (chunkZ * chunkZ) * 4392871L +
-                (long) (chunkZ * 389711) ^ 987234911L);
-        return r.nextInt(10) == 0;
-    }
-
-    private void addSlimeChunk(ChunkPos chunk) {
-        if(!isSlimeChunk(chunk.x, chunk.z)) return;
-        BlockPos minBlockPos = new BlockPos(chunk.getXStart(), 1, chunk.getZStart());
-        BlockPos maxBlockPos = new BlockPos(chunk.getXEnd(), 38, chunk.getZEnd());
-        boundingBoxCache.addBoundingBox(BoundingBoxSlimeChunk.from(minBlockPos, maxBlockPos));
-    }
-
-    @Override
-    public void process(Chunk chunk) {
-        super.process(chunk);
-        addSlimeChunk(chunk.getPos());
-    }
 }
diff --git a/src/main/java/com/irtimaled/bbor/common/events/PlayerChangedDimension.java b/src/main/java/com/irtimaled/bbor/common/events/PlayerChangedDimension.java
deleted file mode 100644 (file)
index 7ba767f..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.irtimaled.bbor.common.events;
-
-import net.minecraft.entity.player.EntityPlayerMP;
-
-public class PlayerChangedDimension {
-    private final EntityPlayerMP player;
-
-    public PlayerChangedDimension(EntityPlayerMP player) {
-        this.player = player;
-    }
-
-    public EntityPlayerMP getPlayer() {
-        return player;
-    }
-}
index 4501d2f483a36b477a6e74583da6e606b3aeae17..447d125a4b1f11793670aad356f739ea47b4c39d 100644 (file)
@@ -15,6 +15,8 @@ public class AddBoundingBox {
     public static final ResourceLocation NAME = new ResourceLocation("bbor:add_bounding_box");
 
     public static SPacketCustomPayload getPayload(DimensionType dimensionType, BoundingBox key, Set<BoundingBox> boundingBoxes) {
+        if(!BoundingBoxSerializer.canSerialize(key)) return null;
+
         PacketBuffer buf = new PacketBuffer(Unpooled.buffer());
         buf.writeVarInt(dimensionType.getId());
         BoundingBoxSerializer.serialize(key, buf);
@@ -29,6 +31,8 @@ public class AddBoundingBox {
     public static AddBoundingBoxReceived getEvent(PacketBuffer buf) {
         DimensionType dimensionType = DimensionType.getById(buf.readVarInt());
         BoundingBox key = BoundingBoxDeserializer.deserialize(buf);
+        if (key == null) return null;
+
         Set<BoundingBox> boundingBoxes = new HashSet<>();
         while (buf.isReadable()) {
             BoundingBox boundingBox = BoundingBoxDeserializer.deserialize(buf);
index 2766663ff591090bbe4aec8b0fee54a60853e00e..10c7b0e9c7893fc4e32b40548ad6b9f0e84a468a 100644 (file)
@@ -14,6 +14,8 @@ import java.util.Set;
 
 class BoundingBoxDeserializer {
     static BoundingBox deserialize(PacketBuffer buf) {
+        if (!buf.isReadable(2)) return null;
+
         char type = buf.readChar();
         switch (type) {
             case 'V':
@@ -28,7 +30,7 @@ class BoundingBoxDeserializer {
 
     private static BoundingBox deserializeStructure(PacketBuffer buf) {
         BoundingBoxType type = BoundingBoxType.getByNameHash(buf.readInt());
-        if(type == null) return null;
+        if (type == null) return null;
         BlockPos minBlockPos = deserializeBlockPos(buf);
         BlockPos maxBlockPos = deserializeBlockPos(buf);
         return BoundingBoxStructure.from(minBlockPos, maxBlockPos, type);
index c94b77139129243c0302c98f6ca6a474054ceae9..c4b2b7f0b7f01373b8f4fb98394cd58158c3e5d4 100644 (file)
@@ -8,18 +8,28 @@ import net.minecraft.network.PacketBuffer;
 import net.minecraft.util.math.BlockPos;
 
 import java.awt.*;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.BiConsumer;
 
 class BoundingBoxSerializer {
+    private static final Map<Class, BiConsumer<BoundingBox, PacketBuffer>> serializers = new HashMap<>();
+
+    static {
+        serializers.put(BoundingBoxVillage.class, (bb, buf) -> serializeVillage((BoundingBoxVillage) bb, buf));
+        serializers.put(BoundingBoxStructure.class, (bb, buf) -> serializeStructure((BoundingBoxStructure) bb, buf));
+        serializers.put(BoundingBoxMobSpawner.class, (bb, buf) -> serializeMobSpawner((BoundingBoxMobSpawner) bb, buf));
+    }
+
+    static boolean canSerialize(BoundingBox key) {
+        return serializers.containsKey(key.getClass());
+    }
+
     static void serialize(BoundingBox boundingBox, PacketBuffer buf) {
-        if (boundingBox instanceof BoundingBoxVillage) {
-            serializeVillage((BoundingBoxVillage) boundingBox, buf);
-        }
-        if (boundingBox instanceof BoundingBoxStructure) {
-            serializeStructure((BoundingBoxStructure) boundingBox, buf);
-        }
-        if (boundingBox instanceof BoundingBoxMobSpawner) {
-            serializeMobSpawner((BoundingBoxMobSpawner) boundingBox, buf);
-        }
+        BiConsumer<BoundingBox, PacketBuffer> serializer = serializers.get(boundingBox.getClass());
+        if (serializer == null) return;
+
+        serializer.accept(boundingBox, buf);
     }
 
     private static void serializeVillage(BoundingBoxVillage boundingBox, PacketBuffer buf) {
index 1d002fe0455b602929024ddf7fd42af19e562993..605f53a46ced0a74a6410b89f2d0204814e17ad1 100644 (file)
@@ -12,6 +12,8 @@ public class RemoveBoundingBox {
     public static final ResourceLocation NAME = new ResourceLocation("bbor:remove_bounding_box");
 
     public static SPacketCustomPayload getPayload(DimensionType dimensionType, BoundingBox key) {
+        if(!BoundingBoxSerializer.canSerialize(key)) return null;
+
         PacketBuffer buf = new PacketBuffer(Unpooled.buffer());
         buf.writeVarInt(dimensionType.getId());
         BoundingBoxSerializer.serialize(key, buf);
@@ -22,6 +24,8 @@ public class RemoveBoundingBox {
     public static RemoveBoundingBoxReceived getEvent(PacketBuffer buf) {
         DimensionType dimensionType = DimensionType.getById(buf.readVarInt());
         BoundingBox key = BoundingBoxDeserializer.deserialize(buf);
+        if(key == null) return null;
+
         return new RemoveBoundingBoxReceived(dimensionType, key);
     }
 }
diff --git a/src/main/java/com/irtimaled/bbor/install/Installer.java b/src/main/java/com/irtimaled/bbor/install/Installer.java
new file mode 100644 (file)
index 0000000..59a8931
--- /dev/null
@@ -0,0 +1,101 @@
+package com.irtimaled.bbor.install;
+
+import javax.swing.*;
+import java.io.File;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+
+public class Installer {
+    public static void install(final String version, final String mcVersion) {
+        try {
+            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+        } catch (Throwable t) {
+            t.printStackTrace();
+        }
+
+        try {
+            String osName = getOsName();
+            File minecraftFolder = getMinecraftFolder(osName);
+            File versionFolder = new File(minecraftFolder, "versions/BBOR-" + version + "/");
+            versionFolder.mkdirs();
+
+            File versionJson = new File(versionFolder, "BBOR-" + version + ".json");
+            Files.copy(Installer.class.getResourceAsStream("/profile.json"), versionJson.toPath(), StandardCopyOption.REPLACE_EXISTING);
+
+            try {
+                File profilesJson = new File(minecraftFolder, "launcher_profiles.json");
+                if (profilesJson.exists()) { // TODO: use gson instead
+                    String identifier = "\"bbor-" + mcVersion + "\"";
+                    String contents = new String(Files.readAllBytes(profilesJson.toPath()));
+                    if (contents.contains(identifier)) {
+                        contents = contents.replaceAll(",\n *" + identifier + ": \\{[^}]*},", ",");
+                        contents = contents.replaceAll(",?\n *" + identifier + ": \\{[^}]*},?", "");
+                    }
+
+                    String date = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
+
+                    contents = contents.replace("\n  \"profiles\": {", "\n  \"profiles\": {\n" +
+                            "    " + identifier + ": {\n" +
+                            "      \"name\": \"Bounding Box Outline Reloaded\",\n" +
+                            "      \"type\": \"custom\",\n" +
+                            "      \"created\": \"" + date + "T00:00:00.000Z\",\n" +
+                            "      \"lastUsed\": \"2100-01-01T00:00:00.000Z\",\n" +
+                            "      \"lastVersionId\": \"BBOR-" + version + "\"\n" +
+                            "    },");
+
+                    Files.write(profilesJson.toPath(), contents.getBytes());
+                }
+            } catch (Throwable t) {
+                t.printStackTrace();
+            }
+
+            try {
+                String source = Installer.class.getProtectionDomain().getCodeSource().getLocation().getPath();
+                if (source.startsWith("/") && osName.contains("win")) {
+                    source = source.substring(1);
+                }
+                File mainJar = new File(minecraftFolder, "libraries/com/irtimaled/bbor/" + version + "/bbor-" + version + ".jar");
+                mainJar.getParentFile().mkdirs();
+                Files.copy(Paths.get(source), mainJar.toPath(), StandardCopyOption.REPLACE_EXISTING);
+            } catch (Throwable t) {
+                t.printStackTrace();
+            }
+
+            JOptionPane.showMessageDialog(null,
+                    "Bounding Box Outline Reloaded " + version + " has been successfully installed!\n" +
+                            "\n" +
+                            "Re-open the Minecraft Launcher to see it in the dropdown.",
+                    "Bounding Box Outline Reloaded Installer", JOptionPane.INFORMATION_MESSAGE);
+        } catch (Throwable t) {
+            StringWriter w = new StringWriter();
+            t.printStackTrace(new PrintWriter(w));
+            JOptionPane.showMessageDialog(null,
+                    "An error occured while installing Bounding Box Outline Reloaded, please report this to the issue\n" +
+                            "tracker (https://github.com/irtimaled/BoundingBoxOutlineReloaded/issues):\n" +
+                            "\n" +
+                            w.toString().replace("\t", "    "), "Bounding Box Outline Reloaded Installer", JOptionPane.ERROR_MESSAGE);
+        }
+    }
+
+    private static File getMinecraftFolder(String osName) {
+        File minecraftFolder;
+        if (osName.contains("win")) {
+            minecraftFolder = new File(System.getenv("APPDATA") + "/.minecraft");
+        } else if (osName.contains("mac")) {
+            minecraftFolder = new File(System.getProperty("user.home") + "/Library/Application Support/minecraft");
+        } else {
+            minecraftFolder = new File(System.getProperty("user.home") + "/.minecraft");
+        }
+        return minecraftFolder;
+    }
+
+    private static String getOsName() {
+        return System.getProperty("os.name").toLowerCase(Locale.ROOT);
+    }
+}
diff --git a/src/main/java/com/irtimaled/bbor/install/Main.java b/src/main/java/com/irtimaled/bbor/install/Main.java
deleted file mode 100644 (file)
index 64a1d91..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-package com.irtimaled.bbor.install;
-
-import javax.swing.*;
-import java.io.File;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.nio.file.StandardCopyOption;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.Locale;
-
-public class Main {
-    public static void main(String... args) throws Throwable {
-        try {
-            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
-        } catch (Throwable t) {
-            t.printStackTrace();
-        }
-
-        try {
-            String osName = getOsName();
-            File minecraftFolder = getMinecraftFolder(osName);
-            File versionFolder = new File(minecraftFolder, "versions/BBOR-@VERSION@/");
-            versionFolder.mkdirs();
-
-            File versionJson = new File(versionFolder, "BBOR-@VERSION@.json");
-            Files.copy(Main.class.getResourceAsStream("/profile.json"), versionJson.toPath(), StandardCopyOption.REPLACE_EXISTING);
-
-            try {
-                File profilesJson = new File(minecraftFolder, "launcher_profiles.json");
-                if (profilesJson.exists()) { // TODO: use gson instead
-                    String identifier = "\"bbor-@MC_VERSION@\"";
-                    String contents = new String(Files.readAllBytes(profilesJson.toPath()));
-                    if (contents.contains(identifier)) {
-                        contents = contents.replaceAll(",\n *" + identifier + ": \\{[^}]*},", ",");
-                        contents = contents.replaceAll(",?\n *" + identifier + ": \\{[^}]*},?", "");
-                    }
-
-                    String date = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
-
-                    contents = contents.replace("\n  \"profiles\": {", "\n  \"profiles\": {\n" +
-                            "    " + identifier + ": {\n" +
-                            "      \"name\": \"Bounding Box Outline Reloaded\",\n" +
-                            "      \"type\": \"custom\",\n" +
-                            "      \"created\": \"" + date + "T00:00:00.000Z\",\n" +
-                            "      \"lastUsed\": \"2100-01-01T00:00:00.000Z\",\n" +
-                            "      \"lastVersionId\": \"BBOR-@VERSION@\"\n" +
-                            "    },");
-
-                    Files.write(profilesJson.toPath(), contents.getBytes());
-                }
-            } catch (Throwable t) {
-                t.printStackTrace();
-            }
-
-            // Copy rift jar to libraries
-            try {
-                String source = Main.class.getProtectionDomain().getCodeSource().getLocation().getPath();
-                if (source.startsWith("/") && osName.contains("win")) {
-                    source = source.substring(1);
-                }
-                File riftJar = new File(minecraftFolder, "libraries/com/irtimaled/bbor/@VERSION@/bbor-@VERSION@.jar");
-                riftJar.getParentFile().mkdirs();
-                Files.copy(Paths.get(source), riftJar.toPath(), StandardCopyOption.REPLACE_EXISTING);
-            } catch (Throwable t) {
-                t.printStackTrace();
-            }
-
-            JOptionPane.showMessageDialog(null,
-                    "Bounding Box Outline Reloaded @VERSION@ has been successfully installed!\n" +
-                            "\n" +
-                            "Re-open the Minecraft Launcher to see it in the dropdown.",
-                    "Bounding Box Outline Reloaded Installer", JOptionPane.INFORMATION_MESSAGE);
-        } catch (Throwable t) {
-            StringWriter w = new StringWriter();
-            t.printStackTrace(new PrintWriter(w));
-            JOptionPane.showMessageDialog(null,
-                    "An error occured while installing Bounding Box Outline Reloaded, please report this to the issue\n" +
-                            "tracker (https://github.com/irtimaled/BoundingBoxOutlineReloaded/issues):\n" +
-                            "\n" +
-                            w.toString().replace("\t", "    "), "Bounding Box Outline Reloaded Installer", JOptionPane.ERROR_MESSAGE);
-        }
-    }
-
-    private static File getMinecraftFolder(String osName) {
-        File minecraftFolder;
-        if (osName.contains("win")) {
-            minecraftFolder = new File(System.getenv("APPDATA") + "/.minecraft");
-        } else if (osName.contains("mac")) {
-            minecraftFolder = new File(System.getProperty("user.home") + "/Library/Application Support/minecraft");
-        } else {
-            minecraftFolder = new File(System.getProperty("user.home") + "/.minecraft");
-        }
-        return minecraftFolder;
-    }
-
-    private static String getOsName() {
-        return System.getProperty("os.name").toLowerCase(Locale.ROOT);
-    }
-}
diff --git a/src/main/java/com/irtimaled/bbor/mixin/entity/player/MixinEntityPlayerMP.java b/src/main/java/com/irtimaled/bbor/mixin/entity/player/MixinEntityPlayerMP.java
deleted file mode 100644 (file)
index abe6ff2..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.irtimaled.bbor.mixin.entity.player;
-
-import com.irtimaled.bbor.common.EventBus;
-import com.irtimaled.bbor.common.events.PlayerChangedDimension;
-import net.minecraft.entity.Entity;
-import net.minecraft.entity.player.EntityPlayerMP;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Inject;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
-
-@Mixin(EntityPlayerMP.class)
-public class MixinEntityPlayerMP {
-    @Inject(method = "changeDimension", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/management/PlayerList;changePlayerDimension(Lnet/minecraft/entity/player/EntityPlayerMP;I)V"))
-    private void changeDimension(int dimensionId, CallbackInfoReturnable<Entity> cir) {
-        EventBus.publish(new PlayerChangedDimension((EntityPlayerMP) (Object) this));
-    }
-}
index 26f7f0c010ed92c480a421bba5a3df2cfdff05a4..86cfb4e896ec70e9904d37ee4fc19a80c25ed77a 100644 (file)
@@ -14,15 +14,11 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
 public class MixinPlayerList {
     @Inject(method = "playerLoggedIn", at = @At("RETURN"))
     private void playerLoggedIn(EntityPlayerMP player, CallbackInfo ci) {
-        if (player.world.isRemote) {
-            EventBus.publish(new PlayerLoggedIn(player));
-        }
+        EventBus.publish(new PlayerLoggedIn(player));
     }
 
     @Inject(method = "playerLoggedOut", at = @At("HEAD"))
     private void playerLoggedOut(EntityPlayerMP player, CallbackInfo ci) {
-        if (player.world.isRemote) {
-            EventBus.publish(new PlayerLoggedOut(player));
-        }
+        EventBus.publish(new PlayerLoggedOut(player));
     }
 }
diff --git a/src/main/java/com/irtimaled/bbor/server/ServerRunner.java b/src/main/java/com/irtimaled/bbor/server/ServerRunner.java
new file mode 100644 (file)
index 0000000..960e16b
--- /dev/null
@@ -0,0 +1,89 @@
+package com.irtimaled.bbor.server;
+
+import net.minecraft.launchwrapper.Launch;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.reflect.Method;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.nio.channels.Channels;
+import java.util.*;
+import java.util.function.Consumer;
+
+public class ServerRunner {
+    private static final Map<String, String> VANILLA_SERVER_JARS = new HashMap<>();
+
+    private static final String[] LIBRARIES = {
+            "https://github.com/irtimaled/Mixin/releases/download/org/spongepowered/mixin/0.7.11-SNAPSHOT/mixin-0.7.11-SNAPSHOT.jar",
+            "https://repo1.maven.org/maven2/org/ow2/asm/asm/6.2/asm-6.2.jar",
+            "https://repo1.maven.org/maven2/org/ow2/asm/asm-commons/6.2/asm-commons-6.2.jar",
+            "https://repo1.maven.org/maven2/org/ow2/asm/asm-tree/6.2/asm-tree-6.2.jar",
+            "https://libraries.minecraft.net/net/minecraft/launchwrapper/1.12/launchwrapper-1.12.jar"
+    };
+
+    //private static final MethodHandle addURLHandle;
+
+    private static final ThrowableConsumer<URL> addURL;
+
+    static {
+        VANILLA_SERVER_JARS.put("1.13.2", "https://launcher.mojang.com/v1/objects/3737db93722a9e39eeada7c27e7aca28b144ffa7/server.jar");
+        VANILLA_SERVER_JARS.put("1.13.1", "https://launcher.mojang.com/v1/objects/fe123682e9cb30031eae351764f653500b7396c9/server.jar");
+        VANILLA_SERVER_JARS.put("1.13", "https://launcher.mojang.com/v1/objects/d0caafb8438ebd206f99930cfaecfa6c9a13dca0/server.jar");
+
+        try {
+            Method method = URLClassLoader.class
+                    .getDeclaredMethod("addURL", URL.class);
+            method.setAccessible(true);
+           // addURLHandle = MethodHandles.lookup().unreflect(method);
+            addURL = url -> method.invoke(ClassLoader.getSystemClassLoader(), url);
+        } catch (ReflectiveOperationException e) {
+            throw new AssertionError(e);
+        }
+    }
+
+    private static void addURLToClasspath(File file) throws MalformedURLException {
+        //try {
+            addURL.accept(file.toURI().toURL());
+            //addURLHandle.invoke(ClassLoader.getSystemClassLoader(), file.toURI().toURL());
+        //} catch (Throwable t) {
+       //     throw t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t);
+       // }
+    }
+
+    public static void run(String version, List<String> args) throws IOException {
+        String serverJarUrl = VANILLA_SERVER_JARS.get(version);
+
+        addURLToClasspath(getOrDownload(new File("."), serverJarUrl));
+        for (String url : LIBRARIES) {
+            addURLToClasspath(getOrDownload(new File("libs"), url));
+        }
+
+        args = new ArrayList<>(args);
+        args.add("--tweakClass");
+        args.add("com.irtimaled.bbor.launch.ServerTweaker");
+
+        System.out.println("Launching server...");
+        Launch.main(args.toArray(new String[0]));
+    }
+
+    private static File getOrDownload(File directory, String url) throws IOException {
+        String fileName = url.substring(url.lastIndexOf('/') + 1);
+        File target = new File(directory, fileName);
+        if (target.isFile()) {
+            return target;
+        }
+        target.getParentFile().mkdirs();
+
+        System.out.println("Downloading library: " + url);
+        new FileOutputStream(target).getChannel()
+                .transferFrom(Channels.newChannel(new URL(url).openStream()), 0, Long.MAX_VALUE);
+
+        return target;
+    }
+
+}
diff --git a/src/main/java/com/irtimaled/bbor/server/ThrowableConsumer.java b/src/main/java/com/irtimaled/bbor/server/ThrowableConsumer.java
new file mode 100644 (file)
index 0000000..25e148f
--- /dev/null
@@ -0,0 +1,16 @@
+package com.irtimaled.bbor.server;
+
+import java.util.function.Consumer;
+
+public interface ThrowableConsumer<T> extends Consumer<T> {
+    @Override
+    default void accept(final T elem) {
+        try {
+            acceptThrows(elem);
+        } catch (final Throwable t) {
+            throw t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t);
+        }
+    }
+
+    void acceptThrows(T elem) throws Throwable;
+}
\ No newline at end of file
index 3e1f43f272844f261efcac268ab55e1e2d9b1eec..0a4f8d45043c2501a60ba3b0c4d91ac239608c8d 100644 (file)
@@ -8,8 +8,6 @@
   "mixins": [
     "world.chunk.MixinChunk",
     "network.play.client.MixinCPacketCustomPayload",
-    "network.play.server.MixinSPacketCustomPayload",
-    "entity.player.MixinEntityPlayerMP",
     "village.MixinVillage",
     "server.management.MixinPlayerList",
     "server.management.MixinPlayerInteractionManager",
@@ -19,6 +17,7 @@
     "client.MixinMinecraft",
     "client.gui.MixinGuiOptions",
     "client.renderer.MixinEntityRenderer",
+    "network.play.server.MixinSPacketCustomPayload",
     "client.multiplayer.MixinWorldClient",
     "client.network.MixinNetHandlerLoginClient",
     "client.settings.MixinKeyBinding",