X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;ds=sidebyside;f=src%2Fmain%2Fjava%2Fcom%2Firtimaled%2Fbbor%2Fcommon%2FCommonProxy.java;h=278d28c8216d4cfeeabd9ffbf7579f5636ab5193;hb=e2b4055fd2ccd326f55e08225e0b5792a39aa29e;hp=de9baff5bff457182373aa7570d78bf7e523589e;hpb=7ca2e3760d98433e125d790fb1589a19d6eb9083;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 de9baff..278d28c 100644 --- a/src/main/java/com/irtimaled/bbor/common/CommonProxy.java +++ b/src/main/java/com/irtimaled/bbor/common/CommonProxy.java @@ -1,68 +1,150 @@ package com.irtimaled.bbor.common; import com.irtimaled.bbor.Logger; -import com.irtimaled.bbor.common.events.ChunkLoaded; -import com.irtimaled.bbor.common.events.MobSpawnerBroken; +import com.irtimaled.bbor.client.config.ConfigManager; +import com.irtimaled.bbor.common.events.PlayerLoggedIn; +import com.irtimaled.bbor.common.events.PlayerLoggedOut; +import com.irtimaled.bbor.common.events.PlayerSubscribed; +import com.irtimaled.bbor.common.events.ServerTick; +import com.irtimaled.bbor.common.events.StructuresLoaded; import com.irtimaled.bbor.common.events.WorldLoaded; -import com.irtimaled.bbor.common.models.BoundingBox; -import com.irtimaled.bbor.common.models.BoundingBoxMobSpawner; -import com.irtimaled.bbor.config.ConfigManager; -import net.minecraft.util.math.BlockPos; -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.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.DimensionId; +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 villageProcessors = new HashSet<>(); + 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 CommonProxy(){ + ConfigManager.loadConfig(); + } public void init() { - dimensionCache = new DimensionCache(); - registerEventHandlers(); + 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) { + DimensionId dimensionId = event.getDimensionId(); + long seed = event.getSeed(); + if (dimensionId == DimensionId.OVERWORLD) { + setSeed(seed); + setWorldSpawn(event.getSpawnX(), event.getSpawnZ()); + } + Logger.info("create world dimension: %s (seed: %d)", dimensionId, seed); + } + + private void structuresLoaded(StructuresLoaded event) { + DimensionId dimensionId = event.getDimensionId(); + StructureProcessor structureProcessor = getStructureProcessor(dimensionId); + structureProcessor.process(event.getStructures()); + } + + private StructureProcessor getStructureProcessor(DimensionId dimensionId) { + StructureProcessor structureProcessor = structureProcessors.get(dimensionId); + if (structureProcessor == null) { + structureProcessor = new StructureProcessor(getOrCreateCache(dimensionId)); + structureProcessors.put(dimensionId, structureProcessor); + } + return structureProcessor; + } + + private void playerLoggedIn(PlayerLoggedIn event) { + if (seed == null || spawnX == null || spawnZ == null) { + return; + } + ServerPlayer player = event.getPlayer(); + player.sendPacket(InitializeClient.getPayload(seed, spawnX, spawnZ)); } - protected void registerEventHandlers() { - 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())); + private void playerLoggedOut(PlayerLoggedOut event) { + int playerId = event.getPlayerId(); + players.remove(playerId); + playerBoundingBoxesCache.remove(playerId); } - private 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, boundingBoxCache)); + private void onPlayerSubscribed(PlayerSubscribed event) { + int playerId = event.getPlayerId(); + ServerPlayer player = event.getPlayer(); + players.put(playerId, player); + sendToPlayer(playerId, player); + } + + private void sendToPlayer(int playerId, ServerPlayer player) { + for (Map.Entry entry : dimensionCache.entrySet()) { + DimensionId dimensionId = entry.getKey(); + BoundingBoxCache boundingBoxCache = entry.getValue(); + if (boundingBoxCache == null) return; + + Set playerBoundingBoxes = playerBoundingBoxesCache.computeIfAbsent(playerId, k -> new HashSet<>()); + + Map> boundingBoxMap = boundingBoxCache.getBoundingBoxes(); + for (AbstractBoundingBox key : boundingBoxMap.keySet()) { + if (playerBoundingBoxes.contains(key)) { + continue; + } + + Set boundingBoxes = boundingBoxMap.get(key); + PayloadBuilder payload = AddBoundingBox.getPayload(dimensionId, key, boundingBoxes); + if (payload != null) + player.sendPacket(payload); + + playerBoundingBoxes.add(key); } } } - private void chunkLoaded(Chunk chunk) { - DimensionType dimensionType = chunk.getWorld().dimension.getType(); - BoundingBoxCache cache = dimensionCache.get(dimensionType); - if (cache instanceof DimensionProcessor) { - ((DimensionProcessor) cache).processChunk(chunk); + private void serverTick() { + for (Map.Entry playerEntry : players.entrySet()) { + int playerId = playerEntry.getKey(); + ServerPlayer player = playerEntry.getValue(); + + sendToPlayer(playerId, player); } } - protected void tick() { - villageProcessors.forEach(VillageProcessor::process); + protected BoundingBoxCache getCache(DimensionId dimensionId) { + return dimensionCache.get(dimensionId); + } + + protected BoundingBoxCache getOrCreateCache(DimensionId dimensionId) { + return dimensionCache.computeIfAbsent(dimensionId, dt -> new BoundingBoxCache()); } - private void mobSpawnerBroken(DimensionType dimensionType, BlockPos pos) { - BoundingBox boundingBox = BoundingBoxMobSpawner.from(pos); - BoundingBoxCache cache = dimensionCache.getBoundingBoxes(dimensionType); - if (cache != null) { - cache.removeBoundingBox(boundingBox); + protected void clearCaches() { + structureProcessors.clear(); + for (BoundingBoxCache cache : dimensionCache.values()) { + cache.clear(); } + dimensionCache.clear(); } }