From 754c10efa6febfa42a15e4afdbf5efcdf00ad45f Mon Sep 17 00:00:00 2001 From: Mike Primm Date: Tue, 5 Oct 2021 20:51:43 -0500 Subject: [PATCH] Strip out obsolete builds --- fabric-1.16.1/.gitignore | 32 - fabric-1.16.1/build.gradle | 78 - fabric-1.16.1/gradle.properties | 12 - .../dynmap/fabric_1_16_1/ChunkSnapshot.java | 302 --- .../org/dynmap/fabric_1_16_1/DynmapMod.java | 50 - .../dynmap/fabric_1_16_1/DynmapPlugin.java | 912 -------- .../dynmap/fabric_1_16_1/FabricAdapter.java | 14 - .../fabric_1_16_1/FabricCommandSender.java | 47 - .../dynmap/fabric_1_16_1/FabricLogger.java | 49 - .../fabric_1_16_1/FabricMapChunkCache.java | 1322 ----------- .../dynmap/fabric_1_16_1/FabricPlayer.java | 249 -- .../dynmap/fabric_1_16_1/FabricServer.java | 603 ----- .../org/dynmap/fabric_1_16_1/FabricWorld.java | 222 -- .../dynmap/fabric_1_16_1/SnapshotCache.java | 201 -- .../org/dynmap/fabric_1_16_1/TaskRecord.java | 38 - .../dynmap/fabric_1_16_1/VersionCheck.java | 98 - .../fabric_1_16_1/command/DmapCommand.java | 9 - .../fabric_1_16_1/command/DmarkerCommand.java | 9 - .../fabric_1_16_1/command/DynmapCommand.java | 9 - .../command/DynmapCommandExecutor.java | 63 - .../command/DynmapExpCommand.java | 9 - .../fabric_1_16_1/event/BlockEvents.java | 23 - .../fabric_1_16_1/event/ChunkDataEvents.java | 24 - .../event/CustomServerLifecycleEvents.java | 14 - .../fabric_1_16_1/event/PlayerEvents.java | 62 - .../fabric_1_16_1/event/ServerChatEvents.java | 23 - .../mixin/BiomeEffectsAccessor.java | 11 - .../mixin/MinecraftServerMixin.java | 16 - .../mixin/PlayerManagerMixin.java | 29 - .../mixin/ServerPlayNetworkHandlerMixin.java | 31 - .../mixin/ServerPlayerEntityMixin.java | 30 - .../ThreadedAnvilChunkStorageAccessor.java | 13 - .../mixin/ThreadedAnvilChunkStorageMixin.java | 26 - .../fabric_1_16_1/mixin/WorldChunkMixin.java | 25 - .../permissions/FilePermissions.java | 103 - .../permissions/OpPermissions.java | 52 - .../permissions/PermissionProvider.java | 16 - .../src/main/resources/assets/dynmap/icon.png | Bin 34043 -> 0 bytes .../src/main/resources/configuration.txt | 467 ---- .../src/main/resources/dynmap.mixins.json | 19 - .../src/main/resources/fabric.mod.json | 33 - .../main/resources/permissions.yml.example | 27 - fabric-1.16.2/.gitignore | 32 - fabric-1.16.2/build.gradle | 78 - fabric-1.16.2/gradle.properties | 12 - .../dynmap/fabric_1_16_2/ChunkSnapshot.java | 302 --- .../org/dynmap/fabric_1_16_2/DynmapMod.java | 50 - .../dynmap/fabric_1_16_2/DynmapPlugin.java | 900 -------- .../dynmap/fabric_1_16_2/FabricAdapter.java | 13 - .../fabric_1_16_2/FabricCommandSender.java | 47 - .../dynmap/fabric_1_16_2/FabricLogger.java | 49 - .../fabric_1_16_2/FabricMapChunkCache.java | 1334 ----------- .../dynmap/fabric_1_16_2/FabricPlayer.java | 249 -- .../dynmap/fabric_1_16_2/FabricServer.java | 629 ----- .../org/dynmap/fabric_1_16_2/FabricWorld.java | 224 -- .../dynmap/fabric_1_16_2/SnapshotCache.java | 201 -- .../org/dynmap/fabric_1_16_2/TaskRecord.java | 38 - .../dynmap/fabric_1_16_2/VersionCheck.java | 98 - .../fabric_1_16_2/command/DmapCommand.java | 9 - .../fabric_1_16_2/command/DmarkerCommand.java | 9 - .../fabric_1_16_2/command/DynmapCommand.java | 9 - .../command/DynmapCommandExecutor.java | 63 - .../command/DynmapExpCommand.java | 9 - .../fabric_1_16_2/event/BlockEvents.java | 23 - .../fabric_1_16_2/event/ChunkDataEvents.java | 24 - .../event/CustomServerLifecycleEvents.java | 14 - .../fabric_1_16_2/event/PlayerEvents.java | 62 - .../fabric_1_16_2/event/ServerChatEvents.java | 23 - .../mixin/BiomeEffectsAccessor.java | 11 - .../mixin/MinecraftServerMixin.java | 16 - .../mixin/PlayerManagerMixin.java | 29 - .../mixin/ServerPlayNetworkHandlerMixin.java | 31 - .../mixin/ServerPlayerEntityMixin.java | 30 - .../ThreadedAnvilChunkStorageAccessor.java | 13 - .../mixin/ThreadedAnvilChunkStorageMixin.java | 26 - .../fabric_1_16_2/mixin/WorldChunkMixin.java | 25 - .../permissions/FilePermissions.java | 103 - .../permissions/OpPermissions.java | 52 - .../permissions/PermissionProvider.java | 16 - .../src/main/resources/assets/dynmap/icon.png | Bin 34043 -> 0 bytes .../src/main/resources/configuration.txt | 467 ---- .../src/main/resources/dynmap.mixins.json | 19 - .../src/main/resources/fabric.mod.json | 33 - .../main/resources/permissions.yml.example | 27 - fabric-1.17/.gitignore | 32 - fabric-1.17/build.gradle | 79 - fabric-1.17/gradle.properties | 12 - .../org/dynmap/fabric_1_17/ChunkSnapshot.java | 302 --- .../org/dynmap/fabric_1_17/DynmapMod.java | 50 - .../org/dynmap/fabric_1_17/DynmapPlugin.java | 901 -------- .../org/dynmap/fabric_1_17/FabricAdapter.java | 13 - .../fabric_1_17/FabricCommandSender.java | 47 - .../org/dynmap/fabric_1_17/FabricLogger.java | 49 - .../fabric_1_17/FabricMapChunkCache.java | 1334 ----------- .../org/dynmap/fabric_1_17/FabricPlayer.java | 252 -- .../org/dynmap/fabric_1_17/FabricServer.java | 629 ----- .../org/dynmap/fabric_1_17/FabricWorld.java | 224 -- .../org/dynmap/fabric_1_17/SnapshotCache.java | 201 -- .../org/dynmap/fabric_1_17/TaskRecord.java | 38 - .../org/dynmap/fabric_1_17/VersionCheck.java | 98 - .../fabric_1_17/command/DmapCommand.java | 9 - .../fabric_1_17/command/DmarkerCommand.java | 9 - .../fabric_1_17/command/DynmapCommand.java | 9 - .../command/DynmapCommandExecutor.java | 63 - .../fabric_1_17/command/DynmapExpCommand.java | 9 - .../dynmap/fabric_1_17/event/BlockEvents.java | 23 - .../fabric_1_17/event/ChunkDataEvents.java | 24 - .../event/CustomServerLifecycleEvents.java | 14 - .../fabric_1_17/event/PlayerEvents.java | 62 - .../fabric_1_17/event/ServerChatEvents.java | 23 - .../mixin/BiomeEffectsAccessor.java | 11 - .../mixin/MinecraftServerMixin.java | 16 - .../fabric_1_17/mixin/PlayerManagerMixin.java | 29 - .../mixin/ServerPlayNetworkHandlerMixin.java | 29 - .../mixin/ServerPlayerEntityMixin.java | 30 - .../ThreadedAnvilChunkStorageAccessor.java | 13 - .../mixin/ThreadedAnvilChunkStorageMixin.java | 26 - .../fabric_1_17/mixin/WorldChunkMixin.java | 25 - .../permissions/FilePermissions.java | 103 - .../permissions/OpPermissions.java | 52 - .../permissions/PermissionProvider.java | 16 - .../src/main/resources/assets/dynmap/icon.png | Bin 34043 -> 0 bytes .../src/main/resources/configuration.txt | 467 ---- .../src/main/resources/dynmap.mixins.json | 19 - .../src/main/resources/fabric.mod.json | 33 - .../main/resources/permissions.yml.example | 27 - forge-1.16.1/.gitignore | 3 - forge-1.16.1/build.gradle | 77 - .../dynmap/forge_1_16_1/ChunkSnapshot.java | 286 --- .../org/dynmap/forge_1_16_1/ClientProxy.java | 6 - .../org/dynmap/forge_1_16_1/DynmapMod.java | 133 -- .../org/dynmap/forge_1_16_1/DynmapPlugin.java | 2010 ---------------- .../forge_1_16_1/ForgeMapChunkCache.java | 1489 ------------ .../org/dynmap/forge_1_16_1/ForgeWorld.java | 233 -- .../java/org/dynmap/forge_1_16_1/Proxy.java | 24 - .../dynmap/forge_1_16_1/SnapshotCache.java | 191 -- .../org/dynmap/forge_1_16_1/VersionCheck.java | 97 - .../permissions/FilePermissions.java | 103 - .../permissions/OpPermissions.java | 51 - .../permissions/PermissionProvider.java | 15 - .../resources/META-INF/accesstransformer.cfg | 3 - .../src/main/resources/META-INF/mods.toml | 25 - .../src/main/resources/configuration.txt | 467 ---- forge-1.16.1/src/main/resources/pack.mcmeta | 6 - .../main/resources/permissions.yml.example | 27 - forge-1.16.2/.gitignore | 2 - forge-1.16.2/build.gradle | 77 - .../dynmap/forge_1_16_2/ChunkSnapshot.java | 286 --- .../org/dynmap/forge_1_16_2/ClientProxy.java | 6 - .../org/dynmap/forge_1_16_2/DynmapMod.java | 133 -- .../org/dynmap/forge_1_16_2/DynmapPlugin.java | 2020 ----------------- .../forge_1_16_2/ForgeMapChunkCache.java | 1489 ------------ .../org/dynmap/forge_1_16_2/ForgeWorld.java | 234 -- .../java/org/dynmap/forge_1_16_2/Proxy.java | 24 - .../dynmap/forge_1_16_2/SnapshotCache.java | 191 -- .../org/dynmap/forge_1_16_2/VersionCheck.java | 97 - .../permissions/FilePermissions.java | 103 - .../permissions/OpPermissions.java | 51 - .../permissions/PermissionProvider.java | 15 - .../resources/META-INF/accesstransformer.cfg | 3 - .../src/main/resources/META-INF/mods.toml | 26 - .../src/main/resources/configuration.txt | 467 ---- forge-1.16.2/src/main/resources/pack.mcmeta | 6 - .../main/resources/permissions.yml.example | 27 - forge-1.16.3/.gitignore | 2 - forge-1.16.3/build.gradle | 77 - .../dynmap/forge_1_16_3/ChunkSnapshot.java | 286 --- .../org/dynmap/forge_1_16_3/ClientProxy.java | 6 - .../org/dynmap/forge_1_16_3/DynmapMod.java | 133 -- .../org/dynmap/forge_1_16_3/DynmapPlugin.java | 2020 ----------------- .../forge_1_16_3/ForgeMapChunkCache.java | 1489 ------------ .../org/dynmap/forge_1_16_3/ForgeWorld.java | 234 -- .../java/org/dynmap/forge_1_16_3/Proxy.java | 24 - .../dynmap/forge_1_16_3/SnapshotCache.java | 191 -- .../org/dynmap/forge_1_16_3/VersionCheck.java | 97 - .../permissions/FilePermissions.java | 103 - .../permissions/OpPermissions.java | 51 - .../permissions/PermissionProvider.java | 15 - .../resources/META-INF/accesstransformer.cfg | 3 - .../src/main/resources/META-INF/mods.toml | 26 - .../src/main/resources/configuration.txt | 467 ---- forge-1.16.3/src/main/resources/pack.mcmeta | 6 - .../main/resources/permissions.yml.example | 27 - forge-1.16.4/.gitignore | 2 - forge-1.16.4/build.gradle | 77 - .../dynmap/forge_1_16_4/ChunkSnapshot.java | 286 --- .../org/dynmap/forge_1_16_4/ClientProxy.java | 6 - .../org/dynmap/forge_1_16_4/DynmapMod.java | 133 -- .../org/dynmap/forge_1_16_4/DynmapPlugin.java | 2020 ----------------- .../forge_1_16_4/ForgeMapChunkCache.java | 1489 ------------ .../org/dynmap/forge_1_16_4/ForgeWorld.java | 234 -- .../java/org/dynmap/forge_1_16_4/Proxy.java | 24 - .../dynmap/forge_1_16_4/SnapshotCache.java | 191 -- .../org/dynmap/forge_1_16_4/VersionCheck.java | 97 - .../permissions/FilePermissions.java | 103 - .../permissions/OpPermissions.java | 51 - .../permissions/PermissionProvider.java | 15 - .../resources/META-INF/accesstransformer.cfg | 3 - .../src/main/resources/META-INF/mods.toml | 26 - .../src/main/resources/configuration.txt | 467 ---- forge-1.16.4/src/main/resources/pack.mcmeta | 6 - .../main/resources/permissions.yml.example | 27 - settings.gradle | 18 - 203 files changed, 37208 deletions(-) delete mode 100644 fabric-1.16.1/.gitignore delete mode 100644 fabric-1.16.1/build.gradle delete mode 100644 fabric-1.16.1/gradle.properties delete mode 100644 fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/ChunkSnapshot.java delete mode 100644 fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/DynmapMod.java delete mode 100644 fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/DynmapPlugin.java delete mode 100644 fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/FabricAdapter.java delete mode 100644 fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/FabricCommandSender.java delete mode 100644 fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/FabricLogger.java delete mode 100644 fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/FabricMapChunkCache.java delete mode 100644 fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/FabricPlayer.java delete mode 100644 fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/FabricServer.java delete mode 100644 fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/FabricWorld.java delete mode 100644 fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/SnapshotCache.java delete mode 100644 fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/TaskRecord.java delete mode 100644 fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/VersionCheck.java delete mode 100644 fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/command/DmapCommand.java delete mode 100644 fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/command/DmarkerCommand.java delete mode 100644 fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/command/DynmapCommand.java delete mode 100644 fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/command/DynmapCommandExecutor.java delete mode 100644 fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/command/DynmapExpCommand.java delete mode 100644 fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/event/BlockEvents.java delete mode 100644 fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/event/ChunkDataEvents.java delete mode 100644 fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/event/CustomServerLifecycleEvents.java delete mode 100644 fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/event/PlayerEvents.java delete mode 100644 fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/event/ServerChatEvents.java delete mode 100644 fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/mixin/BiomeEffectsAccessor.java delete mode 100644 fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/mixin/MinecraftServerMixin.java delete mode 100644 fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/mixin/PlayerManagerMixin.java delete mode 100644 fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/mixin/ServerPlayNetworkHandlerMixin.java delete mode 100644 fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/mixin/ServerPlayerEntityMixin.java delete mode 100644 fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/mixin/ThreadedAnvilChunkStorageAccessor.java delete mode 100644 fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/mixin/ThreadedAnvilChunkStorageMixin.java delete mode 100644 fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/mixin/WorldChunkMixin.java delete mode 100644 fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/permissions/FilePermissions.java delete mode 100644 fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/permissions/OpPermissions.java delete mode 100644 fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/permissions/PermissionProvider.java delete mode 100644 fabric-1.16.1/src/main/resources/assets/dynmap/icon.png delete mode 100644 fabric-1.16.1/src/main/resources/configuration.txt delete mode 100644 fabric-1.16.1/src/main/resources/dynmap.mixins.json delete mode 100644 fabric-1.16.1/src/main/resources/fabric.mod.json delete mode 100644 fabric-1.16.1/src/main/resources/permissions.yml.example delete mode 100644 fabric-1.16.2/.gitignore delete mode 100644 fabric-1.16.2/build.gradle delete mode 100644 fabric-1.16.2/gradle.properties delete mode 100644 fabric-1.16.2/src/main/java/org/dynmap/fabric_1_16_2/ChunkSnapshot.java delete mode 100644 fabric-1.16.2/src/main/java/org/dynmap/fabric_1_16_2/DynmapMod.java delete mode 100644 fabric-1.16.2/src/main/java/org/dynmap/fabric_1_16_2/DynmapPlugin.java delete mode 100644 fabric-1.16.2/src/main/java/org/dynmap/fabric_1_16_2/FabricAdapter.java delete mode 100644 fabric-1.16.2/src/main/java/org/dynmap/fabric_1_16_2/FabricCommandSender.java delete mode 100644 fabric-1.16.2/src/main/java/org/dynmap/fabric_1_16_2/FabricLogger.java delete mode 100644 fabric-1.16.2/src/main/java/org/dynmap/fabric_1_16_2/FabricMapChunkCache.java delete mode 100644 fabric-1.16.2/src/main/java/org/dynmap/fabric_1_16_2/FabricPlayer.java delete mode 100644 fabric-1.16.2/src/main/java/org/dynmap/fabric_1_16_2/FabricServer.java delete mode 100644 fabric-1.16.2/src/main/java/org/dynmap/fabric_1_16_2/FabricWorld.java delete mode 100644 fabric-1.16.2/src/main/java/org/dynmap/fabric_1_16_2/SnapshotCache.java delete mode 100644 fabric-1.16.2/src/main/java/org/dynmap/fabric_1_16_2/TaskRecord.java delete mode 100644 fabric-1.16.2/src/main/java/org/dynmap/fabric_1_16_2/VersionCheck.java delete mode 100644 fabric-1.16.2/src/main/java/org/dynmap/fabric_1_16_2/command/DmapCommand.java delete mode 100644 fabric-1.16.2/src/main/java/org/dynmap/fabric_1_16_2/command/DmarkerCommand.java delete mode 100644 fabric-1.16.2/src/main/java/org/dynmap/fabric_1_16_2/command/DynmapCommand.java delete mode 100644 fabric-1.16.2/src/main/java/org/dynmap/fabric_1_16_2/command/DynmapCommandExecutor.java delete mode 100644 fabric-1.16.2/src/main/java/org/dynmap/fabric_1_16_2/command/DynmapExpCommand.java delete mode 100644 fabric-1.16.2/src/main/java/org/dynmap/fabric_1_16_2/event/BlockEvents.java delete mode 100644 fabric-1.16.2/src/main/java/org/dynmap/fabric_1_16_2/event/ChunkDataEvents.java delete mode 100644 fabric-1.16.2/src/main/java/org/dynmap/fabric_1_16_2/event/CustomServerLifecycleEvents.java delete mode 100644 fabric-1.16.2/src/main/java/org/dynmap/fabric_1_16_2/event/PlayerEvents.java delete mode 100644 fabric-1.16.2/src/main/java/org/dynmap/fabric_1_16_2/event/ServerChatEvents.java delete mode 100644 fabric-1.16.2/src/main/java/org/dynmap/fabric_1_16_2/mixin/BiomeEffectsAccessor.java delete mode 100644 fabric-1.16.2/src/main/java/org/dynmap/fabric_1_16_2/mixin/MinecraftServerMixin.java delete mode 100644 fabric-1.16.2/src/main/java/org/dynmap/fabric_1_16_2/mixin/PlayerManagerMixin.java delete mode 100644 fabric-1.16.2/src/main/java/org/dynmap/fabric_1_16_2/mixin/ServerPlayNetworkHandlerMixin.java delete mode 100644 fabric-1.16.2/src/main/java/org/dynmap/fabric_1_16_2/mixin/ServerPlayerEntityMixin.java delete mode 100644 fabric-1.16.2/src/main/java/org/dynmap/fabric_1_16_2/mixin/ThreadedAnvilChunkStorageAccessor.java delete mode 100644 fabric-1.16.2/src/main/java/org/dynmap/fabric_1_16_2/mixin/ThreadedAnvilChunkStorageMixin.java delete mode 100644 fabric-1.16.2/src/main/java/org/dynmap/fabric_1_16_2/mixin/WorldChunkMixin.java delete mode 100644 fabric-1.16.2/src/main/java/org/dynmap/fabric_1_16_2/permissions/FilePermissions.java delete mode 100644 fabric-1.16.2/src/main/java/org/dynmap/fabric_1_16_2/permissions/OpPermissions.java delete mode 100644 fabric-1.16.2/src/main/java/org/dynmap/fabric_1_16_2/permissions/PermissionProvider.java delete mode 100644 fabric-1.16.2/src/main/resources/assets/dynmap/icon.png delete mode 100644 fabric-1.16.2/src/main/resources/configuration.txt delete mode 100644 fabric-1.16.2/src/main/resources/dynmap.mixins.json delete mode 100644 fabric-1.16.2/src/main/resources/fabric.mod.json delete mode 100644 fabric-1.16.2/src/main/resources/permissions.yml.example delete mode 100644 fabric-1.17/.gitignore delete mode 100644 fabric-1.17/build.gradle delete mode 100644 fabric-1.17/gradle.properties delete mode 100644 fabric-1.17/src/main/java/org/dynmap/fabric_1_17/ChunkSnapshot.java delete mode 100644 fabric-1.17/src/main/java/org/dynmap/fabric_1_17/DynmapMod.java delete mode 100644 fabric-1.17/src/main/java/org/dynmap/fabric_1_17/DynmapPlugin.java delete mode 100644 fabric-1.17/src/main/java/org/dynmap/fabric_1_17/FabricAdapter.java delete mode 100644 fabric-1.17/src/main/java/org/dynmap/fabric_1_17/FabricCommandSender.java delete mode 100644 fabric-1.17/src/main/java/org/dynmap/fabric_1_17/FabricLogger.java delete mode 100644 fabric-1.17/src/main/java/org/dynmap/fabric_1_17/FabricMapChunkCache.java delete mode 100644 fabric-1.17/src/main/java/org/dynmap/fabric_1_17/FabricPlayer.java delete mode 100644 fabric-1.17/src/main/java/org/dynmap/fabric_1_17/FabricServer.java delete mode 100644 fabric-1.17/src/main/java/org/dynmap/fabric_1_17/FabricWorld.java delete mode 100644 fabric-1.17/src/main/java/org/dynmap/fabric_1_17/SnapshotCache.java delete mode 100644 fabric-1.17/src/main/java/org/dynmap/fabric_1_17/TaskRecord.java delete mode 100644 fabric-1.17/src/main/java/org/dynmap/fabric_1_17/VersionCheck.java delete mode 100644 fabric-1.17/src/main/java/org/dynmap/fabric_1_17/command/DmapCommand.java delete mode 100644 fabric-1.17/src/main/java/org/dynmap/fabric_1_17/command/DmarkerCommand.java delete mode 100644 fabric-1.17/src/main/java/org/dynmap/fabric_1_17/command/DynmapCommand.java delete mode 100644 fabric-1.17/src/main/java/org/dynmap/fabric_1_17/command/DynmapCommandExecutor.java delete mode 100644 fabric-1.17/src/main/java/org/dynmap/fabric_1_17/command/DynmapExpCommand.java delete mode 100644 fabric-1.17/src/main/java/org/dynmap/fabric_1_17/event/BlockEvents.java delete mode 100644 fabric-1.17/src/main/java/org/dynmap/fabric_1_17/event/ChunkDataEvents.java delete mode 100644 fabric-1.17/src/main/java/org/dynmap/fabric_1_17/event/CustomServerLifecycleEvents.java delete mode 100644 fabric-1.17/src/main/java/org/dynmap/fabric_1_17/event/PlayerEvents.java delete mode 100644 fabric-1.17/src/main/java/org/dynmap/fabric_1_17/event/ServerChatEvents.java delete mode 100644 fabric-1.17/src/main/java/org/dynmap/fabric_1_17/mixin/BiomeEffectsAccessor.java delete mode 100644 fabric-1.17/src/main/java/org/dynmap/fabric_1_17/mixin/MinecraftServerMixin.java delete mode 100644 fabric-1.17/src/main/java/org/dynmap/fabric_1_17/mixin/PlayerManagerMixin.java delete mode 100644 fabric-1.17/src/main/java/org/dynmap/fabric_1_17/mixin/ServerPlayNetworkHandlerMixin.java delete mode 100644 fabric-1.17/src/main/java/org/dynmap/fabric_1_17/mixin/ServerPlayerEntityMixin.java delete mode 100644 fabric-1.17/src/main/java/org/dynmap/fabric_1_17/mixin/ThreadedAnvilChunkStorageAccessor.java delete mode 100644 fabric-1.17/src/main/java/org/dynmap/fabric_1_17/mixin/ThreadedAnvilChunkStorageMixin.java delete mode 100644 fabric-1.17/src/main/java/org/dynmap/fabric_1_17/mixin/WorldChunkMixin.java delete mode 100644 fabric-1.17/src/main/java/org/dynmap/fabric_1_17/permissions/FilePermissions.java delete mode 100644 fabric-1.17/src/main/java/org/dynmap/fabric_1_17/permissions/OpPermissions.java delete mode 100644 fabric-1.17/src/main/java/org/dynmap/fabric_1_17/permissions/PermissionProvider.java delete mode 100644 fabric-1.17/src/main/resources/assets/dynmap/icon.png delete mode 100644 fabric-1.17/src/main/resources/configuration.txt delete mode 100644 fabric-1.17/src/main/resources/dynmap.mixins.json delete mode 100644 fabric-1.17/src/main/resources/fabric.mod.json delete mode 100644 fabric-1.17/src/main/resources/permissions.yml.example delete mode 100644 forge-1.16.1/.gitignore delete mode 100644 forge-1.16.1/build.gradle delete mode 100644 forge-1.16.1/src/main/java/org/dynmap/forge_1_16_1/ChunkSnapshot.java delete mode 100644 forge-1.16.1/src/main/java/org/dynmap/forge_1_16_1/ClientProxy.java delete mode 100644 forge-1.16.1/src/main/java/org/dynmap/forge_1_16_1/DynmapMod.java delete mode 100644 forge-1.16.1/src/main/java/org/dynmap/forge_1_16_1/DynmapPlugin.java delete mode 100644 forge-1.16.1/src/main/java/org/dynmap/forge_1_16_1/ForgeMapChunkCache.java delete mode 100644 forge-1.16.1/src/main/java/org/dynmap/forge_1_16_1/ForgeWorld.java delete mode 100644 forge-1.16.1/src/main/java/org/dynmap/forge_1_16_1/Proxy.java delete mode 100644 forge-1.16.1/src/main/java/org/dynmap/forge_1_16_1/SnapshotCache.java delete mode 100644 forge-1.16.1/src/main/java/org/dynmap/forge_1_16_1/VersionCheck.java delete mode 100644 forge-1.16.1/src/main/java/org/dynmap/forge_1_16_1/permissions/FilePermissions.java delete mode 100644 forge-1.16.1/src/main/java/org/dynmap/forge_1_16_1/permissions/OpPermissions.java delete mode 100644 forge-1.16.1/src/main/java/org/dynmap/forge_1_16_1/permissions/PermissionProvider.java delete mode 100644 forge-1.16.1/src/main/resources/META-INF/accesstransformer.cfg delete mode 100644 forge-1.16.1/src/main/resources/META-INF/mods.toml delete mode 100644 forge-1.16.1/src/main/resources/configuration.txt delete mode 100644 forge-1.16.1/src/main/resources/pack.mcmeta delete mode 100644 forge-1.16.1/src/main/resources/permissions.yml.example delete mode 100644 forge-1.16.2/.gitignore delete mode 100644 forge-1.16.2/build.gradle delete mode 100644 forge-1.16.2/src/main/java/org/dynmap/forge_1_16_2/ChunkSnapshot.java delete mode 100644 forge-1.16.2/src/main/java/org/dynmap/forge_1_16_2/ClientProxy.java delete mode 100644 forge-1.16.2/src/main/java/org/dynmap/forge_1_16_2/DynmapMod.java delete mode 100644 forge-1.16.2/src/main/java/org/dynmap/forge_1_16_2/DynmapPlugin.java delete mode 100644 forge-1.16.2/src/main/java/org/dynmap/forge_1_16_2/ForgeMapChunkCache.java delete mode 100644 forge-1.16.2/src/main/java/org/dynmap/forge_1_16_2/ForgeWorld.java delete mode 100644 forge-1.16.2/src/main/java/org/dynmap/forge_1_16_2/Proxy.java delete mode 100644 forge-1.16.2/src/main/java/org/dynmap/forge_1_16_2/SnapshotCache.java delete mode 100644 forge-1.16.2/src/main/java/org/dynmap/forge_1_16_2/VersionCheck.java delete mode 100644 forge-1.16.2/src/main/java/org/dynmap/forge_1_16_2/permissions/FilePermissions.java delete mode 100644 forge-1.16.2/src/main/java/org/dynmap/forge_1_16_2/permissions/OpPermissions.java delete mode 100644 forge-1.16.2/src/main/java/org/dynmap/forge_1_16_2/permissions/PermissionProvider.java delete mode 100644 forge-1.16.2/src/main/resources/META-INF/accesstransformer.cfg delete mode 100644 forge-1.16.2/src/main/resources/META-INF/mods.toml delete mode 100644 forge-1.16.2/src/main/resources/configuration.txt delete mode 100644 forge-1.16.2/src/main/resources/pack.mcmeta delete mode 100644 forge-1.16.2/src/main/resources/permissions.yml.example delete mode 100644 forge-1.16.3/.gitignore delete mode 100644 forge-1.16.3/build.gradle delete mode 100644 forge-1.16.3/src/main/java/org/dynmap/forge_1_16_3/ChunkSnapshot.java delete mode 100644 forge-1.16.3/src/main/java/org/dynmap/forge_1_16_3/ClientProxy.java delete mode 100644 forge-1.16.3/src/main/java/org/dynmap/forge_1_16_3/DynmapMod.java delete mode 100644 forge-1.16.3/src/main/java/org/dynmap/forge_1_16_3/DynmapPlugin.java delete mode 100644 forge-1.16.3/src/main/java/org/dynmap/forge_1_16_3/ForgeMapChunkCache.java delete mode 100644 forge-1.16.3/src/main/java/org/dynmap/forge_1_16_3/ForgeWorld.java delete mode 100644 forge-1.16.3/src/main/java/org/dynmap/forge_1_16_3/Proxy.java delete mode 100644 forge-1.16.3/src/main/java/org/dynmap/forge_1_16_3/SnapshotCache.java delete mode 100644 forge-1.16.3/src/main/java/org/dynmap/forge_1_16_3/VersionCheck.java delete mode 100644 forge-1.16.3/src/main/java/org/dynmap/forge_1_16_3/permissions/FilePermissions.java delete mode 100644 forge-1.16.3/src/main/java/org/dynmap/forge_1_16_3/permissions/OpPermissions.java delete mode 100644 forge-1.16.3/src/main/java/org/dynmap/forge_1_16_3/permissions/PermissionProvider.java delete mode 100644 forge-1.16.3/src/main/resources/META-INF/accesstransformer.cfg delete mode 100644 forge-1.16.3/src/main/resources/META-INF/mods.toml delete mode 100644 forge-1.16.3/src/main/resources/configuration.txt delete mode 100644 forge-1.16.3/src/main/resources/pack.mcmeta delete mode 100644 forge-1.16.3/src/main/resources/permissions.yml.example delete mode 100644 forge-1.16.4/.gitignore delete mode 100644 forge-1.16.4/build.gradle delete mode 100644 forge-1.16.4/src/main/java/org/dynmap/forge_1_16_4/ChunkSnapshot.java delete mode 100644 forge-1.16.4/src/main/java/org/dynmap/forge_1_16_4/ClientProxy.java delete mode 100644 forge-1.16.4/src/main/java/org/dynmap/forge_1_16_4/DynmapMod.java delete mode 100644 forge-1.16.4/src/main/java/org/dynmap/forge_1_16_4/DynmapPlugin.java delete mode 100644 forge-1.16.4/src/main/java/org/dynmap/forge_1_16_4/ForgeMapChunkCache.java delete mode 100644 forge-1.16.4/src/main/java/org/dynmap/forge_1_16_4/ForgeWorld.java delete mode 100644 forge-1.16.4/src/main/java/org/dynmap/forge_1_16_4/Proxy.java delete mode 100644 forge-1.16.4/src/main/java/org/dynmap/forge_1_16_4/SnapshotCache.java delete mode 100644 forge-1.16.4/src/main/java/org/dynmap/forge_1_16_4/VersionCheck.java delete mode 100644 forge-1.16.4/src/main/java/org/dynmap/forge_1_16_4/permissions/FilePermissions.java delete mode 100644 forge-1.16.4/src/main/java/org/dynmap/forge_1_16_4/permissions/OpPermissions.java delete mode 100644 forge-1.16.4/src/main/java/org/dynmap/forge_1_16_4/permissions/PermissionProvider.java delete mode 100644 forge-1.16.4/src/main/resources/META-INF/accesstransformer.cfg delete mode 100644 forge-1.16.4/src/main/resources/META-INF/mods.toml delete mode 100644 forge-1.16.4/src/main/resources/configuration.txt delete mode 100644 forge-1.16.4/src/main/resources/pack.mcmeta delete mode 100644 forge-1.16.4/src/main/resources/permissions.yml.example diff --git a/fabric-1.16.1/.gitignore b/fabric-1.16.1/.gitignore deleted file mode 100644 index 8b87af68..00000000 --- a/fabric-1.16.1/.gitignore +++ /dev/null @@ -1,32 +0,0 @@ -# gradle - -.gradle/ -build/ -out/ -classes/ - -# eclipse - -*.launch - -# idea - -.idea/ -*.iml -*.ipr -*.iws - -# vscode - -.settings/ -.vscode/ -bin/ -.classpath -.project - -# fabric - -run/ - -# other -*.log diff --git a/fabric-1.16.1/build.gradle b/fabric-1.16.1/build.gradle deleted file mode 100644 index f0352ecf..00000000 --- a/fabric-1.16.1/build.gradle +++ /dev/null @@ -1,78 +0,0 @@ -buildscript { - repositories { - maven { url = 'https://maven.fabricmc.net/' } - jcenter() - mavenCentral() - } - dependencies { - classpath group: 'net.fabricmc', name: 'fabric-loom', version: '0.6-SNAPSHOT' - } -} -apply plugin: 'fabric-loom' - -sourceCompatibility = JavaVersion.VERSION_1_8 -targetCompatibility = JavaVersion.VERSION_1_8 - -archivesBaseName = project.archives_base_name -version = parent.version -group = parent.group - -configurations { - shadow - compile.extendsFrom(shadow) -} - -dependencies { - //to change the versions see the gradle.properties file - minecraft "com.mojang:minecraft:${project.minecraft_version}" - mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" - modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" - - // Fabric API. This is technically optional, but you probably want it anyway. - modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" - - compileOnly group: 'com.google.code.findbugs', name: 'jsr305', version: '3.0.2' - - shadow project(path: ':DynmapCore', configuration: 'shadow') - - // PSA: Some older mods, compiled on Loom 0.2.1, might have outdated Maven POMs. - // You may need to force-disable transitiveness on them. -} - -processResources { - filesMatching('fabric.mod.json') { - expand "version": project.version - } -} - -// ensure that the encoding is set to UTF-8, no matter what the system default is -// this fixes some edge cases with special characters not displaying correctly -// see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html -tasks.withType(JavaCompile) { - options.encoding = "UTF-8" -} - -// Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task -// if it is present. -// If you remove this task, sources will not be generated. -task sourcesJar(type: Jar, dependsOn: classes) { - classifier = "sources" - from sourceSets.main.allSource -} - -jar { - from "LICENSE" - from { - configurations.shadow.collect { it.toString().contains("guava") ? null : it.isDirectory() ? it : zipTree(it) } - } -} - -remapJar { - archiveName = "${archivesBaseName}-${version}-fabric-${project.minecraft_version}.jar" - destinationDir = file '../target' -} - -remapJar.doLast { - task -> - ant.checksum file: task.archivePath -} diff --git a/fabric-1.16.1/gradle.properties b/fabric-1.16.1/gradle.properties deleted file mode 100644 index ee22bee8..00000000 --- a/fabric-1.16.1/gradle.properties +++ /dev/null @@ -1,12 +0,0 @@ -# Done to increase the memory available to gradle. -org.gradle.jvmargs=-Xmx1G -# Fabric Properties -# check these on https://fabricmc.net/use -minecraft_version=1.16.1 -yarn_mappings=1.16.1+build.21 -loader_version=0.9.1+build.205 -# Mod Properties -archives_base_name=Dynmap -# Dependencies -# currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api -fabric_version=0.17.0+build.386-1.16.1 diff --git a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/ChunkSnapshot.java b/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/ChunkSnapshot.java deleted file mode 100644 index a8e95490..00000000 --- a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/ChunkSnapshot.java +++ /dev/null @@ -1,302 +0,0 @@ -package org.dynmap.fabric_1_16_1; - -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.ListTag; -import net.minecraft.util.collection.PackedIntegerArray; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.WordPackedArray; -import org.dynmap.Log; -import org.dynmap.renderer.DynmapBlockState; - -import java.util.Arrays; - -/** - * Represents a static, thread-safe snapshot of chunk of blocks - * Purpose is to allow clean, efficient copy of a chunk data to be made, and then handed off for processing in another thread (e.g. map rendering) - */ -public class ChunkSnapshot { - private static interface Section { - public DynmapBlockState getBlockType(int x, int y, int z); - - public int getBlockSkyLight(int x, int y, int z); - - public int getBlockEmittedLight(int x, int y, int z); - - public boolean isEmpty(); - } - - private final int x, z; - private final Section[] section; - private final int[] hmap; // Height map - private final int[] biome; - private final long captureFulltime; - private final int sectionCnt; - private final long inhabitedTicks; - - private static final int BLOCKS_PER_SECTION = 16 * 16 * 16; - private static final int COLUMNS_PER_CHUNK = 16 * 16; - private static final byte[] emptyData = new byte[BLOCKS_PER_SECTION / 2]; - private static final byte[] fullData = new byte[BLOCKS_PER_SECTION / 2]; - - static { - Arrays.fill(fullData, (byte) 0xFF); - } - - private static class EmptySection implements Section { - @Override - public DynmapBlockState getBlockType(int x, int y, int z) { - return DynmapBlockState.AIR; - } - - @Override - public int getBlockSkyLight(int x, int y, int z) { - return 15; - } - - @Override - public int getBlockEmittedLight(int x, int y, int z) { - return 0; - } - - @Override - public boolean isEmpty() { - return true; - } - } - - private static final EmptySection empty_section = new EmptySection(); - - private static class StdSection implements Section { - DynmapBlockState[] states; - byte[] skylight; - byte[] emitlight; - - public StdSection() { - states = new DynmapBlockState[BLOCKS_PER_SECTION]; - Arrays.fill(states, DynmapBlockState.AIR); - skylight = emptyData; - emitlight = emptyData; - } - - @Override - public DynmapBlockState getBlockType(int x, int y, int z) { - return states[((y & 0xF) << 8) | (z << 4) | x]; - } - - @Override - public int getBlockSkyLight(int x, int y, int z) { - int off = ((y & 0xF) << 7) | (z << 3) | (x >> 1); - return (skylight[off] >> (4 * (x & 1))) & 0xF; - } - - @Override - public int getBlockEmittedLight(int x, int y, int z) { - int off = ((y & 0xF) << 7) | (z << 3) | (x >> 1); - return (emitlight[off] >> (4 * (x & 1))) & 0xF; - } - - @Override - public boolean isEmpty() { - return false; - } - } - - /** - * Construct empty chunk snapshot - * - * @param x - * @param z - */ - public ChunkSnapshot(int worldheight, int x, int z, long captime, long inhabitedTime) { - this.x = x; - this.z = z; - this.captureFulltime = captime; - this.biome = new int[COLUMNS_PER_CHUNK]; - this.sectionCnt = worldheight / 16; - /* Allocate arrays indexed by section */ - this.section = new Section[this.sectionCnt+1]; - - /* Fill with empty data */ - for (int i = 0; i <= this.sectionCnt; i++) { - this.section[i] = empty_section; - } - - /* Create empty height map */ - this.hmap = new int[16 * 16]; - - this.inhabitedTicks = inhabitedTime; - } - - public static class StateListException extends Exception { - private static boolean loggedOnce = false; - - public StateListException(int x, int z, int actualLength, int expectedLength, int expectedLegacyLength) { - if (Log.verbose || !loggedOnce) { - loggedOnce = true; - Log.info("Skipping chunk at x=" + x + ",z=" + z + ". Expected statelist of length " + expectedLength + " or " + expectedLegacyLength + " but got " + actualLength + ". This can happen if the chunk was not yet converted to the 1.16 format which can be fixed by visiting the chunk."); - if (!Log.verbose) { - Log.info("You will only see this message once. Turn on verbose logging in the configuration to see all messages."); - } - } - } - } - - public ChunkSnapshot(CompoundTag nbt, int worldheight) throws StateListException { - this.x = nbt.getInt("xPos"); - this.z = nbt.getInt("zPos"); - this.captureFulltime = 0; - this.hmap = nbt.getIntArray("HeightMap"); - this.sectionCnt = worldheight / 16; - if (nbt.contains("InhabitedTime")) { - this.inhabitedTicks = nbt.getLong("InhabitedTime"); - } else { - this.inhabitedTicks = 0; - } - /* Allocate arrays indexed by section */ - this.section = new Section[this.sectionCnt+1]; - /* Fill with empty data */ - for (int i = 0; i <= this.sectionCnt; i++) { - this.section[i] = empty_section; - } - /* Get sections */ - ListTag sect = nbt.getList("Sections", 10); - for (int i = 0; i < sect.size(); i++) { - CompoundTag sec = sect.getCompound(i); - int secnum = sec.getByte("Y"); - if (secnum >= this.sectionCnt) { - //Log.info("Section " + (int) secnum + " above world height " + worldheight); - continue; - } - if (secnum < 0) - continue; - //System.out.println("section(" + secnum + ")=" + sec.asString()); - // Create normal section to initialize - StdSection cursect = new StdSection(); - this.section[secnum] = cursect; - DynmapBlockState[] states = cursect.states; - DynmapBlockState[] palette = null; - // If we've got palette and block states list, process non-empty section - if (sec.contains("Palette", 9) && sec.contains("BlockStates", 12)) { - ListTag plist = sec.getList("Palette", 10); - long[] statelist = sec.getLongArray("BlockStates"); - palette = new DynmapBlockState[plist.size()]; - for (int pi = 0; pi < plist.size(); pi++) { - CompoundTag tc = plist.getCompound(pi); - String pname = tc.getString("Name"); - if (tc.contains("Properties")) { - StringBuilder statestr = new StringBuilder(); - CompoundTag prop = tc.getCompound("Properties"); - for (String pid : prop.getKeys()) { - if (statestr.length() > 0) statestr.append(','); - statestr.append(pid).append('=').append(prop.get(pid).asString()); - } - palette[pi] = DynmapBlockState.getStateByNameAndState(pname, statestr.toString()); - } - if (palette[pi] == null) { - palette[pi] = DynmapBlockState.getBaseStateByName(pname); - } - if (palette[pi] == null) { - palette[pi] = DynmapBlockState.AIR; - } - } - - PackedIntegerArray db = null; - WordPackedArray dbp = null; - - int bitsperblock = (statelist.length * 64) / 4096; - int expectedStatelistLength = (4096 + (64 / bitsperblock) - 1) / (64 / bitsperblock); - if (statelist.length == expectedStatelistLength) { - db = new PackedIntegerArray(bitsperblock, 4096, statelist); - } else { - int expectedLegacyStatelistLength = MathHelper.roundUpToMultiple(bitsperblock * 4096, 64) / 64; - if (statelist.length == expectedLegacyStatelistLength) { - dbp = new WordPackedArray(bitsperblock, 4096, statelist); - } else { - throw new StateListException(x, z, statelist.length, expectedStatelistLength, expectedLegacyStatelistLength); - } - } - - if (bitsperblock > 8) { // Not palette - for (int j = 0; j < 4096; j++) { - int v = db != null ? db.get(j) : dbp.get(j); - states[j] = DynmapBlockState.getStateByGlobalIndex(v); - } - } else { - for (int j = 0; j < 4096; j++) { - int v = db != null ? db.get(j) : dbp.get(j); - states[j] = (v < palette.length) ? palette[v] : DynmapBlockState.AIR; - } - } - } - if (sec.contains("BlockLight")) { - cursect.emitlight = sec.getByteArray("BlockLight"); - } - if (sec.contains("SkyLight")) { - cursect.skylight = sec.getByteArray("SkyLight"); - } - } - /* Get biome data */ - this.biome = new int[COLUMNS_PER_CHUNK]; - if (nbt.contains("Biomes")) { - int[] bb = nbt.getIntArray("Biomes"); - if (bb != null) { - // If v1.15+ format - if (bb.length > COLUMNS_PER_CHUNK) { - // For now, just pad the grid with the first 16 - for (int i = 0; i < COLUMNS_PER_CHUNK; i++) { - int off = ((i >> 4) & 0xC) + ((i >> 2) & 0x3); - int bv = bb[off + 64]; // Offset to y=64 - if (bv < 0) bv = 0; - this.biome[i] = bv; - } - } else { // Else, older chunks - for (int i = 0; i < bb.length; i++) { - int bv = bb[i]; - if (bv < 0) bv = 0; - this.biome[i] = bv; - } - } - } - } - } - - public int getX() { - return x; - } - - public int getZ() { - return z; - } - - public DynmapBlockState getBlockType(int x, int y, int z) { - return section[y >> 4].getBlockType(x, y, z); - } - - public int getBlockSkyLight(int x, int y, int z) { - return section[y >> 4].getBlockSkyLight(x, y, z); - } - - public int getBlockEmittedLight(int x, int y, int z) { - return section[y >> 4].getBlockEmittedLight(x, y, z); - } - - public int getHighestBlockYAt(int x, int z) { - return hmap[z << 4 | x]; - } - - public int getBiome(int x, int z) { - return biome[z << 4 | x]; - } - - public final long getCaptureFullTime() { - return captureFulltime; - } - - public boolean isSectionEmpty(int sy) { - return section[sy].isEmpty(); - } - - public long getInhabitedTicks() { - return inhabitedTicks; - } -} diff --git a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/DynmapMod.java b/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/DynmapMod.java deleted file mode 100644 index 730c87cd..00000000 --- a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/DynmapMod.java +++ /dev/null @@ -1,50 +0,0 @@ -package org.dynmap.fabric_1_16_1; - -import net.fabricmc.api.ModInitializer; -import net.fabricmc.loader.api.FabricLoader; -import net.fabricmc.loader.api.ModContainer; -import org.dynmap.DynmapCore; -import org.dynmap.Log; - -import java.io.File; -import java.net.URISyntaxException; -import java.nio.file.Path; -import java.nio.file.Paths; - -public class DynmapMod implements ModInitializer { - private static final String MODID = "dynmap"; - private static final ModContainer MOD_CONTAINER = FabricLoader.getInstance().getModContainer(MODID) - .orElseThrow(() -> new RuntimeException("Failed to get mod container: " + MODID)); - // The instance of your mod that Fabric uses. - public static DynmapMod instance; - - public static DynmapPlugin plugin; - public static File jarfile; - public static String ver; - public static boolean useforcedchunks; - - @Override - public void onInitialize() { - instance = this; - - Path path = MOD_CONTAINER.getRootPath(); - try { - jarfile = new File(DynmapCore.class.getProtectionDomain().getCodeSource().getLocation().toURI()); - } catch (URISyntaxException e) { - Log.severe("Unable to get DynmapCore jar path", e); - } - - if (path.getFileSystem().provider().getScheme().equals("jar")) { - path = Paths.get(path.getFileSystem().toString()); - jarfile = path.toFile(); - } - - ver = MOD_CONTAINER.getMetadata().getVersion().getFriendlyString(); - - Log.setLogger(new FabricLogger()); - org.dynmap.modsupport.ModSupportImpl.init(); - - // Initialize the plugin, we will enable it fully when the server starts. - plugin = new DynmapPlugin(); - } -} diff --git a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/DynmapPlugin.java b/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/DynmapPlugin.java deleted file mode 100644 index 6dd33db3..00000000 --- a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/DynmapPlugin.java +++ /dev/null @@ -1,912 +0,0 @@ -package org.dynmap.fabric_1_16_1; - -import com.mojang.brigadier.CommandDispatcher; -import com.mojang.brigadier.exceptions.CommandSyntaxException; -import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap; -import it.unimi.dsi.fastutil.longs.LongOpenHashSet; -import net.fabricmc.fabric.api.command.v1.CommandRegistrationCallback; -import net.fabricmc.fabric.api.event.lifecycle.v1.ServerChunkEvents; -import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; -import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents; -import net.fabricmc.fabric.api.event.lifecycle.v1.ServerWorldEvents; -import net.minecraft.block.Block; -import net.minecraft.block.BlockState; -import net.minecraft.block.FluidBlock; -import net.minecraft.block.Material; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.Item; -import net.minecraft.network.ClientConnection; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.command.ServerCommandSource; -import net.minecraft.server.network.ServerPlayNetworkHandler; -import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.server.world.ChunkHolder; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.util.Identifier; -import net.minecraft.util.collection.IdList; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.ChunkPos; -import net.minecraft.util.registry.Registry; -import net.minecraft.world.World; -import net.minecraft.world.WorldAccess; -import net.minecraft.world.biome.Biome; -import net.minecraft.world.chunk.Chunk; -import net.minecraft.world.chunk.ChunkSection; -import net.minecraft.world.chunk.ChunkStatus; -import net.minecraft.world.chunk.WorldChunk; -import org.dynmap.*; -import org.dynmap.common.BiomeMap; -import org.dynmap.common.DynmapCommandSender; -import org.dynmap.common.DynmapListenerManager; -import org.dynmap.common.DynmapPlayer; -import org.dynmap.fabric_1_16_1.command.DmapCommand; -import org.dynmap.fabric_1_16_1.command.DmarkerCommand; -import org.dynmap.fabric_1_16_1.command.DynmapCommand; -import org.dynmap.fabric_1_16_1.command.DynmapExpCommand; -import org.dynmap.fabric_1_16_1.event.BlockEvents; -import org.dynmap.fabric_1_16_1.event.ChunkDataEvents; -import org.dynmap.fabric_1_16_1.event.CustomServerLifecycleEvents; -import org.dynmap.fabric_1_16_1.event.PlayerEvents; -import org.dynmap.fabric_1_16_1.mixin.BiomeEffectsAccessor; -import org.dynmap.fabric_1_16_1.mixin.ThreadedAnvilChunkStorageAccessor; -import org.dynmap.fabric_1_16_1.permissions.FilePermissions; -import org.dynmap.fabric_1_16_1.permissions.OpPermissions; -import org.dynmap.fabric_1_16_1.permissions.PermissionProvider; -import org.dynmap.permissions.PermissionsHandler; -import org.dynmap.renderer.DynmapBlockState; - -import java.io.File; -import java.util.*; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.regex.Pattern; - -public class DynmapPlugin { - // FIXME: Fix package-private fields after splitting is done - DynmapCore core; - private PermissionProvider permissions; - private boolean core_enabled; - public SnapshotCache sscache; - public PlayerList playerList; - MapManager mapManager; - /** - * Server is set when running and unset at shutdown. - */ - private net.minecraft.server.MinecraftServer server; - public static DynmapPlugin plugin; - ChatHandler chathandler; - private HashMap sortWeights = new HashMap(); - // Drop world load ticket after 30 seconds - private long worldIdleTimeoutNS = 30 * 1000000000L; - private HashMap worlds = new HashMap(); - private WorldAccess last_world; - private FabricWorld last_fworld; - private Map players = new HashMap(); - //TODO private ForgeMetrics metrics; - private HashSet modsused = new HashSet(); - private FabricServer fserver; - private boolean tickregistered = false; - // TPS calculator - double tps; - long lasttick; - long avgticklen; - // Per tick limit, in nsec - long perTickLimit = (50000000); // 50 ms - private boolean useSaveFolder = true; - - private static final int SIGNPOST_ID = 63; - private static final int WALLSIGN_ID = 68; - - private static final String[] TRIGGER_DEFAULTS = {"blockupdate", "chunkpopulate", "chunkgenerate"}; - - static final Pattern patternControlCode = Pattern.compile("(?i)\\u00A7[0-9A-FK-OR]"); - - DynmapPlugin() { - plugin = this; - // Fabric events persist between server instances - ServerLifecycleEvents.SERVER_STARTING.register(this::serverStart); - CommandRegistrationCallback.EVENT.register((dispatcher, dedicated) -> registerCommands(dispatcher)); - CustomServerLifecycleEvents.SERVER_STARTED_PRE_WORLD_LOAD.register(this::serverStarted); - ServerLifecycleEvents.SERVER_STOPPING.register(this::serverStop); - } - - int getSortWeight(String name) { - return sortWeights.getOrDefault(name, 0); - } - - void setSortWeight(String name, int wt) { - sortWeights.put(name, wt); - } - - void dropSortWeight(String name) { - sortWeights.remove(name); - } - - public static class BlockUpdateRec { - WorldAccess w; - String wid; - int x, y, z; - } - - ConcurrentLinkedQueue blockupdatequeue = new ConcurrentLinkedQueue(); - - public static DynmapBlockState[] stateByID; - - private Map knownloadedchunks = new HashMap(); - private boolean didInitialKnownChunks = false; - - private void addKnownChunk(FabricWorld fw, ChunkPos pos) { - LongOpenHashSet cset = knownloadedchunks.get(fw.getName()); - if (cset == null) { - cset = new LongOpenHashSet(); - knownloadedchunks.put(fw.getName(), cset); - } - cset.add(pos.toLong()); - } - - private void removeKnownChunk(FabricWorld fw, ChunkPos pos) { - LongOpenHashSet cset = knownloadedchunks.get(fw.getName()); - if (cset != null) { - cset.remove(pos.toLong()); - } - } - - private boolean checkIfKnownChunk(FabricWorld fw, ChunkPos pos) { - LongOpenHashSet cset = knownloadedchunks.get(fw.getName()); - if (cset != null) { - return cset.contains(pos.toLong()); - } - return false; - } - - /** - * Initialize block states (org.dynmap.blockstate.DynmapBlockState) - */ - public void initializeBlockStates() { - stateByID = new DynmapBlockState[512 * 32]; // Simple map - scale as needed - Arrays.fill(stateByID, DynmapBlockState.AIR); // Default to air - - IdList bsids = Block.STATE_IDS; - - DynmapBlockState basebs = null; - Block baseb = null; - int baseidx = 0; - - Iterator iter = bsids.iterator(); - while (iter.hasNext()) { - BlockState bs = iter.next(); - int idx = bsids.getId(bs); - if (idx >= stateByID.length) { - int plen = stateByID.length; - stateByID = Arrays.copyOf(stateByID, idx*11/10); // grow array by 10% - Arrays.fill(stateByID, plen, stateByID.length, DynmapBlockState.AIR); - } - Block b = bs.getBlock(); - // If this is new block vs last, it's the base block state - if (b != baseb) { - basebs = null; - baseidx = idx; - baseb = b; - } - - Identifier ui = Registry.BLOCK.getId(b); - if (ui == null) { - continue; - } - String bn = ui.getNamespace() + ":" + ui.getPath(); - // Only do defined names, and not "air" - if (!bn.equals(DynmapBlockState.AIR_BLOCK)) { - Material mat = bs.getMaterial(); - String statename = ""; - for (net.minecraft.state.property.Property p : bs.getProperties()) { - if (statename.length() > 0) { - statename += ","; - } - statename += p.getName() + "=" + bs.get(p).toString(); - } - //Log.info("bn=" + bn + ", statenme=" + statename + ",idx=" + idx + ",baseidx=" + baseidx); - DynmapBlockState dbs = new DynmapBlockState(basebs, idx - baseidx, bn, statename, mat.toString(), idx); - stateByID[idx] = dbs; - if (basebs == null) { - basebs = dbs; - } - if (mat.isSolid()) { - dbs.setSolid(); - } - if (mat == Material.AIR) { - dbs.setAir(); - } - if (mat == Material.WOOD) { - dbs.setLog(); - } - if (mat == Material.LEAVES) { - dbs.setLeaves(); - } - if ((!bs.getFluidState().isEmpty()) && !(bs.getBlock() instanceof FluidBlock)) { - dbs.setWaterlogged(); - } - } - } - for (int gidx = 0; gidx < DynmapBlockState.getGlobalIndexMax(); gidx++) { - DynmapBlockState bs = DynmapBlockState.getStateByGlobalIndex(gidx); - //Log.info(gidx + ":" + bs.toString() + ", gidx=" + bs.globalStateIndex + ", sidx=" + bs.stateIndex); - } - } - - public static final Item getItemByID(int id) { - return Item.byRawId(id); - } - - private static Biome[] biomelist = null; - - public static final Biome[] getBiomeList() { - if (biomelist == null) { - biomelist = new Biome[256]; - Iterator iter = Registry.BIOME.iterator(); - while (iter.hasNext()) { - Biome b = iter.next(); - int bidx = Registry.BIOME.getRawId(b); - if (bidx >= biomelist.length) { - biomelist = Arrays.copyOf(biomelist, bidx + biomelist.length); - } - biomelist[bidx] = b; - } - } - return biomelist; - } - - public static final ClientConnection getNetworkManager(ServerPlayNetworkHandler nh) { - return nh.connection; - } - - FabricPlayer getOrAddPlayer(ServerPlayerEntity player) { - String name = player.getName().getString(); - FabricPlayer fp = players.get(name); - if (fp != null) { - fp.player = player; - } else { - fp = new FabricPlayer(this, player); - players.put(name, fp); - } - return fp; - } - - static class ChatMessage { - String message; - ServerPlayerEntity sender; - } - - ConcurrentLinkedQueue msgqueue = new ConcurrentLinkedQueue(); - - public static class ChatHandler { - private final DynmapPlugin plugin; - - ChatHandler(DynmapPlugin plugin) { - this.plugin = plugin; - } - - public void handleChat(ServerPlayerEntity player, String message) { - if (!message.startsWith("/")) { - ChatMessage cm = new ChatMessage(); - cm.message = message; - cm.sender = player; - plugin.msgqueue.add(cm); - } - } - } - - private void serverStart(MinecraftServer server) { - // Set the server so we don't NPE during setup - this.server = server; - this.fserver = new FabricServer(this, server); - this.onEnable(); - } - - private void serverStarted(MinecraftServer server) { - this.onStart(); - if (core != null) { - core.serverStarted(); - } - } - - private void serverStop(MinecraftServer server) { - this.onDisable(); - this.server = null; - } - - public boolean isOp(String player) { - String[] ops = server.getPlayerManager().getOpList().getNames(); - - for (String op : ops) { - if (op.equalsIgnoreCase(player)) { - return true; - } - } - - // TODO: Consider whether cheats are enabled for integrated server - return server.isSinglePlayer() && player.equalsIgnoreCase(server.getUserName()); - } - - boolean hasPerm(PlayerEntity psender, String permission) { - PermissionsHandler ph = PermissionsHandler.getHandler(); - if ((psender != null) && ph.hasPermission(psender.getName().getString(), permission)) { - return true; - } - return permissions.has(psender, permission); - } - - boolean hasPermNode(PlayerEntity psender, String permission) { - PermissionsHandler ph = PermissionsHandler.getHandler(); - if ((psender != null) && ph.hasPermissionNode(psender.getName().getString(), permission)) { - return true; - } - return permissions.hasPermissionNode(psender, permission); - } - - Set hasOfflinePermissions(String player, Set perms) { - Set rslt = null; - PermissionsHandler ph = PermissionsHandler.getHandler(); - if (ph != null) { - rslt = ph.hasOfflinePermissions(player, perms); - } - Set rslt2 = hasOfflinePermissions(player, perms); - if ((rslt != null) && (rslt2 != null)) { - Set newrslt = new HashSet(rslt); - newrslt.addAll(rslt2); - rslt = newrslt; - } else if (rslt2 != null) { - rslt = rslt2; - } - return rslt; - } - - boolean hasOfflinePermission(String player, String perm) { - PermissionsHandler ph = PermissionsHandler.getHandler(); - if (ph != null) { - if (ph.hasOfflinePermission(player, perm)) { - return true; - } - } - return permissions.hasOfflinePermission(player, perm); - } - - void setChatHandler(ChatHandler chatHandler) { - plugin.chathandler = chatHandler; - } - - public class TexturesPayload { - public long timestamp; - public String profileId; - public String profileName; - public boolean isPublic; - public Map textures; - - } - - public class ProfileTexture { - public String url; - } - - public void loadExtraBiomes(String mcver) { - int cnt = 0; - BiomeMap.loadWellKnownByVersion(mcver); - - Biome[] list = getBiomeList(); - - for (int i = 0; i < list.length; i++) { - Biome bb = list[i]; - if (bb != null) { - String id = Registry.BIOME.getId(bb).getPath(); - float tmp = bb.getTemperature(), hum = bb.getRainfall(); - int watermult = ((BiomeEffectsAccessor) bb.getEffects()).getWaterColor(); - Log.verboseinfo("biome[" + i + "]: hum=" + hum + ", tmp=" + tmp + ", mult=" + Integer.toHexString(watermult)); - - BiomeMap bmap = BiomeMap.byBiomeID(i); - if (bmap.isDefault()) { - bmap = new BiomeMap(i, id, tmp, hum); - Log.verboseinfo("Add custom biome [" + bmap.toString() + "] (" + i + ")"); - cnt++; - } else { - bmap.setTemperature(tmp); - bmap.setRainfall(hum); - } - if (watermult != -1) { - bmap.setWaterColorMultiplier(watermult); - Log.verboseinfo("Set watercolormult for " + bmap.toString() + " (" + i + ") to " + Integer.toHexString(watermult)); - } - } - } - if (cnt > 0) - Log.info("Added " + cnt + " custom biome mappings"); - } - - private String[] getBiomeNames() { - Biome[] list = getBiomeList(); - String[] lst = new String[list.length]; - for (int i = 0; i < list.length; i++) { - Biome bb = list[i]; - if (bb != null) { - lst[i] = Registry.BIOME.getId(bb).getPath(); - } - } - return lst; - } - - public void onEnable() { - /* Get MC version */ - String mcver = server.getVersion(); - - /* Load extra biomes */ - loadExtraBiomes(mcver); - /* Set up player login/quit event handler */ - registerPlayerLoginListener(); - - /* Initialize permissions handler */ - permissions = FilePermissions.create(); - if (permissions == null) { - permissions = new OpPermissions(new String[]{"webchat", "marker.icons", "marker.list", "webregister", "stats", "hide.self", "show.self"}); - } - /* Get and initialize data folder */ - File dataDirectory = new File("dynmap"); - - if (!dataDirectory.exists()) { - dataDirectory.mkdirs(); - } - - /* Instantiate core */ - if (core == null) { - core = new DynmapCore(); - } - - /* Inject dependencies */ - core.setPluginJarFile(DynmapMod.jarfile); - core.setPluginVersion(DynmapMod.ver); - core.setMinecraftVersion(mcver); - core.setDataFolder(dataDirectory); - core.setServer(fserver); - FabricMapChunkCache.init(); - core.setTriggerDefault(TRIGGER_DEFAULTS); - core.setBiomeNames(getBiomeNames()); - - if (!core.initConfiguration(null)) { - return; - } - // Extract default permission example, if needed - File filepermexample = new File(core.getDataFolder(), "permissions.yml.example"); - core.createDefaultFileFromResource("/permissions.yml.example", filepermexample); - - DynmapCommonAPIListener.apiInitialized(core); - } - - private DynmapCommand dynmapCmd; - private DmapCommand dmapCmd; - private DmarkerCommand dmarkerCmd; - private DynmapExpCommand dynmapexpCmd; - - public void registerCommands(CommandDispatcher cd) { - dynmapCmd = new DynmapCommand(this); - dmapCmd = new DmapCommand(this); - dmarkerCmd = new DmarkerCommand(this); - dynmapexpCmd = new DynmapExpCommand(this); - dynmapCmd.register(cd); - dmapCmd.register(cd); - dmarkerCmd.register(cd); - dynmapexpCmd.register(cd); - - Log.info("Register commands"); - } - - public void onStart() { - initializeBlockStates(); - /* Enable core */ - if (!core.enableCore(null)) { - return; - } - core_enabled = true; - VersionCheck.runCheck(core); - // Get per tick time limit - perTickLimit = core.getMaxTickUseMS() * 1000000; - // Prep TPS - lasttick = System.nanoTime(); - tps = 20.0; - - /* Register tick handler */ - if (!tickregistered) { - ServerTickEvents.END_SERVER_TICK.register(server -> fserver.tickEvent(server)); - tickregistered = true; - } - - playerList = core.playerList; - sscache = new SnapshotCache(core.getSnapShotCacheSize(), core.useSoftRefInSnapShotCache()); - /* Get map manager from core */ - mapManager = core.getMapManager(); - - /* Load saved world definitions */ - loadWorlds(); - - /* Initialized the currently loaded worlds */ - if (server.getWorlds() != null) { - for (ServerWorld world : server.getWorlds()) { - FabricWorld w = this.getWorld(world); - /*NOTYET - need rest of forge - if(DimensionManager.getWorld(world.provider.getDimensionId()) == null) { // If not loaded - w.setWorldUnloaded(); - } - */ - } - } - for (FabricWorld w : worlds.values()) { - if (core.processWorldLoad(w)) { /* Have core process load first - fire event listeners if good load after */ - if (w.isLoaded()) { - core.listenerManager.processWorldEvent(DynmapListenerManager.EventType.WORLD_LOAD, w); - } - } - } - core.updateConfigHashcode(); - - /* Register our update trigger events */ - registerEvents(); - Log.info("Register events"); - - //DynmapCommonAPIListener.apiInitialized(core); - - Log.info("Enabled"); - } - - public void onDisable() { - DynmapCommonAPIListener.apiTerminated(); - - //if (metrics != null) { - // metrics.stop(); - // metrics = null; - //} - /* Save worlds */ - saveWorlds(); - - /* Purge tick queue */ - fserver.clearTaskQueue(); - - /* Disable core */ - core.disableCore(); - core_enabled = false; - - if (sscache != null) { - sscache.cleanup(); - sscache = null; - } - - Log.info("Disabled"); - } - - // TODO: Clean a bit - public void handleCommand(ServerCommandSource commandSource, String cmd, String[] args) throws CommandSyntaxException { - DynmapCommandSender dsender; - ServerPlayerEntity psender = null; - - // getPlayer throws a CommandSyntaxException, so getEntity and instanceof for safety - if (commandSource.getEntity() instanceof ServerPlayerEntity) { - psender = commandSource.getPlayer(); - } - - if (psender != null) { - // FIXME: New Player? Why not query the current player list. - dsender = new FabricPlayer(this, psender); - } else { - dsender = new FabricCommandSender(commandSource); - } - - core.processCommand(dsender, cmd, cmd, args); - } - - public class PlayerTracker { - public void onPlayerLogin(ServerPlayerEntity player) { - if (!core_enabled) return; - final DynmapPlayer dp = getOrAddPlayer(player); - /* This event can be called from off server thread, so push processing there */ - core.getServer().scheduleServerTask(new Runnable() { - public void run() { - core.listenerManager.processPlayerEvent(DynmapListenerManager.EventType.PLAYER_JOIN, dp); - } - }, 2); - } - - public void onPlayerLogout(ServerPlayerEntity player) { - if (!core_enabled) return; - final DynmapPlayer dp = getOrAddPlayer(player); - final String name = player.getName().getString(); - /* This event can be called from off server thread, so push processing there */ - core.getServer().scheduleServerTask(new Runnable() { - public void run() { - core.listenerManager.processPlayerEvent(DynmapListenerManager.EventType.PLAYER_QUIT, dp); - players.remove(name); - } - }, 0); - } - - public void onPlayerChangedDimension(ServerPlayerEntity player) { - if (!core_enabled) return; - getOrAddPlayer(player); // Freshen player object reference - } - - public void onPlayerRespawn(ServerPlayerEntity player) { - if (!core_enabled) return; - getOrAddPlayer(player); // Freshen player object reference - } - } - - private PlayerTracker playerTracker = null; - - private void registerPlayerLoginListener() { - if (playerTracker == null) { - playerTracker = new PlayerTracker(); - PlayerEvents.PLAYER_LOGGED_IN.register(player -> playerTracker.onPlayerLogin(player)); - PlayerEvents.PLAYER_LOGGED_OUT.register(player -> playerTracker.onPlayerLogout(player)); - PlayerEvents.PLAYER_CHANGED_DIMENSION.register(player -> playerTracker.onPlayerChangedDimension(player)); - PlayerEvents.PLAYER_RESPAWN.register(player -> playerTracker.onPlayerRespawn(player)); - } - } - - public class WorldTracker { - public void handleWorldLoad(MinecraftServer server, ServerWorld world) { - if (!core_enabled) return; - - final FabricWorld fw = getWorld(world); - // This event can be called from off server thread, so push processing there - core.getServer().scheduleServerTask(new Runnable() { - public void run() { - if (core.processWorldLoad(fw)) // Have core process load first - fire event listeners if good load after - core.listenerManager.processWorldEvent(DynmapListenerManager.EventType.WORLD_LOAD, fw); - } - }, 0); - } - - public void handleWorldUnload(MinecraftServer server, ServerWorld world) { - if (!core_enabled) return; - - final FabricWorld fw = getWorld(world); - if (fw != null) { - // This event can be called from off server thread, so push processing there - core.getServer().scheduleServerTask(new Runnable() { - public void run() { - core.listenerManager.processWorldEvent(DynmapListenerManager.EventType.WORLD_UNLOAD, fw); - core.processWorldUnload(fw); - } - }, 0); - // Set world unloaded (needs to be immediate, since it may be invalid after event) - fw.setWorldUnloaded(); - // Clean up tracker - //WorldUpdateTracker wut = updateTrackers.remove(fw.getName()); - //if(wut != null) wut.world = null; - } - } - - public void handleChunkLoad(ServerWorld world, WorldChunk chunk) { - if (!onchunkgenerate) return; - - if ((chunk != null) && (chunk.getStatus() == ChunkStatus.FULL)) { - FabricWorld fw = getWorld(world, false); - if (fw != null) { - addKnownChunk(fw, chunk.getPos()); - } - } - } - - public void handleChunkUnload(ServerWorld world, WorldChunk chunk) { - if (!onchunkgenerate) return; - - if ((chunk != null) && (chunk.getStatus() == ChunkStatus.FULL)) { - FabricWorld fw = getWorld(world, false); - ChunkPos cp = chunk.getPos(); - if (fw != null) { - if (!checkIfKnownChunk(fw, cp)) { - int ymax = 0; - ChunkSection[] sections = chunk.getSectionArray(); - for (int i = 0; i < sections.length; i++) { - if ((sections[i] != null) && (!sections[i].isEmpty())) { - ymax = 16 * (i + 1); - } - } - int x = cp.x << 4; - int z = cp.z << 4; - // If not empty AND not initial scan - if (ymax > 0) { - Log.info("New generated chunk detected at " + cp + " for " + fw.getName()); - mapManager.touchVolume(fw.getName(), x, 0, z, x + 15, ymax, z + 16, "chunkgenerate"); - } - } - removeKnownChunk(fw, cp); - } - } - } - - public void handleChunkDataSave(ServerWorld world, Chunk chunk) { - if (!onchunkgenerate) return; - - if ((chunk != null) && (chunk.getStatus() == ChunkStatus.FULL)) { - FabricWorld fw = getWorld(world, false); - ChunkPos cp = chunk.getPos(); - if (fw != null) { - if (!checkIfKnownChunk(fw, cp)) { - int ymax = 0; - ChunkSection[] sections = chunk.getSectionArray(); - for (int i = 0; i < sections.length; i++) { - if ((sections[i] != null) && (!sections[i].isEmpty())) { - ymax = 16 * (i + 1); - } - } - int x = cp.x << 4; - int z = cp.z << 4; - // If not empty AND not initial scan - if (ymax > 0) { - mapManager.touchVolume(fw.getName(), x, 0, z, x + 15, ymax, z + 16, "chunkgenerate"); - } - addKnownChunk(fw, cp); - } - } - } - } - - public void handleBlockEvent(World world, BlockPos pos) { - if (!core_enabled) return; - if (!onblockchange) return; - if (!(world instanceof ServerWorld)) return; - - BlockUpdateRec r = new BlockUpdateRec(); - r.w = world; - FabricWorld fw = getWorld(r.w, false); - if (fw == null) return; - r.wid = fw.getName(); - r.x = pos.getX(); - r.y = pos.getY(); - r.z = pos.getZ(); - blockupdatequeue.add(r); - } - } - - private WorldTracker worldTracker = null; - private boolean onblockchange = false; - private boolean onchunkpopulate = false; - private boolean onchunkgenerate = false; - boolean onblockchange_with_id = false; - - private void registerEvents() { - // To trigger rendering. - onblockchange = core.isTrigger("blockupdate"); - onchunkpopulate = core.isTrigger("chunkpopulate"); - onchunkgenerate = core.isTrigger("chunkgenerate"); - onblockchange_with_id = core.isTrigger("blockupdate-with-id"); - if (onblockchange_with_id) - onblockchange = true; - if ((worldTracker == null) && (onblockchange || onchunkpopulate || onchunkgenerate)) { - worldTracker = new WorldTracker(); - ServerWorldEvents.LOAD.register((server, world) -> worldTracker.handleWorldLoad(server, world)); - ServerWorldEvents.UNLOAD.register((server, world) -> worldTracker.handleWorldUnload(server, world)); - ServerChunkEvents.CHUNK_LOAD.register((world, chunk) -> worldTracker.handleChunkLoad(world, chunk)); - ServerChunkEvents.CHUNK_UNLOAD.register((world, chunk) -> worldTracker.handleChunkUnload(world, chunk)); - ChunkDataEvents.SAVE.register((world, chunk) -> worldTracker.handleChunkDataSave(world, chunk)); - BlockEvents.EVENT.register((world, pos) -> worldTracker.handleBlockEvent(world, pos)); - } - // Prime the known full chunks - if (onchunkgenerate && (server.getWorlds() != null)) { - for (ServerWorld world : server.getWorlds()) { - FabricWorld fw = getWorld(world); - if (fw == null) continue; - Long2ObjectLinkedOpenHashMap chunks = ((ThreadedAnvilChunkStorageAccessor) world.getChunkManager().threadedAnvilChunkStorage).getChunkHolders(); - for (Map.Entry k : chunks.long2ObjectEntrySet()) { - long key = k.getKey(); - ChunkHolder ch = k.getValue(); - Chunk c = null; - try { - c = ch.getFuture().getNow(null); - } catch (Exception x) { - } - if (c == null) continue; - ChunkStatus cs = c.getStatus(); - ChunkPos pos = ch.getPos(); - if (cs == ChunkStatus.FULL) { // Cooked? - // Add it as known - addKnownChunk(fw, pos); - } - } - } - } - } - - FabricWorld getWorldByName(String name) { - return worlds.get(name); - } - - FabricWorld getWorld(WorldAccess w) { - return getWorld(w, true); - } - - private FabricWorld getWorld(WorldAccess w, boolean add_if_not_found) { - if (last_world == w) { - return last_fworld; - } - String wname = FabricWorld.getWorldName(w); - - for (FabricWorld fw : worlds.values()) { - if (fw.getRawName().equals(wname)) { - last_world = w; - last_fworld = fw; - if (!fw.isLoaded()) { - fw.setWorldLoaded(w); - } - return fw; - } - } - FabricWorld fw = null; - if (add_if_not_found) { - /* Add to list if not found */ - fw = new FabricWorld(w); - worlds.put(fw.getName(), fw); - } - last_world = w; - last_fworld = fw; - return fw; - } - - private void saveWorlds() { - File f = new File(core.getDataFolder(), FabricWorld.SAVED_WORLDS_FILE); - ConfigurationNode cn = new ConfigurationNode(f); - ArrayList> lst = new ArrayList>(); - for (DynmapWorld fw : core.mapManager.getWorlds()) { - HashMap vals = new HashMap(); - vals.put("name", fw.getRawName()); - vals.put("height", fw.worldheight); - vals.put("sealevel", fw.sealevel); - vals.put("nether", fw.isNether()); - vals.put("the_end", ((FabricWorld) fw).isTheEnd()); - vals.put("title", fw.getTitle()); - lst.add(vals); - } - cn.put("worlds", lst); - cn.put("useSaveFolderAsName", useSaveFolder); - cn.put("maxWorldHeight", FabricWorld.getMaxWorldHeight()); - - cn.save(); - } - - private void loadWorlds() { - File f = new File(core.getDataFolder(), FabricWorld.SAVED_WORLDS_FILE); - if (f.canRead() == false) { - useSaveFolder = true; - return; - } - ConfigurationNode cn = new ConfigurationNode(f); - cn.load(); - // If defined, use maxWorldHeight - FabricWorld.setMaxWorldHeight(cn.getInteger("maxWorldHeight", 256)); - - // If setting defined, use it - if (cn.containsKey("useSaveFolderAsName")) { - useSaveFolder = cn.getBoolean("useSaveFolderAsName", useSaveFolder); - } - List> lst = cn.getMapList("worlds"); - if (lst == null) { - Log.warning(String.format("Discarding bad %s", FabricWorld.SAVED_WORLDS_FILE)); - return; - } - - for (Map world : lst) { - try { - String name = (String) world.get("name"); - int height = (Integer) world.get("height"); - int sealevel = (Integer) world.get("sealevel"); - boolean nether = (Boolean) world.get("nether"); - boolean theend = (Boolean) world.get("the_end"); - String title = (String) world.get("title"); - if (name != null) { - FabricWorld fw = new FabricWorld(name, height, sealevel, nether, theend, title); - fw.setWorldUnloaded(); - core.processWorldLoad(fw); - worlds.put(fw.getName(), fw); - } - } catch (Exception x) { - Log.warning(String.format("Unable to load saved worlds from %s", FabricWorld.SAVED_WORLDS_FILE)); - return; - } - } - } -} - diff --git a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/FabricAdapter.java b/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/FabricAdapter.java deleted file mode 100644 index 2373ad6c..00000000 --- a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/FabricAdapter.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.dynmap.fabric_1_16_1; - -import org.dynmap.DynmapLocation; - -import net.minecraft.server.world.ServerWorld; - -public final class FabricAdapter { - public static DynmapLocation toDynmapLocation(DynmapPlugin plugin, ServerWorld world, double x, double y, double z) { - return new DynmapLocation(plugin.getWorld(world).getName(), x, y, z); - } - - private FabricAdapter() { - } -} diff --git a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/FabricCommandSender.java b/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/FabricCommandSender.java deleted file mode 100644 index 836ed3a4..00000000 --- a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/FabricCommandSender.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.dynmap.fabric_1_16_1; - -import net.minecraft.server.command.ServerCommandSource; -import net.minecraft.text.LiteralText; -import net.minecraft.text.Text; -import org.dynmap.common.DynmapCommandSender; - -/* Handler for generic console command sender */ -public class FabricCommandSender implements DynmapCommandSender { - private ServerCommandSource sender; - - protected FabricCommandSender() { - sender = null; - } - - public FabricCommandSender(ServerCommandSource send) { - sender = send; - } - - @Override - public boolean hasPrivilege(String privid) { - return true; - } - - @Override - public void sendMessage(String msg) { - if (sender != null) { - Text ichatcomponent = new LiteralText(msg); - sender.sendFeedback(ichatcomponent, false); - } - } - - @Override - public boolean isConnected() { - return false; - } - - @Override - public boolean isOp() { - return true; - } - - @Override - public boolean hasPermissionNode(String node) { - return true; - } -} diff --git a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/FabricLogger.java b/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/FabricLogger.java deleted file mode 100644 index df059359..00000000 --- a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/FabricLogger.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.dynmap.fabric_1_16_1; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.dynmap.utils.DynmapLogger; - -public class FabricLogger implements DynmapLogger { - Logger log; - public static final String DM = "[Dynmap] "; - - FabricLogger() { - log = LogManager.getLogger("Dynmap"); - } - - @Override - public void info(String s) { - log.info(DM + s); - } - - @Override - public void severe(Throwable t) { - log.fatal(t); - } - - @Override - public void severe(String s) { - log.fatal(DM + s); - } - - @Override - public void severe(String s, Throwable t) { - log.fatal(DM + s, t); - } - - @Override - public void verboseinfo(String s) { - log.info(DM + s); - } - - @Override - public void warning(String s) { - log.warn(DM + s); - } - - @Override - public void warning(String s, Throwable t) { - log.warn(DM + s, t); - } -} \ No newline at end of file diff --git a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/FabricMapChunkCache.java b/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/FabricMapChunkCache.java deleted file mode 100644 index 9ba27a66..00000000 --- a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/FabricMapChunkCache.java +++ /dev/null @@ -1,1322 +0,0 @@ -package org.dynmap.fabric_1_16_1; - -import net.minecraft.nbt.*; -import net.minecraft.server.world.ServerChunkManager; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.server.world.ThreadedAnvilChunkStorage; -import net.minecraft.util.math.ChunkPos; -import net.minecraft.world.ChunkSerializer; -import net.minecraft.world.World; -import net.minecraft.world.biome.Biome; -import net.minecraft.world.chunk.ChunkManager; -import net.minecraft.world.chunk.ChunkStatus; -import org.dynmap.DynmapChunk; -import org.dynmap.DynmapCore; -import org.dynmap.DynmapWorld; -import org.dynmap.Log; -import org.dynmap.common.BiomeMap; -import org.dynmap.hdmap.HDBlockModels; -import org.dynmap.renderer.DynmapBlockState; -import org.dynmap.renderer.RenderPatchFactory; -import org.dynmap.utils.*; - -import java.lang.reflect.Field; -import java.util.*; - -/** - * Container for managing chunks - dependent upon using chunk snapshots, since rendering is off server thread - */ -public class FabricMapChunkCache extends MapChunkCache { - private static boolean init = false; - private static Field updateEntityTick = null; - /* ChunkManager fields */ - private static Field chunksToRemove = null; // Map - - /* ChunjManager Pending fields */ - private static Field chunkCoord = null; - private static Field nbtTag = null; - - private World w; - private DynmapWorld dw; - private ServerChunkManager cps; - private int nsect; - private List chunks; - private ListIterator iterator; - private int x_min, x_max, z_min, z_max; - private int x_dim; - private boolean biome, biomeraw, highesty, blockdata; - private HiddenChunkStyle hidestyle = HiddenChunkStyle.FILL_AIR; - private List visible_limits = null; - private List hidden_limits = null; - private boolean isempty = true; - private int snapcnt; - private ChunkSnapshot[] snaparray; /* Index = (x-x_min) + ((z-z_min)*x_dim) */ - private DynIntHashMap[] snaptile; - private byte[][] sameneighborbiomecnt; - private BiomeMap[][] biomemap; - private boolean[][] isSectionNotEmpty; /* Indexed by snapshot index, then by section index */ - - - private static final BlockStep unstep[] = {BlockStep.X_MINUS, BlockStep.Y_MINUS, BlockStep.Z_MINUS, - BlockStep.X_PLUS, BlockStep.Y_PLUS, BlockStep.Z_PLUS - }; - - private static BiomeMap[] biome_to_bmap; - - private static final int getIndexInChunk(int cx, int cy, int cz) { - return (cy << 8) | (cz << 4) | cx; - } - - /** - * Iterator for traversing map chunk cache (base is for non-snapshot) - */ - public class OurMapIterator implements MapIterator { - private int x, y, z, chunkindex, bx, bz; - private ChunkSnapshot snap; - private BlockStep laststep; - private DynmapBlockState blk; - private final int worldheight; - private final int x_base; - private final int z_base; - - OurMapIterator(int x0, int y0, int z0) { - x_base = x_min << 4; - z_base = z_min << 4; - - if (biome) { - biomePrep(); - } - - initialize(x0, y0, z0); - worldheight = w.getHeight(); - } - - @Override - public final void initialize(int x0, int y0, int z0) { - this.x = x0; - this.y = y0; - this.z = z0; - this.chunkindex = ((x >> 4) - x_min) + (((z >> 4) - z_min) * x_dim); - this.bx = x & 0xF; - this.bz = z & 0xF; - - if ((chunkindex >= snapcnt) || (chunkindex < 0)) { - snap = EMPTY; - } else { - snap = snaparray[chunkindex]; - } - - laststep = BlockStep.Y_MINUS; - - if ((y >= 0) && (y < worldheight)) { - blk = null; - } else { - blk = DynmapBlockState.AIR; - } - } - - @Override - public int getBlockSkyLight() { - try { - return snap.getBlockSkyLight(bx, y, bz); - } catch (ArrayIndexOutOfBoundsException aioobx) { - return 15; - } - } - - @Override - public final int getBlockEmittedLight() { - try { - return snap.getBlockEmittedLight(bx, y, bz); - } catch (ArrayIndexOutOfBoundsException aioobx) { - return 0; - } - } - - private void biomePrep() { - if (sameneighborbiomecnt != null) { - return; - } - - int x_size = x_dim << 4; - int z_size = (z_max - z_min + 1) << 4; - sameneighborbiomecnt = new byte[x_size][]; - biomemap = new BiomeMap[x_size][]; - - for (int i = 0; i < x_size; i++) { - sameneighborbiomecnt[i] = new byte[z_size]; - biomemap[i] = new BiomeMap[z_size]; - } - - for (int i = 0; i < x_size; i++) { - for (int j = 0; j < z_size; j++) { - if (j == 0) - initialize(i + x_base, 64, z_base); - else - stepPosition(BlockStep.Z_PLUS); - - int bb = snap.getBiome(bx, bz); - BiomeMap bm = BiomeMap.byBiomeID(bb); - - biomemap[i][j] = bm; - int cnt = 0; - - if (i > 0) { - if (bm == biomemap[i - 1][j]) /* Same as one to left */ { - cnt++; - sameneighborbiomecnt[i - 1][j]++; - } - - if ((j > 0) && (bm == biomemap[i - 1][j - 1])) { - cnt++; - sameneighborbiomecnt[i - 1][j - 1]++; - } - - if ((j < (z_size - 1)) && (bm == biomemap[i - 1][j + 1])) { - cnt++; - sameneighborbiomecnt[i - 1][j + 1]++; - } - } - - if ((j > 0) && (biomemap[i][j] == biomemap[i][j - 1])) /* Same as one to above */ { - cnt++; - sameneighborbiomecnt[i][j - 1]++; - } - - sameneighborbiomecnt[i][j] = (byte) cnt; - } - } - } - - @Override - public final BiomeMap getBiome() { - try { - return biomemap[x - x_base][z - z_base]; - } catch (Exception ex) { - return BiomeMap.NULL; - } - } - - @Override - public final int getSmoothGrassColorMultiplier(int[] colormap) { - int mult = 0xFFFFFF; - - try { - int rx = x - x_base; - int rz = z - z_base; - BiomeMap bm = biomemap[rx][rz]; - - if (sameneighborbiomecnt[rx][rz] >= (byte) 8) /* All neighbors same? */ { - mult = bm.getModifiedGrassMultiplier(colormap[bm.biomeLookup()]); - } else { - int raccum = 0; - int gaccum = 0; - int baccum = 0; - - for (int xoff = -1; xoff < 2; xoff++) { - for (int zoff = -1; zoff < 2; zoff++) { - bm = biomemap[rx + xoff][rz + zoff]; - int rmult = bm.getModifiedGrassMultiplier(colormap[bm.biomeLookup()]); - raccum += (rmult >> 16) & 0xFF; - gaccum += (rmult >> 8) & 0xFF; - baccum += rmult & 0xFF; - } - } - - mult = ((raccum / 9) << 16) | ((gaccum / 9) << 8) | (baccum / 9); - } - } catch (Exception x) { - mult = 0xFFFFFF; - } - - return mult; - } - - @Override - public final int getSmoothFoliageColorMultiplier(int[] colormap) { - int mult = 0xFFFFFF; - - try { - int rx = x - x_base; - int rz = z - z_base; - BiomeMap bm = biomemap[rx][rz]; - - if (sameneighborbiomecnt[rx][rz] >= (byte) 8) /* All neighbors same? */ { - mult = bm.getModifiedFoliageMultiplier(colormap[bm.biomeLookup()]); - } else { - int raccum = 0; - int gaccum = 0; - int baccum = 0; - - for (int xoff = -1; xoff < 2; xoff++) { - for (int zoff = -1; zoff < 2; zoff++) { - bm = biomemap[rx + xoff][rz + zoff]; - int rmult = bm.getModifiedFoliageMultiplier(colormap[bm.biomeLookup()]); - raccum += (rmult >> 16) & 0xFF; - gaccum += (rmult >> 8) & 0xFF; - baccum += rmult & 0xFF; - } - } - - mult = ((raccum / 9) << 16) | ((gaccum / 9) << 8) | (baccum / 9); - } - } catch (Exception x) { - mult = 0xFFFFFF; - } - - return mult; - } - - @Override - public final int getSmoothColorMultiplier(int[] colormap, int[] swampmap) { - int mult = 0xFFFFFF; - - try { - int rx = x - x_base; - int rz = z - z_base; - BiomeMap bm = biomemap[rx][rz]; - - if (sameneighborbiomecnt[rx][rz] >= (byte) 8) /* All neighbors same? */ { - if (bm == BiomeMap.SWAMPLAND) { - mult = swampmap[bm.biomeLookup()]; - } else { - mult = colormap[bm.biomeLookup()]; - } - } else { - int raccum = 0; - int gaccum = 0; - int baccum = 0; - - for (int xoff = -1; xoff < 2; xoff++) { - for (int zoff = -1; zoff < 2; zoff++) { - bm = biomemap[rx + xoff][rz + zoff]; - int rmult; - - if (bm == BiomeMap.SWAMPLAND) { - rmult = swampmap[bm.biomeLookup()]; - } else { - rmult = colormap[bm.biomeLookup()]; - } - - raccum += (rmult >> 16) & 0xFF; - gaccum += (rmult >> 8) & 0xFF; - baccum += rmult & 0xFF; - } - } - - mult = ((raccum / 9) << 16) | ((gaccum / 9) << 8) | (baccum / 9); - } - } catch (Exception x) { - mult = 0xFFFFFF; - } - - return mult; - } - - @Override - public final int getSmoothWaterColorMultiplier() { - try { - int rx = x - x_base; - int rz = z - z_base; - BiomeMap bm = biomemap[rx][rz]; - - if (sameneighborbiomecnt[rx][rz] >= (byte) 8) /* All neighbors same? */ { - return bm.getWaterColorMult(); - } - - int raccum = 0; - int gaccum = 0; - int baccum = 0; - - for (int xoff = -1; xoff < 2; xoff++) { - for (int zoff = -1; zoff < 2; zoff++) { - bm = biomemap[rx + xoff][rz + zoff]; - int mult = bm.getWaterColorMult(); - raccum += (mult >> 16) & 0xFF; - gaccum += (mult >> 8) & 0xFF; - baccum += mult & 0xFF; - } - } - - return ((raccum / 9) << 16) | ((gaccum / 9) << 8) | (baccum / 9); - } catch (Exception x) { - return 0xFFFFFF; - } - } - - @Override - public final int getSmoothWaterColorMultiplier(int[] colormap) { - int mult = 0xFFFFFF; - - try { - int rx = x - x_base; - int rz = z - z_base; - BiomeMap bm = biomemap[rx][rz]; - - if (sameneighborbiomecnt[rx][rz] >= (byte) 8) /* All neighbors same? */ { - mult = colormap[bm.biomeLookup()]; - } else { - int raccum = 0; - int gaccum = 0; - int baccum = 0; - - for (int xoff = -1; xoff < 2; xoff++) { - for (int zoff = -1; zoff < 2; zoff++) { - bm = biomemap[rx + xoff][rz + zoff]; - int rmult = colormap[bm.biomeLookup()]; - raccum += (rmult >> 16) & 0xFF; - gaccum += (rmult >> 8) & 0xFF; - baccum += rmult & 0xFF; - } - } - - mult = ((raccum / 9) << 16) | ((gaccum / 9) << 8) | (baccum / 9); - } - } catch (Exception x) { - mult = 0xFFFFFF; - } - - return mult; - } - - /** - * Step current position in given direction - */ - @Override - public final void stepPosition(BlockStep step) { - blk = null; - - switch (step.ordinal()) { - case 0: - x++; - bx++; - - if (bx == 16) /* Next chunk? */ { - bx = 0; - chunkindex++; - if ((chunkindex >= snapcnt) || (chunkindex < 0)) { - snap = EMPTY; - } else { - snap = snaparray[chunkindex]; - } - } - - break; - - case 1: - y++; - - if (y >= worldheight) { - blk = DynmapBlockState.AIR; - } - - break; - - case 2: - z++; - bz++; - - if (bz == 16) /* Next chunk? */ { - bz = 0; - chunkindex += x_dim; - if ((chunkindex >= snapcnt) || (chunkindex < 0)) { - snap = EMPTY; - } else { - snap = snaparray[chunkindex]; - } - } - break; - - case 3: - x--; - bx--; - - if (bx == -1) /* Next chunk? */ { - bx = 15; - chunkindex--; - if ((chunkindex >= snapcnt) || (chunkindex < 0)) { - snap = EMPTY; - } else { - snap = snaparray[chunkindex]; - } - } - - break; - - case 4: - y--; - - if (y < 0) { - blk = DynmapBlockState.AIR; - } - - break; - - case 5: - z--; - bz--; - - if (bz == -1) /* Next chunk? */ { - bz = 15; - chunkindex -= x_dim; - if ((chunkindex >= snapcnt) || (chunkindex < 0)) { - snap = EMPTY; - } else { - snap = snaparray[chunkindex]; - } - } - break; - } - - laststep = step; - } - - /** - * Unstep current position to previous position - */ - @Override - public BlockStep unstepPosition() { - BlockStep ls = laststep; - stepPosition(unstep[ls.ordinal()]); - return ls; - } - - /** - * Unstep current position in oppisite director of given step - */ - @Override - public void unstepPosition(BlockStep s) { - stepPosition(unstep[s.ordinal()]); - } - - @Override - public final void setY(int y) { - if (y > this.y) { - laststep = BlockStep.Y_PLUS; - } else { - laststep = BlockStep.Y_MINUS; - } - - this.y = y; - - if ((y < 0) || (y >= worldheight)) { - blk = DynmapBlockState.AIR; - } else { - blk = null; - } - } - - @Override - public final int getX() { - return x; - } - - @Override - public final int getY() { - return y; - } - - @Override - public final int getZ() { - return z; - } - - @Override - public final DynmapBlockState getBlockTypeAt(BlockStep s) { - if (s == BlockStep.Y_MINUS) { - if (y > 0) { - return snap.getBlockType(bx, y - 1, bz); - } - } else if (s == BlockStep.Y_PLUS) { - if (y < (worldheight - 1)) { - return snap.getBlockType(bx, y + 1, bz); - } - } else { - BlockStep ls = laststep; - stepPosition(s); - DynmapBlockState tid = snap.getBlockType(bx, y, bz); - unstepPosition(); - laststep = ls; - return tid; - } - - return DynmapBlockState.AIR; - } - - @Override - public BlockStep getLastStep() { - return laststep; - } - - @Override - public int getWorldHeight() { - return worldheight; - } - - @Override - public long getBlockKey() { - return (((chunkindex * worldheight) + y) << 8) | (bx << 4) | bz; - } - - @Override - public final boolean isEmptySection() { - try { - return !isSectionNotEmpty[chunkindex][y >> 4]; - } catch (Exception x) { - initSectionData(chunkindex); - return !isSectionNotEmpty[chunkindex][y >> 4]; - } - } - - @Override - public RenderPatchFactory getPatchFactory() { - return HDBlockModels.getPatchDefinitionFactory(); - } - - @Override - public Object getBlockTileEntityField(String fieldId) { - try { - int idx = getIndexInChunk(bx, y, bz); - Object[] vals = (Object[]) snaptile[chunkindex].get(idx); - for (int i = 0; i < vals.length; i += 2) { - if (vals[i].equals(fieldId)) { - return vals[i + 1]; - } - } - } catch (Exception x) { - } - return null; - } - - @Override - public DynmapBlockState getBlockTypeAt(int xoff, int yoff, int zoff) { - int xx = this.x + xoff; - int yy = this.y + yoff; - int zz = this.z + zoff; - int idx = ((xx >> 4) - x_min) + (((zz >> 4) - z_min) * x_dim); - try { - return snaparray[idx].getBlockType(xx & 0xF, yy, zz & 0xF); - } catch (Exception x) { - return DynmapBlockState.AIR; - } - } - - @Override - public Object getBlockTileEntityFieldAt(String fieldId, int xoff, - int yoff, int zoff) { - return null; - } - - @Override - public long getInhabitedTicks() { - try { - return snap.getInhabitedTicks(); - } catch (Exception x) { - return 0; - } - } - - @Override - public DynmapBlockState getBlockType() { - if (blk == null) { - blk = snap.getBlockType(bx, y, bz); - } - return blk; - } - } - - private class OurEndMapIterator extends OurMapIterator { - OurEndMapIterator(int x0, int y0, int z0) { - super(x0, y0, z0); - } - - @Override - public final int getBlockSkyLight() { - return 15; - } - } - - /** - * Chunk cache for representing unloaded chunk (or air) - */ - private static class EmptyChunk extends ChunkSnapshot { - public EmptyChunk() { - super(256, 0, 0, 0, 0); - } - - /* Need these for interface, but not used */ - @Override - public int getX() { - return 0; - } - - @Override - public int getZ() { - return 0; - } - - @Override - public final DynmapBlockState getBlockType(int x, int y, int z) { - return DynmapBlockState.AIR; - } - - @Override - public final int getBlockSkyLight(int x, int y, int z) { - return 15; - } - - @Override - public final int getBlockEmittedLight(int x, int y, int z) { - return 0; - } - - @Override - public final int getHighestBlockYAt(int x, int z) { - return 0; - } - - @Override - public int getBiome(int x, int z) { - return -1; - } - - @Override - public boolean isSectionEmpty(int sy) { - return true; - } - } - - /** - * Chunk cache for representing generic stone chunk - */ - private static class PlainChunk extends ChunkSnapshot { - private DynmapBlockState fill; - - PlainChunk(String fill) { - super(256, 0, 0, 0, 0); - this.fill = DynmapBlockState.getBaseStateByName(fill); - } - - /* Need these for interface, but not used */ - @Override - public int getX() { - return 0; - } - - @Override - public int getZ() { - return 0; - } - - @Override - public int getBiome(int x, int z) { - return -1; - } - - @Override - public final DynmapBlockState getBlockType(int x, int y, int z) { - if (y < 64) { - return fill; - } - - return DynmapBlockState.AIR; - } - - @Override - public final int getBlockSkyLight(int x, int y, int z) { - if (y < 64) { - return 0; - } - - return 15; - } - - @Override - public final int getBlockEmittedLight(int x, int y, int z) { - return 0; - } - - @Override - public final int getHighestBlockYAt(int x, int z) { - return 64; - } - - @Override - public boolean isSectionEmpty(int sy) { - return (sy < 4); - } - } - - private static final EmptyChunk EMPTY = new EmptyChunk(); - private static final PlainChunk STONE = new PlainChunk(DynmapBlockState.STONE_BLOCK); - private static final PlainChunk OCEAN = new PlainChunk(DynmapBlockState.WATER_BLOCK); - - - public static void init() { - if (!init) { - Field[] f = ServerChunkManager.class.getDeclaredFields(); - - f = ServerWorld.class.getDeclaredFields(); - for (int i = 0; i < f.length; i++) { - if ((updateEntityTick == null) && f[i].getType().isAssignableFrom(int.class)) { - updateEntityTick = f[i]; - //Log.info("Found updateEntityTick - " + f[i].getName()); - updateEntityTick.setAccessible(true); - } - } - - f = ChunkManager.class.getDeclaredFields(); - for (int i = 0; i < f.length; i++) { - if ((chunksToRemove == null) && (f[i].getType().equals(Map.class))) { - chunksToRemove = f[i]; - //Log.info("Found chunksToRemove - " + f[i].getName()); - chunksToRemove.setAccessible(true); - } -// else if((pendingAnvilChunksCoordinates == null) && (f[i].getType().equals(it.unimi.dsi.fastutil.longs.LongSet.class))) { -// //Log.info("Found pendingAnvilChunksCoordinates - " + f[i].getName()); -// pendingAnvilChunksCoordinates = f[i]; -// pendingAnvilChunksCoordinates.setAccessible(true); -// } - } - if (updateEntityTick == null) { - Log.severe("ERROR: cannot find updateEntityTick - dynmap cannot drive entity cleanup when no players are active"); - } - - init = true; - } - } - - /** - * Construct empty cache - */ - public FabricMapChunkCache() { - init(); - } - - public void setChunks(FabricWorld dw, List chunks) { - this.dw = dw; - this.w = dw.getWorld(); - if (dw.isLoaded()) { - /* Check if world's provider is ServerChunkManager */ - ChunkManager cp = this.w.getChunkManager(); - - if (cp instanceof ServerChunkManager) { - cps = (ServerChunkManager) cp; - } else { - Log.severe("Error: world " + dw.getName() + " has unsupported chunk provider"); - } - } else { - chunks = new ArrayList(); - } - nsect = dw.worldheight >> 4; - this.chunks = chunks; - - /* Compute range */ - if (chunks.size() == 0) { - this.x_min = 0; - this.x_max = 0; - this.z_min = 0; - this.z_max = 0; - x_dim = 1; - } else { - x_min = x_max = chunks.get(0).x; - z_min = z_max = chunks.get(0).z; - - for (DynmapChunk c : chunks) { - if (c.x > x_max) { - x_max = c.x; - } - - if (c.x < x_min) { - x_min = c.x; - } - - if (c.z > z_max) { - z_max = c.z; - } - - if (c.z < z_min) { - z_min = c.z; - } - } - - x_dim = x_max - x_min + 1; - } - - snapcnt = x_dim * (z_max - z_min + 1); - snaparray = new ChunkSnapshot[snapcnt]; - snaptile = new DynIntHashMap[snapcnt]; - isSectionNotEmpty = new boolean[snapcnt][]; - - } - - private static boolean didError = false; - - public CompoundTag readChunk(int x, int z) { - try { - ThreadedAnvilChunkStorage acl = cps.threadedAnvilChunkStorage; - - ChunkPos coord = new ChunkPos(x, z); - CompoundTag rslt = acl.getNbt(coord); - if (rslt != null) { - rslt = rslt.getCompound("Level"); - // Don't load uncooked chunks - String stat = rslt.getString("Status"); - ChunkStatus cs = ChunkStatus.get(stat); - if ((stat == null) || - // Needs to be at least lighted - (!cs.isAtLeast(ChunkStatus.LIGHT))) { - rslt = null; - } - } - //Log.info(String.format("loadChunk(%d,%d)=%s", x, z, (rslt != null) ? rslt.toString() : "null")); - return rslt; - } catch (Exception exc) { - Log.severe(String.format("Error reading chunk: %s,%d,%d", dw.getName(), x, z), exc); - return null; - } - } - - private Object getNBTValue(Tag v) { - Object val = null; - switch (v.getType()) { - case 1: // Byte - val = ((ByteTag) v).getByte(); - break; - case 2: // Short - val = ((ShortTag) v).getShort(); - break; - case 3: // Int - val = ((IntTag) v).getInt(); - break; - case 4: // Long - val = ((LongTag) v).getLong(); - break; - case 5: // Float - val = ((FloatTag) v).getFloat(); - break; - case 6: // Double - val = ((DoubleTag) v).getDouble(); - break; - case 7: // Byte[] - val = ((ByteArrayTag) v).getByteArray(); - break; - case 8: // String - val = ((StringTag) v).asString(); - break; - case 9: // List - ListTag tl = (ListTag) v; - ArrayList vlist = new ArrayList(); - int type = tl.getElementType(); - for (int i = 0; i < tl.size(); i++) { - switch (type) { - case 5: - float fv = tl.getFloat(i); - vlist.add(fv); - break; - case 6: - double dv = tl.getDouble(i); - vlist.add(dv); - break; - case 8: - String sv = tl.getString(i); - vlist.add(sv); - break; - case 10: - CompoundTag tc = tl.getCompound(i); - vlist.add(getNBTValue(tc)); - break; - case 11: - int[] ia = tl.getIntArray(i); - vlist.add(ia); - break; - } - } - val = vlist; - break; - case 10: // Map - CompoundTag tc = (CompoundTag) v; - HashMap vmap = new HashMap(); - for (Object t : tc.getKeys()) { - String st = (String) t; - Tag tg = tc.get(st); - vmap.put(st, getNBTValue(tg)); - } - val = vmap; - break; - case 11: // Int[] - val = ((IntArrayTag) v).getIntArray(); - break; - } - return val; - } - - private boolean isChunkVisible(DynmapChunk chunk) { - boolean vis = true; - if (visible_limits != null) { - vis = false; - for (VisibilityLimit limit : visible_limits) { - if (limit.doIntersectChunk(chunk.x, chunk.z)) { - vis = true; - break; - } - } - } - if (vis && (hidden_limits != null)) { - for (VisibilityLimit limit : hidden_limits) { - if (limit.doIntersectChunk(chunk.x, chunk.z)) { - vis = false; - break; - } - } - } - return vis; - } - - private boolean tryChunkCache(DynmapChunk chunk, boolean vis) { - /* Check if cached chunk snapshot found */ - ChunkSnapshot ss = null; - SnapshotCache.SnapshotRec ssr = DynmapPlugin.plugin.sscache.getSnapshot(dw.getName(), chunk.x, chunk.z, blockdata, biome, biomeraw, highesty); - if (ssr != null) { - ss = ssr.ss; - if (!vis) { - if (hidestyle == HiddenChunkStyle.FILL_STONE_PLAIN) { - ss = STONE; - } else if (hidestyle == HiddenChunkStyle.FILL_OCEAN) { - ss = OCEAN; - } else { - ss = EMPTY; - } - } - int idx = (chunk.x - x_min) + (chunk.z - z_min) * x_dim; - snaparray[idx] = ss; - snaptile[idx] = ssr.tileData; - } - return (ssr != null); - } - - // Prep snapshot and add to cache - private SnapshotCache.SnapshotRec prepChunkSnapshot(DynmapChunk chunk, CompoundTag nbt) throws ChunkSnapshot.StateListException { - ChunkSnapshot ss = new ChunkSnapshot(nbt, dw.worldheight); - DynIntHashMap tileData = new DynIntHashMap(); - - ListTag tiles = nbt.getList("TileEntities", 10); - if (tiles == null) tiles = new ListTag(); - /* Get tile entity data */ - List vals = new ArrayList(); - for (int tid = 0; tid < tiles.size(); tid++) { - CompoundTag tc = tiles.getCompound(tid); - int tx = tc.getInt("x"); - int ty = tc.getInt("y"); - int tz = tc.getInt("z"); - int cx = tx & 0xF; - int cz = tz & 0xF; - DynmapBlockState blk = ss.getBlockType(cx, ty, cz); - String[] te_fields = HDBlockModels.getTileEntityFieldsNeeded(blk); - if (te_fields != null) { - vals.clear(); - for (String id : te_fields) { - Tag v = tc.get(id); /* Get field */ - if (v != null) { - Object val = getNBTValue(v); - if (val != null) { - vals.add(id); - vals.add(val); - } - } - } - if (vals.size() > 0) { - Object[] vlist = vals.toArray(new Object[vals.size()]); - tileData.put(getIndexInChunk(cx, ty, cz), vlist); - } - } - } - SnapshotCache.SnapshotRec ssr = new SnapshotCache.SnapshotRec(); - ssr.ss = ss; - ssr.tileData = tileData; - DynmapPlugin.plugin.sscache.putSnapshot(dw.getName(), chunk.x, chunk.z, ssr, blockdata, biome, biomeraw, highesty); - - return ssr; - } - - /** - * Read NBT data from loaded chunks - needs to be called from server/world thread to be safe - * - * @returns number loaded - */ - public int getLoadedChunks() { - int cnt = 0; - if (!dw.isLoaded()) { - isempty = true; - unloadChunks(); - return 0; - } - ListIterator iter = chunks.listIterator(); - while (iter.hasNext()) { - long startTime = System.nanoTime(); - DynmapChunk chunk = iter.next(); - int chunkindex = (chunk.x - x_min) + (chunk.z - z_min) * x_dim; - if (snaparray[chunkindex] != null) continue; // Skip if already processed - - boolean vis = isChunkVisible(chunk); - - /* Check if cached chunk snapshot found */ - if (tryChunkCache(chunk, vis)) { - endChunkLoad(startTime, ChunkStats.CACHED_SNAPSHOT_HIT); - cnt++; - } - // If chunk is loaded and not being unloaded, we're grabbing its NBT data - else if (cps.isChunkLoaded(chunk.x, chunk.z)) { - ChunkSnapshot ss; - DynIntHashMap tileData; - if (vis) { // If visible - CompoundTag nbt = ChunkSerializer.serialize((ServerWorld) w, cps.getWorldChunk(chunk.x, chunk.z, false)); - if (nbt != null) nbt = nbt.getCompound("Level"); - try { - SnapshotCache.SnapshotRec ssr = prepChunkSnapshot(chunk, nbt); - ss = ssr.ss; - tileData = ssr.tileData; - } catch (ChunkSnapshot.StateListException e) { - continue; - } - } else { - if (hidestyle == HiddenChunkStyle.FILL_STONE_PLAIN) { - ss = STONE; - } else if (hidestyle == HiddenChunkStyle.FILL_OCEAN) { - ss = OCEAN; - } else { - ss = EMPTY; - } - tileData = new DynIntHashMap(); - } - snaparray[chunkindex] = ss; - snaptile[chunkindex] = tileData; - endChunkLoad(startTime, ChunkStats.LOADED_CHUNKS); - cnt++; - } - } - return cnt; - } - - @Override - public int loadChunks(int max_to_load) { - return getLoadedChunks() + readChunks(max_to_load); - - } - - public int readChunks(int max_to_load) { - if (!dw.isLoaded()) { - isempty = true; - unloadChunks(); - return 0; - } - - int cnt = 0; - - if (iterator == null) { - iterator = chunks.listIterator(); - } - - DynmapCore.setIgnoreChunkLoads(true); - - // Load the required chunks. - while ((cnt < max_to_load) && iterator.hasNext()) { - long startTime = System.nanoTime(); - - DynmapChunk chunk = iterator.next(); - - int chunkindex = (chunk.x - x_min) + (chunk.z - z_min) * x_dim; - - if (snaparray[chunkindex] != null) continue; // Skip if already processed - - boolean vis = isChunkVisible(chunk); - - /* Check if cached chunk snapshot found */ - if (tryChunkCache(chunk, vis)) { - endChunkLoad(startTime, ChunkStats.CACHED_SNAPSHOT_HIT); - } else { - CompoundTag nbt = readChunk(chunk.x, chunk.z); - // If read was good - if (nbt != null) { - ChunkSnapshot ss; - DynIntHashMap tileData; - // If hidden - if (!vis) { - if (hidestyle == HiddenChunkStyle.FILL_STONE_PLAIN) { - ss = STONE; - } else if (hidestyle == HiddenChunkStyle.FILL_OCEAN) { - ss = OCEAN; - } else { - ss = EMPTY; - } - tileData = new DynIntHashMap(); - } else { - // Prep snapshot - try { - SnapshotCache.SnapshotRec ssr = prepChunkSnapshot(chunk, nbt); - ss = ssr.ss; - tileData = ssr.tileData; - } catch (ChunkSnapshot.StateListException e) { - continue; - } - } - snaparray[chunkindex] = ss; - snaptile[chunkindex] = tileData; - endChunkLoad(startTime, ChunkStats.UNLOADED_CHUNKS); - } else { - endChunkLoad(startTime, ChunkStats.UNGENERATED_CHUNKS); - } - } - cnt++; - } - - DynmapCore.setIgnoreChunkLoads(false); - - if (iterator.hasNext() == false) /* If we're done */ { - isempty = true; - - /* Fill missing chunks with empty dummy chunk */ - for (int i = 0; i < snaparray.length; i++) { - if (snaparray[i] == null) { - snaparray[i] = EMPTY; - } else if (snaparray[i] != EMPTY) { - isempty = false; - } - } - } - return cnt; - } - - /** - * Test if done loading - */ - public boolean isDoneLoading() { - if (!dw.isLoaded()) { - return true; - } - if (iterator != null) { - return !iterator.hasNext(); - } - - return false; - } - - /** - * Test if all empty blocks - */ - public boolean isEmpty() { - return isempty; - } - - /** - * Unload chunks - */ - public void unloadChunks() { - if (snaparray != null) { - for (int i = 0; i < snaparray.length; i++) { - snaparray[i] = null; - } - - snaparray = null; - } - } - - private void initSectionData(int idx) { - isSectionNotEmpty[idx] = new boolean[nsect + 1]; - - if (snaparray[idx] != EMPTY) { - for (int i = 0; i < nsect; i++) { - if (snaparray[idx].isSectionEmpty(i) == false) { - isSectionNotEmpty[idx][i] = true; - } - } - } - } - - public boolean isEmptySection(int sx, int sy, int sz) { - int idx = (sx - x_min) + (sz - z_min) * x_dim; - - if (isSectionNotEmpty[idx] == null) { - initSectionData(idx); - } - - return !isSectionNotEmpty[idx][sy]; - } - - /** - * Get cache iterator - */ - public MapIterator getIterator(int x, int y, int z) { - if (dw.getEnvironment().equals("the_end")) { - return new OurEndMapIterator(x, y, z); - } - - return new OurMapIterator(x, y, z); - } - - /** - * Set hidden chunk style (default is FILL_AIR) - */ - public void setHiddenFillStyle(HiddenChunkStyle style) { - this.hidestyle = style; - } - - /** - * Add visible area limit - can be called more than once - * Needs to be set before chunks are loaded - * Coordinates are block coordinates - */ - public void setVisibleRange(VisibilityLimit lim) { - if (visible_limits == null) - visible_limits = new ArrayList(); - visible_limits.add(lim); - } - - /** - * Add hidden area limit - can be called more than once - * Needs to be set before chunks are loaded - * Coordinates are block coordinates - */ - public void setHiddenRange(VisibilityLimit lim) { - if (hidden_limits == null) - hidden_limits = new ArrayList(); - hidden_limits.add(lim); - } - - @Override - public boolean setChunkDataTypes(boolean blockdata, boolean biome, boolean highestblocky, boolean rawbiome) { - this.biome = biome; - this.biomeraw = rawbiome; - this.highesty = highestblocky; - this.blockdata = blockdata; - return true; - } - - @Override - public DynmapWorld getWorld() { - return dw; - } - - static { - Biome b[] = DynmapPlugin.getBiomeList(); - BiomeMap[] bm = BiomeMap.values(); - biome_to_bmap = new BiomeMap[256]; - - for (int i = 0; i < biome_to_bmap.length; i++) { - biome_to_bmap[i] = BiomeMap.NULL; - } - - for (int i = 0; i < b.length; i++) { - if (b[i] == null) continue; - - String bs = b[i].getTranslationKey(); - - for (int j = 0; j < bm.length; j++) { - if (bm[j].toString().equals(bs)) { - biome_to_bmap[i] = bm[j]; - break; - } - } - } - } -} diff --git a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/FabricPlayer.java b/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/FabricPlayer.java deleted file mode 100644 index 22d1b455..00000000 --- a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/FabricPlayer.java +++ /dev/null @@ -1,249 +0,0 @@ -package org.dynmap.fabric_1_16_1; - -import com.google.common.collect.Iterables; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonParseException; -import com.mojang.authlib.GameProfile; -import com.mojang.authlib.properties.Property; -import net.minecraft.network.packet.s2c.play.TitleS2CPacket; -import net.minecraft.server.network.ServerPlayNetworkHandler; -import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.text.LiteralText; -import net.minecraft.text.Text; -import net.minecraft.util.Util; -import net.minecraft.util.math.Vec3d; -import org.apache.commons.codec.binary.Base64; -import org.dynmap.DynmapLocation; -import org.dynmap.common.DynmapPlayer; - -import java.net.InetSocketAddress; -import java.net.SocketAddress; -import java.nio.charset.StandardCharsets; -import java.util.UUID; - -/** - * Player access abstraction class - */ -public class FabricPlayer extends FabricCommandSender implements DynmapPlayer { - private static final Gson GSON = new GsonBuilder().create(); - private final DynmapPlugin plugin; - // FIXME: Proper setter - ServerPlayerEntity player; - private final String skinurl; - private final UUID uuid; - - public FabricPlayer(DynmapPlugin plugin, ServerPlayerEntity player) { - this.plugin = plugin; - this.player = player; - String url = null; - if (this.player != null) { - uuid = this.player.getUuid(); - GameProfile prof = this.player.getGameProfile(); - if (prof != null) { - Property textureProperty = Iterables.getFirst(prof.getProperties().get("textures"), null); - - if (textureProperty != null) { - DynmapPlugin.TexturesPayload result = null; - try { - String json = new String(Base64.decodeBase64(textureProperty.getValue()), StandardCharsets.UTF_8); - result = GSON.fromJson(json, DynmapPlugin.TexturesPayload.class); - } catch (JsonParseException e) { - } - if ((result != null) && (result.textures != null) && (result.textures.containsKey("SKIN"))) { - url = result.textures.get("SKIN").url; - } - } - } - } else { - uuid = null; - } - skinurl = url; - } - - @Override - public boolean isConnected() { - return true; - } - - @Override - public String getName() { - if (player != null) { - String n = player.getName().getString(); - ; - return n; - } else - return "[Server]"; - } - - @Override - public String getDisplayName() { - if (player != null) { - String n = player.getDisplayName().getString(); - return n; - } else - return "[Server]"; - } - - @Override - public boolean isOnline() { - return true; - } - - @Override - public DynmapLocation getLocation() { - if (player == null) { - return null; - } - - Vec3d pos = player.getPos(); - return FabricAdapter.toDynmapLocation(plugin, player.getServerWorld(), pos.getX(), pos.getY(), pos.getZ()); - } - - @Override - public String getWorld() { - if (player == null) { - return null; - } - - if (player.world != null) { - return plugin.getWorld(player.world).getName(); - } - - return null; - } - - @Override - public InetSocketAddress getAddress() { - if (player != null) { - ServerPlayNetworkHandler networkHandler = player.networkHandler; - if ((networkHandler != null) && (networkHandler.getConnection() != null)) { - SocketAddress sa = networkHandler.getConnection().getAddress(); - if (sa instanceof InetSocketAddress) { - return (InetSocketAddress) sa; - } - } - } - return null; - } - - @Override - public boolean isSneaking() { - if (player != null) { - return player.isSneaking(); - } - - return false; - } - - @Override - public double getHealth() { - if (player != null) { - double h = player.getHealth(); - if (h > 20) h = 20; - return h; // Scale to 20 range - } else { - return 0; - } - } - - @Override - public int getArmorPoints() { - if (player != null) { - return player.getArmor(); - } else { - return 0; - } - } - - @Override - public DynmapLocation getBedSpawnLocation() { - return null; - } - - @Override - public long getLastLoginTime() { - return 0; - } - - @Override - public long getFirstLoginTime() { - return 0; - } - - @Override - public boolean hasPrivilege(String privid) { - if (player != null) - return plugin.hasPerm(player, privid); - return false; - } - - @Override - public boolean isOp() { - return plugin.isOp(player.getName().getString()); - } - - @Override - public void sendMessage(String msg) { - Text ichatcomponent = new LiteralText(msg); - player.sendSystemMessage(ichatcomponent, Util.NIL_UUID); - } - - @Override - public boolean isInvisible() { - if (player != null) { - return player.isInvisible(); - } - return false; - } - - @Override - public int getSortWeight() { - return plugin.getSortWeight(getName()); - } - - @Override - public void setSortWeight(int wt) { - if (wt == 0) { - plugin.dropSortWeight(getName()); - } else { - plugin.setSortWeight(getName(), wt); - } - } - - @Override - public boolean hasPermissionNode(String node) { - return player != null && plugin.hasPermNode(player, node); - } - - @Override - public String getSkinURL() { - return skinurl; - } - - @Override - public UUID getUUID() { - return uuid; - } - - /** - * Send title and subtitle text (called from server thread) - */ - @Override - public void sendTitleText(String title, String subtitle, int fadeInTicks, int stayTicks, int fadeOutTicks) { - if (player != null) { - ServerPlayerEntity player = this.player; - TitleS2CPacket times = new TitleS2CPacket(fadeInTicks, stayTicks, fadeOutTicks); - player.networkHandler.sendPacket(times); - if (title != null) { - TitleS2CPacket titlepkt = new TitleS2CPacket(TitleS2CPacket.Action.TITLE, new LiteralText(title)); - player.networkHandler.sendPacket(titlepkt); - } - - if (subtitle != null) { - TitleS2CPacket subtitlepkt = new TitleS2CPacket(TitleS2CPacket.Action.SUBTITLE, new LiteralText(subtitle)); - player.networkHandler.sendPacket(subtitlepkt); - } - } - } -} diff --git a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/FabricServer.java b/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/FabricServer.java deleted file mode 100644 index e2bb6316..00000000 --- a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/FabricServer.java +++ /dev/null @@ -1,603 +0,0 @@ -package org.dynmap.fabric_1_16_1; - -import com.mojang.authlib.GameProfile; -import net.fabricmc.loader.api.FabricLoader; -import net.fabricmc.loader.api.ModContainer; -import net.minecraft.block.Block; -import net.minecraft.block.BlockState; -import net.minecraft.network.MessageType; -import net.minecraft.server.BannedIpList; -import net.minecraft.server.BannedPlayerList; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.PlayerManager; -import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.text.LiteralText; -import net.minecraft.text.Text; -import net.minecraft.util.UserCache; -import net.minecraft.util.Util; -import net.minecraft.util.math.BlockPos; -import org.dynmap.DynmapChunk; -import org.dynmap.DynmapCommonAPIListener; -import org.dynmap.DynmapWorld; -import org.dynmap.Log; -import org.dynmap.common.BiomeMap; -import org.dynmap.common.DynmapListenerManager; -import org.dynmap.common.DynmapPlayer; -import org.dynmap.common.DynmapServerInterface; -import org.dynmap.fabric_1_16_1.event.ServerChatEvents; -import org.dynmap.utils.MapChunkCache; -import org.dynmap.utils.VisibilityLimit; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.*; -import java.util.concurrent.*; -import java.util.function.Function; -import java.util.function.Predicate; -import java.util.stream.Collectors; - -/** - * Server access abstraction class - */ -public class FabricServer extends DynmapServerInterface { - /* Server thread scheduler */ - private final Object schedlock = new Object(); - private final DynmapPlugin plugin; - private final MinecraftServer server; - private long cur_tick; - private long next_id; - private long cur_tick_starttime; - private PriorityQueue runqueue = new PriorityQueue(); - - public FabricServer(DynmapPlugin plugin, MinecraftServer server) { - this.plugin = plugin; - this.server = server; - } - - private GameProfile getProfileByName(String player) { - UserCache cache = server.getUserCache(); - return cache.findByName(player); - } - - @Override - public int getBlockIDAt(String wname, int x, int y, int z) { - return -1; - } - - @Override - public int isSignAt(String wname, int x, int y, int z) { - return -1; - } - - @Override - public void scheduleServerTask(Runnable run, long delay) { - /* Add task record to queue */ - synchronized (schedlock) { - TaskRecord tr = new TaskRecord(cur_tick + delay, next_id++, new FutureTask(run, null)); - runqueue.add(tr); - } - } - - @Override - public DynmapPlayer[] getOnlinePlayers() { - if (server.getPlayerManager() == null) return new DynmapPlayer[0]; - - List players = server.getPlayerManager().getPlayerList(); - int playerCount = players.size(); - DynmapPlayer[] dplay = new DynmapPlayer[players.size()]; - - for (int i = 0; i < playerCount; i++) { - ServerPlayerEntity player = players.get(i); - dplay[i] = plugin.getOrAddPlayer(player); - } - - return dplay; - } - - @Override - public void reload() { - plugin.onDisable(); - plugin.onEnable(); - plugin.onStart(); - } - - @Override - public DynmapPlayer getPlayer(String name) { - List players = server.getPlayerManager().getPlayerList(); - - for (ServerPlayerEntity player : players) { - - if (player.getName().getString().equalsIgnoreCase(name)) { - return plugin.getOrAddPlayer(player); - } - } - - return null; - } - - @Override - public Set getIPBans() { - BannedIpList bl = server.getPlayerManager().getIpBanList(); - Set ips = new HashSet(); - - for (String s : bl.getNames()) { - ips.add(s); - } - - return ips; - } - - @Override - public Future callSyncMethod(Callable task) { - return callSyncMethod(task, 0); - } - - public Future callSyncMethod(Callable task, long delay) { - FutureTask ft = new FutureTask(task); - - /* Add task record to queue */ - synchronized (schedlock) { - TaskRecord tr = new TaskRecord(cur_tick + delay, next_id++, ft); - runqueue.add(tr); - } - - return ft; - } - - void clearTaskQueue() { - this.runqueue.clear(); - } - - @Override - public String getServerName() { - String sn; - if (server.isSinglePlayer()) - sn = "Integrated"; - else - sn = server.getServerIp(); - if (sn == null) sn = "Unknown Server"; - return sn; - } - - @Override - public boolean isPlayerBanned(String pid) { - BannedPlayerList bl = server.getPlayerManager().getUserBanList(); - return bl.contains(getProfileByName(pid)); - } - - @Override - public String stripChatColor(String s) { - return plugin.patternControlCode.matcher(s).replaceAll(""); - } - - private Set registered = new HashSet(); - - @Override - public boolean requestEventNotification(DynmapListenerManager.EventType type) { - if (registered.contains(type)) { - return true; - } - - switch (type) { - case WORLD_LOAD: - case WORLD_UNLOAD: - /* Already called for normal world activation/deactivation */ - break; - - case WORLD_SPAWN_CHANGE: - /*TODO - pm.registerEvents(new Listener() { - @EventHandler(priority=EventPriority.MONITOR) - public void onSpawnChange(SpawnChangeEvent evt) { - DynmapWorld w = new BukkitWorld(evt.getWorld()); - core.listenerManager.processWorldEvent(EventType.WORLD_SPAWN_CHANGE, w); - } - }, DynmapPlugin.this); - */ - break; - - case PLAYER_JOIN: - case PLAYER_QUIT: - /* Already handled */ - break; - - case PLAYER_BED_LEAVE: - /*TODO - pm.registerEvents(new Listener() { - @EventHandler(priority=EventPriority.MONITOR) - public void onPlayerBedLeave(PlayerBedLeaveEvent evt) { - DynmapPlayer p = new BukkitPlayer(evt.getPlayer()); - core.listenerManager.processPlayerEvent(EventType.PLAYER_BED_LEAVE, p); - } - }, DynmapPlugin.this); - */ - break; - - case PLAYER_CHAT: - if (plugin.chathandler == null) { - plugin.setChatHandler(new DynmapPlugin.ChatHandler(plugin)); - ServerChatEvents.EVENT.register((player, message) -> plugin.chathandler.handleChat(player, message)); - } - break; - - case BLOCK_BREAK: - /*TODO - pm.registerEvents(new Listener() { - @EventHandler(priority=EventPriority.MONITOR) - public void onBlockBreak(BlockBreakEvent evt) { - if(evt.isCancelled()) return; - Block b = evt.getBlock(); - if(b == null) return; - Location l = b.getLocation(); - core.listenerManager.processBlockEvent(EventType.BLOCK_BREAK, b.getType().getId(), - BukkitWorld.normalizeWorldName(l.getWorld().getName()), l.getBlockX(), l.getBlockY(), l.getBlockZ()); - } - }, DynmapPlugin.this); - */ - break; - - case SIGN_CHANGE: - /*TODO - pm.registerEvents(new Listener() { - @EventHandler(priority=EventPriority.MONITOR) - public void onSignChange(SignChangeEvent evt) { - if(evt.isCancelled()) return; - Block b = evt.getBlock(); - Location l = b.getLocation(); - String[] lines = evt.getLines(); - DynmapPlayer dp = null; - Player p = evt.getPlayer(); - if(p != null) dp = new BukkitPlayer(p); - core.listenerManager.processSignChangeEvent(EventType.SIGN_CHANGE, b.getType().getId(), - BukkitWorld.normalizeWorldName(l.getWorld().getName()), l.getBlockX(), l.getBlockY(), l.getBlockZ(), lines, dp); - } - }, DynmapPlugin.this); - */ - break; - - default: - Log.severe("Unhandled event type: " + type); - return false; - } - - registered.add(type); - return true; - } - - @Override - public boolean sendWebChatEvent(String source, String name, String msg) { - return DynmapCommonAPIListener.fireWebChatEvent(source, name, msg); - } - - @Override - public void broadcastMessage(String msg) { - Text component = new LiteralText(msg); - server.getPlayerManager().broadcastChatMessage(component, MessageType.SYSTEM, Util.NIL_UUID); - Log.info(stripChatColor(msg)); - } - - @Override - public String[] getBiomeIDs() { - BiomeMap[] b = BiomeMap.values(); - String[] bname = new String[b.length]; - - for (int i = 0; i < bname.length; i++) { - bname[i] = b[i].toString(); - } - - return bname; - } - - @Override - public double getCacheHitRate() { - if (plugin.sscache != null) - return plugin.sscache.getHitRate(); - return 0.0; - } - - @Override - public void resetCacheStats() { - if (plugin.sscache != null) - plugin.sscache.resetStats(); - } - - @Override - public DynmapWorld getWorldByName(String wname) { - return plugin.getWorldByName(wname); - } - - @Override - public DynmapPlayer getOfflinePlayer(String name) { - /* - OfflinePlayer op = getServer().getOfflinePlayer(name); - if(op != null) { - return new BukkitPlayer(op); - } - */ - return null; - } - - @Override - public Set checkPlayerPermissions(String player, Set perms) { - PlayerManager scm = server.getPlayerManager(); - if (scm == null) return Collections.emptySet(); - BannedPlayerList bl = scm.getUserBanList(); - if (bl == null) return Collections.emptySet(); - if (bl.contains(getProfileByName(player))) { - return Collections.emptySet(); - } - Set rslt = plugin.hasOfflinePermissions(player, perms); - if (rslt == null) { - rslt = new HashSet(); - if (plugin.isOp(player)) { - rslt.addAll(perms); - } - } - return rslt; - } - - @Override - public boolean checkPlayerPermission(String player, String perm) { - PlayerManager scm = server.getPlayerManager(); - if (scm == null) return false; - BannedPlayerList bl = scm.getUserBanList(); - if (bl == null) return false; - if (bl.contains(getProfileByName(player))) { - return false; - } - return plugin.hasOfflinePermission(player, perm); - } - - /** - * Render processor helper - used by code running on render threads to request chunk snapshot cache from server/sync thread - */ - @Override - public MapChunkCache createMapChunkCache(DynmapWorld w, List chunks, - boolean blockdata, boolean highesty, boolean biome, boolean rawbiome) { - FabricMapChunkCache c = (FabricMapChunkCache) w.getChunkCache(chunks); - if (c == null) { - return null; - } - if (w.visibility_limits != null) { - for (VisibilityLimit limit : w.visibility_limits) { - c.setVisibleRange(limit); - } - - c.setHiddenFillStyle(w.hiddenchunkstyle); - } - - if (w.hidden_limits != null) { - for (VisibilityLimit limit : w.hidden_limits) { - c.setHiddenRange(limit); - } - - c.setHiddenFillStyle(w.hiddenchunkstyle); - } - - if (!c.setChunkDataTypes(blockdata, biome, highesty, rawbiome)) { - Log.severe("CraftBukkit build does not support biome APIs"); - } - - if (chunks.size() == 0) /* No chunks to get? */ { - c.loadChunks(0); - return c; - } - - //Now handle any chunks in server thread that are already loaded (on server thread) - final FabricMapChunkCache cc = c; - Future f = this.callSyncMethod(new Callable() { - public Boolean call() throws Exception { - // Update busy state on world - FabricWorld fw = (FabricWorld) cc.getWorld(); - //TODO - //setBusy(fw.getWorld()); - cc.getLoadedChunks(); - return true; - } - }, 0); - try { - f.get(); - } catch (CancellationException cx) { - return null; - } catch (ExecutionException xx) { - Log.severe("Exception while loading chunks", xx.getCause()); - return null; - } catch (Exception ix) { - Log.severe(ix); - return null; - } - if (!w.isLoaded()) { - return null; - } - // Now, do rest of chunk reading from calling thread - c.readChunks(chunks.size()); - - return c; - } - - @Override - public int getMaxPlayers() { - return server.getMaxPlayerCount(); - } - - @Override - public int getCurrentPlayers() { - return server.getPlayerManager().getCurrentPlayerCount(); - } - - public void tickEvent(MinecraftServer server) { - cur_tick_starttime = System.nanoTime(); - long elapsed = cur_tick_starttime - plugin.lasttick; - plugin.lasttick = cur_tick_starttime; - plugin.avgticklen = ((plugin.avgticklen * 99) / 100) + (elapsed / 100); - plugin.tps = (double) 1E9 / (double) plugin.avgticklen; - // Tick core - if (plugin.core != null) { - plugin.core.serverTick(plugin.tps); - } - - boolean done = false; - TaskRecord tr = null; - - while (!plugin.blockupdatequeue.isEmpty()) { - DynmapPlugin.BlockUpdateRec r = plugin.blockupdatequeue.remove(); - BlockState bs = r.w.getBlockState(new BlockPos(r.x, r.y, r.z)); - int idx = Block.STATE_IDS.getId(bs); - if (!org.dynmap.hdmap.HDBlockModels.isChangeIgnoredBlock(DynmapPlugin.stateByID[idx])) { - if (plugin.onblockchange_with_id) - plugin.mapManager.touch(r.wid, r.x, r.y, r.z, "blockchange[" + idx + "]"); - else - plugin.mapManager.touch(r.wid, r.x, r.y, r.z, "blockchange"); - } - } - - long now; - - synchronized (schedlock) { - cur_tick++; - now = System.nanoTime(); - tr = runqueue.peek(); - /* Nothing due to run */ - if ((tr == null) || (tr.getTickToRun() > cur_tick) || ((now - cur_tick_starttime) > plugin.perTickLimit)) { - done = true; - } else { - tr = runqueue.poll(); - } - } - while (!done) { - tr.run(); - - synchronized (schedlock) { - tr = runqueue.peek(); - now = System.nanoTime(); - /* Nothing due to run */ - if ((tr == null) || (tr.getTickToRun() > cur_tick) || ((now - cur_tick_starttime) > plugin.perTickLimit)) { - done = true; - } else { - tr = runqueue.poll(); - } - } - } - while (!plugin.msgqueue.isEmpty()) { - DynmapPlugin.ChatMessage cm = plugin.msgqueue.poll(); - DynmapPlayer dp = null; - if (cm.sender != null) - dp = plugin.getOrAddPlayer(cm.sender); - else - dp = new FabricPlayer(plugin, null); - - plugin.core.listenerManager.processChatEvent(DynmapListenerManager.EventType.PLAYER_CHAT, dp, cm.message); - } - // Check for generated chunks - if ((cur_tick % 20) == 0) { - } - } - - private Predicate distinctByKeyAndNonNull(Function keyExtractor) { - Set seen = ConcurrentHashMap.newKeySet(); - return t -> t != null && seen.add(keyExtractor.apply(t)); - } - - private Optional getModContainerById(String id) { - return FabricLoader.getInstance().getModContainer(id); - } - - @Override - public boolean isModLoaded(String name) { - return FabricLoader.getInstance().getModContainer(name).isPresent(); - } - - @Override - public String getModVersion(String name) { - Optional mod = getModContainerById(name); // Try case sensitive lookup - return mod.map(modContainer -> modContainer.getMetadata().getVersion().getFriendlyString()).orElse(null); - } - - @Override - public double getServerTPS() { - return plugin.tps; - } - - @Override - public String getServerIP() { - if (server.isSinglePlayer()) - return "0.0.0.0"; - else - return server.getServerIp(); - } - - @Override - public File getModContainerFile(String name) { - Optional container = getModContainerById(name); // Try case sensitive lookup - if (container.isPresent()) { - Path path = container.get().getRootPath(); - if (path.getFileSystem().provider().getScheme().equals("jar")) { - path = Paths.get(path.getFileSystem().toString()); - } - return path.toFile(); - } - return null; - } - - @Override - public List getModList() { - return FabricLoader.getInstance() - .getAllMods() - .stream() - .map(container -> container.getMetadata().getId()) - .collect(Collectors.toList()); - } - - @Override - public Map getBlockIDMap() { - Map map = new HashMap(); - return map; - } - - @Override - public InputStream openResource(String modid, String rname) { - if (modid == null) modid = "minecraft"; - - if ("minecraft".equals(modid)) { - return MinecraftServer.class.getClassLoader().getResourceAsStream(rname); - } else { - if (rname.startsWith("/") || rname.startsWith("\\")) { - rname = rname.substring(1); - } - - final String finalModid = modid; - final String finalRname = rname; - return getModContainerById(modid).map(container -> { - try { - return Files.newInputStream(container.getPath(finalRname)); - } catch (IOException e) { - Log.severe("Failed to load resource of mod :" + finalModid, e); - return null; - } - }).orElse(null); - } - } - - /** - * Get block unique ID map (module:blockid) - */ - @Override - public Map getBlockUniqueIDMap() { - HashMap map = new HashMap(); - return map; - } - - /** - * Get item unique ID map (module:itemid) - */ - @Override - public Map getItemUniqueIDMap() { - HashMap map = new HashMap(); - return map; - } - -} diff --git a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/FabricWorld.java b/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/FabricWorld.java deleted file mode 100644 index 5ac2ada6..00000000 --- a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/FabricWorld.java +++ /dev/null @@ -1,222 +0,0 @@ -package org.dynmap.fabric_1_16_1; - -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.registry.RegistryKey; -import net.minecraft.world.Heightmap; -import net.minecraft.world.LightType; -import net.minecraft.world.World; -import net.minecraft.world.WorldAccess; -import net.minecraft.world.border.WorldBorder; -import org.dynmap.DynmapChunk; -import org.dynmap.DynmapLocation; -import org.dynmap.DynmapWorld; -import org.dynmap.utils.MapChunkCache; -import org.dynmap.utils.Polygon; - -import java.util.List; - -public class FabricWorld extends DynmapWorld { - // TODO: Store this relative to World saves for integrated server - public static final String SAVED_WORLDS_FILE = "fabricworlds.yml"; - private WorldAccess world; - private final boolean skylight; - private final boolean isnether; - private final boolean istheend; - private final String env; - private DynmapLocation spawnloc = new DynmapLocation(); - private static int maxWorldHeight = 256; // Maximum allows world height - - public static int getMaxWorldHeight() { - return maxWorldHeight; - } - - public static void setMaxWorldHeight(int h) { - maxWorldHeight = h; - } - - public static String getWorldName(WorldAccess w) { - RegistryKey rk = w.getWorld().getRegistryKey(); - if (rk == World.OVERWORLD) { // Overworld? - return w.getWorld().getServer().getSaveProperties().getLevelName(); - } else if (rk == World.END) { - return "DIM1"; - } else if (rk == World.NETHER) { - return "DIM-1"; - } else { - return rk.getValue().getNamespace() + "_" + rk.getValue().getPath(); - } - } - - public FabricWorld(WorldAccess w) { - this(getWorldName(w), w.getWorld().getHeight(), - w.getWorld().getSeaLevel(), - w.getWorld().getRegistryKey() == World.NETHER, - w.getWorld().getRegistryKey() == World.END, - w.getWorld().getRegistryKey().getValue().getPath()); - setWorldLoaded(w); - } - - public FabricWorld(String name, int height, int sealevel, boolean nether, boolean the_end, String deftitle) { - super(name, (height > maxWorldHeight) ? maxWorldHeight : height, sealevel); - world = null; - setTitle(deftitle); - isnether = nether; - istheend = the_end; - skylight = !(isnether || istheend); - - if (isnether) { - env = "nether"; - } else if (istheend) { - env = "the_end"; - } else { - env = "normal"; - } - - } - - /* Test if world is nether */ - @Override - public boolean isNether() { - return isnether; - } - - public boolean isTheEnd() { - return istheend; - } - - /* Get world spawn location */ - @Override - public DynmapLocation getSpawnLocation() { - if (world != null) { - spawnloc.x = world.getLevelProperties().getSpawnX(); - spawnloc.y = world.getLevelProperties().getSpawnY(); - spawnloc.z = world.getLevelProperties().getSpawnZ(); - spawnloc.world = this.getName(); - } - return spawnloc; - } - - /* Get world time */ - @Override - public long getTime() { - if (world != null) - return world.getWorld().getTime(); - else - return -1; - } - - /* World is storming */ - @Override - public boolean hasStorm() { - if (world != null) - return world.getWorld().isRaining(); - else - return false; - } - - /* World is thundering */ - @Override - public boolean isThundering() { - if (world != null) - return world.getWorld().isThundering(); - else - return false; - } - - /* World is loaded */ - @Override - public boolean isLoaded() { - return (world != null); - } - - /* Set world to unloaded */ - @Override - public void setWorldUnloaded() { - getSpawnLocation(); - world = null; - } - - /* Set world to loaded */ - public void setWorldLoaded(WorldAccess w) { - world = w; - this.sealevel = w.getSeaLevel(); // Read actual current sealevel from world - // Update lighting table - for (int i = 0; i < 16; i++) { - this.setBrightnessTableEntry(i, w.getWorld().getDimension().method_28516(i)); - } - } - - /* Get light level of block */ - @Override - public int getLightLevel(int x, int y, int z) { - if (world != null) - return world.getLightLevel(new BlockPos(x, y, z)); - else - return -1; - } - - /* Get highest Y coord of given location */ - @Override - public int getHighestBlockYAt(int x, int z) { - if (world != null) { - return world.getWorld().getChunk(x >> 4, z >> 4).getHeightmap(Heightmap.Type.MOTION_BLOCKING).get(x & 15, z & 15); - } else - return -1; - } - - /* Test if sky light level is requestable */ - @Override - public boolean canGetSkyLightLevel() { - return skylight; - } - - /* Return sky light level */ - @Override - public int getSkyLightLevel(int x, int y, int z) { - if (world != null) { - return world.getLightLevel(LightType.SKY, new BlockPos(x, y, z)); - } else - return -1; - } - - /** - * Get world environment ID (lower case - normal, the_end, nether) - */ - @Override - public String getEnvironment() { - return env; - } - - /** - * Get map chunk cache for world - */ - @Override - public MapChunkCache getChunkCache(List chunks) { - if (world != null) { - FabricMapChunkCache c = new FabricMapChunkCache(); - c.setChunks(this, chunks); - return c; - } - return null; - } - - public World getWorld() { - return world.getWorld(); - } - - @Override - public Polygon getWorldBorder() { - if (world != null) { - WorldBorder wb = world.getWorldBorder(); - if ((wb != null) && (wb.getSize() < 5.9E7)) { - Polygon p = new Polygon(); - p.addVertex(wb.getBoundWest(), wb.getBoundNorth()); - p.addVertex(wb.getBoundWest(), wb.getBoundSouth()); - p.addVertex(wb.getBoundEast(), wb.getBoundSouth()); - p.addVertex(wb.getBoundEast(), wb.getBoundNorth()); - return p; - } - } - return null; - } -} diff --git a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/SnapshotCache.java b/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/SnapshotCache.java deleted file mode 100644 index 9c7f2e6f..00000000 --- a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/SnapshotCache.java +++ /dev/null @@ -1,201 +0,0 @@ -package org.dynmap.fabric_1_16_1; - -import org.dynmap.utils.DynIntHashMap; - -import java.lang.ref.Reference; -import java.lang.ref.ReferenceQueue; -import java.lang.ref.SoftReference; -import java.lang.ref.WeakReference; -import java.util.IdentityHashMap; -import java.util.LinkedHashMap; -import java.util.Map; - -public class SnapshotCache { - public static class SnapshotRec { - public ChunkSnapshot ss; - public DynIntHashMap tileData; - } - - private CacheHashMap snapcache; - private ReferenceQueue refqueue; - private long cache_attempts; - private long cache_success; - private boolean softref; - - private static class CacheRec { - Reference ref; - boolean hasbiome; - boolean hasrawbiome; - boolean hasblockdata; - boolean hashighesty; - } - - @SuppressWarnings("serial") - public class CacheHashMap extends LinkedHashMap { - private int limit; - private IdentityHashMap, String> reverselookup; - - public CacheHashMap(int lim) { - super(16, (float) 0.75, true); - limit = lim; - reverselookup = new IdentityHashMap, String>(); - } - - protected boolean removeEldestEntry(Map.Entry last) { - boolean remove = (size() >= limit); - if (remove && (last != null) && (last.getValue() != null)) { - reverselookup.remove(last.getValue().ref); - } - return remove; - } - } - - /** - * Create snapshot cache - */ - public SnapshotCache(int max_size, boolean softref) { - snapcache = new CacheHashMap(max_size); - refqueue = new ReferenceQueue(); - this.softref = softref; - } - - private String getKey(String w, int cx, int cz) { - return w + ":" + cx + ":" + cz; - } - - /** - * Invalidate cached snapshot, if in cache - */ - public void invalidateSnapshot(String w, int x, int y, int z) { - String key = getKey(w, x >> 4, z >> 4); - synchronized (snapcache) { - CacheRec rec = snapcache.remove(key); - if (rec != null) { - snapcache.reverselookup.remove(rec.ref); - rec.ref.clear(); - } - } - //processRefQueue(); - } - - /** - * Invalidate cached snapshot, if in cache - */ - public void invalidateSnapshot(String w, int x0, int y0, int z0, int x1, int y1, int z1) { - for (int xx = (x0 >> 4); xx <= (x1 >> 4); xx++) { - for (int zz = (z0 >> 4); zz <= (z1 >> 4); zz++) { - String key = getKey(w, xx, zz); - synchronized (snapcache) { - CacheRec rec = snapcache.remove(key); - if (rec != null) { - snapcache.reverselookup.remove(rec.ref); - rec.ref.clear(); - } - } - } - } - //processRefQueue(); - } - - /** - * Look for chunk snapshot in cache - */ - public SnapshotRec getSnapshot(String w, int chunkx, int chunkz, - boolean blockdata, boolean biome, boolean biomeraw, boolean highesty) { - String key = getKey(w, chunkx, chunkz); - processRefQueue(); - SnapshotRec ss = null; - CacheRec rec; - synchronized (snapcache) { - rec = snapcache.get(key); - if (rec != null) { - ss = rec.ref.get(); - if (ss == null) { - snapcache.reverselookup.remove(rec.ref); - snapcache.remove(key); - } - } - } - if (ss != null) { - if ((blockdata && (!rec.hasblockdata)) || - (biome && (!rec.hasbiome)) || - (biomeraw && (!rec.hasrawbiome)) || - (highesty && (!rec.hashighesty))) { - ss = null; - } - } - cache_attempts++; - if (ss != null) cache_success++; - - return ss; - } - - /** - * Add chunk snapshot to cache - */ - public void putSnapshot(String w, int chunkx, int chunkz, SnapshotRec ss, - boolean blockdata, boolean biome, boolean biomeraw, boolean highesty) { - String key = getKey(w, chunkx, chunkz); - processRefQueue(); - CacheRec rec = new CacheRec(); - rec.hasblockdata = blockdata; - rec.hasbiome = biome; - rec.hasrawbiome = biomeraw; - rec.hashighesty = highesty; - if (softref) - rec.ref = new SoftReference(ss, refqueue); - else - rec.ref = new WeakReference(ss, refqueue); - synchronized (snapcache) { - CacheRec prevrec = snapcache.put(key, rec); - if (prevrec != null) { - snapcache.reverselookup.remove(prevrec.ref); - } - snapcache.reverselookup.put(rec.ref, key); - } - } - - /** - * Process reference queue - */ - private void processRefQueue() { - Reference ref; - while ((ref = refqueue.poll()) != null) { - synchronized (snapcache) { - String k = snapcache.reverselookup.remove(ref); - if (k != null) { - snapcache.remove(k); - } - } - } - } - - /** - * Get hit rate (percent) - */ - public double getHitRate() { - if (cache_attempts > 0) { - return (100.0 * cache_success) / (double) cache_attempts; - } - return 0.0; - } - - /** - * Reset cache stats - */ - public void resetStats() { - cache_attempts = cache_success = 0; - } - - /** - * Cleanup - */ - public void cleanup() { - if (snapcache != null) { - snapcache.clear(); - snapcache.reverselookup.clear(); - snapcache.reverselookup = null; - snapcache = null; - } - } -} diff --git a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/TaskRecord.java b/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/TaskRecord.java deleted file mode 100644 index cfd6dff6..00000000 --- a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/TaskRecord.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.dynmap.fabric_1_16_1; - -import java.util.concurrent.FutureTask; - -class TaskRecord implements Comparable { - TaskRecord(long ticktorun, long id, FutureTask future) { - this.ticktorun = ticktorun; - this.id = id; - this.future = future; - } - - private final long ticktorun; - private final long id; - private final FutureTask future; - - void run() { - this.future.run(); - } - - long getTickToRun() { - return this.ticktorun; - } - - @Override - public int compareTo(TaskRecord o) { - if (this.ticktorun < o.ticktorun) { - return -1; - } else if (this.ticktorun > o.ticktorun) { - return 1; - } else if (this.id < o.id) { - return -1; - } else if (this.id > o.id) { - return 1; - } else { - return 0; - } - } -} diff --git a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/VersionCheck.java b/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/VersionCheck.java deleted file mode 100644 index ab751af4..00000000 --- a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/VersionCheck.java +++ /dev/null @@ -1,98 +0,0 @@ -package org.dynmap.fabric_1_16_1; - -import org.dynmap.DynmapCore; -import org.dynmap.Log; - -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.URL; - -public class VersionCheck { - private static final String VERSION_URL = "http://mikeprimm.com/dynmap/releases.php"; - - public static void runCheck(final DynmapCore core) { - new Thread(new Runnable() { - public void run() { - doCheck(core); - } - }).start(); - } - - private static int getReleaseVersion(String s) { - int index = s.lastIndexOf('-'); - if (index < 0) - index = s.lastIndexOf('.'); - if (index >= 0) - s = s.substring(0, index); - String[] split = s.split("\\."); - int v = 0; - try { - for (int i = 0; (i < split.length) && (i < 3); i++) { - v += Integer.parseInt(split[i]) << (8 * (2 - i)); - } - } catch (NumberFormatException nfx) { - } - return v; - } - - private static int getBuildNumber(String s) { - int index = s.lastIndexOf('-'); - if (index < 0) - index = s.lastIndexOf('.'); - if (index >= 0) - s = s.substring(index + 1); - try { - return Integer.parseInt(s); - } catch (NumberFormatException nfx) { - return 99999999; - } - } - - private static void doCheck(DynmapCore core) { - String pluginver = core.getDynmapPluginVersion(); - String platform = core.getDynmapPluginPlatform(); - String platver = core.getDynmapPluginPlatformVersion(); - if ((pluginver == null) || (platform == null) || (platver == null)) - return; - HttpURLConnection conn = null; - String loc = VERSION_URL; - int cur_ver = getReleaseVersion(pluginver); - int cur_bn = getBuildNumber(pluginver); - try { - while ((loc != null) && (!loc.isEmpty())) { - URL url = new URL(loc); - conn = (HttpURLConnection) url.openConnection(); - conn.setRequestProperty("User-Agent", "Dynmap (" + platform + "/" + platver + "/" + pluginver); - conn.connect(); - loc = conn.getHeaderField("Location"); - } - BufferedReader rdr = new BufferedReader(new InputStreamReader(conn.getInputStream())); - String line = null; - while ((line = rdr.readLine()) != null) { - String[] split = line.split(":"); - if (split.length < 4) continue; - /* If our platform and version, or wildcard platform version */ - if (split[0].equals(platform) && (split[1].equals("*") || split[1].equals(platver))) { - int recommended_ver = getReleaseVersion(split[2]); - int recommended_bn = getBuildNumber(split[2]); - if ((recommended_ver > cur_ver) || ((recommended_ver == cur_ver) && (recommended_bn > cur_bn))) { /* Newer recommended build */ - Log.info("Version obsolete: new recommended version " + split[2] + " is available."); - } else if (cur_ver > recommended_ver) { /* Running dev or prerelease? */ - int prerel_ver = getReleaseVersion(split[3]); - int prerel_bn = getBuildNumber(split[3]); - if ((prerel_ver > cur_ver) || ((prerel_ver == cur_ver) && (prerel_bn > cur_bn))) { - Log.info("Version obsolete: new prerelease version " + split[3] + " is available."); - } - } - } - } - } catch (Exception x) { - Log.info("Error checking for latest version"); - } finally { - if (conn != null) { - conn.disconnect(); - } - } - } -} diff --git a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/command/DmapCommand.java b/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/command/DmapCommand.java deleted file mode 100644 index 707dc891..00000000 --- a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/command/DmapCommand.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.dynmap.fabric_1_16_1.command; - -import org.dynmap.fabric_1_16_1.DynmapPlugin; - -public class DmapCommand extends DynmapCommandExecutor { - public DmapCommand(DynmapPlugin p) { - super("dmap", p); - } -} diff --git a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/command/DmarkerCommand.java b/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/command/DmarkerCommand.java deleted file mode 100644 index bfb70f03..00000000 --- a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/command/DmarkerCommand.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.dynmap.fabric_1_16_1.command; - -import org.dynmap.fabric_1_16_1.DynmapPlugin; - -public class DmarkerCommand extends DynmapCommandExecutor { - public DmarkerCommand(DynmapPlugin p) { - super("dmarker", p); - } -} diff --git a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/command/DynmapCommand.java b/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/command/DynmapCommand.java deleted file mode 100644 index db480f9d..00000000 --- a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/command/DynmapCommand.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.dynmap.fabric_1_16_1.command; - -import org.dynmap.fabric_1_16_1.DynmapPlugin; - -public class DynmapCommand extends DynmapCommandExecutor { - public DynmapCommand(DynmapPlugin p) { - super("dynmap", p); - } -} diff --git a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/command/DynmapCommandExecutor.java b/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/command/DynmapCommandExecutor.java deleted file mode 100644 index 85031c89..00000000 --- a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/command/DynmapCommandExecutor.java +++ /dev/null @@ -1,63 +0,0 @@ -package org.dynmap.fabric_1_16_1.command; - -import com.mojang.brigadier.Command; -import com.mojang.brigadier.CommandDispatcher; -import com.mojang.brigadier.context.CommandContext; -import com.mojang.brigadier.exceptions.CommandSyntaxException; -import com.mojang.brigadier.tree.ArgumentCommandNode; -import com.mojang.brigadier.tree.LiteralCommandNode; -import com.mojang.brigadier.tree.RootCommandNode; -import net.minecraft.server.command.ServerCommandSource; -import org.dynmap.fabric_1_16_1.DynmapPlugin; - -import java.util.Arrays; - -import static com.mojang.brigadier.arguments.StringArgumentType.greedyString; -import static net.minecraft.server.command.CommandManager.argument; -import static net.minecraft.server.command.CommandManager.literal; - -public class DynmapCommandExecutor implements Command { - private final String cmd; - private final DynmapPlugin plugin; - - DynmapCommandExecutor(String cmd, DynmapPlugin plugin) { - this.cmd = cmd; - this.plugin = plugin; - } - - public void register(CommandDispatcher dispatcher) { - final RootCommandNode root = dispatcher.getRoot(); - - final LiteralCommandNode command = literal(this.cmd) - .executes(this) - .build(); - - final ArgumentCommandNode args = argument("args", greedyString()) - .executes(this) - .build(); - - // So this becomes "cmd" [args] - command.addChild(args); - - // Add command to the command dispatcher via root node. - root.addChild(command); - } - - @Override - public int run(CommandContext context) throws CommandSyntaxException { - // Commands in brigadier may be proxied in Minecraft via a syntax like `/execute ... ... run dmap [args]` - // Dynmap will fail to parse this properly, so we find the starting position of the actual command being parsed after any forks or redirects. - // The start position of the range specifies where the actual command dynmap has registered starts - int start = context.getRange().getStart(); - String dynmapInput = context.getInput().substring(start); - - String[] args = dynmapInput.split("\\s+"); - plugin.handleCommand(context.getSource(), cmd, Arrays.copyOfRange(args, 1, args.length)); - return 1; - } - - // @Override // TODO: Usage? - public String getUsage(ServerCommandSource commandSource) { - return "Run /" + cmd + " help for details on using command"; - } -} diff --git a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/command/DynmapExpCommand.java b/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/command/DynmapExpCommand.java deleted file mode 100644 index 6b6eb748..00000000 --- a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/command/DynmapExpCommand.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.dynmap.fabric_1_16_1.command; - -import org.dynmap.fabric_1_16_1.DynmapPlugin; - -public class DynmapExpCommand extends DynmapCommandExecutor { - public DynmapExpCommand(DynmapPlugin p) { - super("dynmapexp", p); - } -} diff --git a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/event/BlockEvents.java b/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/event/BlockEvents.java deleted file mode 100644 index 93c0be43..00000000 --- a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/event/BlockEvents.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.dynmap.fabric_1_16_1.event; - -import net.fabricmc.fabric.api.event.Event; -import net.fabricmc.fabric.api.event.EventFactory; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; - -public class BlockEvents { - private BlockEvents() { - } - - public static Event EVENT = EventFactory.createArrayBacked(BlockCallback.class, - (listeners) -> (world, pos) -> { - for (BlockCallback callback : listeners) { - callback.onBlockEvent(world, pos); - } - } - ); - - public interface BlockCallback { - void onBlockEvent(World world, BlockPos pos); - } -} diff --git a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/event/ChunkDataEvents.java b/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/event/ChunkDataEvents.java deleted file mode 100644 index 5734d5e8..00000000 --- a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/event/ChunkDataEvents.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.dynmap.fabric_1_16_1.event; - -import net.fabricmc.fabric.api.event.Event; -import net.fabricmc.fabric.api.event.EventFactory; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.world.chunk.Chunk; - -public class ChunkDataEvents { - private ChunkDataEvents() { - } - - public static Event SAVE = EventFactory.createArrayBacked(Save.class, - (listeners) -> (world, chunk) -> { - for (Save callback : listeners) { - callback.onSave(world, chunk); - } - } - ); - - @FunctionalInterface - public interface Save { - void onSave(ServerWorld world, Chunk chunk); - } -} diff --git a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/event/CustomServerLifecycleEvents.java b/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/event/CustomServerLifecycleEvents.java deleted file mode 100644 index fd7be1db..00000000 --- a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/event/CustomServerLifecycleEvents.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.dynmap.fabric_1_16_1.event; - -import net.fabricmc.fabric.api.event.Event; -import net.fabricmc.fabric.api.event.EventFactory; -import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; - -public class CustomServerLifecycleEvents { - public static final Event SERVER_STARTED_PRE_WORLD_LOAD = - EventFactory.createArrayBacked(ServerLifecycleEvents.ServerStarted.class, (callbacks) -> (server) -> { - for (ServerLifecycleEvents.ServerStarted callback : callbacks) { - callback.onServerStarted(server); - } - }); -} diff --git a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/event/PlayerEvents.java b/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/event/PlayerEvents.java deleted file mode 100644 index 8e345851..00000000 --- a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/event/PlayerEvents.java +++ /dev/null @@ -1,62 +0,0 @@ -package org.dynmap.fabric_1_16_1.event; - -import net.fabricmc.fabric.api.event.Event; -import net.fabricmc.fabric.api.event.EventFactory; -import net.minecraft.server.network.ServerPlayerEntity; - -public class PlayerEvents { - private PlayerEvents() { - } - - public static Event PLAYER_LOGGED_IN = EventFactory.createArrayBacked(PlayerLoggedIn.class, - (listeners) -> (player) -> { - for (PlayerLoggedIn callback : listeners) { - callback.onPlayerLoggedIn(player); - } - } - ); - - public static Event PLAYER_LOGGED_OUT = EventFactory.createArrayBacked(PlayerLoggedOut.class, - (listeners) -> (player) -> { - for (PlayerLoggedOut callback : listeners) { - callback.onPlayerLoggedOut(player); - } - } - ); - - public static Event PLAYER_CHANGED_DIMENSION = EventFactory.createArrayBacked(PlayerChangedDimension.class, - (listeners) -> (player) -> { - for (PlayerChangedDimension callback : listeners) { - callback.onPlayerChangedDimension(player); - } - } - ); - - public static Event PLAYER_RESPAWN = EventFactory.createArrayBacked(PlayerRespawn.class, - (listeners) -> (player) -> { - for (PlayerRespawn callback : listeners) { - callback.onPlayerRespawn(player); - } - } - ); - - @FunctionalInterface - public interface PlayerLoggedIn { - void onPlayerLoggedIn(ServerPlayerEntity player); - } - - @FunctionalInterface - public interface PlayerLoggedOut { - void onPlayerLoggedOut(ServerPlayerEntity player); - } - - @FunctionalInterface - public interface PlayerChangedDimension { - void onPlayerChangedDimension(ServerPlayerEntity player); - } - - @FunctionalInterface - public interface PlayerRespawn { - void onPlayerRespawn(ServerPlayerEntity player); - } -} diff --git a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/event/ServerChatEvents.java b/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/event/ServerChatEvents.java deleted file mode 100644 index 606390e3..00000000 --- a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/event/ServerChatEvents.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.dynmap.fabric_1_16_1.event; - -import net.fabricmc.fabric.api.event.Event; -import net.fabricmc.fabric.api.event.EventFactory; -import net.minecraft.server.network.ServerPlayerEntity; - -public class ServerChatEvents { - private ServerChatEvents() { - } - - public static Event EVENT = EventFactory.createArrayBacked(ServerChatCallback.class, - (listeners) -> (player, message) -> { - for (ServerChatCallback callback : listeners) { - callback.onChatMessage(player, message); - } - } - ); - - @FunctionalInterface - public interface ServerChatCallback { - void onChatMessage(ServerPlayerEntity player, String message); - } -} \ No newline at end of file diff --git a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/mixin/BiomeEffectsAccessor.java b/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/mixin/BiomeEffectsAccessor.java deleted file mode 100644 index 0f16d961..00000000 --- a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/mixin/BiomeEffectsAccessor.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.dynmap.fabric_1_16_1.mixin; - -import net.minecraft.world.biome.BiomeEffects; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -@Mixin(BiomeEffects.class) -public interface BiomeEffectsAccessor { - @Accessor - int getWaterColor(); -} diff --git a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/mixin/MinecraftServerMixin.java b/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/mixin/MinecraftServerMixin.java deleted file mode 100644 index 74cb9775..00000000 --- a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/mixin/MinecraftServerMixin.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.dynmap.fabric_1_16_1.mixin; - -import net.minecraft.server.MinecraftServer; -import org.dynmap.fabric_1_16_1.event.CustomServerLifecycleEvents; -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.CallbackInfo; - -@Mixin(MinecraftServer.class) -public class MinecraftServerMixin { - @Inject(method = "loadWorld", at = @At("HEAD")) - protected void loadWorld(CallbackInfo info) { - CustomServerLifecycleEvents.SERVER_STARTED_PRE_WORLD_LOAD.invoker().onServerStarted((MinecraftServer) (Object) this); - } -} diff --git a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/mixin/PlayerManagerMixin.java b/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/mixin/PlayerManagerMixin.java deleted file mode 100644 index a988dc0a..00000000 --- a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/mixin/PlayerManagerMixin.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.dynmap.fabric_1_16_1.mixin; - -import net.minecraft.network.ClientConnection; -import net.minecraft.server.PlayerManager; -import net.minecraft.server.network.ServerPlayerEntity; -import org.dynmap.fabric_1_16_1.event.PlayerEvents; -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.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(PlayerManager.class) -public class PlayerManagerMixin { - @Inject(method = "onPlayerConnect", at = @At("TAIL")) - public void onPlayerConnect(ClientConnection connection, ServerPlayerEntity player, CallbackInfo info) { - PlayerEvents.PLAYER_LOGGED_IN.invoker().onPlayerLoggedIn(player); - } - - @Inject(method = "remove", at = @At("HEAD")) - public void remove(ServerPlayerEntity player, CallbackInfo info) { - PlayerEvents.PLAYER_LOGGED_OUT.invoker().onPlayerLoggedOut(player); - } - - @Inject(method = "respawnPlayer", at = @At("RETURN")) - public void respawnPlayer(ServerPlayerEntity player, boolean alive, CallbackInfoReturnable info) { - PlayerEvents.PLAYER_RESPAWN.invoker().onPlayerRespawn(info.getReturnValue()); - } -} diff --git a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/mixin/ServerPlayNetworkHandlerMixin.java b/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/mixin/ServerPlayNetworkHandlerMixin.java deleted file mode 100644 index 36904be8..00000000 --- a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/mixin/ServerPlayNetworkHandlerMixin.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.dynmap.fabric_1_16_1.mixin; - -import net.minecraft.network.packet.c2s.play.ChatMessageC2SPacket; -import net.minecraft.server.network.ServerPlayNetworkHandler; -import net.minecraft.server.network.ServerPlayerEntity; -import org.dynmap.fabric_1_16_1.event.ServerChatEvents; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.LocalCapture; - -@Mixin(ServerPlayNetworkHandler.class) -public abstract class ServerPlayNetworkHandlerMixin { - @Shadow - public ServerPlayerEntity player; - - @Inject( - method = "onGameMessage", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/server/PlayerManager;broadcastChatMessage(Lnet/minecraft/text/Text;Lnet/minecraft/network/MessageType;Ljava/util/UUID;)V", - shift = At.Shift.BEFORE - ), - locals = LocalCapture.CAPTURE_FAILSOFT - ) - public void onGameMessage(ChatMessageC2SPacket packet, CallbackInfo info, String string) { - ServerChatEvents.EVENT.invoker().onChatMessage(player, string); - } -} diff --git a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/mixin/ServerPlayerEntityMixin.java b/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/mixin/ServerPlayerEntityMixin.java deleted file mode 100644 index 7bd93895..00000000 --- a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/mixin/ServerPlayerEntityMixin.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.dynmap.fabric_1_16_1.mixin; - -import net.minecraft.entity.Entity; -import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.server.world.ServerWorld; -import org.dynmap.fabric_1_16_1.event.PlayerEvents; -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.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(ServerPlayerEntity.class) -public class ServerPlayerEntityMixin { - @Inject(method = "teleport", at = @At("RETURN")) - public void teleport(ServerWorld targetWorld, double x, double y, double z, float yaw, float pitch, CallbackInfo info) { - ServerPlayerEntity player = (ServerPlayerEntity) (Object) this; - if (targetWorld != player.world) { - PlayerEvents.PLAYER_CHANGED_DIMENSION.invoker().onPlayerChangedDimension(player); - } - } - - @Inject(method = "changeDimension", at = @At("RETURN")) - public void changeDimension(ServerWorld destination, CallbackInfoReturnable info) { - ServerPlayerEntity player = (ServerPlayerEntity) (Object) this; - if (!player.removed) { - PlayerEvents.PLAYER_CHANGED_DIMENSION.invoker().onPlayerChangedDimension(player); - } - } -} diff --git a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/mixin/ThreadedAnvilChunkStorageAccessor.java b/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/mixin/ThreadedAnvilChunkStorageAccessor.java deleted file mode 100644 index 3648cc23..00000000 --- a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/mixin/ThreadedAnvilChunkStorageAccessor.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.dynmap.fabric_1_16_1.mixin; - -import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap; -import net.minecraft.server.world.ChunkHolder; -import net.minecraft.server.world.ThreadedAnvilChunkStorage; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -@Mixin(ThreadedAnvilChunkStorage.class) -public interface ThreadedAnvilChunkStorageAccessor { - @Accessor - Long2ObjectLinkedOpenHashMap getChunkHolders(); -} diff --git a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/mixin/ThreadedAnvilChunkStorageMixin.java b/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/mixin/ThreadedAnvilChunkStorageMixin.java deleted file mode 100644 index 5eb73d83..00000000 --- a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/mixin/ThreadedAnvilChunkStorageMixin.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.dynmap.fabric_1_16_1.mixin; - -import net.minecraft.server.world.ServerWorld; -import net.minecraft.server.world.ThreadedAnvilChunkStorage; -import net.minecraft.world.chunk.Chunk; -import org.dynmap.fabric_1_16_1.event.ChunkDataEvents; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(ThreadedAnvilChunkStorage.class) -public abstract class ThreadedAnvilChunkStorageMixin { - @Shadow - @Final - private ServerWorld world; - - @Inject(method = "save(Lnet/minecraft/world/chunk/Chunk;)Z", at = @At("RETURN")) - private void save(Chunk chunk, CallbackInfoReturnable info) { - if (info.getReturnValueZ()) { - ChunkDataEvents.SAVE.invoker().onSave(this.world, chunk); - } - } -} diff --git a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/mixin/WorldChunkMixin.java b/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/mixin/WorldChunkMixin.java deleted file mode 100644 index 6d9cb096..00000000 --- a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/mixin/WorldChunkMixin.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.dynmap.fabric_1_16_1.mixin; - -import net.minecraft.block.BlockState; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; -import net.minecraft.world.chunk.WorldChunk; -import org.dynmap.fabric_1_16_1.event.BlockEvents; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(WorldChunk.class) -public abstract class WorldChunkMixin { - @Shadow - public abstract World getWorld(); - - @Inject(method = "setBlockState", at = @At("RETURN")) - public void setBlockState(BlockPos pos, BlockState state, boolean moved, CallbackInfoReturnable info) { - if (info.getReturnValue() != null) { - BlockEvents.EVENT.invoker().onBlockEvent(this.getWorld(), pos); - } - } -} diff --git a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/permissions/FilePermissions.java b/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/permissions/FilePermissions.java deleted file mode 100644 index f16c90c0..00000000 --- a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/permissions/FilePermissions.java +++ /dev/null @@ -1,103 +0,0 @@ -package org.dynmap.fabric_1_16_1.permissions; - -import net.minecraft.entity.player.PlayerEntity; -import org.dynmap.ConfigurationNode; -import org.dynmap.Log; -import org.dynmap.fabric_1_16_1.DynmapPlugin; - -import java.io.File; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -public class FilePermissions implements PermissionProvider { - private HashMap> perms; - private Set defperms; - - public static FilePermissions create() { - File f = new File("dynmap/permissions.yml"); - if (!f.exists()) - return null; - ConfigurationNode cfg = new ConfigurationNode(f); - cfg.load(); - - Log.info("Using permissions.yml for access control"); - - return new FilePermissions(cfg); - } - - private FilePermissions(ConfigurationNode cfg) { - perms = new HashMap>(); - for (String k : cfg.keySet()) { - List p = cfg.getStrings(k, null); - if (p != null) { - k = k.toLowerCase(); - HashSet pset = new HashSet(); - for (String perm : p) { - pset.add(perm.toLowerCase()); - } - perms.put(k, pset); - if (k.equals("defaultuser")) { - defperms = pset; - } - } - } - } - - private boolean hasPerm(String player, String perm) { - Set ps = perms.get(player); - if ((ps != null) && (ps.contains(perm))) { - return true; - } - if (defperms.contains(perm)) { - return true; - } - return false; - } - - @Override - public Set hasOfflinePermissions(String player, Set perms) { - player = player.toLowerCase(); - HashSet rslt = new HashSet(); - if (DynmapPlugin.plugin.isOp(player)) { - rslt.addAll(perms); - } else { - for (String p : perms) { - if (hasPerm(player, p)) { - rslt.add(p); - } - } - } - return rslt; - } - - @Override - public boolean hasOfflinePermission(String player, String perm) { - player = player.toLowerCase(); - if (DynmapPlugin.plugin.isOp(player)) { - return true; - } else { - return hasPerm(player, perm); - } - } - - @Override - public boolean has(PlayerEntity psender, String permission) { - if (psender != null) { - String n = psender.getName().getString().toLowerCase(); - return hasPerm(n, permission); - } - return true; - } - - @Override - public boolean hasPermissionNode(PlayerEntity psender, String permission) { - if (psender != null) { - String player = psender.getName().getString().toLowerCase(); - return DynmapPlugin.plugin.isOp(player); - } - return false; - } - -} diff --git a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/permissions/OpPermissions.java b/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/permissions/OpPermissions.java deleted file mode 100644 index 9b9c880d..00000000 --- a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/permissions/OpPermissions.java +++ /dev/null @@ -1,52 +0,0 @@ -package org.dynmap.fabric_1_16_1.permissions; - -import net.minecraft.entity.player.PlayerEntity; -import org.dynmap.Log; -import org.dynmap.fabric_1_16_1.DynmapPlugin; - -import java.util.HashSet; -import java.util.Set; - -public class OpPermissions implements PermissionProvider { - public HashSet usrCommands = new HashSet(); - - public OpPermissions(String[] usrCommands) { - for (String usrCommand : usrCommands) { - this.usrCommands.add(usrCommand); - } - Log.info("Using ops.txt for access control"); - } - - @Override - public Set hasOfflinePermissions(String player, Set perms) { - HashSet rslt = new HashSet(); - if (DynmapPlugin.plugin.isOp(player)) { - rslt.addAll(perms); - } - return rslt; - } - - @Override - public boolean hasOfflinePermission(String player, String perm) { - return DynmapPlugin.plugin.isOp(player); - } - - @Override - public boolean has(PlayerEntity psender, String permission) { - if (psender != null) { - if (usrCommands.contains(permission)) { - return true; - } - return DynmapPlugin.plugin.isOp(psender.getName().getString()); - } - return true; - } - - @Override - public boolean hasPermissionNode(PlayerEntity psender, String permission) { - if (psender != null) { - return DynmapPlugin.plugin.isOp(psender.getName().getString()); - } - return true; - } -} diff --git a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/permissions/PermissionProvider.java b/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/permissions/PermissionProvider.java deleted file mode 100644 index 45eb8b1b..00000000 --- a/fabric-1.16.1/src/main/java/org/dynmap/fabric_1_16_1/permissions/PermissionProvider.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.dynmap.fabric_1_16_1.permissions; - -import net.minecraft.entity.player.PlayerEntity; - -import java.util.Set; - -public interface PermissionProvider { - boolean has(PlayerEntity sender, String permission); - - boolean hasPermissionNode(PlayerEntity sender, String permission); - - Set hasOfflinePermissions(String player, Set perms); - - boolean hasOfflinePermission(String player, String perm); - -} diff --git a/fabric-1.16.1/src/main/resources/assets/dynmap/icon.png b/fabric-1.16.1/src/main/resources/assets/dynmap/icon.png deleted file mode 100644 index d18f3e145d02440b065b2365ff14b9261b5877c4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 34043 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%0AL%*pBb$DiCiIy`b6`#WF% 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