X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fmain%2Fjava%2Fcom%2Firtimaled%2Fbbor%2Fcommon%2FCommonProxy.java;h=b39613757230eceebc55cb616c8ef59baf9d9931;hb=8b00bea443167b9e6e7c1a30b5c25994d301cfab;hp=88d44c41126d140d89b7c1e6c35750716c156cc2;hpb=b672e7635a150602b9ad7b662671f6a0279b5fd4;p=BoundingBoxOutlineReloaded.git diff --git a/src/main/java/com/irtimaled/bbor/common/CommonProxy.java b/src/main/java/com/irtimaled/bbor/common/CommonProxy.java index 88d44c4..b396137 100644 --- a/src/main/java/com/irtimaled/bbor/common/CommonProxy.java +++ b/src/main/java/com/irtimaled/bbor/common/CommonProxy.java @@ -1,208 +1,138 @@ package com.irtimaled.bbor.common; import com.irtimaled.bbor.Logger; -import com.irtimaled.bbor.common.chunkProcessors.ChunkProcessor; -import com.irtimaled.bbor.common.chunkProcessors.EndChunkProcessor; -import com.irtimaled.bbor.common.chunkProcessors.NetherChunkProcessor; -import com.irtimaled.bbor.common.chunkProcessors.OverworldChunkProcessor; 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.RemoveBoundingBox; -import com.irtimaled.bbor.common.models.BoundingBox; -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; -import net.minecraft.village.Village; -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.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; -import java.util.function.Consumer; public class CommonProxy { - private Set players = new HashSet<>(); - private Map> playerBoundingBoxesCache = new HashMap<>(); - private Map villageCache = new HashMap<>(); - private Map chunkProcessors = new HashMap<>(); - private WorldData worldData = null; - private final Map dimensionCache = new ConcurrentHashMap<>(); + private final Map players = new ConcurrentHashMap<>(); + private final Map> playerBoundingBoxesCache = new HashMap<>(); + private final Map structureProcessors = new HashMap<>(); + private final Map dimensionCache = new ConcurrentHashMap<>(); + private Long seed = null; + private Integer spawnX = null; + private Integer spawnZ = null; public void init() { - 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(PlayerLoggedIn.class, e -> playerLoggedIn(e.getPlayer())); - EventBus.subscribe(PlayerLoggedOut.class, e -> playerLoggedOut(e.getPlayer())); - EventBus.subscribe(PlayerSubscribed.class, e -> sendBoundingBoxes(e.getPlayer())); - EventBus.subscribe(Tick.class, e -> tick()); - if (ConfigManager.drawVillages.get()) { - EventBus.subscribe(VillageUpdated.class, e -> villageUpdated(e.getDimensionType(), e.getVillage())); - } + 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 setWorldData(long seed, int spawnX, int spawnZ) { - worldData = new WorldData(seed, spawnX, spawnZ); + protected void setSeed(long seed) { + this.seed = seed; } - private void worldLoaded(World world) { - IChunkProvider chunkProvider = world.getChunkProvider(); - if (chunkProvider instanceof ChunkProviderServer) { - DimensionType dimensionType = world.dimension.getType(); - BoundingBoxCache boundingBoxCache = getOrCreateCache(dimensionType); - ChunkProcessor chunkProcessor = null; - if (dimensionType == DimensionType.OVERWORLD) { - setWorldData(world.getSeed(), world.getWorldInfo().getSpawnX(), world.getWorldInfo().getSpawnZ()); - chunkProcessor = new OverworldChunkProcessor(boundingBoxCache); - } - if (dimensionType == DimensionType.NETHER) { - chunkProcessor = new NetherChunkProcessor(boundingBoxCache); - } - if (dimensionType == DimensionType.THE_END) { - chunkProcessor = new EndChunkProcessor(boundingBoxCache); - } - Logger.info("create world dimension: %s, %s (seed: %d)", dimensionType, world.getClass().toString(), world.getSeed()); - chunkProcessors.put(dimensionType, chunkProcessor); - } + protected void setWorldSpawn(int spawnX, int spawnZ) { + this.spawnX = spawnX; + this.spawnZ = spawnZ; } - private void chunkLoaded(Chunk chunk) { - DimensionType dimensionType = chunk.getWorld().dimension.getType(); - ChunkProcessor chunkProcessor = chunkProcessors.get(dimensionType); - if (chunkProcessor != null) { - chunkProcessor.process(chunk); + 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 playerLoggedIn(EntityPlayerMP player) { - if (player.connection.netManager.getRemoteAddress() instanceof LocalAddress) return; - player.connection.sendPacket(InitializeClient.getPayload(worldData)); + private void structuresLoaded(StructuresLoaded event) { + int dimensionId = event.getDimensionId(); + StructureProcessor structureProcessor = getStructureProcessor(dimensionId); + structureProcessor.process(event.getStructures()); } - private void playerLoggedOut(EntityPlayerMP player) { - players.remove(player); - playerBoundingBoxesCache.remove(player); + private StructureProcessor getStructureProcessor(int dimensionId) { + StructureProcessor structureProcessor = structureProcessors.get(dimensionId); + if (structureProcessor == null) { + structureProcessor = new StructureProcessor(getOrCreateCache(dimensionId)); + structureProcessors.put(dimensionId, structureProcessor); + } + return structureProcessor; } - private void sendRemoveBoundingBox(DimensionType dimensionType, BoundingBox boundingBox) { - SPacketCustomPayload payload = RemoveBoundingBox.getPayload(dimensionType, boundingBox); - if (payload == null) return; - - for (EntityPlayerMP player : players) { - if (DimensionType.getById(player.dimension) == dimensionType) { - player.connection.sendPacket(payload); - - if (playerBoundingBoxesCache.containsKey(player)) { - playerBoundingBoxesCache.get(player).remove(boundingBox); - } - } + private void playerLoggedIn(PlayerLoggedIn event) { + if (seed == null || spawnX == null || spawnZ == null) { + return; } + ServerPlayer player = event.getPlayer(); + player.sendPacket(InitializeClient.getPayload(seed, spawnX, spawnZ)); } - private void sendBoundingBoxes(EntityPlayerMP player) { - DimensionType dimensionType = DimensionType.getById(player.dimension); - players.add(player); - sendToPlayer(player, getCache(dimensionType)); + private void playerLoggedOut(PlayerLoggedOut event) { + int playerId = event.getPlayerId(); + players.remove(playerId); + playerBoundingBoxesCache.remove(playerId); } - private void sendToPlayer(EntityPlayerMP player, BoundingBoxCache boundingBoxCache) { - if (boundingBoxCache == null) return; - - Map> cacheSubset = getBoundingBoxMap(player, boundingBoxCache.getBoundingBoxes()); - - DimensionType dimensionType = DimensionType.getById(player.dimension); - - for (BoundingBox key : cacheSubset.keySet()) { - Set boundingBoxes = cacheSubset.get(key); - SPacketCustomPayload payload = AddBoundingBox.getPayload(dimensionType, key, boundingBoxes); - if (payload != null) - player.connection.sendPacket(payload); - - if (!playerBoundingBoxesCache.containsKey(player)) { - playerBoundingBoxesCache.put(player, new HashSet<>()); - } - playerBoundingBoxesCache.get(player).add(key); - } + private void onPlayerSubscribed(PlayerSubscribed event) { + int playerId = event.getPlayerId(); + ServerPlayer player = event.getPlayer(); + players.put(playerId, player); + sendToPlayer(playerId, player); } - private Map> getBoundingBoxMap(EntityPlayerMP player, Map> boundingBoxMap) { - Map> cacheSubset = new HashMap<>(); - for (BoundingBox key : boundingBoxMap.keySet()) { - if (!playerBoundingBoxesCache.containsKey(player) || !playerBoundingBoxesCache.get(player).contains(key)) { - cacheSubset.put(key, boundingBoxMap.get(key)); - } - } - return cacheSubset; - } + private void sendToPlayer(int playerId, ServerPlayer player) { + for (Map.Entry entry : dimensionCache.entrySet()) { + int dimensionId = entry.getKey(); + BoundingBoxCache boundingBoxCache = entry.getValue(); + if (boundingBoxCache == null) return; - protected void removeBoundingBox(DimensionType dimensionType, BoundingBox key) { - BoundingBoxCache cache = getCache(dimensionType); - if (cache == null) return; + Set playerBoundingBoxes = playerBoundingBoxesCache.computeIfAbsent(playerId, k -> new HashSet<>()); - cache.removeBoundingBox(key); - } + Map> boundingBoxMap = boundingBoxCache.getBoundingBoxes(); + for (AbstractBoundingBox key : boundingBoxMap.keySet()) { + if (playerBoundingBoxes.contains(key)) { + continue; + } - private void mobSpawnerBroken(DimensionType dimensionType, BlockPos pos) { - BoundingBox boundingBox = BoundingBoxMobSpawner.from(pos); - removeBoundingBox(dimensionType, boundingBox); - sendRemoveBoundingBox(dimensionType, boundingBox); - } + Set boundingBoxes = boundingBoxMap.get(key); + PayloadBuilder payload = AddBoundingBox.getPayload(dimensionId, key, boundingBoxes); + if (payload != null) + player.sendPacket(payload); - private void tick() { - for (EntityPlayerMP player : players) { - DimensionType dimensionType = DimensionType.getById(player.dimension); - sendToPlayer(player, getCache(dimensionType)); + playerBoundingBoxes.add(key); + } } } - private void villageUpdated(DimensionType dimensionType, Village village) { - BoundingBoxCache cache = getCache(dimensionType); - if (cache == null) return; + private void serverTick() { + for (Map.Entry playerEntry : players.entrySet()) { + int playerId = playerEntry.getKey(); + ServerPlayer player = playerEntry.getValue(); - int villageId = village.hashCode(); - BoundingBoxVillage oldVillage = villageCache.get(villageId); - if (oldVillage != null && !oldVillage.matches(village)) { - cache.removeBoundingBox(oldVillage); - sendRemoveBoundingBox(dimensionType, oldVillage); - oldVillage = null; + sendToPlayer(playerId, player); } - if (village.isAnnihilated()) { - villageCache.remove(villageId); - } else { - BoundingBoxVillage newVillage = oldVillage == null ? BoundingBoxVillage.from(village) : oldVillage; - cache.addBoundingBox(newVillage); - villageCache.put(villageId, newVillage); - } - } - - protected BoundingBoxCache getCache(DimensionType dimensionType) { - return dimensionCache.get(dimensionType); } - protected BoundingBoxCache getOrCreateCache(DimensionType dimensionType) { - return dimensionCache.computeIfAbsent(dimensionType, dt -> new BoundingBoxCache()); + protected BoundingBoxCache getCache(int dimensionId) { + return dimensionCache.get(dimensionId); } - protected void runOnCache(DimensionType dimensionType, Consumer action) { - action.accept(getOrCreateCache(dimensionType)); + protected BoundingBoxCache getOrCreateCache(int dimensionId) { + return dimensionCache.computeIfAbsent(dimensionId, dt -> new BoundingBoxCache()); } protected void clearCaches() { - villageCache.clear(); + structureProcessors.clear(); for (BoundingBoxCache cache : dimensionCache.values()) { - cache.close(); + cache.clear(); } dimensionCache.clear(); }