]> git.lizzy.rs Git - BoundingBoxOutlineReloaded.git/blobdiff - src/main/java/com/irtimaled/bbor/common/CommonProxy.java
Upgrade to 1.14.2
[BoundingBoxOutlineReloaded.git] / src / main / java / com / irtimaled / bbor / common / CommonProxy.java
index 0021d4323f90f31290124535e727c878b80d5d4a..b39613757230eceebc55cb616c8ef59baf9d9931 100644 (file)
 package com.irtimaled.bbor.common;
 
 import com.irtimaled.bbor.Logger;
-import com.irtimaled.bbor.config.ConfigManager;
-import net.minecraft.world.World;
-import net.minecraft.world.chunk.Chunk;
-import net.minecraft.world.chunk.IChunkProvider;
-import net.minecraft.world.dimension.DimensionType;
-import net.minecraft.world.gen.ChunkProviderServer;
+import com.irtimaled.bbor.common.events.*;
+import com.irtimaled.bbor.common.messages.AddBoundingBox;
+import com.irtimaled.bbor.common.messages.InitializeClient;
+import com.irtimaled.bbor.common.messages.PayloadBuilder;
+import com.irtimaled.bbor.common.models.AbstractBoundingBox;
+import com.irtimaled.bbor.common.models.ServerPlayer;
 
+import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 
 public class CommonProxy {
-    protected DimensionCache dimensionCache;
-    protected Set<VillageProcessor> villageProcessors = new HashSet<>();
-
-    private IVillageEventHandler eventHandler = null;
-
-    public void worldLoaded(World world) {
-        IChunkProvider chunkProvider = world.getChunkProvider();
-        if (chunkProvider instanceof ChunkProviderServer) {
-            dimensionCache.setWorldData(world.getSeed(), world.getWorldInfo().getSpawnX(), world.getWorldInfo().getSpawnZ());
-            DimensionType dimensionType = world.dimension.getType();
-            Logger.info("create world dimension: %s, %s (seed: %d)", dimensionType, world.getClass().toString(), world.getSeed());
-            DimensionProcessor boundingBoxCache = new DimensionProcessor(dimensionType);
-            dimensionCache.put(dimensionType, boundingBoxCache);
-            if (ConfigManager.drawVillages.getBoolean()) {
-                villageProcessors.add(new VillageProcessor(world, dimensionType, eventHandler, boundingBoxCache));
-            }
+    private final Map<Integer, ServerPlayer> players = new ConcurrentHashMap<>();
+    private final Map<Integer, Set<AbstractBoundingBox>> playerBoundingBoxesCache = new HashMap<>();
+    private final Map<Integer, StructureProcessor> structureProcessors = new HashMap<>();
+    private final Map<Integer, BoundingBoxCache> dimensionCache = new ConcurrentHashMap<>();
+    private Long seed = null;
+    private Integer spawnX = null;
+    private Integer spawnZ = null;
+
+    public void init() {
+        BoundingBoxType.registerTypes();
+        EventBus.subscribe(WorldLoaded.class, this::worldLoaded);
+        EventBus.subscribe(StructuresLoaded.class, this::structuresLoaded);
+        EventBus.subscribe(PlayerLoggedIn.class, this::playerLoggedIn);
+        EventBus.subscribe(PlayerLoggedOut.class, this::playerLoggedOut);
+        EventBus.subscribe(PlayerSubscribed.class, this::onPlayerSubscribed);
+        EventBus.subscribe(ServerTick.class, e -> serverTick());
+    }
+
+    protected void setSeed(long seed) {
+        this.seed = seed;
+    }
+
+    protected void setWorldSpawn(int spawnX, int spawnZ) {
+        this.spawnX = spawnX;
+        this.spawnZ = spawnZ;
+    }
+
+    private void worldLoaded(WorldLoaded event) {
+        int dimensionId = event.getDimensionId();
+        long seed = event.getSeed();
+        if (dimensionId == Dimensions.OVERWORLD) {
+            setSeed(seed);
+            setWorldSpawn(event.getSpawnX(), event.getSpawnZ());
         }
+        Logger.info("create world dimension: %s (seed: %d)", dimensionId, seed);
+    }
+
+    private void structuresLoaded(StructuresLoaded event) {
+        int dimensionId = event.getDimensionId();
+        StructureProcessor structureProcessor = getStructureProcessor(dimensionId);
+        structureProcessor.process(event.getStructures());
     }
 
-    public void chunkLoaded(Chunk chunk) {
-        DimensionType dimensionType = chunk.getWorld().dimension.getType();
-        BoundingBoxCache cache = dimensionCache.get(dimensionType);
-        if(cache instanceof DimensionProcessor) {
-            ((DimensionProcessor)cache).processChunk(chunk);
+    private StructureProcessor getStructureProcessor(int dimensionId) {
+        StructureProcessor structureProcessor = structureProcessors.get(dimensionId);
+        if (structureProcessor == null) {
+            structureProcessor = new StructureProcessor(getOrCreateCache(dimensionId));
+            structureProcessors.put(dimensionId, structureProcessor);
         }
+        return structureProcessor;
     }
 
-    public void tick() {
-        villageProcessors.forEach(VillageProcessor::process);
+    private void playerLoggedIn(PlayerLoggedIn event) {
+        if (seed == null || spawnX == null || spawnZ == null) {
+            return;
+        }
+        ServerPlayer player = event.getPlayer();
+        player.sendPacket(InitializeClient.getPayload(seed, spawnX, spawnZ));
     }
 
-    public void init() {
-        dimensionCache = new DimensionCache();
+    private void playerLoggedOut(PlayerLoggedOut event) {
+        int playerId = event.getPlayerId();
+        players.remove(playerId);
+        playerBoundingBoxesCache.remove(playerId);
+    }
+
+    private void onPlayerSubscribed(PlayerSubscribed event) {
+        int playerId = event.getPlayerId();
+        ServerPlayer player = event.getPlayer();
+        players.put(playerId, player);
+        sendToPlayer(playerId, player);
     }
 
-    public void setEventHandler(IVillageEventHandler eventHandler) {
-        this.eventHandler = eventHandler;
+    private void sendToPlayer(int playerId, ServerPlayer player) {
+        for (Map.Entry<Integer, BoundingBoxCache> entry : dimensionCache.entrySet()) {
+            int dimensionId = entry.getKey();
+            BoundingBoxCache boundingBoxCache = entry.getValue();
+            if (boundingBoxCache == null) return;
+
+            Set<AbstractBoundingBox> playerBoundingBoxes = playerBoundingBoxesCache.computeIfAbsent(playerId, k -> new HashSet<>());
+
+            Map<AbstractBoundingBox, Set<AbstractBoundingBox>> boundingBoxMap = boundingBoxCache.getBoundingBoxes();
+            for (AbstractBoundingBox key : boundingBoxMap.keySet()) {
+                if (playerBoundingBoxes.contains(key)) {
+                    continue;
+                }
+
+                Set<AbstractBoundingBox> boundingBoxes = boundingBoxMap.get(key);
+                PayloadBuilder payload = AddBoundingBox.getPayload(dimensionId, key, boundingBoxes);
+                if (payload != null)
+                    player.sendPacket(payload);
+
+                playerBoundingBoxes.add(key);
+            }
+        }
     }
 
-    public DimensionCache getDimensionCache() {
-        return dimensionCache;
+    private void serverTick() {
+        for (Map.Entry<Integer, ServerPlayer> playerEntry : players.entrySet()) {
+            int playerId = playerEntry.getKey();
+            ServerPlayer player = playerEntry.getValue();
+
+            sendToPlayer(playerId, player);
+        }
+    }
+
+    protected BoundingBoxCache getCache(int dimensionId) {
+        return dimensionCache.get(dimensionId);
+    }
+
+    protected BoundingBoxCache getOrCreateCache(int dimensionId) {
+        return dimensionCache.computeIfAbsent(dimensionId, dt -> new BoundingBoxCache());
+    }
+
+    protected void clearCaches() {
+        structureProcessors.clear();
+        for (BoundingBoxCache cache : dimensionCache.values()) {
+            cache.clear();
+        }
+        dimensionCache.clear();
     }
 }