From 987871933797ebd402b5ac1aee05cc9d261e1a90 Mon Sep 17 00:00:00 2001 From: Michael Primm Date: Sat, 23 Dec 2023 15:03:35 -0600 Subject: [PATCH] Drop older 1.19 Forge and Fabric builds --- fabric-1.19.1/.gitignore | 32 - fabric-1.19.1/build.gradle | 69 - fabric-1.19.1/gradle.properties | 4 - .../org/dynmap/fabric_1_19_1/DynmapMod.java | 50 - .../dynmap/fabric_1_19_1/DynmapPlugin.java | 800 ------- .../dynmap/fabric_1_19_1/FabricAdapter.java | 13 - .../fabric_1_19_1/FabricCommandSender.java | 47 - .../dynmap/fabric_1_19_1/FabricLogger.java | 49 - .../fabric_1_19_1/FabricMapChunkCache.java | 116 - .../dynmap/fabric_1_19_1/FabricPlayer.java | 258 --- .../dynmap/fabric_1_19_1/FabricServer.java | 609 ----- .../org/dynmap/fabric_1_19_1/FabricWorld.java | 236 -- .../java/org/dynmap/fabric_1_19_1/NBT.java | 126 - .../org/dynmap/fabric_1_19_1/TaskRecord.java | 38 - .../dynmap/fabric_1_19_1/VersionCheck.java | 98 - .../access/ProtoChunkAccessor.java | 5 - .../fabric_1_19_1/command/DmapCommand.java | 9 - .../fabric_1_19_1/command/DmarkerCommand.java | 9 - .../fabric_1_19_1/command/DynmapCommand.java | 9 - .../command/DynmapCommandExecutor.java | 63 - .../command/DynmapExpCommand.java | 9 - .../fabric_1_19_1/event/BlockEvents.java | 40 - .../event/CustomServerChunkEvents.java | 21 - .../event/CustomServerLifecycleEvents.java | 14 - .../fabric_1_19_1/event/PlayerEvents.java | 62 - .../fabric_1_19_1/event/ServerChatEvents.java | 23 - .../mixin/BiomeEffectsAccessor.java | 11 - .../mixin/MinecraftServerMixin.java | 16 - .../mixin/PlayerManagerMixin.java | 29 - .../fabric_1_19_1/mixin/ProtoChunkMixin.java | 30 - .../mixin/ServerPlayNetworkHandlerMixin.java | 68 - .../mixin/ServerPlayerEntityMixin.java | 30 - .../mixin/ThreadedAnvilChunkStorageMixin.java | 32 - .../fabric_1_19_1/mixin/WorldChunkMixin.java | 25 - .../permissions/FabricPermissions.java | 47 - .../permissions/FilePermissions.java | 103 - .../permissions/LuckPermissions.java | 102 - .../permissions/OpPermissions.java | 52 - .../permissions/PermissionProvider.java | 16 - .../src/main/resources/assets/dynmap/icon.png | Bin 34043 -> 0 bytes .../src/main/resources/configuration.txt | 498 ---- .../src/main/resources/dynmap.mixins.json | 19 - .../src/main/resources/fabric.mod.json | 33 - .../main/resources/permissions.yml.example | 27 - fabric-1.19.3/.gitignore | 32 - fabric-1.19.3/build.gradle | 69 - fabric-1.19.3/gradle.properties | 4 - .../org/dynmap/fabric_1_19_3/DynmapMod.java | 50 - .../dynmap/fabric_1_19_3/DynmapPlugin.java | 801 ------- .../dynmap/fabric_1_19_3/FabricAdapter.java | 13 - .../fabric_1_19_3/FabricCommandSender.java | 47 - .../dynmap/fabric_1_19_3/FabricLogger.java | 49 - .../fabric_1_19_3/FabricMapChunkCache.java | 116 - .../dynmap/fabric_1_19_3/FabricPlayer.java | 258 --- .../dynmap/fabric_1_19_3/FabricServer.java | 610 ----- .../org/dynmap/fabric_1_19_3/FabricWorld.java | 236 -- .../java/org/dynmap/fabric_1_19_3/NBT.java | 126 - .../org/dynmap/fabric_1_19_3/TaskRecord.java | 38 - .../dynmap/fabric_1_19_3/VersionCheck.java | 98 - .../access/ProtoChunkAccessor.java | 5 - .../fabric_1_19_3/command/DmapCommand.java | 9 - .../fabric_1_19_3/command/DmarkerCommand.java | 9 - .../fabric_1_19_3/command/DynmapCommand.java | 9 - .../command/DynmapCommandExecutor.java | 63 - .../command/DynmapExpCommand.java | 9 - .../fabric_1_19_3/event/BlockEvents.java | 40 - .../event/CustomServerChunkEvents.java | 21 - .../event/CustomServerLifecycleEvents.java | 14 - .../fabric_1_19_3/event/PlayerEvents.java | 62 - .../fabric_1_19_3/event/ServerChatEvents.java | 23 - .../mixin/BiomeEffectsAccessor.java | 11 - .../mixin/MinecraftServerMixin.java | 16 - .../mixin/PlayerManagerMixin.java | 29 - .../fabric_1_19_3/mixin/ProtoChunkMixin.java | 30 - .../mixin/ServerPlayNetworkHandlerMixin.java | 66 - .../mixin/ServerPlayerEntityMixin.java | 30 - .../mixin/ThreadedAnvilChunkStorageMixin.java | 32 - .../fabric_1_19_3/mixin/WorldChunkMixin.java | 25 - .../permissions/FabricPermissions.java | 47 - .../permissions/FilePermissions.java | 103 - .../permissions/LuckPermissions.java | 102 - .../permissions/OpPermissions.java | 52 - .../permissions/PermissionProvider.java | 16 - .../src/main/resources/assets/dynmap/icon.png | Bin 34043 -> 0 bytes .../src/main/resources/configuration.txt | 498 ---- .../src/main/resources/dynmap.mixins.json | 19 - .../src/main/resources/fabric.mod.json | 33 - .../main/resources/permissions.yml.example | 27 - fabric-1.19/.gitignore | 32 - fabric-1.19/build.gradle | 69 - fabric-1.19/gradle.properties | 4 - .../org/dynmap/fabric_1_19/DynmapMod.java | 50 - .../org/dynmap/fabric_1_19/DynmapPlugin.java | 800 ------- .../org/dynmap/fabric_1_19/FabricAdapter.java | 13 - .../fabric_1_19/FabricCommandSender.java | 47 - .../org/dynmap/fabric_1_19/FabricLogger.java | 49 - .../fabric_1_19/FabricMapChunkCache.java | 116 - .../org/dynmap/fabric_1_19/FabricPlayer.java | 258 --- .../org/dynmap/fabric_1_19/FabricServer.java | 609 ----- .../org/dynmap/fabric_1_19/FabricWorld.java | 236 -- .../main/java/org/dynmap/fabric_1_19/NBT.java | 126 - .../org/dynmap/fabric_1_19/TaskRecord.java | 38 - .../org/dynmap/fabric_1_19/VersionCheck.java | 98 - .../access/ProtoChunkAccessor.java | 5 - .../fabric_1_19/command/DmapCommand.java | 9 - .../fabric_1_19/command/DmarkerCommand.java | 9 - .../fabric_1_19/command/DynmapCommand.java | 9 - .../command/DynmapCommandExecutor.java | 63 - .../fabric_1_19/command/DynmapExpCommand.java | 9 - .../dynmap/fabric_1_19/event/BlockEvents.java | 40 - .../event/CustomServerChunkEvents.java | 21 - .../event/CustomServerLifecycleEvents.java | 14 - .../fabric_1_19/event/PlayerEvents.java | 62 - .../fabric_1_19/event/ServerChatEvents.java | 23 - .../mixin/BiomeEffectsAccessor.java | 11 - .../mixin/MinecraftServerMixin.java | 16 - .../fabric_1_19/mixin/PlayerManagerMixin.java | 29 - .../fabric_1_19/mixin/ProtoChunkMixin.java | 30 - .../mixin/ServerPlayNetworkHandlerMixin.java | 70 - .../mixin/ServerPlayerEntityMixin.java | 30 - .../mixin/ThreadedAnvilChunkStorageMixin.java | 32 - .../fabric_1_19/mixin/WorldChunkMixin.java | 25 - .../permissions/FabricPermissions.java | 47 - .../permissions/FilePermissions.java | 103 - .../permissions/LuckPermissions.java | 102 - .../permissions/OpPermissions.java | 52 - .../permissions/PermissionProvider.java | 16 - .../src/main/resources/assets/dynmap/icon.png | Bin 34043 -> 0 bytes .../src/main/resources/configuration.txt | 498 ---- .../src/main/resources/dynmap.mixins.json | 19 - .../src/main/resources/fabric.mod.json | 33 - .../main/resources/permissions.yml.example | 27 - forge-1.19.2/.gitignore | 1 - forge-1.19.2/bin/.gitignore | 2 - forge-1.19.2/build.gradle | 92 - .../org/dynmap/forge_1_19_2/ClientProxy.java | 6 - .../org/dynmap/forge_1_19_2/DynmapMod.java | 136 -- .../org/dynmap/forge_1_19_2/DynmapPlugin.java | 2039 ----------------- .../forge_1_19_2/ForgeMapChunkCache.java | 109 - .../org/dynmap/forge_1_19_2/ForgeWorld.java | 249 -- .../java/org/dynmap/forge_1_19_2/NBT.java | 126 - .../java/org/dynmap/forge_1_19_2/Proxy.java | 24 - .../org/dynmap/forge_1_19_2/VersionCheck.java | 97 - .../permissions/FilePermissions.java | 103 - .../permissions/OpPermissions.java | 51 - .../permissions/PermissionProvider.java | 15 - .../resources/META-INF/accesstransformer.cfg | 4 - .../src/main/resources/META-INF/mods.toml | 26 - .../src/main/resources/configuration.txt | 503 ---- forge-1.19.2/src/main/resources/pack.mcmeta | 6 - .../main/resources/permissions.yml.example | 27 - forge-1.19/.gitignore | 1 - forge-1.19/bin/.gitignore | 2 - forge-1.19/build.gradle | 92 - .../org/dynmap/forge_1_19/ClientProxy.java | 6 - .../java/org/dynmap/forge_1_19/DynmapMod.java | 136 -- .../org/dynmap/forge_1_19/DynmapPlugin.java | 2039 ----------------- .../dynmap/forge_1_19/ForgeMapChunkCache.java | 109 - .../org/dynmap/forge_1_19/ForgeWorld.java | 249 -- .../main/java/org/dynmap/forge_1_19/NBT.java | 126 - .../java/org/dynmap/forge_1_19/Proxy.java | 24 - .../org/dynmap/forge_1_19/VersionCheck.java | 97 - .../permissions/FilePermissions.java | 103 - .../forge_1_19/permissions/OpPermissions.java | 51 - .../permissions/PermissionProvider.java | 15 - .../resources/META-INF/accesstransformer.cfg | 4 - .../src/main/resources/META-INF/mods.toml | 26 - .../src/main/resources/configuration.txt | 503 ---- forge-1.19/src/main/resources/pack.mcmeta | 6 - .../main/resources/permissions.yml.example | 27 - settings.gradle | 9 - 171 files changed, 19084 deletions(-) delete mode 100644 fabric-1.19.1/.gitignore delete mode 100644 fabric-1.19.1/build.gradle delete mode 100644 fabric-1.19.1/gradle.properties delete mode 100644 fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/DynmapMod.java delete mode 100644 fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/DynmapPlugin.java delete mode 100644 fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/FabricAdapter.java delete mode 100644 fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/FabricCommandSender.java delete mode 100644 fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/FabricLogger.java delete mode 100644 fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/FabricMapChunkCache.java delete mode 100644 fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/FabricPlayer.java delete mode 100644 fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/FabricServer.java delete mode 100644 fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/FabricWorld.java delete mode 100644 fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/NBT.java delete mode 100644 fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/TaskRecord.java delete mode 100644 fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/VersionCheck.java delete mode 100644 fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/access/ProtoChunkAccessor.java delete mode 100644 fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/command/DmapCommand.java delete mode 100644 fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/command/DmarkerCommand.java delete mode 100644 fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/command/DynmapCommand.java delete mode 100644 fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/command/DynmapCommandExecutor.java delete mode 100644 fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/command/DynmapExpCommand.java delete mode 100644 fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/event/BlockEvents.java delete mode 100644 fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/event/CustomServerChunkEvents.java delete mode 100644 fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/event/CustomServerLifecycleEvents.java delete mode 100644 fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/event/PlayerEvents.java delete mode 100644 fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/event/ServerChatEvents.java delete mode 100644 fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/mixin/BiomeEffectsAccessor.java delete mode 100644 fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/mixin/MinecraftServerMixin.java delete mode 100644 fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/mixin/PlayerManagerMixin.java delete mode 100644 fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/mixin/ProtoChunkMixin.java delete mode 100644 fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/mixin/ServerPlayNetworkHandlerMixin.java delete mode 100644 fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/mixin/ServerPlayerEntityMixin.java delete mode 100644 fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/mixin/ThreadedAnvilChunkStorageMixin.java delete mode 100644 fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/mixin/WorldChunkMixin.java delete mode 100644 fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/permissions/FabricPermissions.java delete mode 100644 fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/permissions/FilePermissions.java delete mode 100644 fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/permissions/LuckPermissions.java delete mode 100644 fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/permissions/OpPermissions.java delete mode 100644 fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/permissions/PermissionProvider.java delete mode 100644 fabric-1.19.1/src/main/resources/assets/dynmap/icon.png delete mode 100644 fabric-1.19.1/src/main/resources/configuration.txt delete mode 100644 fabric-1.19.1/src/main/resources/dynmap.mixins.json delete mode 100644 fabric-1.19.1/src/main/resources/fabric.mod.json delete mode 100644 fabric-1.19.1/src/main/resources/permissions.yml.example delete mode 100644 fabric-1.19.3/.gitignore delete mode 100644 fabric-1.19.3/build.gradle delete mode 100644 fabric-1.19.3/gradle.properties delete mode 100644 fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/DynmapMod.java delete mode 100644 fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/DynmapPlugin.java delete mode 100644 fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/FabricAdapter.java delete mode 100644 fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/FabricCommandSender.java delete mode 100644 fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/FabricLogger.java delete mode 100644 fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/FabricMapChunkCache.java delete mode 100644 fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/FabricPlayer.java delete mode 100644 fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/FabricServer.java delete mode 100644 fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/FabricWorld.java delete mode 100644 fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/NBT.java delete mode 100644 fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/TaskRecord.java delete mode 100644 fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/VersionCheck.java delete mode 100644 fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/access/ProtoChunkAccessor.java delete mode 100644 fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/command/DmapCommand.java delete mode 100644 fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/command/DmarkerCommand.java delete mode 100644 fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/command/DynmapCommand.java delete mode 100644 fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/command/DynmapCommandExecutor.java delete mode 100644 fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/command/DynmapExpCommand.java delete mode 100644 fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/event/BlockEvents.java delete mode 100644 fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/event/CustomServerChunkEvents.java delete mode 100644 fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/event/CustomServerLifecycleEvents.java delete mode 100644 fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/event/PlayerEvents.java delete mode 100644 fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/event/ServerChatEvents.java delete mode 100644 fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/mixin/BiomeEffectsAccessor.java delete mode 100644 fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/mixin/MinecraftServerMixin.java delete mode 100644 fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/mixin/PlayerManagerMixin.java delete mode 100644 fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/mixin/ProtoChunkMixin.java delete mode 100644 fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/mixin/ServerPlayNetworkHandlerMixin.java delete mode 100644 fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/mixin/ServerPlayerEntityMixin.java delete mode 100644 fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/mixin/ThreadedAnvilChunkStorageMixin.java delete mode 100644 fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/mixin/WorldChunkMixin.java delete mode 100644 fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/permissions/FabricPermissions.java delete mode 100644 fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/permissions/FilePermissions.java delete mode 100644 fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/permissions/LuckPermissions.java delete mode 100644 fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/permissions/OpPermissions.java delete mode 100644 fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/permissions/PermissionProvider.java delete mode 100644 fabric-1.19.3/src/main/resources/assets/dynmap/icon.png delete mode 100644 fabric-1.19.3/src/main/resources/configuration.txt delete mode 100644 fabric-1.19.3/src/main/resources/dynmap.mixins.json delete mode 100644 fabric-1.19.3/src/main/resources/fabric.mod.json delete mode 100644 fabric-1.19.3/src/main/resources/permissions.yml.example delete mode 100644 fabric-1.19/.gitignore delete mode 100644 fabric-1.19/build.gradle delete mode 100644 fabric-1.19/gradle.properties delete mode 100644 fabric-1.19/src/main/java/org/dynmap/fabric_1_19/DynmapMod.java delete mode 100644 fabric-1.19/src/main/java/org/dynmap/fabric_1_19/DynmapPlugin.java delete mode 100644 fabric-1.19/src/main/java/org/dynmap/fabric_1_19/FabricAdapter.java delete mode 100644 fabric-1.19/src/main/java/org/dynmap/fabric_1_19/FabricCommandSender.java delete mode 100644 fabric-1.19/src/main/java/org/dynmap/fabric_1_19/FabricLogger.java delete mode 100644 fabric-1.19/src/main/java/org/dynmap/fabric_1_19/FabricMapChunkCache.java delete mode 100644 fabric-1.19/src/main/java/org/dynmap/fabric_1_19/FabricPlayer.java delete mode 100644 fabric-1.19/src/main/java/org/dynmap/fabric_1_19/FabricServer.java delete mode 100644 fabric-1.19/src/main/java/org/dynmap/fabric_1_19/FabricWorld.java delete mode 100644 fabric-1.19/src/main/java/org/dynmap/fabric_1_19/NBT.java delete mode 100644 fabric-1.19/src/main/java/org/dynmap/fabric_1_19/TaskRecord.java delete mode 100644 fabric-1.19/src/main/java/org/dynmap/fabric_1_19/VersionCheck.java delete mode 100644 fabric-1.19/src/main/java/org/dynmap/fabric_1_19/access/ProtoChunkAccessor.java delete mode 100644 fabric-1.19/src/main/java/org/dynmap/fabric_1_19/command/DmapCommand.java delete mode 100644 fabric-1.19/src/main/java/org/dynmap/fabric_1_19/command/DmarkerCommand.java delete mode 100644 fabric-1.19/src/main/java/org/dynmap/fabric_1_19/command/DynmapCommand.java delete mode 100644 fabric-1.19/src/main/java/org/dynmap/fabric_1_19/command/DynmapCommandExecutor.java delete mode 100644 fabric-1.19/src/main/java/org/dynmap/fabric_1_19/command/DynmapExpCommand.java delete mode 100644 fabric-1.19/src/main/java/org/dynmap/fabric_1_19/event/BlockEvents.java delete mode 100644 fabric-1.19/src/main/java/org/dynmap/fabric_1_19/event/CustomServerChunkEvents.java delete mode 100644 fabric-1.19/src/main/java/org/dynmap/fabric_1_19/event/CustomServerLifecycleEvents.java delete mode 100644 fabric-1.19/src/main/java/org/dynmap/fabric_1_19/event/PlayerEvents.java delete mode 100644 fabric-1.19/src/main/java/org/dynmap/fabric_1_19/event/ServerChatEvents.java delete mode 100644 fabric-1.19/src/main/java/org/dynmap/fabric_1_19/mixin/BiomeEffectsAccessor.java delete mode 100644 fabric-1.19/src/main/java/org/dynmap/fabric_1_19/mixin/MinecraftServerMixin.java delete mode 100644 fabric-1.19/src/main/java/org/dynmap/fabric_1_19/mixin/PlayerManagerMixin.java delete mode 100644 fabric-1.19/src/main/java/org/dynmap/fabric_1_19/mixin/ProtoChunkMixin.java delete mode 100644 fabric-1.19/src/main/java/org/dynmap/fabric_1_19/mixin/ServerPlayNetworkHandlerMixin.java delete mode 100644 fabric-1.19/src/main/java/org/dynmap/fabric_1_19/mixin/ServerPlayerEntityMixin.java delete mode 100644 fabric-1.19/src/main/java/org/dynmap/fabric_1_19/mixin/ThreadedAnvilChunkStorageMixin.java delete mode 100644 fabric-1.19/src/main/java/org/dynmap/fabric_1_19/mixin/WorldChunkMixin.java delete mode 100644 fabric-1.19/src/main/java/org/dynmap/fabric_1_19/permissions/FabricPermissions.java delete mode 100644 fabric-1.19/src/main/java/org/dynmap/fabric_1_19/permissions/FilePermissions.java delete mode 100644 fabric-1.19/src/main/java/org/dynmap/fabric_1_19/permissions/LuckPermissions.java delete mode 100644 fabric-1.19/src/main/java/org/dynmap/fabric_1_19/permissions/OpPermissions.java delete mode 100644 fabric-1.19/src/main/java/org/dynmap/fabric_1_19/permissions/PermissionProvider.java delete mode 100644 fabric-1.19/src/main/resources/assets/dynmap/icon.png delete mode 100644 fabric-1.19/src/main/resources/configuration.txt delete mode 100644 fabric-1.19/src/main/resources/dynmap.mixins.json delete mode 100644 fabric-1.19/src/main/resources/fabric.mod.json delete mode 100644 fabric-1.19/src/main/resources/permissions.yml.example delete mode 100644 forge-1.19.2/.gitignore delete mode 100644 forge-1.19.2/bin/.gitignore delete mode 100644 forge-1.19.2/build.gradle delete mode 100644 forge-1.19.2/src/main/java/org/dynmap/forge_1_19_2/ClientProxy.java delete mode 100644 forge-1.19.2/src/main/java/org/dynmap/forge_1_19_2/DynmapMod.java delete mode 100644 forge-1.19.2/src/main/java/org/dynmap/forge_1_19_2/DynmapPlugin.java delete mode 100644 forge-1.19.2/src/main/java/org/dynmap/forge_1_19_2/ForgeMapChunkCache.java delete mode 100644 forge-1.19.2/src/main/java/org/dynmap/forge_1_19_2/ForgeWorld.java delete mode 100644 forge-1.19.2/src/main/java/org/dynmap/forge_1_19_2/NBT.java delete mode 100644 forge-1.19.2/src/main/java/org/dynmap/forge_1_19_2/Proxy.java delete mode 100644 forge-1.19.2/src/main/java/org/dynmap/forge_1_19_2/VersionCheck.java delete mode 100644 forge-1.19.2/src/main/java/org/dynmap/forge_1_19_2/permissions/FilePermissions.java delete mode 100644 forge-1.19.2/src/main/java/org/dynmap/forge_1_19_2/permissions/OpPermissions.java delete mode 100644 forge-1.19.2/src/main/java/org/dynmap/forge_1_19_2/permissions/PermissionProvider.java delete mode 100644 forge-1.19.2/src/main/resources/META-INF/accesstransformer.cfg delete mode 100644 forge-1.19.2/src/main/resources/META-INF/mods.toml delete mode 100644 forge-1.19.2/src/main/resources/configuration.txt delete mode 100644 forge-1.19.2/src/main/resources/pack.mcmeta delete mode 100644 forge-1.19.2/src/main/resources/permissions.yml.example delete mode 100644 forge-1.19/.gitignore delete mode 100644 forge-1.19/bin/.gitignore delete mode 100644 forge-1.19/build.gradle delete mode 100644 forge-1.19/src/main/java/org/dynmap/forge_1_19/ClientProxy.java delete mode 100644 forge-1.19/src/main/java/org/dynmap/forge_1_19/DynmapMod.java delete mode 100644 forge-1.19/src/main/java/org/dynmap/forge_1_19/DynmapPlugin.java delete mode 100644 forge-1.19/src/main/java/org/dynmap/forge_1_19/ForgeMapChunkCache.java delete mode 100644 forge-1.19/src/main/java/org/dynmap/forge_1_19/ForgeWorld.java delete mode 100644 forge-1.19/src/main/java/org/dynmap/forge_1_19/NBT.java delete mode 100644 forge-1.19/src/main/java/org/dynmap/forge_1_19/Proxy.java delete mode 100644 forge-1.19/src/main/java/org/dynmap/forge_1_19/VersionCheck.java delete mode 100644 forge-1.19/src/main/java/org/dynmap/forge_1_19/permissions/FilePermissions.java delete mode 100644 forge-1.19/src/main/java/org/dynmap/forge_1_19/permissions/OpPermissions.java delete mode 100644 forge-1.19/src/main/java/org/dynmap/forge_1_19/permissions/PermissionProvider.java delete mode 100644 forge-1.19/src/main/resources/META-INF/accesstransformer.cfg delete mode 100644 forge-1.19/src/main/resources/META-INF/mods.toml delete mode 100644 forge-1.19/src/main/resources/configuration.txt delete mode 100644 forge-1.19/src/main/resources/pack.mcmeta delete mode 100644 forge-1.19/src/main/resources/permissions.yml.example diff --git a/fabric-1.19.1/.gitignore b/fabric-1.19.1/.gitignore deleted file mode 100644 index 8b87af68..00000000 --- a/fabric-1.19.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.19.1/build.gradle b/fabric-1.19.1/build.gradle deleted file mode 100644 index dbf7fdf5..00000000 --- a/fabric-1.19.1/build.gradle +++ /dev/null @@ -1,69 +0,0 @@ -plugins { - id 'fabric-loom' version '1.1.10' -} - -archivesBaseName = "Dynmap" -version = parent.version -group = parent.group - -eclipse { - project { - name = "Dynmap(Fabric-1.19.1)" - } -} - -sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = JavaLanguageVersion.of(17) // Need this here so eclipse task generates correctly. - -configurations { - shadow - implementation.extendsFrom(shadow) -} - -repositories { - mavenCentral() - maven { url 'https://oss.sonatype.org/content/repositories/snapshots' } -} - -dependencies { - minecraft "com.mojang:minecraft:${project.minecraft_version}" - mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" - modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" - 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') - - modCompileOnly "me.lucko:fabric-permissions-api:0.1-SNAPSHOT" - compileOnly 'net.luckperms:api:5.4' -} - -processResources { - filesMatching('fabric.mod.json') { - expand "version": project.version - } -} - -java { - // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task - // if it is present. - // If you remove this line, sources will not be generated. - withSourcesJar() -} - -jar { - from "LICENSE" - from { - configurations.shadow.collect { it.toString().contains("guava") ? null : it.isDirectory() ? it : zipTree(it) } - } -} - -remapJar { - archiveFileName = "${archivesBaseName}-${project.version}-fabric-${project.minecraft_version}.jar" - destinationDirectory = file '../target' -} - -remapJar.doLast { - task -> - ant.checksum file: task.archivePath -} diff --git a/fabric-1.19.1/gradle.properties b/fabric-1.19.1/gradle.properties deleted file mode 100644 index cf9d1bea..00000000 --- a/fabric-1.19.1/gradle.properties +++ /dev/null @@ -1,4 +0,0 @@ -minecraft_version=1.19.1 -yarn_mappings=1.19.1+build.4 -loader_version=0.14.8 -fabric_version=0.58.5+1.19.1 diff --git a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/DynmapMod.java b/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/DynmapMod.java deleted file mode 100644 index 0c1e8657..00000000 --- a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/DynmapMod.java +++ /dev/null @@ -1,50 +0,0 @@ -package org.dynmap.fabric_1_19_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.19.1/src/main/java/org/dynmap/fabric_1_19_1/DynmapPlugin.java b/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/DynmapPlugin.java deleted file mode 100644 index f7e309ee..00000000 --- a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/DynmapPlugin.java +++ /dev/null @@ -1,800 +0,0 @@ -package org.dynmap.fabric_1_19_1; - -import com.mojang.brigadier.CommandDispatcher; -import com.mojang.brigadier.exceptions.CommandSyntaxException; -import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; -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.fabricmc.loader.api.FabricLoader; -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.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.EmptyBlockView; -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 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.common.chunk.GenericChunkCache; -import org.dynmap.fabric_1_19_1.command.DmapCommand; -import org.dynmap.fabric_1_19_1.command.DmarkerCommand; -import org.dynmap.fabric_1_19_1.command.DynmapCommand; -import org.dynmap.fabric_1_19_1.command.DynmapExpCommand; -import org.dynmap.fabric_1_19_1.event.BlockEvents; -import org.dynmap.fabric_1_19_1.event.CustomServerChunkEvents; -import org.dynmap.fabric_1_19_1.event.CustomServerLifecycleEvents; -import org.dynmap.fabric_1_19_1.event.PlayerEvents; -import org.dynmap.fabric_1_19_1.mixin.BiomeEffectsAccessor; -import org.dynmap.fabric_1_19_1.permissions.*; -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 GenericChunkCache 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(); - private HashMap worlds = new HashMap(); - private WorldAccess last_world; - private FabricWorld last_fworld; - private Map players = new HashMap(); - 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 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, registryAccess, environment) -> 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; - - /** - * 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(); - DynmapBlockState.Builder bld = new DynmapBlockState.Builder(); - while (iter.hasNext()) { - BlockState bs = iter.next(); - int idx = bsids.getRawId(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(); - } - int lightAtten = bs.isOpaqueFullCube(EmptyBlockView.INSTANCE, BlockPos.ORIGIN) ? 15 : (bs.isTranslucent(EmptyBlockView.INSTANCE, BlockPos.ORIGIN) ? 0 : 1); - //Log.info("statename=" + bn + "[" + statename + "], lightAtten=" + lightAtten); - // Fill in base attributes - bld.setBaseState(basebs).setStateIndex(idx - baseidx).setBlockName(bn).setStateName(statename).setMaterial(mat.toString()).setLegacyBlockID(idx).setAttenuatesLight(lightAtten); - if (mat.isSolid()) { bld.setSolid(); } - if (mat == Material.AIR) { bld.setAir(); } - if (mat == Material.WOOD) { bld.setLog(); } - if (mat == Material.LEAVES) { bld.setLeaves(); } - if ((!bs.getFluidState().isEmpty()) && !(bs.getBlock() instanceof FluidBlock)) { - bld.setWaterlogged(); - } - DynmapBlockState dbs = bld.build(); // Build state - stateByID[idx] = dbs; - if (basebs == null) { basebs = dbs; } - } - } -// 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); - } - - 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); - } - } - } - - public FabricServer getFabricServer() { - return fserver; - } - - 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() && server.isHost(server.getPlayerManager().getPlayer(player).getGameProfile()); - } - - boolean hasPerm(PlayerEntity psender, String permission) { - PermissionsHandler ph = PermissionsHandler.getHandler(); - if ((ph != null) && (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 ((ph != null) && (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); - - Registry biomeRegistry = getFabricServer().getBiomeRegistry(); - Biome[] list = getFabricServer().getBiomeList(biomeRegistry); - - for (int i = 0; i < list.length; i++) { - Biome bb = list[i]; - if (bb != null) { - String id = biomeRegistry.getId(bb).getPath(); - String rl = biomeRegistry.getId(bb).toString(); - float tmp = bb.getTemperature(), hum = bb.getDownfall(); - int watermult = ((BiomeEffectsAccessor) bb.getEffects()).getWaterColor(); - Log.verboseinfo("biome[" + i + "]: hum=" + hum + ", tmp=" + tmp + ", mult=" + Integer.toHexString(watermult)); - - BiomeMap bmap = BiomeMap.NULL; - if (rl != null) { // If resource location, lookup by this - bmap = BiomeMap.byBiomeResourceLocation(rl); - } - else { - bmap = BiomeMap.byBiomeID(i); - } - if (bmap.isDefault() || (bmap == BiomeMap.NULL)) { - bmap = new BiomeMap((rl != null) ? BiomeMap.NO_INDEX : i, id, tmp, hum, rl); - 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)); - } - bmap.setBiomeObject(bb); - } - } - if (cnt > 0) - Log.info("Added " + cnt + " custom biome mappings"); - } - - private String[] getBiomeNames() { - Registry biomeRegistry = getFabricServer().getBiomeRegistry(); - Biome[] list = getFabricServer().getBiomeList(biomeRegistry); - String[] lst = new String[list.length]; - for (int i = 0; i < list.length; i++) { - Biome bb = list[i]; - if (bb != null) { - lst[i] = biomeRegistry.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 */ - if (FabricLoader.getInstance().isModLoaded("luckperms")) { - Log.info("Using luckperms for access control"); - permissions = new LuckPermissions(); - } - else if (FabricLoader.getInstance().isModLoaded("fabric-permissions-api-v0")) { - Log.info("Using fabric-permissions-api for access control"); - permissions = new FabricPermissions(); - } else { - /* 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); - 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 GenericChunkCache(core.getSnapShotCacheSize(), core.useSoftRefInSnapShotCache()); - /* Get map manager from core */ - mapManager = core.getMapManager(); - - /* Load saved world definitions */ - loadWorlds(); - - 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.getPlayerOrThrow(); - } - - 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 handleChunkGenerate(ServerWorld world, Chunk chunk) { - if (!onchunkgenerate) return; - - FabricWorld fw = getWorld(world, false); - ChunkPos chunkPos = chunk.getPos(); - - int ymax = Integer.MIN_VALUE; - int ymin = Integer.MAX_VALUE; - ChunkSection[] sections = chunk.getSectionArray(); - for (int i = 0; i < sections.length; i++) { - if ((sections[i] != null) && (!sections[i].isEmpty())) { - int sy = sections[i].getYOffset(); - if (sy < ymin) ymin = sy; - if ((sy+16) > ymax) ymax = sy + 16; - } - } - if (ymax != Integer.MIN_VALUE) { - mapManager.touchVolume(fw.getName(), - chunkPos.getStartX(), ymin, chunkPos.getStartZ(), - chunkPos.getEndX(), ymax, chunkPos.getEndZ(), - "chunkgenerate"); - //Log.info("New generated chunk detected at %s[%s]".formatted(fw.getName(), chunkPos.getStartPos())); - } - } - - 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(world, 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) - worldTracker = new WorldTracker(); - if (onchunkpopulate || onchunkgenerate) { - CustomServerChunkEvents.CHUNK_GENERATE.register((world, chunk) -> worldTracker.handleChunkGenerate(world, chunk)); - } - if (onblockchange) { - BlockEvents.BLOCK_EVENT.register((world, pos) -> worldTracker.handleBlockEvent(world, pos)); - } - - ServerWorldEvents.LOAD.register((server, world) -> worldTracker.handleWorldLoad(server, world)); - ServerWorldEvents.UNLOAD.register((server, world) -> worldTracker.handleWorldUnload(server, world)); - } - - FabricWorld getWorldByName(String name) { - return worlds.get(name); - } - - FabricWorld getWorld(World w) { - return getWorld(w, true); - } - - private FabricWorld getWorld(World w, boolean add_if_not_found) { - if (last_world == w) { - return last_fworld; - } - String wname = FabricWorld.getWorldName(this, w); - - for (FabricWorld fw : worlds.values()) { - if (fw.getRawName().equals(wname)) { - last_world = w; - last_fworld = fw; - if (!fw.isLoaded()) { - fw.setWorldLoaded(w); - } - fw.updateWorld(w); - return fw; - } - } - FabricWorld fw = null; - if (add_if_not_found) { - /* Add to list if not found */ - fw = new FabricWorld(this, 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("miny", fw.minY); - 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"); - Integer miny = (Integer) world.get("miny"); - 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(this, name, height, sealevel, nether, theend, title, (miny != null) ? miny : 0); - 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; - } - } - } -} \ No newline at end of file diff --git a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/FabricAdapter.java b/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/FabricAdapter.java deleted file mode 100644 index 56e8edeb..00000000 --- a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/FabricAdapter.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.dynmap.fabric_1_19_1; - -import net.minecraft.server.world.ServerWorld; -import org.dynmap.DynmapLocation; - -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.19.1/src/main/java/org/dynmap/fabric_1_19_1/FabricCommandSender.java b/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/FabricCommandSender.java deleted file mode 100644 index 50cb055d..00000000 --- a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/FabricCommandSender.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.dynmap.fabric_1_19_1; - -import net.minecraft.server.command.ServerCommandSource; -import net.minecraft.text.LiteralTextContent; -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 = Text.literal(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.19.1/src/main/java/org/dynmap/fabric_1_19_1/FabricLogger.java b/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/FabricLogger.java deleted file mode 100644 index b67d8149..00000000 --- a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/FabricLogger.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.dynmap.fabric_1_19_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.19.1/src/main/java/org/dynmap/fabric_1_19_1/FabricMapChunkCache.java b/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/FabricMapChunkCache.java deleted file mode 100644 index 867ae29b..00000000 --- a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/FabricMapChunkCache.java +++ /dev/null @@ -1,116 +0,0 @@ -package org.dynmap.fabric_1_19_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.collection.PackedIntegerArray; -import net.minecraft.util.math.ChunkPos; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.WordPackedArray; -import net.minecraft.util.registry.Registry; -import net.minecraft.world.ChunkSerializer; -import net.minecraft.world.World; -import net.minecraft.world.biome.Biome; -import net.minecraft.world.biome.BiomeEffects; -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.common.chunk.GenericChunk; -import org.dynmap.common.chunk.GenericChunkSection; -import org.dynmap.common.chunk.GenericMapChunkCache; -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 GenericMapChunkCache { - private World w; - private ServerChunkManager cps; - - /** - * Construct empty cache - */ - public FabricMapChunkCache(DynmapPlugin plugin) { - super(plugin.sscache); - } - - public void setChunks(FabricWorld dw, List chunks) { - 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"); - } - } - super.setChunks(dw, chunks); - } - - // Load generic chunk from existing and already loaded chunk - protected GenericChunk getLoadedChunk(DynmapChunk chunk) { - GenericChunk gc = null; - if (cps.isChunkLoaded(chunk.x, chunk.z)) { - NbtCompound nbt = null; - try { - nbt = ChunkSerializer.serialize((ServerWorld) w, cps.getWorldChunk(chunk.x, chunk.z, false)); - } catch (NullPointerException e) { - // TODO: find out why this is happening and why it only seems to happen since 1.16.2 - Log.severe("ChunkSerializer.serialize threw a NullPointerException", e); - } - if (nbt != null) { - gc = parseChunkFromNBT(new NBT.NBTCompound(nbt)); - } - } - return gc; - } - - private NbtCompound readChunk(int x, int z) { - try { - ThreadedAnvilChunkStorage acl = cps.threadedAnvilChunkStorage; - - ChunkPos coord = new ChunkPos(x, z); - // Async chunk reading is synchronized here. Perhaps we can do async and improve performance? - return acl.getNbt(coord).join().orElse(null); - } catch (Exception exc) { - Log.severe(String.format("Error reading chunk: %s,%d,%d", dw.getName(), x, z), exc); - return null; - } - } - - // Load generic chunk from unloaded chunk - protected GenericChunk loadChunk(DynmapChunk chunk) { - GenericChunk gc = null; - NbtCompound nbt = readChunk(chunk.x, chunk.z); - // If read was good - if (nbt != null) { - gc = parseChunkFromNBT(new NBT.NBTCompound(nbt)); - } - return gc; - } - @Override - public int getFoliageColor(BiomeMap bm, int[] colormap, int x, int z) { - return bm.getBiomeObject().map(Biome::getEffects).flatMap(BiomeEffects::getFoliageColor).orElse(colormap[bm.biomeLookup()]); - } - - @Override - public int getGrassColor(BiomeMap bm, int[] colormap, int x, int z) { - BiomeEffects effects = bm.getBiomeObject().map(Biome::getEffects).orElse(null); - if (effects == null) return colormap[bm.biomeLookup()]; - return effects.getGrassColorModifier().getModifiedGrassColor(x, z, effects.getGrassColor().orElse(colormap[bm.biomeLookup()])); - } -} diff --git a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/FabricPlayer.java b/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/FabricPlayer.java deleted file mode 100644 index 66c94674..00000000 --- a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/FabricPlayer.java +++ /dev/null @@ -1,258 +0,0 @@ -package org.dynmap.fabric_1_19_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.SubtitleS2CPacket; -import net.minecraft.network.packet.s2c.play.TitleFadeS2CPacket; -import net.minecraft.network.packet.s2c.play.TitleS2CPacket; -import net.minecraft.server.network.ServerPlayNetworkHandler; -import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.text.LiteralTextContent; -import net.minecraft.text.Text; -import net.minecraft.util.Util; -import net.minecraft.util.math.Vec3d; -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.Base64; -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.getDecoder().decode(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.getWorld(), 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 = Text.literal(msg); - player.sendMessage(ichatcomponent); - } - - @Override - public boolean isInvisible() { - if(player != null) { - return player.isInvisible(); - } - return false; - } - @Override - public boolean isSpectator() { - if(player != null) { - return player.isSpectator(); - } - 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; - TitleFadeS2CPacket times = new TitleFadeS2CPacket(fadeInTicks, stayTicks, fadeOutTicks); - player.networkHandler.sendPacket(times); - if (title != null) { - TitleS2CPacket titlepkt = new TitleS2CPacket(Text.literal(title)); - player.networkHandler.sendPacket(titlepkt); - } - - if (subtitle != null) { - SubtitleS2CPacket subtitlepkt = new SubtitleS2CPacket(Text.literal(subtitle)); - player.networkHandler.sendPacket(subtitlepkt); - } - } - } -} diff --git a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/FabricServer.java b/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/FabricServer.java deleted file mode 100644 index afe0b444..00000000 --- a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/FabricServer.java +++ /dev/null @@ -1,609 +0,0 @@ -package org.dynmap.fabric_1_19_1; - -import com.mojang.authlib.GameProfile; -import net.fabricmc.loader.api.FabricLoader; -import net.fabricmc.loader.api.ModContainer; -import net.minecraft.block.AbstractSignBlock; -import net.minecraft.block.Block; -import net.minecraft.block.BlockState; -import net.minecraft.network.message.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.LiteralTextContent; -import net.minecraft.text.Text; -import net.minecraft.util.UserCache; -import net.minecraft.util.Util; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.registry.Registry; -import net.minecraft.world.World; -import net.minecraft.world.biome.Biome; -import org.dynmap.DynmapChunk; -import org.dynmap.DynmapWorld; -import org.dynmap.Log; -import org.dynmap.DynmapCommonAPIListener; -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_19_1.event.BlockEvents; -import org.dynmap.fabric_1_19_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.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 final Registry biomeRegistry; - 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; - this.biomeRegistry = server.getRegistryManager().get(Registry.BIOME_KEY); - } - - private Optional getProfileByName(String player) { - UserCache cache = server.getUserCache(); - return cache.findByName(player); - } - - public final Registry getBiomeRegistry() { - return biomeRegistry; - } - - private Biome[] biomelist = null; - - public final Biome[] getBiomeList(Registry biomeRegistry) { - if (biomelist == null) { - biomelist = new Biome[256]; - Iterator iter = biomeRegistry.iterator(); - while (iter.hasNext()) { - Biome b = iter.next(); - int bidx = biomeRegistry.getRawId(b); - if (bidx >= biomelist.length) { - biomelist = Arrays.copyOf(biomelist, bidx + biomelist.length); - } - biomelist[bidx] = b; - } - } - return biomelist; - } - - @Override - public int getBlockIDAt(String wname, int x, int y, int z) { - return -1; - } - - @SuppressWarnings("deprecation") /* Not much I can do... fix this if it breaks. */ - @Override - public int isSignAt(String wname, int x, int y, int z) { - World world = plugin.getWorldByName(wname).getWorld(); - - BlockPos pos = new BlockPos(x, y, z); - if (!world.isChunkLoaded(pos)) - return -1; - - Block block = world.getBlockState(pos).getBlock(); - return (block instanceof AbstractSignBlock ? 1 : 0); - } - - @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) { - PlayerManager scm = server.getPlayerManager(); - BannedPlayerList bl = scm.getUserBanList(); - try { - return bl.contains(getProfileByName(pid).get()); - } catch (NoSuchElementException e) { - /* If this profile doesn't exist, default to "banned" for good measure. */ - return true; - } - } - - @Override - public String stripChatColor(String s) { - return DynmapPlugin.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: - /* Already handled by BlockEvents logic */ - break; - - case SIGN_CHANGE: - BlockEvents.SIGN_CHANGE_EVENT.register((world, pos, lines, material, player) -> { - plugin.core.processSignChange("fabric", FabricWorld.getWorldName(plugin, world), - pos.getX(), pos.getY(), pos.getZ(), lines, player.getName().getString()); - }); - 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 = Text.literal(msg); - server.getPlayerManager().broadcast(component, false); - 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) { - if (isPlayerBanned(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) { - if (isPlayerBanned(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 (InterruptedException 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.getRawId(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 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.19.1/src/main/java/org/dynmap/fabric_1_19_1/FabricWorld.java b/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/FabricWorld.java deleted file mode 100644 index 4bbd58cb..00000000 --- a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/FabricWorld.java +++ /dev/null @@ -1,236 +0,0 @@ -package org.dynmap.fabric_1_19_1; - -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.MathHelper; -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.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 final DynmapPlugin plugin; - private World 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 = 320; // Maximum allows world height - - public static int getMaxWorldHeight() { - return maxWorldHeight; - } - - public static void setMaxWorldHeight(int h) { - maxWorldHeight = h; - } - - public static String getWorldName(DynmapPlugin plugin, World w) { - RegistryKey rk = w.getRegistryKey(); - if (rk == World.OVERWORLD) { // Overworld? - return w.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 void updateWorld(World w) { - this.updateWorldHeights(w.getHeight(), w.getBottomY(), w.getSeaLevel()); - } - - public FabricWorld(DynmapPlugin plugin, World w) { - this(plugin, getWorldName(plugin, w), w.getHeight(), - w.getSeaLevel(), - w.getRegistryKey() == World.NETHER, - w.getRegistryKey() == World.END, - w.getRegistryKey().getValue().getPath(), - w.getBottomY()); - setWorldLoaded(w); - } - - public FabricWorld(DynmapPlugin plugin, String name, int height, int sealevel, boolean nether, boolean the_end, String deftitle, int miny) { - super(name, (height > maxWorldHeight) ? maxWorldHeight : height, sealevel, miny); - this.plugin = plugin; - 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.getTimeOfDay(); - else - return -1; - } - - /* World is storming */ - @Override - public boolean hasStorm() { - if (world != null) - return world.isRaining(); - else - return false; - } - - /* World is thundering */ - @Override - public boolean isThundering() { - if (world != null) - return world.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(World w) { - world = w; - this.sealevel = w.getSeaLevel(); // Read actual current sealevel from world - // Update lighting table - for (int lightLevel = 0; lightLevel < 16; lightLevel++) { - // Algorithm based on LightmapTextureManager.getBrightness() - // We can't call that method because it's client-only. - // This means the code below can stop being correct if Mojang ever - // updates the curve; in that case we should reflect the changes. - float value = (float) lightLevel / 15.0f; - float brightness = value / (4.0f - 3.0f * value); - this.setBrightnessTableEntry(lightLevel, MathHelper.lerp(w.getDimension().ambientLight(), brightness, 1.0F)); - } - } - - /* 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.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(plugin); - c.setChunks(this, chunks); - return c; - } - return null; - } - - public World getWorld() { - return world; - } - - @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.19.1/src/main/java/org/dynmap/fabric_1_19_1/NBT.java b/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/NBT.java deleted file mode 100644 index 468353c2..00000000 --- a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/NBT.java +++ /dev/null @@ -1,126 +0,0 @@ -package org.dynmap.fabric_1_19_1; - -import org.dynmap.common.chunk.GenericBitStorage; -import org.dynmap.common.chunk.GenericNBTCompound; -import org.dynmap.common.chunk.GenericNBTList; - -import java.util.Set; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.nbt.NbtList; -import net.minecraft.util.collection.PackedIntegerArray; - -public class NBT { - - public static class NBTCompound implements GenericNBTCompound { - private final NbtCompound obj; - public NBTCompound(NbtCompound t) { - this.obj = t; - } - @Override - public Set getAllKeys() { - return obj.getKeys(); - } - @Override - public boolean contains(String s) { - return obj.contains(s); - } - @Override - public boolean contains(String s, int i) { - return obj.contains(s, i); - } - @Override - public byte getByte(String s) { - return obj.getByte(s); - } - @Override - public short getShort(String s) { - return obj.getShort(s); - } - @Override - public int getInt(String s) { - return obj.getInt(s); - } - @Override - public long getLong(String s) { - return obj.getLong(s); - } - @Override - public float getFloat(String s) { - return obj.getFloat(s); - } - @Override - public double getDouble(String s) { - return obj.getDouble(s); - } - @Override - public String getString(String s) { - return obj.getString(s); - } - @Override - public byte[] getByteArray(String s) { - return obj.getByteArray(s); - } - @Override - public int[] getIntArray(String s) { - return obj.getIntArray(s); - } - @Override - public long[] getLongArray(String s) { - return obj.getLongArray(s); - } - @Override - public GenericNBTCompound getCompound(String s) { - return new NBTCompound(obj.getCompound(s)); - } - @Override - public GenericNBTList getList(String s, int i) { - return new NBTList(obj.getList(s, i)); - } - @Override - public boolean getBoolean(String s) { - return obj.getBoolean(s); - } - @Override - public String getAsString(String s) { - return obj.get(s).asString(); - } - @Override - public GenericBitStorage makeBitStorage(int bits, int count, long[] data) { - return new OurBitStorage(bits, count, data); - } - public String toString() { - return obj.toString(); - } - } - public static class NBTList implements GenericNBTList { - private final NbtList obj; - public NBTList(NbtList t) { - obj = t; - } - @Override - public int size() { - return obj.size(); - } - @Override - public String getString(int idx) { - return obj.getString(idx); - } - @Override - public GenericNBTCompound getCompound(int idx) { - return new NBTCompound(obj.getCompound(idx)); - } - public String toString() { - return obj.toString(); - } - } - public static class OurBitStorage implements GenericBitStorage { - private final PackedIntegerArray bs; - public OurBitStorage(int bits, int count, long[] data) { - bs = new PackedIntegerArray(bits, count, data); - } - @Override - public int get(int idx) { - return bs.get(idx); - } - } -} diff --git a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/TaskRecord.java b/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/TaskRecord.java deleted file mode 100644 index 02f66432..00000000 --- a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/TaskRecord.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.dynmap.fabric_1_19_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.19.1/src/main/java/org/dynmap/fabric_1_19_1/VersionCheck.java b/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/VersionCheck.java deleted file mode 100644 index ebcaa363..00000000 --- a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/VersionCheck.java +++ /dev/null @@ -1,98 +0,0 @@ -package org.dynmap.fabric_1_19_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.19.1/src/main/java/org/dynmap/fabric_1_19_1/access/ProtoChunkAccessor.java b/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/access/ProtoChunkAccessor.java deleted file mode 100644 index 02a1de02..00000000 --- a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/access/ProtoChunkAccessor.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.dynmap.fabric_1_19_1.access; - -public interface ProtoChunkAccessor { - boolean getTouchedByWorldGen(); -} diff --git a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/command/DmapCommand.java b/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/command/DmapCommand.java deleted file mode 100644 index e1a70142..00000000 --- a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/command/DmapCommand.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.dynmap.fabric_1_19_1.command; - -import org.dynmap.fabric_1_19_1.DynmapPlugin; - -public class DmapCommand extends DynmapCommandExecutor { - public DmapCommand(DynmapPlugin p) { - super("dmap", p); - } -} diff --git a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/command/DmarkerCommand.java b/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/command/DmarkerCommand.java deleted file mode 100644 index c33e62cd..00000000 --- a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/command/DmarkerCommand.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.dynmap.fabric_1_19_1.command; - -import org.dynmap.fabric_1_19_1.DynmapPlugin; - -public class DmarkerCommand extends DynmapCommandExecutor { - public DmarkerCommand(DynmapPlugin p) { - super("dmarker", p); - } -} diff --git a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/command/DynmapCommand.java b/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/command/DynmapCommand.java deleted file mode 100644 index be1addf4..00000000 --- a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/command/DynmapCommand.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.dynmap.fabric_1_19_1.command; - -import org.dynmap.fabric_1_19_1.DynmapPlugin; - -public class DynmapCommand extends DynmapCommandExecutor { - public DynmapCommand(DynmapPlugin p) { - super("dynmap", p); - } -} diff --git a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/command/DynmapCommandExecutor.java b/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/command/DynmapCommandExecutor.java deleted file mode 100644 index 09518e11..00000000 --- a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/command/DynmapCommandExecutor.java +++ /dev/null @@ -1,63 +0,0 @@ -package org.dynmap.fabric_1_19_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_19_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.19.1/src/main/java/org/dynmap/fabric_1_19_1/command/DynmapExpCommand.java b/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/command/DynmapExpCommand.java deleted file mode 100644 index 97b442af..00000000 --- a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/command/DynmapExpCommand.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.dynmap.fabric_1_19_1.command; - -import org.dynmap.fabric_1_19_1.DynmapPlugin; - -public class DynmapExpCommand extends DynmapCommandExecutor { - public DynmapExpCommand(DynmapPlugin p) { - super("dynmapexp", p); - } -} diff --git a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/event/BlockEvents.java b/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/event/BlockEvents.java deleted file mode 100644 index f15fbb88..00000000 --- a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/event/BlockEvents.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.dynmap.fabric_1_19_1.event; - -import net.fabricmc.fabric.api.event.Event; -import net.fabricmc.fabric.api.event.EventFactory; -import net.minecraft.block.Material; -import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; - -public class BlockEvents { - private BlockEvents() { - } - - public static Event BLOCK_EVENT = EventFactory.createArrayBacked(BlockCallback.class, - (listeners) -> (world, pos) -> { - for (BlockCallback callback : listeners) { - callback.onBlockEvent(world, pos); - } - } - ); - - public static Event SIGN_CHANGE_EVENT = EventFactory.createArrayBacked(SignChangeCallback.class, - (listeners) -> (world, pos, lines, material, player) -> { - for (SignChangeCallback callback : listeners) { - callback.onSignChange(world, pos, lines, material, player); - } - } - ); - - @FunctionalInterface - public interface BlockCallback { - void onBlockEvent(World world, BlockPos pos); - } - - @FunctionalInterface - public interface SignChangeCallback { - void onSignChange(ServerWorld world, BlockPos pos, String[] lines, Material material, ServerPlayerEntity player); - } -} diff --git a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/event/CustomServerChunkEvents.java b/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/event/CustomServerChunkEvents.java deleted file mode 100644 index b0e7d783..00000000 --- a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/event/CustomServerChunkEvents.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.dynmap.fabric_1_19_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 CustomServerChunkEvents { - public static Event CHUNK_GENERATE = EventFactory.createArrayBacked(ChunkGenerate.class, - (listeners) -> (world, chunk) -> { - for (ChunkGenerate callback : listeners) { - callback.onChunkGenerate(world, chunk); - } - } - ); - - @FunctionalInterface - public interface ChunkGenerate { - void onChunkGenerate(ServerWorld world, Chunk chunk); - } -} \ No newline at end of file diff --git a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/event/CustomServerLifecycleEvents.java b/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/event/CustomServerLifecycleEvents.java deleted file mode 100644 index 6a9c18c1..00000000 --- a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/event/CustomServerLifecycleEvents.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.dynmap.fabric_1_19_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.19.1/src/main/java/org/dynmap/fabric_1_19_1/event/PlayerEvents.java b/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/event/PlayerEvents.java deleted file mode 100644 index b9aac27b..00000000 --- a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/event/PlayerEvents.java +++ /dev/null @@ -1,62 +0,0 @@ -package org.dynmap.fabric_1_19_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.19.1/src/main/java/org/dynmap/fabric_1_19_1/event/ServerChatEvents.java b/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/event/ServerChatEvents.java deleted file mode 100644 index a2781856..00000000 --- a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/event/ServerChatEvents.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.dynmap.fabric_1_19_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.19.1/src/main/java/org/dynmap/fabric_1_19_1/mixin/BiomeEffectsAccessor.java b/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/mixin/BiomeEffectsAccessor.java deleted file mode 100644 index 27fc56e6..00000000 --- a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/mixin/BiomeEffectsAccessor.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.dynmap.fabric_1_19_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.19.1/src/main/java/org/dynmap/fabric_1_19_1/mixin/MinecraftServerMixin.java b/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/mixin/MinecraftServerMixin.java deleted file mode 100644 index 7afa2cc9..00000000 --- a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/mixin/MinecraftServerMixin.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.dynmap.fabric_1_19_1.mixin; - -import net.minecraft.server.MinecraftServer; -import org.dynmap.fabric_1_19_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.19.1/src/main/java/org/dynmap/fabric_1_19_1/mixin/PlayerManagerMixin.java b/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/mixin/PlayerManagerMixin.java deleted file mode 100644 index bf06dcb5..00000000 --- a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/mixin/PlayerManagerMixin.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.dynmap.fabric_1_19_1.mixin; - -import net.minecraft.network.ClientConnection; -import net.minecraft.server.PlayerManager; -import net.minecraft.server.network.ServerPlayerEntity; -import org.dynmap.fabric_1_19_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.19.1/src/main/java/org/dynmap/fabric_1_19_1/mixin/ProtoChunkMixin.java b/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/mixin/ProtoChunkMixin.java deleted file mode 100644 index fb438179..00000000 --- a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/mixin/ProtoChunkMixin.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.dynmap.fabric_1_19_1.mixin; - -import net.minecraft.block.BlockState; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.chunk.ProtoChunk; -import org.dynmap.fabric_1_19_1.access.ProtoChunkAccessor; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(ProtoChunk.class) -public class ProtoChunkMixin implements ProtoChunkAccessor { - private boolean touchedByWorldGen = false; - - @Inject( - method = "setBlockState", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/world/chunk/ChunkSection;setBlockState(IIILnet/minecraft/block/BlockState;)Lnet/minecraft/block/BlockState;" - ) - ) - public void setBlockState(BlockPos pos, BlockState state, boolean moved, CallbackInfoReturnable info) { - touchedByWorldGen = true; - } - - public boolean getTouchedByWorldGen() { - return touchedByWorldGen; - } -} \ No newline at end of file diff --git a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/mixin/ServerPlayNetworkHandlerMixin.java b/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/mixin/ServerPlayNetworkHandlerMixin.java deleted file mode 100644 index 5fcdd3ed..00000000 --- a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/mixin/ServerPlayNetworkHandlerMixin.java +++ /dev/null @@ -1,68 +0,0 @@ -package org.dynmap.fabric_1_19_1.mixin; - -import net.minecraft.block.BlockState; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.block.entity.SignBlockEntity; -import net.minecraft.network.message.SignedMessage; -import net.minecraft.network.packet.c2s.play.UpdateSignC2SPacket; -import net.minecraft.server.filter.FilteredMessage; -import net.minecraft.server.filter.TextStream; -import net.minecraft.server.network.ServerPlayNetworkHandler; -import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.text.LiteralTextContent; -import net.minecraft.text.Text; -import net.minecraft.util.math.BlockPos; - -import java.util.List; - -import net.minecraft.util.registry.RegistryKey; -import org.dynmap.fabric_1_19_1.event.BlockEvents; -import org.dynmap.fabric_1_19_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 = "handleDecoratedMessage", - at = @At( - value = "HEAD" - ) - ) - public void onGameMessage(SignedMessage signedMessage, CallbackInfo ci) { - ServerChatEvents.EVENT.invoker().onChatMessage(player, signedMessage.getContent().getString()); - } - - @Inject( - method = "onSignUpdate", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/block/entity/SignBlockEntity;markDirty()V", - shift = At.Shift.BEFORE - ), - locals = LocalCapture.CAPTURE_FAILHARD - ) - public void onSignUpdate(UpdateSignC2SPacket packet, List signText, CallbackInfo info, - ServerWorld serverWorld, BlockPos blockPos, BlockState blockState, BlockEntity blockEntity, SignBlockEntity signBlockEntity) - { - // Pull the raw text from the input. - String[] rawTexts = new String[4]; - for (int i=0; i info) { - ServerPlayerEntity player = (ServerPlayerEntity) (Object) this; - if (player.getRemovalReason() == null) { - PlayerEvents.PLAYER_CHANGED_DIMENSION.invoker().onPlayerChangedDimension(player); - } - } -} diff --git a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/mixin/ThreadedAnvilChunkStorageMixin.java b/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/mixin/ThreadedAnvilChunkStorageMixin.java deleted file mode 100644 index 6ae09a04..00000000 --- a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/mixin/ThreadedAnvilChunkStorageMixin.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.dynmap.fabric_1_19_1.mixin; - -import net.minecraft.server.world.ChunkHolder; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.server.world.ThreadedAnvilChunkStorage; -import net.minecraft.world.chunk.Chunk; -import org.dynmap.fabric_1_19_1.access.ProtoChunkAccessor; -import org.dynmap.fabric_1_19_1.event.CustomServerChunkEvents; -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(value = ThreadedAnvilChunkStorage.class, priority = 666 /* fire before Fabric API CHUNK_LOAD event */) -public abstract class ThreadedAnvilChunkStorageMixin { - @Final - @Shadow - ServerWorld world; - - @Inject( - /* Same place as fabric-lifecycle-events-v1 event CHUNK_LOAD (we will fire before it) */ - method = "method_17227", - at = @At("TAIL") - ) - private void onChunkGenerate(ChunkHolder chunkHolder, Chunk protoChunk, CallbackInfoReturnable callbackInfoReturnable) { - if (((ProtoChunkAccessor)protoChunk).getTouchedByWorldGen()) { - CustomServerChunkEvents.CHUNK_GENERATE.invoker().onChunkGenerate(this.world, callbackInfoReturnable.getReturnValue()); - } - } -} \ No newline at end of file diff --git a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/mixin/WorldChunkMixin.java b/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/mixin/WorldChunkMixin.java deleted file mode 100644 index 1d45cb0b..00000000 --- a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/mixin/WorldChunkMixin.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.dynmap.fabric_1_19_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_19_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.BLOCK_EVENT.invoker().onBlockEvent(this.getWorld(), pos); - } - } -} diff --git a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/permissions/FabricPermissions.java b/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/permissions/FabricPermissions.java deleted file mode 100644 index f9a49339..00000000 --- a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/permissions/FabricPermissions.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.dynmap.fabric_1_19_1.permissions; - -import me.lucko.fabric.api.permissions.v0.Permissions; -import net.minecraft.entity.player.PlayerEntity; -import org.dynmap.Log; -import org.dynmap.fabric_1_19_1.DynmapPlugin; -import org.dynmap.json.simple.parser.JSONParser; - -import java.util.Set; -import java.util.stream.Collectors; - -public class FabricPermissions implements PermissionProvider { - - private String permissionKey(String perm) { - return "dynmap." + perm; - } - - @Override - public Set hasOfflinePermissions(String player, Set perms) { - return perms.stream() - .filter(perm -> hasOfflinePermission(player, perm)) - .collect(Collectors.toSet()); - } - - @Override - public boolean hasOfflinePermission(String player, String perm) { - return DynmapPlugin.plugin.isOp(player.toLowerCase()); - } - - @Override - public boolean has(PlayerEntity player, String permission) { - if (player == null) return false; - String name = player.getName().getString().toLowerCase(); - if (DynmapPlugin.plugin.isOp(name)) return true; - return Permissions.check(player, permissionKey(permission)); - } - - @Override - public boolean hasPermissionNode(PlayerEntity player, String permission) { - if (player != null) { - String name = player.getName().getString().toLowerCase(); - return DynmapPlugin.plugin.isOp(name); - } - return false; - } - -} diff --git a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/permissions/FilePermissions.java b/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/permissions/FilePermissions.java deleted file mode 100644 index ea548077..00000000 --- a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/permissions/FilePermissions.java +++ /dev/null @@ -1,103 +0,0 @@ -package org.dynmap.fabric_1_19_1.permissions; - -import net.minecraft.entity.player.PlayerEntity; -import org.dynmap.ConfigurationNode; -import org.dynmap.Log; -import org.dynmap.fabric_1_19_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.19.1/src/main/java/org/dynmap/fabric_1_19_1/permissions/LuckPermissions.java b/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/permissions/LuckPermissions.java deleted file mode 100644 index 57afb5c4..00000000 --- a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/permissions/LuckPermissions.java +++ /dev/null @@ -1,102 +0,0 @@ -package org.dynmap.fabric_1_19_1.permissions; - -import me.lucko.fabric.api.permissions.v0.Permissions; -import net.luckperms.api.LuckPerms; -import net.luckperms.api.LuckPermsProvider; -import net.luckperms.api.cacheddata.CachedPermissionData; -import net.luckperms.api.model.user.User; -import net.luckperms.api.util.Tristate; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.server.MinecraftServer; -import org.dynmap.Log; -import org.dynmap.fabric_1_19_1.DynmapPlugin; -import org.dynmap.json.simple.JSONArray; -import org.dynmap.json.simple.JSONObject; -import org.dynmap.json.simple.parser.JSONParser; -import org.dynmap.json.simple.parser.ParseException; - -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.IOException; -import java.util.Optional; -import java.util.Set; -import java.util.UUID; -import java.util.stream.Collectors; - -public class LuckPermissions implements PermissionProvider { - - private final JSONParser parser = new JSONParser(); - private LuckPerms api = null; - - private Optional getApi() { - if (api != null) return Optional.of(api); - try { - api = LuckPermsProvider.get(); - return Optional.of(api); - } catch (Exception ex) { - Log.warning("Trying to access LuckPerms before it has loaded"); - return Optional.empty(); - } - } - - private Optional cachedUUID(String username) { - try { - BufferedReader reader = new BufferedReader(new FileReader("usercache.json")); - JSONArray cache = (JSONArray) parser.parse(reader); - for (Object it : cache) { - JSONObject user = (JSONObject) it; - if (user.get("name").toString().equalsIgnoreCase(username)) { - String uuid = user.get("uuid").toString(); - return Optional.of(UUID.fromString(uuid)); - } - } - - reader.close(); - } catch (IOException | ParseException ex) { - Log.warning("Unable to read usercache.json"); - } - - return Optional.empty(); - } - - private String permissionKey(String perm) { - return "dynmap." + perm; - } - - @Override - public Set hasOfflinePermissions(String player, Set perms) { - return perms.stream() - .filter(perm -> hasOfflinePermission(player, perm)) - .collect(Collectors.toSet()); - } - - @Override - public boolean hasOfflinePermission(String player, String perm) { - if (DynmapPlugin.plugin.isOp(player.toLowerCase())) return true; - Optional api = getApi(); - Optional uuid = cachedUUID(player); - if (!uuid.isPresent() || !api.isPresent()) return false; - User user = api.get().getUserManager().loadUser(uuid.get()).join(); - CachedPermissionData permissions = user.getCachedData().getPermissionData(); - Tristate state = permissions.checkPermission(permissionKey(perm)); - return state.asBoolean(); - } - - @Override - public boolean has(PlayerEntity player, String permission) { - if (player == null) return false; - String name = player.getName().getString().toLowerCase(); - if (DynmapPlugin.plugin.isOp(name)) return true; - return Permissions.check(player, permissionKey(permission)); - } - - @Override - public boolean hasPermissionNode(PlayerEntity player, String permission) { - if (player != null) { - String name = player.getName().getString().toLowerCase(); - return DynmapPlugin.plugin.isOp(name); - } - return false; - } - -} diff --git a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/permissions/OpPermissions.java b/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/permissions/OpPermissions.java deleted file mode 100644 index fb26a1d5..00000000 --- a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/permissions/OpPermissions.java +++ /dev/null @@ -1,52 +0,0 @@ -package org.dynmap.fabric_1_19_1.permissions; - -import net.minecraft.entity.player.PlayerEntity; -import org.dynmap.Log; -import org.dynmap.fabric_1_19_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.19.1/src/main/java/org/dynmap/fabric_1_19_1/permissions/PermissionProvider.java b/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/permissions/PermissionProvider.java deleted file mode 100644 index af70f030..00000000 --- a/fabric-1.19.1/src/main/java/org/dynmap/fabric_1_19_1/permissions/PermissionProvider.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.dynmap.fabric_1_19_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.19.1/src/main/resources/assets/dynmap/icon.png b/fabric-1.19.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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" - #aws_secret_access_key: "" - #prefix: "" - #override_endpoint: "" - -components: - - class: org.dynmap.ClientConfigurationComponent - - # Remember to change the following class to org.dynmap.JsonFileClientUpdateComponent when using an external web server. - - class: org.dynmap.InternalClientUpdateComponent - sendhealth: true - sendposition: true - allowwebchat: true - webchat-interval: 5 - hidewebchatip: false - trustclientname: false - includehiddenplayers: false - # (optional) if true, color codes in player display names are used - use-name-colors: false - # (optional) if true, player login IDs will be used for web chat when their IPs match - use-player-login-ip: true - # (optional) if use-player-login-ip is true, setting this to true will cause chat messages not matching a known player IP to be ignored - require-player-login-ip: false - # (optional) block player login IDs that are banned from chatting - block-banned-player-chat: true - # Require login for web-to-server chat (requires login-enabled: true) - webchat-requires-login: false - # If set to true, users must have dynmap.webchat permission in order to chat - webchat-permissions: false - # Limit length of single chat messages - chatlengthlimit: 256 - # # Optional - make players hidden when they are inside/underground/in shadows (#=light level: 0=full shadow,15=sky) - # hideifshadow: 4 - # # Optional - make player hidden when they are under cover (#=sky light level,0=underground,15=open to sky) - # hideifundercover: 14 - # # (Optional) if true, players that are crouching/sneaking will be hidden - hideifsneaking: false - # optional, if true, players that are in spectator mode will be hidden - hideifspectator: false - # If true, player positions/status is protected (login with ID with dynmap.playermarkers.seeall permission required for info other than self) - protected-player-info: false - # If true, hide players with invisibility potion effects active - hide-if-invisiblity-potion: true - # If true, player names are not shown on map, chat, list - hidenames: false - #- class: org.dynmap.JsonFileClientUpdateComponent - # writeinterval: 1 - # sendhealth: true - # sendposition: true - # allowwebchat: true - # webchat-interval: 5 - # hidewebchatip: false - # includehiddenplayers: false - # use-name-colors: false - # use-player-login-ip: false - # require-player-login-ip: false - # block-banned-player-chat: true - # hideifshadow: 0 - # hideifundercover: 0 - # hideifsneaking: false - # # Require login for web-to-server chat (requires login-enabled: true) - # webchat-requires-login: false - # # If set to true, users must have dynmap.webchat permission in order to chat - # webchat-permissions: false - # # Limit length of single chat messages - # chatlengthlimit: 256 - # hide-if-invisiblity-potion: true - # hidenames: false - - - class: org.dynmap.SimpleWebChatComponent - allowchat: true - # If true, web UI users can supply name for chat using 'playername' URL parameter. 'trustclientname' must also be set true. - allowurlname: false - - # Note: this component is needed for the dmarker commands, and for the Marker API to be available to other plugins - - class: org.dynmap.MarkersComponent - type: markers - showlabel: false - enablesigns: false - # Default marker set for sign markers - default-sign-set: markers - # (optional) add spawn point markers to standard marker layer - showspawn: true - spawnicon: world - spawnlabel: "Spawn" - # (optional) layer for showing offline player's positions (for 'maxofflinetime' minutes after logoff) - showofflineplayers: false - offlinelabel: "Offline" - offlineicon: offlineuser - offlinehidebydefault: true - offlineminzoom: 0 - maxofflinetime: 30 - # (optional) layer for showing player's spawn beds - showspawnbeds: false - spawnbedlabel: "Spawn Beds" - spawnbedicon: bed - spawnbedhidebydefault: true - spawnbedminzoom: 0 - spawnbedformat: "%name%'s bed" - # (optional) Show world border (vanilla 1.8+) - showworldborder: true - worldborderlabel: "Border" - - - class: org.dynmap.ClientComponent - type: chat - allowurlname: false - - class: org.dynmap.ClientComponent - type: chatballoon - focuschatballoons: false - - class: org.dynmap.ClientComponent - type: chatbox - showplayerfaces: true - messagettl: 5 - # Optional: set number of lines in scrollable message history: if set, messagettl is not used to age out messages - #scrollback: 100 - # Optional: set maximum number of lines visible for chatbox - #visiblelines: 10 - # Optional: send push button - sendbutton: false - - class: org.dynmap.ClientComponent - type: playermarkers - showplayerfaces: true - showplayerhealth: true - # If true, show player body too (only valid if showplayerfaces=true) - showplayerbody: false - # Option to make player faces small - don't use with showplayerhealth or largeplayerfaces - smallplayerfaces: false - # Option to make player faces larger - don't use with showplayerhealth or smallplayerfaces - largeplayerfaces: false - # Optional - make player faces layer hidden by default - hidebydefault: false - # Optional - ordering priority in layer menu (low goes before high - default is 0) - layerprio: 0 - # Optional - label for player marker layer (default is 'Players') - label: "Players" - - #- class: org.dynmap.ClientComponent - # type: digitalclock - - class: org.dynmap.ClientComponent - type: link - - - class: org.dynmap.ClientComponent - type: timeofdayclock - showdigitalclock: true - #showweather: true - # Mouse pointer world coordinate display - - class: org.dynmap.ClientComponent - type: coord - label: "Location" - hidey: false - show-mcr: false - show-chunk: false - - # Note: more than one logo component can be defined - #- class: org.dynmap.ClientComponent - # type: logo - # text: "Dynmap" - # #logourl: "images/block_surface.png" - # linkurl: "http://forums.bukkit.org/threads/dynmap.489/" - # # Valid positions: top-left, top-right, bottom-left, bottom-right - # position: bottom-right - - #- class: org.dynmap.ClientComponent - # type: inactive - # timeout: 1800 # in seconds (1800 seconds = 30 minutes) - # redirecturl: inactive.html - # #showmessage: 'You were inactive for too long.' - - #- class: org.dynmap.TestComponent - # stuff: "This is some configuration-value" - -# Treat hiddenplayers.txt as a whitelist for players to be shown on the map? (Default false) -display-whitelist: false - -# How often a tile gets rendered (in seconds). -renderinterval: 1 - -# How many tiles on update queue before accelerate render interval -renderacceleratethreshold: 60 - -# How often to render tiles when backlog is above renderacceleratethreshold -renderaccelerateinterval: 0.2 - -# How many update tiles to work on at once (if not defined, default is 1/2 the number of cores) -tiles-rendered-at-once: 2 - -# If true, use normal priority threads for rendering (versus low priority) - this can keep rendering -# from starving on busy Windows boxes (Linux JVMs pretty much ignore thread priority), but may result -# in more competition for CPU resources with other processes -usenormalthreadpriority: true - -# Save and restore pending tile renders - prevents their loss on server shutdown or /reload -saverestorepending: true - -# Save period for pending jobs (in seconds): periodic saving for crash recovery of jobs -save-pending-period: 900 - -# Zoom-out tile update period - how often to scan for and process tile updates into zoom-out tiles (in seconds) -zoomoutperiod: 30 - -# Control whether zoom out tiles are validated on startup (can be needed if zoomout processing is interrupted, but can be expensive on large maps) -initial-zoomout-validate: true - -# Default delay on processing of updated tiles, in seconds. This can reduce potentially expensive re-rendering -# of frequently updated tiles (such as due to machines, pistons, quarries or other automation). Values can -# also be set on individual worlds and individual maps. -tileupdatedelay: 30 - -# Tile hashing is used to minimize tile file updates when no changes have occurred - set to false to disable -enabletilehash: true - -# Optional - hide ores: render as normal stone (so that they aren't revealed by maps) -#hideores: true - -# Optional - enabled BetterGrass style rendering of grass and snow block sides -#better-grass: true - -# Optional - enable smooth lighting by default on all maps supporting it (can be set per map as lighting option) -smooth-lighting: true - -# Optional - use world provider lighting table (good for custom worlds with custom lighting curves, like nether) -# false=classic Dynmap lighting curve -use-brightness-table: true - -# Optional - render specific block names using the textures and models of another block name: can be used to hide/disguise specific -# blocks (e.g. make ores look like stone, hide chests) or to provide simple support for rendering unsupported custom blocks -block-alias: -# "minecraft:quartz_ore": "stone" -# "diamond_ore": "coal_ore" - -# Default image format for HDMaps (png, jpg, jpg-q75, jpg-q80, jpg-q85, jpg-q90, jpg-q95, jpg-q100, webp, webp-q75, webp-q80, webp-q85, webp-q90, webp-q95, webp-q100, webp-l), -# Note: any webp format requires the presence of the 'webp command line tools' (cwebp, dwebp) (https://developers.google.com/speed/webp/download) -# -# Has no effect on maps with explicit format settings -image-format: jpg-q90 - -# If cwebp or dwebp are not on the PATH, use these settings to provide their full path. Do not use these settings if the tools are on the PATH -# For Windows, include .exe -# -#cwebpPath: /usr/bin/cwebp -#dwebpPath: /usr/bin/dwebp - -# use-generated-textures: if true, use generated textures (same as client); false is static water/lava textures -# correct-water-lighting: if true, use corrected water lighting (same as client); false is legacy water (darker) -# transparent-leaves: if true, leaves are transparent (lighting-wise): false is needed for some Spout versions that break lighting on leaf blocks -use-generated-textures: true -correct-water-lighting: true -transparent-leaves: true - -# ctm-support: if true, Connected Texture Mod (CTM) in texture packs is enabled (default) -ctm-support: true -# custom-colors-support: if true, Custom Colors in texture packs is enabled (default) -custom-colors-support: true - -# Control loading of player faces (if set to false, skins are never fetched) -#fetchskins: false - -# Control updating of player faces, once loaded (if faces are being managed by other apps or manually) -#refreshskins: false - -# Customize URL used for fetching player skins (%player% is macro for name, %uuid% for UUID) -skin-url: "http://skins.minecraft.net/MinecraftSkins/%player%.png" - -# Control behavior for new (1.0+) compass orientation (sunrise moved 90 degrees: east is now what used to be south) -# default is 'newrose' (preserve pre-1.0 maps, rotate rose) -# 'newnorth' is used to rotate maps and rose (requires fullrender of any HDMap map - same as 'newrose' for FlatMap or KzedMap) -compass-mode: newnorth - -# Triggers for automatic updates : blockupdate-with-id is debug for breaking down updates by ID:meta -# To disable, set just 'none' and comment/delete the rest -render-triggers: - - blockupdate - #- blockupdate-with-id - - chunkgenerate - #- none - -# Title for the web page - if not specified, defaults to the server's name (unless it is the default of 'Unknown Server') -#webpage-title: "My Awesome Server Map" - -# The path where the tile-files are placed. -tilespath: web/tiles - -# The path where the web-files are located. -webpath: web - -# If set to false, disable extraction of webpath content (good if using custom web UI or 3rd party web UI) -# Note: web interface is unsupported in this configuration - you're on your own -update-webpath-files: true - -# The path were the /dynmapexp command exports OBJ ZIP files -exportpath: export - -# The path where files can be imported for /dmarker commands -importpath: import - -# The network-interface the webserver will bind to (0.0.0.0 for all interfaces, 127.0.0.1 for only local access). -# If not set, uses same setting as server in server.properties (or 0.0.0.0 if not specified) -#webserver-bindaddress: 0.0.0.0 - -# The TCP-port the webserver will listen on. -webserver-port: 8123 - -# Maximum concurrent session on internal web server - limits resources used in Bukkit server -max-sessions: 30 - -# Disables Webserver portion of Dynmap (Advanced users only) -disable-webserver: false - -# Enable/disable having the web server allow symbolic links (true=compatible with existing code, false=more secure (default)) -allow-symlinks: true - -# Enable login support -login-enabled: false -# Require login to access website (requires login-enabled: true) -login-required: false - -# Period between tile renders for fullrender, in seconds (non-zero to pace fullrenders, lessen CPU load) -timesliceinterval: 0.0 - -# Maximum chunk loads per server tick (1/20th of a second) - reducing this below 90 will impact render performance, but also will reduce server thread load -maxchunkspertick: 200 - -# Progress report interval for fullrender/radiusrender, in tiles. Must be 100 or greater -progressloginterval: 100 - -# Parallel fullrender: if defined, number of concurrent threads used for fullrender or radiusrender -# Note: setting this will result in much more intensive CPU use, some additional memory use. Caution should be used when -# setting this to equal or exceed the number of physical cores on the system. -#parallelrendercnt: 4 - -# Interval the browser should poll for updates. -updaterate: 2000 - -# If nonzero, server will pause fullrender/radiusrender processing when 'fullrenderplayerlimit' or more users are logged in -fullrenderplayerlimit: 0 -# If nonzero, server will pause update render processing when 'updateplayerlimit' or more users are logged in -updateplayerlimit: 0 -# Target limit on server thread use - msec per tick -per-tick-time-limit: 50 -# If TPS of server is below this setting, update renders processing is paused -update-min-tps: 18.0 -# If TPS of server is below this setting, full/radius renders processing is paused -fullrender-min-tps: 18.0 -# If TPS of server is below this setting, zoom out processing is paused -zoomout-min-tps: 18.0 - -showplayerfacesinmenu: true - -# Control whether players that are hidden or not on current map are grayed out (true=yes) -grayplayerswhenhidden: true - -# Set sidebaropened: 'true' to pin menu sidebar opened permanently, 'pinned' to default the sidebar to pinned, but allow it to unpin -#sidebaropened: true - -# Customized HTTP response headers - add 'id: value' pairs to all HTTP response headers (internal web server only) -#http-response-headers: -# Access-Control-Allow-Origin: "my-domain.com" -# X-Custom-Header-Of-Mine: "MyHeaderValue" - -# Trusted proxies for web server - which proxy addresses are trusted to supply valid X-Forwarded-For fields -# This now supports both IP address, and subnet ranges (e.g. 192.168.1.0/24 or 202.24.0.0/14 ) -trusted-proxies: - - "127.0.0.1" - - "0:0:0:0:0:0:0:1" - -joinmessage: "%playername% joined" -quitmessage: "%playername% quit" -spammessage: "You may only chat once every %interval% seconds." -# format for messages from web: %playername% substitutes sender ID (typically IP), %message% includes text -webmsgformat: "&color;2[WEB] %playername%: &color;f%message%" - -# Control whether layer control is presented on the UI (default is true) -showlayercontrol: true - -# Enable checking for banned IPs via banned-ips.txt (internal web server only) -check-banned-ips: true - -# Default selection when map page is loaded -defaultzoom: 0 -defaultworld: world -defaultmap: flat -# (optional) Zoom level and map to switch to when following a player, if possible -#followzoom: 3 -#followmap: surface - -# If true, make persistent record of IP addresses used by player logins, to support web IP to player matching -persist-ids-by-ip: true - -# If true, map text to cyrillic -cyrillic-support: false - -# Messages to customize -msg: - maptypes: "Map Types" - players: "Players" - chatrequireslogin: "Chat Requires Login" - chatnotallowed: "You are not permitted to send chat messages" - hiddennamejoin: "Player joined" - hiddennamequit: "Player quit" - -# URL for client configuration (only need to be tailored for proxies or other non-standard configurations) -url: - # configuration URL - #configuration: "up/configuration" - # update URL - #update: "up/world/{world}/{timestamp}" - # sendmessage URL - #sendmessage: "up/sendmessage" - # login URL - #login: "up/login" - # register URL - #register: "up/register" - # tiles base URL - #tiles: "tiles/" - # markers base URL - #markers: "tiles/" - # Snapshot cache size, in chunks -snapshotcachesize: 500 -# Snapshot cache uses soft references (true), else weak references (false) -soft-ref-cache: true - -# Player enter/exit title messages for map markers -# -# Processing period - how often to check player positions vs markers - default is 1000ms (1 second) -#enterexitperiod: 1000 -# Title message fade in time, in ticks (0.05 second intervals) - default is 10 (1/2 second) -#titleFadeIn: 10 -# Title message stay time, in ticks (0.05 second intervals) - default is 70 (3.5 seconds) -#titleStay: 70 -# Title message fade out time, in ticks (0.05 seocnd intervals) - default is 20 (1 second) -#titleFadeOut: 20 -# Enter/exit messages use on screen titles (true - default), if false chat messages are sent instead -#enterexitUseTitle: true -# Set true if new enter messages should supercede pending exit messages (vs being queued in order), default false -#enterReplacesExits: true - -# Published public URL for Dynmap server (allows users to use 'dynmap url' command to get public URL usable to access server -# If not set, 'dynmap url' will not return anything. URL should be fully qualified (e.g. https://mc.westeroscraft.com/) -#publicURL: http://my.greatserver.com/dynmap - -# Set to true to enable verbose startup messages - can help with debugging map configuration problems -# Set to false for a much quieter startup log -verbose: false - -# Enables debugging. -#debuggers: -# - class: org.dynmap.debug.LogDebugger -# Debug: dump blocks missing render data -dump-missing-blocks: false - -# Log4J defense: string substituted for attempts to use macros in web chat -hackAttemptBlurb: "(IaM5uchA1337Haxr-Ban Me!)" diff --git a/fabric-1.19.1/src/main/resources/dynmap.mixins.json b/fabric-1.19.1/src/main/resources/dynmap.mixins.json deleted file mode 100644 index 3e139d78..00000000 --- a/fabric-1.19.1/src/main/resources/dynmap.mixins.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "required": true, - "minVersion": "0.8", - "package": "org.dynmap.fabric_1_19_1.mixin", - "compatibilityLevel": "JAVA_17", - "mixins": [ - "BiomeEffectsAccessor", - "MinecraftServerMixin", - "PlayerManagerMixin", - "ProtoChunkMixin", - "ServerPlayerEntityMixin", - "ServerPlayNetworkHandlerMixin", - "ThreadedAnvilChunkStorageMixin", - "WorldChunkMixin" - ], - "injectors": { - "defaultRequire": 1 - } -} diff --git a/fabric-1.19.1/src/main/resources/fabric.mod.json b/fabric-1.19.1/src/main/resources/fabric.mod.json deleted file mode 100644 index 67bb8404..00000000 --- a/fabric-1.19.1/src/main/resources/fabric.mod.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "schemaVersion": 1, - "id": "dynmap", - "version": "${version}", - "name": "Dynmap", - "description": "Dynamic, Google-maps style rendered maps for your Minecraft server", - "authors": [ - "mikeprimm", - "LolHens", - "i509VCB" - ], - "contact": { - "homepage": "https://github.com/webbukkit/dynmap", - "sources": "https://github.com/webbukkit/dynmap" - }, - "license": "Apache-2.0", - "icon": "assets/dynmap/icon.png", - "environment": "*", - "entrypoints": { - "main": [ - "org.dynmap.fabric_1_19_1.DynmapMod" - ] - }, - "mixins": [ - "dynmap.mixins.json" - ], - - "depends": { - "fabricloader": ">=0.14.8", - "fabric": ">=0.58.5", - "minecraft": ["1.19.1", "1.19.2"] - } -} diff --git a/fabric-1.19.1/src/main/resources/permissions.yml.example b/fabric-1.19.1/src/main/resources/permissions.yml.example deleted file mode 100644 index a25f9adc..00000000 --- a/fabric-1.19.1/src/main/resources/permissions.yml.example +++ /dev/null @@ -1,27 +0,0 @@ -# -# Sample permissions.yml for dynmap - trivial, flat-file based permissions for dynmap features -# To use, copy this file to dynmap/permissions.yml, and edit appropriate. File is YAML format. -# -# All operators have full permissions to all functions. -# All users receive the permissions under the 'defaultuser' section -# Specific users can be given more permissions by defining a section with their name containing their permisssions -# All permissions correspond to those documented here (https://github.com/webbukkit/dynmap/wiki/Permissions), but -# do NOT have the 'dynmap.' prefix when used here (e.g. 'dynmap.fullrender' permission is just 'fullrender' here). -# -defaultuser: - - render - - show.self - - hide.self - - sendtoweb - - stats - - marker.list - - marker.listsets - - marker.icons - - webregister - - webchat - #- marker.sign - -#playername1: -# - fullrender -# - cancelrender -# - radiusrender diff --git a/fabric-1.19.3/.gitignore b/fabric-1.19.3/.gitignore deleted file mode 100644 index 8b87af68..00000000 --- a/fabric-1.19.3/.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.19.3/build.gradle b/fabric-1.19.3/build.gradle deleted file mode 100644 index 05ad532b..00000000 --- a/fabric-1.19.3/build.gradle +++ /dev/null @@ -1,69 +0,0 @@ -plugins { - id 'fabric-loom' version '1.1.10' -} - -archivesBaseName = "Dynmap" -version = parent.version -group = parent.group - -eclipse { - project { - name = "Dynmap(Fabric-1.19.3)" - } -} - -sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = JavaLanguageVersion.of(17) // Need this here so eclipse task generates correctly. - -configurations { - shadow - implementation.extendsFrom(shadow) -} - -repositories { - mavenCentral() - maven { url 'https://oss.sonatype.org/content/repositories/snapshots' } -} - -dependencies { - minecraft "com.mojang:minecraft:${project.minecraft_version}" - mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" - modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" - 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') - - modCompileOnly "me.lucko:fabric-permissions-api:0.1-SNAPSHOT" - compileOnly 'net.luckperms:api:5.4' -} - -processResources { - filesMatching('fabric.mod.json') { - expand "version": project.version - } -} - -java { - // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task - // if it is present. - // If you remove this line, sources will not be generated. - withSourcesJar() -} - -jar { - from "LICENSE" - from { - configurations.shadow.collect { it.toString().contains("guava") ? null : it.isDirectory() ? it : zipTree(it) } - } -} - -remapJar { - archiveFileName = "${archivesBaseName}-${project.version}-fabric-${project.minecraft_version}.jar" - destinationDirectory = file '../target' -} - -remapJar.doLast { - task -> - ant.checksum file: task.archivePath -} diff --git a/fabric-1.19.3/gradle.properties b/fabric-1.19.3/gradle.properties deleted file mode 100644 index 37baa4e7..00000000 --- a/fabric-1.19.3/gradle.properties +++ /dev/null @@ -1,4 +0,0 @@ -minecraft_version=1.19.3 -yarn_mappings=1.19.3+build.2 -loader_version=0.14.11 -fabric_version=0.68.1+1.19.3 diff --git a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/DynmapMod.java b/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/DynmapMod.java deleted file mode 100644 index 338425ae..00000000 --- a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/DynmapMod.java +++ /dev/null @@ -1,50 +0,0 @@ -package org.dynmap.fabric_1_19_3; - -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.19.3/src/main/java/org/dynmap/fabric_1_19_3/DynmapPlugin.java b/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/DynmapPlugin.java deleted file mode 100644 index 309229e3..00000000 --- a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/DynmapPlugin.java +++ /dev/null @@ -1,801 +0,0 @@ -package org.dynmap.fabric_1_19_3; - -import com.mojang.brigadier.CommandDispatcher; -import com.mojang.brigadier.exceptions.CommandSyntaxException; -import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; -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.fabricmc.loader.api.FabricLoader; -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.registry.Registries; -import net.minecraft.registry.Registry; -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.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.world.EmptyBlockView; -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 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.common.chunk.GenericChunkCache; -import org.dynmap.fabric_1_19_3.command.DmapCommand; -import org.dynmap.fabric_1_19_3.command.DmarkerCommand; -import org.dynmap.fabric_1_19_3.command.DynmapCommand; -import org.dynmap.fabric_1_19_3.command.DynmapExpCommand; -import org.dynmap.fabric_1_19_3.event.BlockEvents; -import org.dynmap.fabric_1_19_3.event.CustomServerChunkEvents; -import org.dynmap.fabric_1_19_3.event.CustomServerLifecycleEvents; -import org.dynmap.fabric_1_19_3.event.PlayerEvents; -import org.dynmap.fabric_1_19_3.mixin.BiomeEffectsAccessor; -import org.dynmap.fabric_1_19_3.permissions.*; -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 GenericChunkCache 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(); - private HashMap worlds = new HashMap(); - private WorldAccess last_world; - private FabricWorld last_fworld; - private Map players = new HashMap(); - 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 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, registryAccess, environment) -> 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; - - /** - * 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(); - DynmapBlockState.Builder bld = new DynmapBlockState.Builder(); - while (iter.hasNext()) { - BlockState bs = iter.next(); - int idx = bsids.getRawId(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 = Registries.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(); - } - int lightAtten = bs.isOpaqueFullCube(EmptyBlockView.INSTANCE, BlockPos.ORIGIN) ? 15 : (bs.isTranslucent(EmptyBlockView.INSTANCE, BlockPos.ORIGIN) ? 0 : 1); - //Log.info("statename=" + bn + "[" + statename + "], lightAtten=" + lightAtten); - // Fill in base attributes - bld.setBaseState(basebs).setStateIndex(idx - baseidx).setBlockName(bn).setStateName(statename).setMaterial(mat.toString()).setLegacyBlockID(idx).setAttenuatesLight(lightAtten); - if (mat.isSolid()) { bld.setSolid(); } - if (mat == Material.AIR) { bld.setAir(); } - if (mat == Material.WOOD) { bld.setLog(); } - if (mat == Material.LEAVES) { bld.setLeaves(); } - if ((!bs.getFluidState().isEmpty()) && !(bs.getBlock() instanceof FluidBlock)) { - bld.setWaterlogged(); - } - DynmapBlockState dbs = bld.build(); // Build state - stateByID[idx] = dbs; - if (basebs == null) { basebs = dbs; } - } - } -// 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); - } - - 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); - } - } - } - - public FabricServer getFabricServer() { - return fserver; - } - - 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() && server.isHost(server.getPlayerManager().getPlayer(player).getGameProfile()); - } - - boolean hasPerm(PlayerEntity psender, String permission) { - PermissionsHandler ph = PermissionsHandler.getHandler(); - if ((ph != null) && (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 ((ph != null) && (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); - - Registry biomeRegistry = getFabricServer().getBiomeRegistry(); - Biome[] list = getFabricServer().getBiomeList(biomeRegistry); - - for (int i = 0; i < list.length; i++) { - Biome bb = list[i]; - if (bb != null) { - String id = biomeRegistry.getId(bb).getPath(); - String rl = biomeRegistry.getId(bb).toString(); - float tmp = bb.getTemperature(), hum = bb.getDownfall(); - int watermult = ((BiomeEffectsAccessor) bb.getEffects()).getWaterColor(); - Log.verboseinfo("biome[" + i + "]: hum=" + hum + ", tmp=" + tmp + ", mult=" + Integer.toHexString(watermult)); - - BiomeMap bmap = BiomeMap.NULL; - if (rl != null) { // If resource location, lookup by this - bmap = BiomeMap.byBiomeResourceLocation(rl); - } - else { - bmap = BiomeMap.byBiomeID(i); - } - if (bmap.isDefault() || (bmap == BiomeMap.NULL)) { - bmap = new BiomeMap((rl != null) ? BiomeMap.NO_INDEX : i, id, tmp, hum, rl); - 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)); - } - bmap.setBiomeObject(bb); - } - } - if (cnt > 0) - Log.info("Added " + cnt + " custom biome mappings"); - } - - private String[] getBiomeNames() { - Registry biomeRegistry = getFabricServer().getBiomeRegistry(); - Biome[] list = getFabricServer().getBiomeList(biomeRegistry); - String[] lst = new String[list.length]; - for (int i = 0; i < list.length; i++) { - Biome bb = list[i]; - if (bb != null) { - lst[i] = biomeRegistry.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 */ - if (FabricLoader.getInstance().isModLoaded("luckperms")) { - Log.info("Using luckperms for access control"); - permissions = new LuckPermissions(); - } - else if (FabricLoader.getInstance().isModLoaded("fabric-permissions-api-v0")) { - Log.info("Using fabric-permissions-api for access control"); - permissions = new FabricPermissions(); - } else { - /* 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); - 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 GenericChunkCache(core.getSnapShotCacheSize(), core.useSoftRefInSnapShotCache()); - /* Get map manager from core */ - mapManager = core.getMapManager(); - - /* Load saved world definitions */ - loadWorlds(); - - 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.getPlayerOrThrow(); - } - - 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 handleChunkGenerate(ServerWorld world, Chunk chunk) { - if (!onchunkgenerate) return; - - FabricWorld fw = getWorld(world, false); - ChunkPos chunkPos = chunk.getPos(); - - int ymax = Integer.MIN_VALUE; - int ymin = Integer.MAX_VALUE; - ChunkSection[] sections = chunk.getSectionArray(); - for (int i = 0; i < sections.length; i++) { - if ((sections[i] != null) && (!sections[i].isEmpty())) { - int sy = sections[i].getYOffset(); - if (sy < ymin) ymin = sy; - if ((sy+16) > ymax) ymax = sy + 16; - } - } - if (ymax != Integer.MIN_VALUE) { - mapManager.touchVolume(fw.getName(), - chunkPos.getStartX(), ymin, chunkPos.getStartZ(), - chunkPos.getEndX(), ymax, chunkPos.getEndZ(), - "chunkgenerate"); - //Log.info("New generated chunk detected at %s[%s]".formatted(fw.getName(), chunkPos.getStartPos())); - } - } - - 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(world, 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) - worldTracker = new WorldTracker(); - if (onchunkpopulate || onchunkgenerate) { - CustomServerChunkEvents.CHUNK_GENERATE.register((world, chunk) -> worldTracker.handleChunkGenerate(world, chunk)); - } - if (onblockchange) { - BlockEvents.BLOCK_EVENT.register((world, pos) -> worldTracker.handleBlockEvent(world, pos)); - } - - ServerWorldEvents.LOAD.register((server, world) -> worldTracker.handleWorldLoad(server, world)); - ServerWorldEvents.UNLOAD.register((server, world) -> worldTracker.handleWorldUnload(server, world)); - } - - FabricWorld getWorldByName(String name) { - return worlds.get(name); - } - - FabricWorld getWorld(World w) { - return getWorld(w, true); - } - - private FabricWorld getWorld(World w, boolean add_if_not_found) { - if (last_world == w) { - return last_fworld; - } - String wname = FabricWorld.getWorldName(this, w); - - for (FabricWorld fw : worlds.values()) { - if (fw.getRawName().equals(wname)) { - last_world = w; - last_fworld = fw; - if (!fw.isLoaded()) { - fw.setWorldLoaded(w); - } - fw.updateWorld(w); - return fw; - } - } - FabricWorld fw = null; - if (add_if_not_found) { - /* Add to list if not found */ - fw = new FabricWorld(this, 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("miny", fw.minY); - 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"); - Integer miny = (Integer) world.get("miny"); - 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(this, name, height, sealevel, nether, theend, title, (miny != null) ? miny : 0); - 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; - } - } - } -} \ No newline at end of file diff --git a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/FabricAdapter.java b/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/FabricAdapter.java deleted file mode 100644 index 8d29c613..00000000 --- a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/FabricAdapter.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.dynmap.fabric_1_19_3; - -import net.minecraft.server.world.ServerWorld; -import org.dynmap.DynmapLocation; - -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.19.3/src/main/java/org/dynmap/fabric_1_19_3/FabricCommandSender.java b/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/FabricCommandSender.java deleted file mode 100644 index 24e8266e..00000000 --- a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/FabricCommandSender.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.dynmap.fabric_1_19_3; - -import net.minecraft.server.command.ServerCommandSource; -import net.minecraft.text.LiteralTextContent; -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 = Text.literal(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.19.3/src/main/java/org/dynmap/fabric_1_19_3/FabricLogger.java b/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/FabricLogger.java deleted file mode 100644 index f65647fb..00000000 --- a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/FabricLogger.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.dynmap.fabric_1_19_3; - -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.19.3/src/main/java/org/dynmap/fabric_1_19_3/FabricMapChunkCache.java b/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/FabricMapChunkCache.java deleted file mode 100644 index 37743fb1..00000000 --- a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/FabricMapChunkCache.java +++ /dev/null @@ -1,116 +0,0 @@ -package org.dynmap.fabric_1_19_3; - -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.collection.PackedIntegerArray; -import net.minecraft.util.math.ChunkPos; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.WordPackedArray; -import net.minecraft.world.ChunkSerializer; -import net.minecraft.world.World; -import net.minecraft.world.biome.Biome; -import net.minecraft.world.biome.BiomeEffects; -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.common.chunk.GenericChunk; -import org.dynmap.common.chunk.GenericChunkSection; -import org.dynmap.common.chunk.GenericMapChunkCache; -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 GenericMapChunkCache { - private World w; - private ServerChunkManager cps; - - /** - * Construct empty cache - */ - public FabricMapChunkCache(DynmapPlugin plugin) { - super(plugin.sscache); - } - - public void setChunks(FabricWorld dw, List chunks) { - 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"); - } - } - super.setChunks(dw, chunks); - } - - // Load generic chunk from existing and already loaded chunk - protected GenericChunk getLoadedChunk(DynmapChunk chunk) { - GenericChunk gc = null; - if (cps.isChunkLoaded(chunk.x, chunk.z)) { - NbtCompound nbt = null; - try { - nbt = ChunkSerializer.serialize((ServerWorld) w, cps.getWorldChunk(chunk.x, chunk.z, false)); - } catch (NullPointerException e) { - // TODO: find out why this is happening and why it only seems to happen since 1.16.2 - Log.severe("ChunkSerializer.serialize threw a NullPointerException", e); - } - if (nbt != null) { - gc = parseChunkFromNBT(new NBT.NBTCompound(nbt)); - } - } - return gc; - } - - private NbtCompound readChunk(int x, int z) { - try { - ThreadedAnvilChunkStorage acl = cps.threadedAnvilChunkStorage; - - ChunkPos coord = new ChunkPos(x, z); - // Async chunk reading is synchronized here. Perhaps we can do async and improve performance? - return acl.getNbt(coord).join().orElse(null); - } catch (Exception exc) { - Log.severe(String.format("Error reading chunk: %s,%d,%d", dw.getName(), x, z), exc); - return null; - } - } - - // Load generic chunk from unloaded chunk - protected GenericChunk loadChunk(DynmapChunk chunk) { - GenericChunk gc = null; - NbtCompound nbt = readChunk(chunk.x, chunk.z); - // If read was good - if (nbt != null) { - gc = parseChunkFromNBT(new NBT.NBTCompound(nbt)); - } - return gc; - } - - @Override - public int getFoliageColor(BiomeMap bm, int[] colormap, int x, int z) { - return bm.getBiomeObject().map(Biome::getEffects).flatMap(BiomeEffects::getFoliageColor).orElse(colormap[bm.biomeLookup()]); - } - - @Override - public int getGrassColor(BiomeMap bm, int[] colormap, int x, int z) { - BiomeEffects effects = bm.getBiomeObject().map(Biome::getEffects).orElse(null); - if (effects == null) return colormap[bm.biomeLookup()]; - return effects.getGrassColorModifier().getModifiedGrassColor(x, z, effects.getGrassColor().orElse(colormap[bm.biomeLookup()])); - } -} diff --git a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/FabricPlayer.java b/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/FabricPlayer.java deleted file mode 100644 index 4c9ef740..00000000 --- a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/FabricPlayer.java +++ /dev/null @@ -1,258 +0,0 @@ -package org.dynmap.fabric_1_19_3; - -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.SubtitleS2CPacket; -import net.minecraft.network.packet.s2c.play.TitleFadeS2CPacket; -import net.minecraft.network.packet.s2c.play.TitleS2CPacket; -import net.minecraft.server.network.ServerPlayNetworkHandler; -import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.text.LiteralTextContent; -import net.minecraft.text.Text; -import net.minecraft.util.Util; -import net.minecraft.util.math.Vec3d; -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.Base64; -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.getDecoder().decode(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.getWorld(), 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 = Text.literal(msg); - player.sendMessage(ichatcomponent); - } - - @Override - public boolean isInvisible() { - if(player != null) { - return player.isInvisible(); - } - return false; - } - @Override - public boolean isSpectator() { - if(player != null) { - return player.isSpectator(); - } - 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; - TitleFadeS2CPacket times = new TitleFadeS2CPacket(fadeInTicks, stayTicks, fadeOutTicks); - player.networkHandler.sendPacket(times); - if (title != null) { - TitleS2CPacket titlepkt = new TitleS2CPacket(Text.literal(title)); - player.networkHandler.sendPacket(titlepkt); - } - - if (subtitle != null) { - SubtitleS2CPacket subtitlepkt = new SubtitleS2CPacket(Text.literal(subtitle)); - player.networkHandler.sendPacket(subtitlepkt); - } - } - } -} diff --git a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/FabricServer.java b/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/FabricServer.java deleted file mode 100644 index 39a5906b..00000000 --- a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/FabricServer.java +++ /dev/null @@ -1,610 +0,0 @@ -package org.dynmap.fabric_1_19_3; - -import com.mojang.authlib.GameProfile; -import net.fabricmc.loader.api.FabricLoader; -import net.fabricmc.loader.api.ModContainer; -import net.minecraft.block.AbstractSignBlock; -import net.minecraft.block.Block; -import net.minecraft.block.BlockState; -import net.minecraft.network.message.MessageType; -import net.minecraft.registry.Registry; -import net.minecraft.registry.RegistryKeys; -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.LiteralTextContent; -import net.minecraft.text.Text; -import net.minecraft.util.UserCache; -import net.minecraft.util.Util; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; -import net.minecraft.world.biome.Biome; -import org.dynmap.DynmapChunk; -import org.dynmap.DynmapWorld; -import org.dynmap.Log; -import org.dynmap.DynmapCommonAPIListener; -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_19_3.event.BlockEvents; -import org.dynmap.fabric_1_19_3.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.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 final Registry biomeRegistry; - 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; - this.biomeRegistry = server.getRegistryManager().get(RegistryKeys.BIOME); - } - - private Optional getProfileByName(String player) { - UserCache cache = server.getUserCache(); - return cache.findByName(player); - } - - public final Registry getBiomeRegistry() { - return biomeRegistry; - } - - private Biome[] biomelist = null; - - public final Biome[] getBiomeList(Registry biomeRegistry) { - if (biomelist == null) { - biomelist = new Biome[256]; - Iterator iter = biomeRegistry.iterator(); - while (iter.hasNext()) { - Biome b = iter.next(); - int bidx = biomeRegistry.getRawId(b); - if (bidx >= biomelist.length) { - biomelist = Arrays.copyOf(biomelist, bidx + biomelist.length); - } - biomelist[bidx] = b; - } - } - return biomelist; - } - - @Override - public int getBlockIDAt(String wname, int x, int y, int z) { - return -1; - } - - @SuppressWarnings("deprecation") /* Not much I can do... fix this if it breaks. */ - @Override - public int isSignAt(String wname, int x, int y, int z) { - World world = plugin.getWorldByName(wname).getWorld(); - - BlockPos pos = new BlockPos(x, y, z); - if (!world.isChunkLoaded(pos)) - return -1; - - Block block = world.getBlockState(pos).getBlock(); - return (block instanceof AbstractSignBlock ? 1 : 0); - } - - @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) { - PlayerManager scm = server.getPlayerManager(); - BannedPlayerList bl = scm.getUserBanList(); - try { - return bl.contains(getProfileByName(pid).get()); - } catch (NoSuchElementException e) { - /* If this profile doesn't exist, default to "banned" for good measure. */ - return true; - } - } - - @Override - public String stripChatColor(String s) { - return DynmapPlugin.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: - /* Already handled by BlockEvents logic */ - break; - - case SIGN_CHANGE: - BlockEvents.SIGN_CHANGE_EVENT.register((world, pos, lines, material, player) -> { - plugin.core.processSignChange("fabric", FabricWorld.getWorldName(plugin, world), - pos.getX(), pos.getY(), pos.getZ(), lines, player.getName().getString()); - }); - 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 = Text.literal(msg); - server.getPlayerManager().broadcast(component, false); - 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) { - if (isPlayerBanned(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) { - if (isPlayerBanned(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 (InterruptedException 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.getRawId(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 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.19.3/src/main/java/org/dynmap/fabric_1_19_3/FabricWorld.java b/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/FabricWorld.java deleted file mode 100644 index cc39790f..00000000 --- a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/FabricWorld.java +++ /dev/null @@ -1,236 +0,0 @@ -package org.dynmap.fabric_1_19_3; - -import net.minecraft.registry.RegistryKey; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.MathHelper; -import net.minecraft.world.Heightmap; -import net.minecraft.world.LightType; -import net.minecraft.world.World; -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 final DynmapPlugin plugin; - private World 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 = 320; // Maximum allows world height - - public static int getMaxWorldHeight() { - return maxWorldHeight; - } - - public static void setMaxWorldHeight(int h) { - maxWorldHeight = h; - } - - public static String getWorldName(DynmapPlugin plugin, World w) { - RegistryKey rk = w.getRegistryKey(); - if (rk == World.OVERWORLD) { // Overworld? - return w.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 void updateWorld(World w) { - this.updateWorldHeights(w.getHeight(), w.getBottomY(), w.getSeaLevel()); - } - - public FabricWorld(DynmapPlugin plugin, World w) { - this(plugin, getWorldName(plugin, w), w.getHeight(), - w.getSeaLevel(), - w.getRegistryKey() == World.NETHER, - w.getRegistryKey() == World.END, - w.getRegistryKey().getValue().getPath(), - w.getBottomY()); - setWorldLoaded(w); - } - - public FabricWorld(DynmapPlugin plugin, String name, int height, int sealevel, boolean nether, boolean the_end, String deftitle, int miny) { - super(name, (height > maxWorldHeight) ? maxWorldHeight : height, sealevel, miny); - this.plugin = plugin; - 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.getTimeOfDay(); - else - return -1; - } - - /* World is storming */ - @Override - public boolean hasStorm() { - if (world != null) - return world.isRaining(); - else - return false; - } - - /* World is thundering */ - @Override - public boolean isThundering() { - if (world != null) - return world.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(World w) { - world = w; - this.sealevel = w.getSeaLevel(); // Read actual current sealevel from world - // Update lighting table - for (int lightLevel = 0; lightLevel < 16; lightLevel++) { - // Algorithm based on LightmapTextureManager.getBrightness() - // We can't call that method because it's client-only. - // This means the code below can stop being correct if Mojang ever - // updates the curve; in that case we should reflect the changes. - float value = (float) lightLevel / 15.0f; - float brightness = value / (4.0f - 3.0f * value); - this.setBrightnessTableEntry(lightLevel, MathHelper.lerp(w.getDimension().ambientLight(), brightness, 1.0F)); - } - } - - /* 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.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(plugin); - c.setChunks(this, chunks); - return c; - } - return null; - } - - public World getWorld() { - return world; - } - - @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.19.3/src/main/java/org/dynmap/fabric_1_19_3/NBT.java b/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/NBT.java deleted file mode 100644 index 30d561e7..00000000 --- a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/NBT.java +++ /dev/null @@ -1,126 +0,0 @@ -package org.dynmap.fabric_1_19_3; - -import org.dynmap.common.chunk.GenericBitStorage; -import org.dynmap.common.chunk.GenericNBTCompound; -import org.dynmap.common.chunk.GenericNBTList; - -import java.util.Set; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.nbt.NbtList; -import net.minecraft.util.collection.PackedIntegerArray; - -public class NBT { - - public static class NBTCompound implements GenericNBTCompound { - private final NbtCompound obj; - public NBTCompound(NbtCompound t) { - this.obj = t; - } - @Override - public Set getAllKeys() { - return obj.getKeys(); - } - @Override - public boolean contains(String s) { - return obj.contains(s); - } - @Override - public boolean contains(String s, int i) { - return obj.contains(s, i); - } - @Override - public byte getByte(String s) { - return obj.getByte(s); - } - @Override - public short getShort(String s) { - return obj.getShort(s); - } - @Override - public int getInt(String s) { - return obj.getInt(s); - } - @Override - public long getLong(String s) { - return obj.getLong(s); - } - @Override - public float getFloat(String s) { - return obj.getFloat(s); - } - @Override - public double getDouble(String s) { - return obj.getDouble(s); - } - @Override - public String getString(String s) { - return obj.getString(s); - } - @Override - public byte[] getByteArray(String s) { - return obj.getByteArray(s); - } - @Override - public int[] getIntArray(String s) { - return obj.getIntArray(s); - } - @Override - public long[] getLongArray(String s) { - return obj.getLongArray(s); - } - @Override - public GenericNBTCompound getCompound(String s) { - return new NBTCompound(obj.getCompound(s)); - } - @Override - public GenericNBTList getList(String s, int i) { - return new NBTList(obj.getList(s, i)); - } - @Override - public boolean getBoolean(String s) { - return obj.getBoolean(s); - } - @Override - public String getAsString(String s) { - return obj.get(s).asString(); - } - @Override - public GenericBitStorage makeBitStorage(int bits, int count, long[] data) { - return new OurBitStorage(bits, count, data); - } - public String toString() { - return obj.toString(); - } - } - public static class NBTList implements GenericNBTList { - private final NbtList obj; - public NBTList(NbtList t) { - obj = t; - } - @Override - public int size() { - return obj.size(); - } - @Override - public String getString(int idx) { - return obj.getString(idx); - } - @Override - public GenericNBTCompound getCompound(int idx) { - return new NBTCompound(obj.getCompound(idx)); - } - public String toString() { - return obj.toString(); - } - } - public static class OurBitStorage implements GenericBitStorage { - private final PackedIntegerArray bs; - public OurBitStorage(int bits, int count, long[] data) { - bs = new PackedIntegerArray(bits, count, data); - } - @Override - public int get(int idx) { - return bs.get(idx); - } - } -} diff --git a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/TaskRecord.java b/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/TaskRecord.java deleted file mode 100644 index 1a4cb981..00000000 --- a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/TaskRecord.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.dynmap.fabric_1_19_3; - -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.19.3/src/main/java/org/dynmap/fabric_1_19_3/VersionCheck.java b/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/VersionCheck.java deleted file mode 100644 index bd72963e..00000000 --- a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/VersionCheck.java +++ /dev/null @@ -1,98 +0,0 @@ -package org.dynmap.fabric_1_19_3; - -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.19.3/src/main/java/org/dynmap/fabric_1_19_3/access/ProtoChunkAccessor.java b/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/access/ProtoChunkAccessor.java deleted file mode 100644 index d3b81783..00000000 --- a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/access/ProtoChunkAccessor.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.dynmap.fabric_1_19_3.access; - -public interface ProtoChunkAccessor { - boolean getTouchedByWorldGen(); -} diff --git a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/command/DmapCommand.java b/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/command/DmapCommand.java deleted file mode 100644 index ad06ae3d..00000000 --- a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/command/DmapCommand.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.dynmap.fabric_1_19_3.command; - -import org.dynmap.fabric_1_19_3.DynmapPlugin; - -public class DmapCommand extends DynmapCommandExecutor { - public DmapCommand(DynmapPlugin p) { - super("dmap", p); - } -} diff --git a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/command/DmarkerCommand.java b/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/command/DmarkerCommand.java deleted file mode 100644 index 9de454db..00000000 --- a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/command/DmarkerCommand.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.dynmap.fabric_1_19_3.command; - -import org.dynmap.fabric_1_19_3.DynmapPlugin; - -public class DmarkerCommand extends DynmapCommandExecutor { - public DmarkerCommand(DynmapPlugin p) { - super("dmarker", p); - } -} diff --git a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/command/DynmapCommand.java b/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/command/DynmapCommand.java deleted file mode 100644 index 619f5d75..00000000 --- a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/command/DynmapCommand.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.dynmap.fabric_1_19_3.command; - -import org.dynmap.fabric_1_19_3.DynmapPlugin; - -public class DynmapCommand extends DynmapCommandExecutor { - public DynmapCommand(DynmapPlugin p) { - super("dynmap", p); - } -} diff --git a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/command/DynmapCommandExecutor.java b/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/command/DynmapCommandExecutor.java deleted file mode 100644 index bb79b509..00000000 --- a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/command/DynmapCommandExecutor.java +++ /dev/null @@ -1,63 +0,0 @@ -package org.dynmap.fabric_1_19_3.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_19_3.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.19.3/src/main/java/org/dynmap/fabric_1_19_3/command/DynmapExpCommand.java b/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/command/DynmapExpCommand.java deleted file mode 100644 index 3392672d..00000000 --- a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/command/DynmapExpCommand.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.dynmap.fabric_1_19_3.command; - -import org.dynmap.fabric_1_19_3.DynmapPlugin; - -public class DynmapExpCommand extends DynmapCommandExecutor { - public DynmapExpCommand(DynmapPlugin p) { - super("dynmapexp", p); - } -} diff --git a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/event/BlockEvents.java b/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/event/BlockEvents.java deleted file mode 100644 index 6077f042..00000000 --- a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/event/BlockEvents.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.dynmap.fabric_1_19_3.event; - -import net.fabricmc.fabric.api.event.Event; -import net.fabricmc.fabric.api.event.EventFactory; -import net.minecraft.block.Material; -import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; - -public class BlockEvents { - private BlockEvents() { - } - - public static Event BLOCK_EVENT = EventFactory.createArrayBacked(BlockCallback.class, - (listeners) -> (world, pos) -> { - for (BlockCallback callback : listeners) { - callback.onBlockEvent(world, pos); - } - } - ); - - public static Event SIGN_CHANGE_EVENT = EventFactory.createArrayBacked(SignChangeCallback.class, - (listeners) -> (world, pos, lines, material, player) -> { - for (SignChangeCallback callback : listeners) { - callback.onSignChange(world, pos, lines, material, player); - } - } - ); - - @FunctionalInterface - public interface BlockCallback { - void onBlockEvent(World world, BlockPos pos); - } - - @FunctionalInterface - public interface SignChangeCallback { - void onSignChange(ServerWorld world, BlockPos pos, String[] lines, Material material, ServerPlayerEntity player); - } -} diff --git a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/event/CustomServerChunkEvents.java b/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/event/CustomServerChunkEvents.java deleted file mode 100644 index ec73e63d..00000000 --- a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/event/CustomServerChunkEvents.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.dynmap.fabric_1_19_3.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 CustomServerChunkEvents { - public static Event CHUNK_GENERATE = EventFactory.createArrayBacked(ChunkGenerate.class, - (listeners) -> (world, chunk) -> { - for (ChunkGenerate callback : listeners) { - callback.onChunkGenerate(world, chunk); - } - } - ); - - @FunctionalInterface - public interface ChunkGenerate { - void onChunkGenerate(ServerWorld world, Chunk chunk); - } -} \ No newline at end of file diff --git a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/event/CustomServerLifecycleEvents.java b/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/event/CustomServerLifecycleEvents.java deleted file mode 100644 index 52dab481..00000000 --- a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/event/CustomServerLifecycleEvents.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.dynmap.fabric_1_19_3.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.19.3/src/main/java/org/dynmap/fabric_1_19_3/event/PlayerEvents.java b/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/event/PlayerEvents.java deleted file mode 100644 index b0c55d5a..00000000 --- a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/event/PlayerEvents.java +++ /dev/null @@ -1,62 +0,0 @@ -package org.dynmap.fabric_1_19_3.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.19.3/src/main/java/org/dynmap/fabric_1_19_3/event/ServerChatEvents.java b/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/event/ServerChatEvents.java deleted file mode 100644 index a316a308..00000000 --- a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/event/ServerChatEvents.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.dynmap.fabric_1_19_3.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.19.3/src/main/java/org/dynmap/fabric_1_19_3/mixin/BiomeEffectsAccessor.java b/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/mixin/BiomeEffectsAccessor.java deleted file mode 100644 index dd6e5a2f..00000000 --- a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/mixin/BiomeEffectsAccessor.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.dynmap.fabric_1_19_3.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.19.3/src/main/java/org/dynmap/fabric_1_19_3/mixin/MinecraftServerMixin.java b/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/mixin/MinecraftServerMixin.java deleted file mode 100644 index f6c5f284..00000000 --- a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/mixin/MinecraftServerMixin.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.dynmap.fabric_1_19_3.mixin; - -import net.minecraft.server.MinecraftServer; -import org.dynmap.fabric_1_19_3.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.19.3/src/main/java/org/dynmap/fabric_1_19_3/mixin/PlayerManagerMixin.java b/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/mixin/PlayerManagerMixin.java deleted file mode 100644 index f42587de..00000000 --- a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/mixin/PlayerManagerMixin.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.dynmap.fabric_1_19_3.mixin; - -import net.minecraft.network.ClientConnection; -import net.minecraft.server.PlayerManager; -import net.minecraft.server.network.ServerPlayerEntity; -import org.dynmap.fabric_1_19_3.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.19.3/src/main/java/org/dynmap/fabric_1_19_3/mixin/ProtoChunkMixin.java b/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/mixin/ProtoChunkMixin.java deleted file mode 100644 index e8e5cc0b..00000000 --- a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/mixin/ProtoChunkMixin.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.dynmap.fabric_1_19_3.mixin; - -import net.minecraft.block.BlockState; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.chunk.ProtoChunk; -import org.dynmap.fabric_1_19_3.access.ProtoChunkAccessor; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(ProtoChunk.class) -public class ProtoChunkMixin implements ProtoChunkAccessor { - private boolean touchedByWorldGen = false; - - @Inject( - method = "setBlockState", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/world/chunk/ChunkSection;setBlockState(IIILnet/minecraft/block/BlockState;)Lnet/minecraft/block/BlockState;" - ) - ) - public void setBlockState(BlockPos pos, BlockState state, boolean moved, CallbackInfoReturnable info) { - touchedByWorldGen = true; - } - - public boolean getTouchedByWorldGen() { - return touchedByWorldGen; - } -} \ No newline at end of file diff --git a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/mixin/ServerPlayNetworkHandlerMixin.java b/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/mixin/ServerPlayNetworkHandlerMixin.java deleted file mode 100644 index 1e44112b..00000000 --- a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/mixin/ServerPlayNetworkHandlerMixin.java +++ /dev/null @@ -1,66 +0,0 @@ -package org.dynmap.fabric_1_19_3.mixin; - -import net.minecraft.block.BlockState; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.block.entity.SignBlockEntity; -import net.minecraft.network.message.SignedMessage; -import net.minecraft.network.packet.c2s.play.UpdateSignC2SPacket; -import net.minecraft.server.filter.FilteredMessage; -import net.minecraft.server.filter.TextStream; -import net.minecraft.server.network.ServerPlayNetworkHandler; -import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.text.LiteralTextContent; -import net.minecraft.text.Text; -import net.minecraft.util.math.BlockPos; - -import java.util.List; -import org.dynmap.fabric_1_19_3.event.BlockEvents; -import org.dynmap.fabric_1_19_3.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 = "handleDecoratedMessage", - at = @At( - value = "HEAD" - ) - ) - public void onGameMessage(SignedMessage signedMessage, CallbackInfo ci) { - ServerChatEvents.EVENT.invoker().onChatMessage(player, signedMessage.getContent().getString()); - } - - @Inject( - method = "onSignUpdate", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/block/entity/SignBlockEntity;markDirty()V", - shift = At.Shift.BEFORE - ), - locals = LocalCapture.CAPTURE_FAILHARD - ) - public void onSignUpdate(UpdateSignC2SPacket packet, List signText, CallbackInfo info, - ServerWorld serverWorld, BlockPos blockPos, BlockState blockState, BlockEntity blockEntity, SignBlockEntity signBlockEntity) - { - // Pull the raw text from the input. - String[] rawTexts = new String[4]; - for (int i=0; i info) { - ServerPlayerEntity player = (ServerPlayerEntity) (Object) this; - if (player.getRemovalReason() == null) { - PlayerEvents.PLAYER_CHANGED_DIMENSION.invoker().onPlayerChangedDimension(player); - } - } -} diff --git a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/mixin/ThreadedAnvilChunkStorageMixin.java b/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/mixin/ThreadedAnvilChunkStorageMixin.java deleted file mode 100644 index bc76ede7..00000000 --- a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/mixin/ThreadedAnvilChunkStorageMixin.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.dynmap.fabric_1_19_3.mixin; - -import net.minecraft.server.world.ChunkHolder; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.server.world.ThreadedAnvilChunkStorage; -import net.minecraft.world.chunk.Chunk; -import org.dynmap.fabric_1_19_3.access.ProtoChunkAccessor; -import org.dynmap.fabric_1_19_3.event.CustomServerChunkEvents; -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(value = ThreadedAnvilChunkStorage.class, priority = 666 /* fire before Fabric API CHUNK_LOAD event */) -public abstract class ThreadedAnvilChunkStorageMixin { - @Final - @Shadow - ServerWorld world; - - @Inject( - /* Same place as fabric-lifecycle-events-v1 event CHUNK_LOAD (we will fire before it) */ - method = "method_17227", - at = @At("TAIL") - ) - private void onChunkGenerate(ChunkHolder chunkHolder, Chunk protoChunk, CallbackInfoReturnable callbackInfoReturnable) { - if (((ProtoChunkAccessor)protoChunk).getTouchedByWorldGen()) { - CustomServerChunkEvents.CHUNK_GENERATE.invoker().onChunkGenerate(this.world, callbackInfoReturnable.getReturnValue()); - } - } -} \ No newline at end of file diff --git a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/mixin/WorldChunkMixin.java b/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/mixin/WorldChunkMixin.java deleted file mode 100644 index c63b1b19..00000000 --- a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/mixin/WorldChunkMixin.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.dynmap.fabric_1_19_3.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_19_3.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.BLOCK_EVENT.invoker().onBlockEvent(this.getWorld(), pos); - } - } -} diff --git a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/permissions/FabricPermissions.java b/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/permissions/FabricPermissions.java deleted file mode 100644 index 8f104e01..00000000 --- a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/permissions/FabricPermissions.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.dynmap.fabric_1_19_3.permissions; - -import me.lucko.fabric.api.permissions.v0.Permissions; -import net.minecraft.entity.player.PlayerEntity; -import org.dynmap.Log; -import org.dynmap.fabric_1_19_3.DynmapPlugin; -import org.dynmap.json.simple.parser.JSONParser; - -import java.util.Set; -import java.util.stream.Collectors; - -public class FabricPermissions implements PermissionProvider { - - private String permissionKey(String perm) { - return "dynmap." + perm; - } - - @Override - public Set hasOfflinePermissions(String player, Set perms) { - return perms.stream() - .filter(perm -> hasOfflinePermission(player, perm)) - .collect(Collectors.toSet()); - } - - @Override - public boolean hasOfflinePermission(String player, String perm) { - return DynmapPlugin.plugin.isOp(player.toLowerCase()); - } - - @Override - public boolean has(PlayerEntity player, String permission) { - if (player == null) return false; - String name = player.getName().getString().toLowerCase(); - if (DynmapPlugin.plugin.isOp(name)) return true; - return Permissions.check(player, permissionKey(permission)); - } - - @Override - public boolean hasPermissionNode(PlayerEntity player, String permission) { - if (player != null) { - String name = player.getName().getString().toLowerCase(); - return DynmapPlugin.plugin.isOp(name); - } - return false; - } - -} diff --git a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/permissions/FilePermissions.java b/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/permissions/FilePermissions.java deleted file mode 100644 index 89efd403..00000000 --- a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/permissions/FilePermissions.java +++ /dev/null @@ -1,103 +0,0 @@ -package org.dynmap.fabric_1_19_3.permissions; - -import net.minecraft.entity.player.PlayerEntity; -import org.dynmap.ConfigurationNode; -import org.dynmap.Log; -import org.dynmap.fabric_1_19_3.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.19.3/src/main/java/org/dynmap/fabric_1_19_3/permissions/LuckPermissions.java b/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/permissions/LuckPermissions.java deleted file mode 100644 index 96ba679a..00000000 --- a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/permissions/LuckPermissions.java +++ /dev/null @@ -1,102 +0,0 @@ -package org.dynmap.fabric_1_19_3.permissions; - -import me.lucko.fabric.api.permissions.v0.Permissions; -import net.luckperms.api.LuckPerms; -import net.luckperms.api.LuckPermsProvider; -import net.luckperms.api.cacheddata.CachedPermissionData; -import net.luckperms.api.model.user.User; -import net.luckperms.api.util.Tristate; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.server.MinecraftServer; -import org.dynmap.Log; -import org.dynmap.fabric_1_19_3.DynmapPlugin; -import org.dynmap.json.simple.JSONArray; -import org.dynmap.json.simple.JSONObject; -import org.dynmap.json.simple.parser.JSONParser; -import org.dynmap.json.simple.parser.ParseException; - -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.IOException; -import java.util.Optional; -import java.util.Set; -import java.util.UUID; -import java.util.stream.Collectors; - -public class LuckPermissions implements PermissionProvider { - - private final JSONParser parser = new JSONParser(); - private LuckPerms api = null; - - private Optional getApi() { - if (api != null) return Optional.of(api); - try { - api = LuckPermsProvider.get(); - return Optional.of(api); - } catch (Exception ex) { - Log.warning("Trying to access LuckPerms before it has loaded"); - return Optional.empty(); - } - } - - private Optional cachedUUID(String username) { - try { - BufferedReader reader = new BufferedReader(new FileReader("usercache.json")); - JSONArray cache = (JSONArray) parser.parse(reader); - for (Object it : cache) { - JSONObject user = (JSONObject) it; - if (user.get("name").toString().equalsIgnoreCase(username)) { - String uuid = user.get("uuid").toString(); - return Optional.of(UUID.fromString(uuid)); - } - } - - reader.close(); - } catch (IOException | ParseException ex) { - Log.warning("Unable to read usercache.json"); - } - - return Optional.empty(); - } - - private String permissionKey(String perm) { - return "dynmap." + perm; - } - - @Override - public Set hasOfflinePermissions(String player, Set perms) { - return perms.stream() - .filter(perm -> hasOfflinePermission(player, perm)) - .collect(Collectors.toSet()); - } - - @Override - public boolean hasOfflinePermission(String player, String perm) { - if (DynmapPlugin.plugin.isOp(player.toLowerCase())) return true; - Optional api = getApi(); - Optional uuid = cachedUUID(player); - if (!uuid.isPresent() || !api.isPresent()) return false; - User user = api.get().getUserManager().loadUser(uuid.get()).join(); - CachedPermissionData permissions = user.getCachedData().getPermissionData(); - Tristate state = permissions.checkPermission(permissionKey(perm)); - return state.asBoolean(); - } - - @Override - public boolean has(PlayerEntity player, String permission) { - if (player == null) return false; - String name = player.getName().getString().toLowerCase(); - if (DynmapPlugin.plugin.isOp(name)) return true; - return Permissions.check(player, permissionKey(permission)); - } - - @Override - public boolean hasPermissionNode(PlayerEntity player, String permission) { - if (player != null) { - String name = player.getName().getString().toLowerCase(); - return DynmapPlugin.plugin.isOp(name); - } - return false; - } - -} diff --git a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/permissions/OpPermissions.java b/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/permissions/OpPermissions.java deleted file mode 100644 index 2dd4c1b7..00000000 --- a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/permissions/OpPermissions.java +++ /dev/null @@ -1,52 +0,0 @@ -package org.dynmap.fabric_1_19_3.permissions; - -import net.minecraft.entity.player.PlayerEntity; -import org.dynmap.Log; -import org.dynmap.fabric_1_19_3.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.19.3/src/main/java/org/dynmap/fabric_1_19_3/permissions/PermissionProvider.java b/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/permissions/PermissionProvider.java deleted file mode 100644 index d2dc072c..00000000 --- a/fabric-1.19.3/src/main/java/org/dynmap/fabric_1_19_3/permissions/PermissionProvider.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.dynmap.fabric_1_19_3.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.19.3/src/main/resources/assets/dynmap/icon.png b/fabric-1.19.3/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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" - #aws_secret_access_key: "" - #prefix: "" - #override_endpoint: "" - -components: - - class: org.dynmap.ClientConfigurationComponent - - # Remember to change the following class to org.dynmap.JsonFileClientUpdateComponent when using an external web server. - - class: org.dynmap.InternalClientUpdateComponent - sendhealth: true - sendposition: true - allowwebchat: true - webchat-interval: 5 - hidewebchatip: false - trustclientname: false - includehiddenplayers: false - # (optional) if true, color codes in player display names are used - use-name-colors: false - # (optional) if true, player login IDs will be used for web chat when their IPs match - use-player-login-ip: true - # (optional) if use-player-login-ip is true, setting this to true will cause chat messages not matching a known player IP to be ignored - require-player-login-ip: false - # (optional) block player login IDs that are banned from chatting - block-banned-player-chat: true - # Require login for web-to-server chat (requires login-enabled: true) - webchat-requires-login: false - # If set to true, users must have dynmap.webchat permission in order to chat - webchat-permissions: false - # Limit length of single chat messages - chatlengthlimit: 256 - # # Optional - make players hidden when they are inside/underground/in shadows (#=light level: 0=full shadow,15=sky) - # hideifshadow: 4 - # # Optional - make player hidden when they are under cover (#=sky light level,0=underground,15=open to sky) - # hideifundercover: 14 - # # (Optional) if true, players that are crouching/sneaking will be hidden - hideifsneaking: false - # optional, if true, players that are in spectator mode will be hidden - hideifspectator: false - # If true, player positions/status is protected (login with ID with dynmap.playermarkers.seeall permission required for info other than self) - protected-player-info: false - # If true, hide players with invisibility potion effects active - hide-if-invisiblity-potion: true - # If true, player names are not shown on map, chat, list - hidenames: false - #- class: org.dynmap.JsonFileClientUpdateComponent - # writeinterval: 1 - # sendhealth: true - # sendposition: true - # allowwebchat: true - # webchat-interval: 5 - # hidewebchatip: false - # includehiddenplayers: false - # use-name-colors: false - # use-player-login-ip: false - # require-player-login-ip: false - # block-banned-player-chat: true - # hideifshadow: 0 - # hideifundercover: 0 - # hideifsneaking: false - # # Require login for web-to-server chat (requires login-enabled: true) - # webchat-requires-login: false - # # If set to true, users must have dynmap.webchat permission in order to chat - # webchat-permissions: false - # # Limit length of single chat messages - # chatlengthlimit: 256 - # hide-if-invisiblity-potion: true - # hidenames: false - - - class: org.dynmap.SimpleWebChatComponent - allowchat: true - # If true, web UI users can supply name for chat using 'playername' URL parameter. 'trustclientname' must also be set true. - allowurlname: false - - # Note: this component is needed for the dmarker commands, and for the Marker API to be available to other plugins - - class: org.dynmap.MarkersComponent - type: markers - showlabel: false - enablesigns: false - # Default marker set for sign markers - default-sign-set: markers - # (optional) add spawn point markers to standard marker layer - showspawn: true - spawnicon: world - spawnlabel: "Spawn" - # (optional) layer for showing offline player's positions (for 'maxofflinetime' minutes after logoff) - showofflineplayers: false - offlinelabel: "Offline" - offlineicon: offlineuser - offlinehidebydefault: true - offlineminzoom: 0 - maxofflinetime: 30 - # (optional) layer for showing player's spawn beds - showspawnbeds: false - spawnbedlabel: "Spawn Beds" - spawnbedicon: bed - spawnbedhidebydefault: true - spawnbedminzoom: 0 - spawnbedformat: "%name%'s bed" - # (optional) Show world border (vanilla 1.8+) - showworldborder: true - worldborderlabel: "Border" - - - class: org.dynmap.ClientComponent - type: chat - allowurlname: false - - class: org.dynmap.ClientComponent - type: chatballoon - focuschatballoons: false - - class: org.dynmap.ClientComponent - type: chatbox - showplayerfaces: true - messagettl: 5 - # Optional: set number of lines in scrollable message history: if set, messagettl is not used to age out messages - #scrollback: 100 - # Optional: set maximum number of lines visible for chatbox - #visiblelines: 10 - # Optional: send push button - sendbutton: false - - class: org.dynmap.ClientComponent - type: playermarkers - showplayerfaces: true - showplayerhealth: true - # If true, show player body too (only valid if showplayerfaces=true) - showplayerbody: false - # Option to make player faces small - don't use with showplayerhealth or largeplayerfaces - smallplayerfaces: false - # Option to make player faces larger - don't use with showplayerhealth or smallplayerfaces - largeplayerfaces: false - # Optional - make player faces layer hidden by default - hidebydefault: false - # Optional - ordering priority in layer menu (low goes before high - default is 0) - layerprio: 0 - # Optional - label for player marker layer (default is 'Players') - label: "Players" - - #- class: org.dynmap.ClientComponent - # type: digitalclock - - class: org.dynmap.ClientComponent - type: link - - - class: org.dynmap.ClientComponent - type: timeofdayclock - showdigitalclock: true - #showweather: true - # Mouse pointer world coordinate display - - class: org.dynmap.ClientComponent - type: coord - label: "Location" - hidey: false - show-mcr: false - show-chunk: false - - # Note: more than one logo component can be defined - #- class: org.dynmap.ClientComponent - # type: logo - # text: "Dynmap" - # #logourl: "images/block_surface.png" - # linkurl: "http://forums.bukkit.org/threads/dynmap.489/" - # # Valid positions: top-left, top-right, bottom-left, bottom-right - # position: bottom-right - - #- class: org.dynmap.ClientComponent - # type: inactive - # timeout: 1800 # in seconds (1800 seconds = 30 minutes) - # redirecturl: inactive.html - # #showmessage: 'You were inactive for too long.' - - #- class: org.dynmap.TestComponent - # stuff: "This is some configuration-value" - -# Treat hiddenplayers.txt as a whitelist for players to be shown on the map? (Default false) -display-whitelist: false - -# How often a tile gets rendered (in seconds). -renderinterval: 1 - -# How many tiles on update queue before accelerate render interval -renderacceleratethreshold: 60 - -# How often to render tiles when backlog is above renderacceleratethreshold -renderaccelerateinterval: 0.2 - -# How many update tiles to work on at once (if not defined, default is 1/2 the number of cores) -tiles-rendered-at-once: 2 - -# If true, use normal priority threads for rendering (versus low priority) - this can keep rendering -# from starving on busy Windows boxes (Linux JVMs pretty much ignore thread priority), but may result -# in more competition for CPU resources with other processes -usenormalthreadpriority: true - -# Save and restore pending tile renders - prevents their loss on server shutdown or /reload -saverestorepending: true - -# Save period for pending jobs (in seconds): periodic saving for crash recovery of jobs -save-pending-period: 900 - -# Zoom-out tile update period - how often to scan for and process tile updates into zoom-out tiles (in seconds) -zoomoutperiod: 30 - -# Control whether zoom out tiles are validated on startup (can be needed if zoomout processing is interrupted, but can be expensive on large maps) -initial-zoomout-validate: true - -# Default delay on processing of updated tiles, in seconds. This can reduce potentially expensive re-rendering -# of frequently updated tiles (such as due to machines, pistons, quarries or other automation). Values can -# also be set on individual worlds and individual maps. -tileupdatedelay: 30 - -# Tile hashing is used to minimize tile file updates when no changes have occurred - set to false to disable -enabletilehash: true - -# Optional - hide ores: render as normal stone (so that they aren't revealed by maps) -#hideores: true - -# Optional - enabled BetterGrass style rendering of grass and snow block sides -#better-grass: true - -# Optional - enable smooth lighting by default on all maps supporting it (can be set per map as lighting option) -smooth-lighting: true - -# Optional - use world provider lighting table (good for custom worlds with custom lighting curves, like nether) -# false=classic Dynmap lighting curve -use-brightness-table: true - -# Optional - render specific block names using the textures and models of another block name: can be used to hide/disguise specific -# blocks (e.g. make ores look like stone, hide chests) or to provide simple support for rendering unsupported custom blocks -block-alias: -# "minecraft:quartz_ore": "stone" -# "diamond_ore": "coal_ore" - -# Default image format for HDMaps (png, jpg, jpg-q75, jpg-q80, jpg-q85, jpg-q90, jpg-q95, jpg-q100, webp, webp-q75, webp-q80, webp-q85, webp-q90, webp-q95, webp-q100, webp-l), -# Note: any webp format requires the presence of the 'webp command line tools' (cwebp, dwebp) (https://developers.google.com/speed/webp/download) -# -# Has no effect on maps with explicit format settings -image-format: jpg-q90 - -# If cwebp or dwebp are not on the PATH, use these settings to provide their full path. Do not use these settings if the tools are on the PATH -# For Windows, include .exe -# -#cwebpPath: /usr/bin/cwebp -#dwebpPath: /usr/bin/dwebp - -# use-generated-textures: if true, use generated textures (same as client); false is static water/lava textures -# correct-water-lighting: if true, use corrected water lighting (same as client); false is legacy water (darker) -# transparent-leaves: if true, leaves are transparent (lighting-wise): false is needed for some Spout versions that break lighting on leaf blocks -use-generated-textures: true -correct-water-lighting: true -transparent-leaves: true - -# ctm-support: if true, Connected Texture Mod (CTM) in texture packs is enabled (default) -ctm-support: true -# custom-colors-support: if true, Custom Colors in texture packs is enabled (default) -custom-colors-support: true - -# Control loading of player faces (if set to false, skins are never fetched) -#fetchskins: false - -# Control updating of player faces, once loaded (if faces are being managed by other apps or manually) -#refreshskins: false - -# Customize URL used for fetching player skins (%player% is macro for name, %uuid% for UUID) -skin-url: "http://skins.minecraft.net/MinecraftSkins/%player%.png" - -# Control behavior for new (1.0+) compass orientation (sunrise moved 90 degrees: east is now what used to be south) -# default is 'newrose' (preserve pre-1.0 maps, rotate rose) -# 'newnorth' is used to rotate maps and rose (requires fullrender of any HDMap map - same as 'newrose' for FlatMap or KzedMap) -compass-mode: newnorth - -# Triggers for automatic updates : blockupdate-with-id is debug for breaking down updates by ID:meta -# To disable, set just 'none' and comment/delete the rest -render-triggers: - - blockupdate - #- blockupdate-with-id - - chunkgenerate - #- none - -# Title for the web page - if not specified, defaults to the server's name (unless it is the default of 'Unknown Server') -#webpage-title: "My Awesome Server Map" - -# The path where the tile-files are placed. -tilespath: web/tiles - -# The path where the web-files are located. -webpath: web - -# If set to false, disable extraction of webpath content (good if using custom web UI or 3rd party web UI) -# Note: web interface is unsupported in this configuration - you're on your own -update-webpath-files: true - -# The path were the /dynmapexp command exports OBJ ZIP files -exportpath: export - -# The path where files can be imported for /dmarker commands -importpath: import - -# The network-interface the webserver will bind to (0.0.0.0 for all interfaces, 127.0.0.1 for only local access). -# If not set, uses same setting as server in server.properties (or 0.0.0.0 if not specified) -#webserver-bindaddress: 0.0.0.0 - -# The TCP-port the webserver will listen on. -webserver-port: 8123 - -# Maximum concurrent session on internal web server - limits resources used in Bukkit server -max-sessions: 30 - -# Disables Webserver portion of Dynmap (Advanced users only) -disable-webserver: false - -# Enable/disable having the web server allow symbolic links (true=compatible with existing code, false=more secure (default)) -allow-symlinks: true - -# Enable login support -login-enabled: false -# Require login to access website (requires login-enabled: true) -login-required: false - -# Period between tile renders for fullrender, in seconds (non-zero to pace fullrenders, lessen CPU load) -timesliceinterval: 0.0 - -# Maximum chunk loads per server tick (1/20th of a second) - reducing this below 90 will impact render performance, but also will reduce server thread load -maxchunkspertick: 200 - -# Progress report interval for fullrender/radiusrender, in tiles. Must be 100 or greater -progressloginterval: 100 - -# Parallel fullrender: if defined, number of concurrent threads used for fullrender or radiusrender -# Note: setting this will result in much more intensive CPU use, some additional memory use. Caution should be used when -# setting this to equal or exceed the number of physical cores on the system. -#parallelrendercnt: 4 - -# Interval the browser should poll for updates. -updaterate: 2000 - -# If nonzero, server will pause fullrender/radiusrender processing when 'fullrenderplayerlimit' or more users are logged in -fullrenderplayerlimit: 0 -# If nonzero, server will pause update render processing when 'updateplayerlimit' or more users are logged in -updateplayerlimit: 0 -# Target limit on server thread use - msec per tick -per-tick-time-limit: 50 -# If TPS of server is below this setting, update renders processing is paused -update-min-tps: 18.0 -# If TPS of server is below this setting, full/radius renders processing is paused -fullrender-min-tps: 18.0 -# If TPS of server is below this setting, zoom out processing is paused -zoomout-min-tps: 18.0 - -showplayerfacesinmenu: true - -# Control whether players that are hidden or not on current map are grayed out (true=yes) -grayplayerswhenhidden: true - -# Set sidebaropened: 'true' to pin menu sidebar opened permanently, 'pinned' to default the sidebar to pinned, but allow it to unpin -#sidebaropened: true - -# Customized HTTP response headers - add 'id: value' pairs to all HTTP response headers (internal web server only) -#http-response-headers: -# Access-Control-Allow-Origin: "my-domain.com" -# X-Custom-Header-Of-Mine: "MyHeaderValue" - -# Trusted proxies for web server - which proxy addresses are trusted to supply valid X-Forwarded-For fields -# This now supports both IP address, and subnet ranges (e.g. 192.168.1.0/24 or 202.24.0.0/14 ) -trusted-proxies: - - "127.0.0.1" - - "0:0:0:0:0:0:0:1" - -joinmessage: "%playername% joined" -quitmessage: "%playername% quit" -spammessage: "You may only chat once every %interval% seconds." -# format for messages from web: %playername% substitutes sender ID (typically IP), %message% includes text -webmsgformat: "&color;2[WEB] %playername%: &color;f%message%" - -# Control whether layer control is presented on the UI (default is true) -showlayercontrol: true - -# Enable checking for banned IPs via banned-ips.txt (internal web server only) -check-banned-ips: true - -# Default selection when map page is loaded -defaultzoom: 0 -defaultworld: world -defaultmap: flat -# (optional) Zoom level and map to switch to when following a player, if possible -#followzoom: 3 -#followmap: surface - -# If true, make persistent record of IP addresses used by player logins, to support web IP to player matching -persist-ids-by-ip: true - -# If true, map text to cyrillic -cyrillic-support: false - -# Messages to customize -msg: - maptypes: "Map Types" - players: "Players" - chatrequireslogin: "Chat Requires Login" - chatnotallowed: "You are not permitted to send chat messages" - hiddennamejoin: "Player joined" - hiddennamequit: "Player quit" - -# URL for client configuration (only need to be tailored for proxies or other non-standard configurations) -url: - # configuration URL - #configuration: "up/configuration" - # update URL - #update: "up/world/{world}/{timestamp}" - # sendmessage URL - #sendmessage: "up/sendmessage" - # login URL - #login: "up/login" - # register URL - #register: "up/register" - # tiles base URL - #tiles: "tiles/" - # markers base URL - #markers: "tiles/" - # Snapshot cache size, in chunks -snapshotcachesize: 500 -# Snapshot cache uses soft references (true), else weak references (false) -soft-ref-cache: true - -# Player enter/exit title messages for map markers -# -# Processing period - how often to check player positions vs markers - default is 1000ms (1 second) -#enterexitperiod: 1000 -# Title message fade in time, in ticks (0.05 second intervals) - default is 10 (1/2 second) -#titleFadeIn: 10 -# Title message stay time, in ticks (0.05 second intervals) - default is 70 (3.5 seconds) -#titleStay: 70 -# Title message fade out time, in ticks (0.05 seocnd intervals) - default is 20 (1 second) -#titleFadeOut: 20 -# Enter/exit messages use on screen titles (true - default), if false chat messages are sent instead -#enterexitUseTitle: true -# Set true if new enter messages should supercede pending exit messages (vs being queued in order), default false -#enterReplacesExits: true - -# Published public URL for Dynmap server (allows users to use 'dynmap url' command to get public URL usable to access server -# If not set, 'dynmap url' will not return anything. URL should be fully qualified (e.g. https://mc.westeroscraft.com/) -#publicURL: http://my.greatserver.com/dynmap - -# Set to true to enable verbose startup messages - can help with debugging map configuration problems -# Set to false for a much quieter startup log -verbose: false - -# Enables debugging. -#debuggers: -# - class: org.dynmap.debug.LogDebugger -# Debug: dump blocks missing render data -dump-missing-blocks: false - -# Log4J defense: string substituted for attempts to use macros in web chat -hackAttemptBlurb: "(IaM5uchA1337Haxr-Ban Me!)" diff --git a/fabric-1.19.3/src/main/resources/dynmap.mixins.json b/fabric-1.19.3/src/main/resources/dynmap.mixins.json deleted file mode 100644 index 2ab78ea5..00000000 --- a/fabric-1.19.3/src/main/resources/dynmap.mixins.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "required": true, - "minVersion": "0.8", - "package": "org.dynmap.fabric_1_19_3.mixin", - "compatibilityLevel": "JAVA_17", - "mixins": [ - "BiomeEffectsAccessor", - "MinecraftServerMixin", - "PlayerManagerMixin", - "ProtoChunkMixin", - "ServerPlayerEntityMixin", - "ServerPlayNetworkHandlerMixin", - "ThreadedAnvilChunkStorageMixin", - "WorldChunkMixin" - ], - "injectors": { - "defaultRequire": 1 - } -} diff --git a/fabric-1.19.3/src/main/resources/fabric.mod.json b/fabric-1.19.3/src/main/resources/fabric.mod.json deleted file mode 100644 index d4326a70..00000000 --- a/fabric-1.19.3/src/main/resources/fabric.mod.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "schemaVersion": 1, - "id": "dynmap", - "version": "${version}", - "name": "Dynmap", - "description": "Dynamic, Google-maps style rendered maps for your Minecraft server", - "authors": [ - "mikeprimm", - "LolHens", - "i509VCB" - ], - "contact": { - "homepage": "https://github.com/webbukkit/dynmap", - "sources": "https://github.com/webbukkit/dynmap" - }, - "license": "Apache-2.0", - "icon": "assets/dynmap/icon.png", - "environment": "*", - "entrypoints": { - "main": [ - "org.dynmap.fabric_1_19_3.DynmapMod" - ] - }, - "mixins": [ - "dynmap.mixins.json" - ], - - "depends": { - "fabricloader": ">=0.14.11", - "fabric": ">=0.68.1", - "minecraft": ["1.19.3"] - } -} diff --git a/fabric-1.19.3/src/main/resources/permissions.yml.example b/fabric-1.19.3/src/main/resources/permissions.yml.example deleted file mode 100644 index a25f9adc..00000000 --- a/fabric-1.19.3/src/main/resources/permissions.yml.example +++ /dev/null @@ -1,27 +0,0 @@ -# -# Sample permissions.yml for dynmap - trivial, flat-file based permissions for dynmap features -# To use, copy this file to dynmap/permissions.yml, and edit appropriate. File is YAML format. -# -# All operators have full permissions to all functions. -# All users receive the permissions under the 'defaultuser' section -# Specific users can be given more permissions by defining a section with their name containing their permisssions -# All permissions correspond to those documented here (https://github.com/webbukkit/dynmap/wiki/Permissions), but -# do NOT have the 'dynmap.' prefix when used here (e.g. 'dynmap.fullrender' permission is just 'fullrender' here). -# -defaultuser: - - render - - show.self - - hide.self - - sendtoweb - - stats - - marker.list - - marker.listsets - - marker.icons - - webregister - - webchat - #- marker.sign - -#playername1: -# - fullrender -# - cancelrender -# - radiusrender diff --git a/fabric-1.19/.gitignore b/fabric-1.19/.gitignore deleted file mode 100644 index 8b87af68..00000000 --- a/fabric-1.19/.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.19/build.gradle b/fabric-1.19/build.gradle deleted file mode 100644 index 6bbedfaf..00000000 --- a/fabric-1.19/build.gradle +++ /dev/null @@ -1,69 +0,0 @@ -plugins { - id 'fabric-loom' version '1.1.10' -} - -archivesBaseName = "Dynmap" -version = parent.version -group = parent.group - -eclipse { - project { - name = "Dynmap(Fabric-1.19)" - } -} - -sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = JavaLanguageVersion.of(17) // Need this here so eclipse task generates correctly. - -configurations { - shadow - implementation.extendsFrom(shadow) -} - -repositories { - mavenCentral() - maven { url 'https://oss.sonatype.org/content/repositories/snapshots' } -} - -dependencies { - minecraft "com.mojang:minecraft:${project.minecraft_version}" - mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" - modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" - 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') - - modCompileOnly "me.lucko:fabric-permissions-api:0.1-SNAPSHOT" - compileOnly 'net.luckperms:api:5.4' -} - -processResources { - filesMatching('fabric.mod.json') { - expand "version": project.version - } -} - -java { - // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task - // if it is present. - // If you remove this line, sources will not be generated. - withSourcesJar() -} - -jar { - from "LICENSE" - from { - configurations.shadow.collect { it.toString().contains("guava") ? null : it.isDirectory() ? it : zipTree(it) } - } -} - -remapJar { - archiveFileName = "${archivesBaseName}-${project.version}-fabric-${project.minecraft_version}.jar" - destinationDirectory = file '../target' -} - -remapJar.doLast { - task -> - ant.checksum file: task.archivePath -} diff --git a/fabric-1.19/gradle.properties b/fabric-1.19/gradle.properties deleted file mode 100644 index 20c5066a..00000000 --- a/fabric-1.19/gradle.properties +++ /dev/null @@ -1,4 +0,0 @@ -minecraft_version=1.19 -yarn_mappings=1.19+build.1 -loader_version=0.14.6 -fabric_version=0.55.2+1.19 diff --git a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/DynmapMod.java b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/DynmapMod.java deleted file mode 100644 index 3bcf5f32..00000000 --- a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/DynmapMod.java +++ /dev/null @@ -1,50 +0,0 @@ -package org.dynmap.fabric_1_19; - -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.19/src/main/java/org/dynmap/fabric_1_19/DynmapPlugin.java b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/DynmapPlugin.java deleted file mode 100644 index 1b84835e..00000000 --- a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/DynmapPlugin.java +++ /dev/null @@ -1,800 +0,0 @@ -package org.dynmap.fabric_1_19; - -import com.mojang.brigadier.CommandDispatcher; -import com.mojang.brigadier.exceptions.CommandSyntaxException; -import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; -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.fabricmc.loader.api.FabricLoader; -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.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.EmptyBlockView; -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 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.common.chunk.GenericChunkCache; -import org.dynmap.fabric_1_19.command.DmapCommand; -import org.dynmap.fabric_1_19.command.DmarkerCommand; -import org.dynmap.fabric_1_19.command.DynmapCommand; -import org.dynmap.fabric_1_19.command.DynmapExpCommand; -import org.dynmap.fabric_1_19.event.BlockEvents; -import org.dynmap.fabric_1_19.event.CustomServerChunkEvents; -import org.dynmap.fabric_1_19.event.CustomServerLifecycleEvents; -import org.dynmap.fabric_1_19.event.PlayerEvents; -import org.dynmap.fabric_1_19.mixin.BiomeEffectsAccessor; -import org.dynmap.fabric_1_19.permissions.*; -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 GenericChunkCache 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(); - private HashMap worlds = new HashMap(); - private WorldAccess last_world; - private FabricWorld last_fworld; - private Map players = new HashMap(); - 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 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, registryAccess, environment) -> 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; - - /** - * 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(); - DynmapBlockState.Builder bld = new DynmapBlockState.Builder(); - while (iter.hasNext()) { - BlockState bs = iter.next(); - int idx = bsids.getRawId(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(); - } - int lightAtten = bs.isOpaqueFullCube(EmptyBlockView.INSTANCE, BlockPos.ORIGIN) ? 15 : (bs.isTranslucent(EmptyBlockView.INSTANCE, BlockPos.ORIGIN) ? 0 : 1); - //Log.info("statename=" + bn + "[" + statename + "], lightAtten=" + lightAtten); - // Fill in base attributes - bld.setBaseState(basebs).setStateIndex(idx - baseidx).setBlockName(bn).setStateName(statename).setMaterial(mat.toString()).setLegacyBlockID(idx).setAttenuatesLight(lightAtten); - if (mat.isSolid()) { bld.setSolid(); } - if (mat == Material.AIR) { bld.setAir(); } - if (mat == Material.WOOD) { bld.setLog(); } - if (mat == Material.LEAVES) { bld.setLeaves(); } - if ((!bs.getFluidState().isEmpty()) && !(bs.getBlock() instanceof FluidBlock)) { - bld.setWaterlogged(); - } - DynmapBlockState dbs = bld.build(); // Build state - stateByID[idx] = dbs; - if (basebs == null) { basebs = dbs; } - } - } -// 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); - } - - 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); - } - } - } - - public FabricServer getFabricServer() { - return fserver; - } - - 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() && server.isHost(server.getPlayerManager().getPlayer(player).getGameProfile()); - } - - boolean hasPerm(PlayerEntity psender, String permission) { - PermissionsHandler ph = PermissionsHandler.getHandler(); - if ((ph != null) && (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 ((ph != null) && (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); - - Registry biomeRegistry = getFabricServer().getBiomeRegistry(); - Biome[] list = getFabricServer().getBiomeList(biomeRegistry); - - for (int i = 0; i < list.length; i++) { - Biome bb = list[i]; - if (bb != null) { - String id = biomeRegistry.getId(bb).getPath(); - String rl = biomeRegistry.getId(bb).toString(); - float tmp = bb.getTemperature(), hum = bb.getDownfall(); - int watermult = ((BiomeEffectsAccessor) bb.getEffects()).getWaterColor(); - Log.verboseinfo("biome[" + i + "]: hum=" + hum + ", tmp=" + tmp + ", mult=" + Integer.toHexString(watermult)); - - BiomeMap bmap = BiomeMap.NULL; - if (rl != null) { // If resource location, lookup by this - bmap = BiomeMap.byBiomeResourceLocation(rl); - } - else { - bmap = BiomeMap.byBiomeID(i); - } - if (bmap.isDefault() || (bmap == BiomeMap.NULL)) { - bmap = new BiomeMap((rl != null) ? BiomeMap.NO_INDEX : i, id, tmp, hum, rl); - 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)); - } - bmap.setBiomeObject(bb); - } - } - if (cnt > 0) - Log.info("Added " + cnt + " custom biome mappings"); - } - - private String[] getBiomeNames() { - Registry biomeRegistry = getFabricServer().getBiomeRegistry(); - Biome[] list = getFabricServer().getBiomeList(biomeRegistry); - String[] lst = new String[list.length]; - for (int i = 0; i < list.length; i++) { - Biome bb = list[i]; - if (bb != null) { - lst[i] = biomeRegistry.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 */ - if (FabricLoader.getInstance().isModLoaded("luckperms")) { - Log.info("Using luckperms for access control"); - permissions = new LuckPermissions(); - } - else if (FabricLoader.getInstance().isModLoaded("fabric-permissions-api-v0")) { - Log.info("Using fabric-permissions-api for access control"); - permissions = new FabricPermissions(); - } else { - /* 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); - 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 GenericChunkCache(core.getSnapShotCacheSize(), core.useSoftRefInSnapShotCache()); - /* Get map manager from core */ - mapManager = core.getMapManager(); - - /* Load saved world definitions */ - loadWorlds(); - - 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.getPlayerOrThrow(); - } - - 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 handleChunkGenerate(ServerWorld world, Chunk chunk) { - if (!onchunkgenerate) return; - - FabricWorld fw = getWorld(world, false); - ChunkPos chunkPos = chunk.getPos(); - - int ymax = Integer.MIN_VALUE; - int ymin = Integer.MAX_VALUE; - ChunkSection[] sections = chunk.getSectionArray(); - for (int i = 0; i < sections.length; i++) { - if ((sections[i] != null) && (!sections[i].isEmpty())) { - int sy = sections[i].getYOffset(); - if (sy < ymin) ymin = sy; - if ((sy+16) > ymax) ymax = sy + 16; - } - } - if (ymax != Integer.MIN_VALUE) { - mapManager.touchVolume(fw.getName(), - chunkPos.getStartX(), ymin, chunkPos.getStartZ(), - chunkPos.getEndX(), ymax, chunkPos.getEndZ(), - "chunkgenerate"); - //Log.info("New generated chunk detected at %s[%s]".formatted(fw.getName(), chunkPos.getStartPos())); - } - } - - 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(world, 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) - worldTracker = new WorldTracker(); - if (onchunkpopulate || onchunkgenerate) { - CustomServerChunkEvents.CHUNK_GENERATE.register((world, chunk) -> worldTracker.handleChunkGenerate(world, chunk)); - } - if (onblockchange) { - BlockEvents.BLOCK_EVENT.register((world, pos) -> worldTracker.handleBlockEvent(world, pos)); - } - - ServerWorldEvents.LOAD.register((server, world) -> worldTracker.handleWorldLoad(server, world)); - ServerWorldEvents.UNLOAD.register((server, world) -> worldTracker.handleWorldUnload(server, world)); - } - - FabricWorld getWorldByName(String name) { - return worlds.get(name); - } - - FabricWorld getWorld(World w) { - return getWorld(w, true); - } - - private FabricWorld getWorld(World w, boolean add_if_not_found) { - if (last_world == w) { - return last_fworld; - } - String wname = FabricWorld.getWorldName(this, w); - - for (FabricWorld fw : worlds.values()) { - if (fw.getRawName().equals(wname)) { - last_world = w; - last_fworld = fw; - if (!fw.isLoaded()) { - fw.setWorldLoaded(w); - } - fw.updateWorld(w); - return fw; - } - } - FabricWorld fw = null; - if (add_if_not_found) { - /* Add to list if not found */ - fw = new FabricWorld(this, 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("miny", fw.minY); - 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"); - Integer miny = (Integer) world.get("miny"); - 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(this, name, height, sealevel, nether, theend, title, (miny != null) ? miny : 0); - 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; - } - } - } -} \ No newline at end of file diff --git a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/FabricAdapter.java b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/FabricAdapter.java deleted file mode 100644 index d10f7060..00000000 --- a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/FabricAdapter.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.dynmap.fabric_1_19; - -import net.minecraft.server.world.ServerWorld; -import org.dynmap.DynmapLocation; - -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.19/src/main/java/org/dynmap/fabric_1_19/FabricCommandSender.java b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/FabricCommandSender.java deleted file mode 100644 index b2bf4e49..00000000 --- a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/FabricCommandSender.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.dynmap.fabric_1_19; - -import net.minecraft.server.command.ServerCommandSource; -import net.minecraft.text.LiteralTextContent; -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 = Text.literal(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.19/src/main/java/org/dynmap/fabric_1_19/FabricLogger.java b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/FabricLogger.java deleted file mode 100644 index 0aeebc45..00000000 --- a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/FabricLogger.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.dynmap.fabric_1_19; - -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.19/src/main/java/org/dynmap/fabric_1_19/FabricMapChunkCache.java b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/FabricMapChunkCache.java deleted file mode 100644 index 41eed383..00000000 --- a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/FabricMapChunkCache.java +++ /dev/null @@ -1,116 +0,0 @@ -package org.dynmap.fabric_1_19; - -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.collection.PackedIntegerArray; -import net.minecraft.util.math.ChunkPos; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.WordPackedArray; -import net.minecraft.util.registry.Registry; -import net.minecraft.world.ChunkSerializer; -import net.minecraft.world.World; -import net.minecraft.world.biome.Biome; -import net.minecraft.world.biome.BiomeEffects; -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.common.chunk.GenericChunk; -import org.dynmap.common.chunk.GenericChunkSection; -import org.dynmap.common.chunk.GenericMapChunkCache; -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 GenericMapChunkCache { - private World w; - private ServerChunkManager cps; - - /** - * Construct empty cache - */ - public FabricMapChunkCache(DynmapPlugin plugin) { - super(plugin.sscache); - } - - public void setChunks(FabricWorld dw, List chunks) { - 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"); - } - } - super.setChunks(dw, chunks); - } - - // Load generic chunk from existing and already loaded chunk - protected GenericChunk getLoadedChunk(DynmapChunk chunk) { - GenericChunk gc = null; - if (cps.isChunkLoaded(chunk.x, chunk.z)) { - NbtCompound nbt = null; - try { - nbt = ChunkSerializer.serialize((ServerWorld) w, cps.getWorldChunk(chunk.x, chunk.z, false)); - } catch (NullPointerException e) { - // TODO: find out why this is happening and why it only seems to happen since 1.16.2 - Log.severe("ChunkSerializer.serialize threw a NullPointerException", e); - } - if (nbt != null) { - gc = parseChunkFromNBT(new NBT.NBTCompound(nbt)); - } - } - return gc; - } - - private NbtCompound readChunk(int x, int z) { - try { - ThreadedAnvilChunkStorage acl = cps.threadedAnvilChunkStorage; - - ChunkPos coord = new ChunkPos(x, z); - // Async chunk reading is synchronized here. Perhaps we can do async and improve performance? - return acl.getNbt(coord).join().orElse(null); - } catch (Exception exc) { - Log.severe(String.format("Error reading chunk: %s,%d,%d", dw.getName(), x, z), exc); - return null; - } - } - - // Load generic chunk from unloaded chunk - protected GenericChunk loadChunk(DynmapChunk chunk) { - GenericChunk gc = null; - NbtCompound nbt = readChunk(chunk.x, chunk.z); - // If read was good - if (nbt != null) { - gc = parseChunkFromNBT(new NBT.NBTCompound(nbt)); - } - return gc; - } - @Override - public int getFoliageColor(BiomeMap bm, int[] colormap, int x, int z) { - return bm.getBiomeObject().map(Biome::getEffects).flatMap(BiomeEffects::getFoliageColor).orElse(colormap[bm.biomeLookup()]); - } - - @Override - public int getGrassColor(BiomeMap bm, int[] colormap, int x, int z) { - BiomeEffects effects = bm.getBiomeObject().map(Biome::getEffects).orElse(null); - if (effects == null) return colormap[bm.biomeLookup()]; - return effects.getGrassColorModifier().getModifiedGrassColor(x, z, effects.getGrassColor().orElse(colormap[bm.biomeLookup()])); - } -} diff --git a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/FabricPlayer.java b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/FabricPlayer.java deleted file mode 100644 index d652df0f..00000000 --- a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/FabricPlayer.java +++ /dev/null @@ -1,258 +0,0 @@ -package org.dynmap.fabric_1_19; - -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.SubtitleS2CPacket; -import net.minecraft.network.packet.s2c.play.TitleFadeS2CPacket; -import net.minecraft.network.packet.s2c.play.TitleS2CPacket; -import net.minecraft.server.network.ServerPlayNetworkHandler; -import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.text.LiteralTextContent; -import net.minecraft.text.Text; -import net.minecraft.util.Util; -import net.minecraft.util.math.Vec3d; -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.Base64; -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.getDecoder().decode(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.getWorld(), 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 = Text.literal(msg); - player.sendMessage(ichatcomponent); - } - - @Override - public boolean isInvisible() { - if(player != null) { - return player.isInvisible(); - } - return false; - } - @Override - public boolean isSpectator() { - if(player != null) { - return player.isSpectator(); - } - 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; - TitleFadeS2CPacket times = new TitleFadeS2CPacket(fadeInTicks, stayTicks, fadeOutTicks); - player.networkHandler.sendPacket(times); - if (title != null) { - TitleS2CPacket titlepkt = new TitleS2CPacket(Text.literal(title)); - player.networkHandler.sendPacket(titlepkt); - } - - if (subtitle != null) { - SubtitleS2CPacket subtitlepkt = new SubtitleS2CPacket(Text.literal(subtitle)); - player.networkHandler.sendPacket(subtitlepkt); - } - } - } -} diff --git a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/FabricServer.java b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/FabricServer.java deleted file mode 100644 index 645dd540..00000000 --- a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/FabricServer.java +++ /dev/null @@ -1,609 +0,0 @@ -package org.dynmap.fabric_1_19; - -import com.mojang.authlib.GameProfile; -import net.fabricmc.loader.api.FabricLoader; -import net.fabricmc.loader.api.ModContainer; -import net.minecraft.block.AbstractSignBlock; -import net.minecraft.block.Block; -import net.minecraft.block.BlockState; -import net.minecraft.network.message.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.LiteralTextContent; -import net.minecraft.text.Text; -import net.minecraft.util.UserCache; -import net.minecraft.util.Util; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.registry.Registry; -import net.minecraft.world.World; -import net.minecraft.world.biome.Biome; -import org.dynmap.DynmapChunk; -import org.dynmap.DynmapWorld; -import org.dynmap.Log; -import org.dynmap.DynmapCommonAPIListener; -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_19.event.BlockEvents; -import org.dynmap.fabric_1_19.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.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 final Registry biomeRegistry; - 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; - this.biomeRegistry = server.getRegistryManager().get(Registry.BIOME_KEY); - } - - private Optional getProfileByName(String player) { - UserCache cache = server.getUserCache(); - return cache.findByName(player); - } - - public final Registry getBiomeRegistry() { - return biomeRegistry; - } - - private Biome[] biomelist = null; - - public final Biome[] getBiomeList(Registry biomeRegistry) { - if (biomelist == null) { - biomelist = new Biome[256]; - Iterator iter = biomeRegistry.iterator(); - while (iter.hasNext()) { - Biome b = iter.next(); - int bidx = biomeRegistry.getRawId(b); - if (bidx >= biomelist.length) { - biomelist = Arrays.copyOf(biomelist, bidx + biomelist.length); - } - biomelist[bidx] = b; - } - } - return biomelist; - } - - @Override - public int getBlockIDAt(String wname, int x, int y, int z) { - return -1; - } - - @SuppressWarnings("deprecation") /* Not much I can do... fix this if it breaks. */ - @Override - public int isSignAt(String wname, int x, int y, int z) { - World world = plugin.getWorldByName(wname).getWorld(); - - BlockPos pos = new BlockPos(x, y, z); - if (!world.isChunkLoaded(pos)) - return -1; - - Block block = world.getBlockState(pos).getBlock(); - return (block instanceof AbstractSignBlock ? 1 : 0); - } - - @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) { - PlayerManager scm = server.getPlayerManager(); - BannedPlayerList bl = scm.getUserBanList(); - try { - return bl.contains(getProfileByName(pid).get()); - } catch (NoSuchElementException e) { - /* If this profile doesn't exist, default to "banned" for good measure. */ - return true; - } - } - - @Override - public String stripChatColor(String s) { - return DynmapPlugin.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: - /* Already handled by BlockEvents logic */ - break; - - case SIGN_CHANGE: - BlockEvents.SIGN_CHANGE_EVENT.register((world, pos, lines, material, player) -> { - plugin.core.processSignChange("fabric", FabricWorld.getWorldName(plugin, world), - pos.getX(), pos.getY(), pos.getZ(), lines, player.getName().getString()); - }); - 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 = Text.literal(msg); - server.getPlayerManager().broadcast(component, MessageType.SYSTEM); - 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) { - if (isPlayerBanned(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) { - if (isPlayerBanned(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 (InterruptedException 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.getRawId(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 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.19/src/main/java/org/dynmap/fabric_1_19/FabricWorld.java b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/FabricWorld.java deleted file mode 100644 index 500d4cba..00000000 --- a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/FabricWorld.java +++ /dev/null @@ -1,236 +0,0 @@ -package org.dynmap.fabric_1_19; - -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.MathHelper; -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.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 final DynmapPlugin plugin; - private World 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 = 320; // Maximum allows world height - - public static int getMaxWorldHeight() { - return maxWorldHeight; - } - - public static void setMaxWorldHeight(int h) { - maxWorldHeight = h; - } - - public static String getWorldName(DynmapPlugin plugin, World w) { - RegistryKey rk = w.getRegistryKey(); - if (rk == World.OVERWORLD) { // Overworld? - return w.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 void updateWorld(World w) { - this.updateWorldHeights(w.getHeight(), w.getBottomY(), w.getSeaLevel()); - } - - public FabricWorld(DynmapPlugin plugin, World w) { - this(plugin, getWorldName(plugin, w), w.getHeight(), - w.getSeaLevel(), - w.getRegistryKey() == World.NETHER, - w.getRegistryKey() == World.END, - w.getRegistryKey().getValue().getPath(), - w.getBottomY()); - setWorldLoaded(w); - } - - public FabricWorld(DynmapPlugin plugin, String name, int height, int sealevel, boolean nether, boolean the_end, String deftitle, int miny) { - super(name, (height > maxWorldHeight) ? maxWorldHeight : height, sealevel, miny); - this.plugin = plugin; - 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.getTimeOfDay(); - else - return -1; - } - - /* World is storming */ - @Override - public boolean hasStorm() { - if (world != null) - return world.isRaining(); - else - return false; - } - - /* World is thundering */ - @Override - public boolean isThundering() { - if (world != null) - return world.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(World w) { - world = w; - this.sealevel = w.getSeaLevel(); // Read actual current sealevel from world - // Update lighting table - for (int lightLevel = 0; lightLevel < 16; lightLevel++) { - // Algorithm based on LightmapTextureManager.getBrightness() - // We can't call that method because it's client-only. - // This means the code below can stop being correct if Mojang ever - // updates the curve; in that case we should reflect the changes. - float value = (float) lightLevel / 15.0f; - float brightness = value / (4.0f - 3.0f * value); - this.setBrightnessTableEntry(lightLevel, MathHelper.lerp(w.getDimension().ambientLight(), brightness, 1.0F)); - } - } - - /* 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.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(plugin); - c.setChunks(this, chunks); - return c; - } - return null; - } - - public World getWorld() { - return world; - } - - @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.19/src/main/java/org/dynmap/fabric_1_19/NBT.java b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/NBT.java deleted file mode 100644 index 2f8b52a5..00000000 --- a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/NBT.java +++ /dev/null @@ -1,126 +0,0 @@ -package org.dynmap.fabric_1_19; - -import org.dynmap.common.chunk.GenericBitStorage; -import org.dynmap.common.chunk.GenericNBTCompound; -import org.dynmap.common.chunk.GenericNBTList; - -import java.util.Set; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.nbt.NbtList; -import net.minecraft.util.collection.PackedIntegerArray; - -public class NBT { - - public static class NBTCompound implements GenericNBTCompound { - private final NbtCompound obj; - public NBTCompound(NbtCompound t) { - this.obj = t; - } - @Override - public Set getAllKeys() { - return obj.getKeys(); - } - @Override - public boolean contains(String s) { - return obj.contains(s); - } - @Override - public boolean contains(String s, int i) { - return obj.contains(s, i); - } - @Override - public byte getByte(String s) { - return obj.getByte(s); - } - @Override - public short getShort(String s) { - return obj.getShort(s); - } - @Override - public int getInt(String s) { - return obj.getInt(s); - } - @Override - public long getLong(String s) { - return obj.getLong(s); - } - @Override - public float getFloat(String s) { - return obj.getFloat(s); - } - @Override - public double getDouble(String s) { - return obj.getDouble(s); - } - @Override - public String getString(String s) { - return obj.getString(s); - } - @Override - public byte[] getByteArray(String s) { - return obj.getByteArray(s); - } - @Override - public int[] getIntArray(String s) { - return obj.getIntArray(s); - } - @Override - public long[] getLongArray(String s) { - return obj.getLongArray(s); - } - @Override - public GenericNBTCompound getCompound(String s) { - return new NBTCompound(obj.getCompound(s)); - } - @Override - public GenericNBTList getList(String s, int i) { - return new NBTList(obj.getList(s, i)); - } - @Override - public boolean getBoolean(String s) { - return obj.getBoolean(s); - } - @Override - public String getAsString(String s) { - return obj.get(s).asString(); - } - @Override - public GenericBitStorage makeBitStorage(int bits, int count, long[] data) { - return new OurBitStorage(bits, count, data); - } - public String toString() { - return obj.toString(); - } - } - public static class NBTList implements GenericNBTList { - private final NbtList obj; - public NBTList(NbtList t) { - obj = t; - } - @Override - public int size() { - return obj.size(); - } - @Override - public String getString(int idx) { - return obj.getString(idx); - } - @Override - public GenericNBTCompound getCompound(int idx) { - return new NBTCompound(obj.getCompound(idx)); - } - public String toString() { - return obj.toString(); - } - } - public static class OurBitStorage implements GenericBitStorage { - private final PackedIntegerArray bs; - public OurBitStorage(int bits, int count, long[] data) { - bs = new PackedIntegerArray(bits, count, data); - } - @Override - public int get(int idx) { - return bs.get(idx); - } - } -} diff --git a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/TaskRecord.java b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/TaskRecord.java deleted file mode 100644 index 1c7e4440..00000000 --- a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/TaskRecord.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.dynmap.fabric_1_19; - -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.19/src/main/java/org/dynmap/fabric_1_19/VersionCheck.java b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/VersionCheck.java deleted file mode 100644 index 4b6f5bf5..00000000 --- a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/VersionCheck.java +++ /dev/null @@ -1,98 +0,0 @@ -package org.dynmap.fabric_1_19; - -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.19/src/main/java/org/dynmap/fabric_1_19/access/ProtoChunkAccessor.java b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/access/ProtoChunkAccessor.java deleted file mode 100644 index 350a250b..00000000 --- a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/access/ProtoChunkAccessor.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.dynmap.fabric_1_19.access; - -public interface ProtoChunkAccessor { - boolean getTouchedByWorldGen(); -} diff --git a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/command/DmapCommand.java b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/command/DmapCommand.java deleted file mode 100644 index d6907648..00000000 --- a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/command/DmapCommand.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.dynmap.fabric_1_19.command; - -import org.dynmap.fabric_1_19.DynmapPlugin; - -public class DmapCommand extends DynmapCommandExecutor { - public DmapCommand(DynmapPlugin p) { - super("dmap", p); - } -} diff --git a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/command/DmarkerCommand.java b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/command/DmarkerCommand.java deleted file mode 100644 index a5c31f02..00000000 --- a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/command/DmarkerCommand.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.dynmap.fabric_1_19.command; - -import org.dynmap.fabric_1_19.DynmapPlugin; - -public class DmarkerCommand extends DynmapCommandExecutor { - public DmarkerCommand(DynmapPlugin p) { - super("dmarker", p); - } -} diff --git a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/command/DynmapCommand.java b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/command/DynmapCommand.java deleted file mode 100644 index 698b847e..00000000 --- a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/command/DynmapCommand.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.dynmap.fabric_1_19.command; - -import org.dynmap.fabric_1_19.DynmapPlugin; - -public class DynmapCommand extends DynmapCommandExecutor { - public DynmapCommand(DynmapPlugin p) { - super("dynmap", p); - } -} diff --git a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/command/DynmapCommandExecutor.java b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/command/DynmapCommandExecutor.java deleted file mode 100644 index bb4fc01b..00000000 --- a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/command/DynmapCommandExecutor.java +++ /dev/null @@ -1,63 +0,0 @@ -package org.dynmap.fabric_1_19.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_19.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.19/src/main/java/org/dynmap/fabric_1_19/command/DynmapExpCommand.java b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/command/DynmapExpCommand.java deleted file mode 100644 index 29df91fc..00000000 --- a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/command/DynmapExpCommand.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.dynmap.fabric_1_19.command; - -import org.dynmap.fabric_1_19.DynmapPlugin; - -public class DynmapExpCommand extends DynmapCommandExecutor { - public DynmapExpCommand(DynmapPlugin p) { - super("dynmapexp", p); - } -} diff --git a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/event/BlockEvents.java b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/event/BlockEvents.java deleted file mode 100644 index 3fefe2fa..00000000 --- a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/event/BlockEvents.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.dynmap.fabric_1_19.event; - -import net.fabricmc.fabric.api.event.Event; -import net.fabricmc.fabric.api.event.EventFactory; -import net.minecraft.block.Material; -import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; - -public class BlockEvents { - private BlockEvents() { - } - - public static Event BLOCK_EVENT = EventFactory.createArrayBacked(BlockCallback.class, - (listeners) -> (world, pos) -> { - for (BlockCallback callback : listeners) { - callback.onBlockEvent(world, pos); - } - } - ); - - public static Event SIGN_CHANGE_EVENT = EventFactory.createArrayBacked(SignChangeCallback.class, - (listeners) -> (world, pos, lines, material, player) -> { - for (SignChangeCallback callback : listeners) { - callback.onSignChange(world, pos, lines, material, player); - } - } - ); - - @FunctionalInterface - public interface BlockCallback { - void onBlockEvent(World world, BlockPos pos); - } - - @FunctionalInterface - public interface SignChangeCallback { - void onSignChange(ServerWorld world, BlockPos pos, String[] lines, Material material, ServerPlayerEntity player); - } -} diff --git a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/event/CustomServerChunkEvents.java b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/event/CustomServerChunkEvents.java deleted file mode 100644 index ee756e20..00000000 --- a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/event/CustomServerChunkEvents.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.dynmap.fabric_1_19.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 CustomServerChunkEvents { - public static Event CHUNK_GENERATE = EventFactory.createArrayBacked(ChunkGenerate.class, - (listeners) -> (world, chunk) -> { - for (ChunkGenerate callback : listeners) { - callback.onChunkGenerate(world, chunk); - } - } - ); - - @FunctionalInterface - public interface ChunkGenerate { - void onChunkGenerate(ServerWorld world, Chunk chunk); - } -} \ No newline at end of file diff --git a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/event/CustomServerLifecycleEvents.java b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/event/CustomServerLifecycleEvents.java deleted file mode 100644 index b6385ddd..00000000 --- a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/event/CustomServerLifecycleEvents.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.dynmap.fabric_1_19.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.19/src/main/java/org/dynmap/fabric_1_19/event/PlayerEvents.java b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/event/PlayerEvents.java deleted file mode 100644 index fc02bd34..00000000 --- a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/event/PlayerEvents.java +++ /dev/null @@ -1,62 +0,0 @@ -package org.dynmap.fabric_1_19.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.19/src/main/java/org/dynmap/fabric_1_19/event/ServerChatEvents.java b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/event/ServerChatEvents.java deleted file mode 100644 index 6ab805c4..00000000 --- a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/event/ServerChatEvents.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.dynmap.fabric_1_19.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.19/src/main/java/org/dynmap/fabric_1_19/mixin/BiomeEffectsAccessor.java b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/mixin/BiomeEffectsAccessor.java deleted file mode 100644 index ab6e135c..00000000 --- a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/mixin/BiomeEffectsAccessor.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.dynmap.fabric_1_19.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.19/src/main/java/org/dynmap/fabric_1_19/mixin/MinecraftServerMixin.java b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/mixin/MinecraftServerMixin.java deleted file mode 100644 index 6eee0d55..00000000 --- a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/mixin/MinecraftServerMixin.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.dynmap.fabric_1_19.mixin; - -import net.minecraft.server.MinecraftServer; -import org.dynmap.fabric_1_19.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.19/src/main/java/org/dynmap/fabric_1_19/mixin/PlayerManagerMixin.java b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/mixin/PlayerManagerMixin.java deleted file mode 100644 index a356cf25..00000000 --- a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/mixin/PlayerManagerMixin.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.dynmap.fabric_1_19.mixin; - -import net.minecraft.network.ClientConnection; -import net.minecraft.server.PlayerManager; -import net.minecraft.server.network.ServerPlayerEntity; -import org.dynmap.fabric_1_19.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.19/src/main/java/org/dynmap/fabric_1_19/mixin/ProtoChunkMixin.java b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/mixin/ProtoChunkMixin.java deleted file mode 100644 index 4d0856be..00000000 --- a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/mixin/ProtoChunkMixin.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.dynmap.fabric_1_19.mixin; - -import net.minecraft.block.BlockState; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.chunk.ProtoChunk; -import org.dynmap.fabric_1_19.access.ProtoChunkAccessor; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(ProtoChunk.class) -public class ProtoChunkMixin implements ProtoChunkAccessor { - private boolean touchedByWorldGen = false; - - @Inject( - method = "setBlockState", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/world/chunk/ChunkSection;setBlockState(IIILnet/minecraft/block/BlockState;)Lnet/minecraft/block/BlockState;" - ) - ) - public void setBlockState(BlockPos pos, BlockState state, boolean moved, CallbackInfoReturnable info) { - touchedByWorldGen = true; - } - - public boolean getTouchedByWorldGen() { - return touchedByWorldGen; - } -} \ No newline at end of file diff --git a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/mixin/ServerPlayNetworkHandlerMixin.java b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/mixin/ServerPlayNetworkHandlerMixin.java deleted file mode 100644 index cabe6a5a..00000000 --- a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/mixin/ServerPlayNetworkHandlerMixin.java +++ /dev/null @@ -1,70 +0,0 @@ -package org.dynmap.fabric_1_19.mixin; - -import net.minecraft.block.BlockState; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.block.entity.SignBlockEntity; -import net.minecraft.network.message.SignedMessage; -import net.minecraft.network.packet.c2s.play.UpdateSignC2SPacket; -import net.minecraft.server.filter.FilteredMessage; -import net.minecraft.server.filter.TextStream; -import net.minecraft.server.network.ServerPlayNetworkHandler; -import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.text.LiteralTextContent; -import net.minecraft.text.Text; -import net.minecraft.util.math.BlockPos; - -import java.util.List; - -import net.minecraft.util.registry.RegistryKey; -import org.dynmap.fabric_1_19.event.BlockEvents; -import org.dynmap.fabric_1_19.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 = "handleDecoratedMessage", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/server/PlayerManager;broadcast(Lnet/minecraft/server/filter/FilteredMessage;Lnet/minecraft/server/network/ServerPlayerEntity;Lnet/minecraft/util/registry/RegistryKey;)V", - shift = At.Shift.BEFORE - ) - ) - public void onGameMessage(FilteredMessage message, CallbackInfo ci) { - ServerChatEvents.EVENT.invoker().onChatMessage(player, message.raw().getContent().getString()); - } - - @Inject( - method = "onSignUpdate", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/block/entity/SignBlockEntity;markDirty()V", - shift = At.Shift.BEFORE - ), - locals = LocalCapture.CAPTURE_FAILHARD - ) - public void onSignUpdate(UpdateSignC2SPacket packet, List> signText, CallbackInfo info, - ServerWorld serverWorld, BlockPos blockPos, BlockState blockState, BlockEntity blockEntity, SignBlockEntity signBlockEntity) - { - // Pull the raw text from the input. - String[] rawTexts = new String[4]; - for (int i=0; i info) { - ServerPlayerEntity player = (ServerPlayerEntity) (Object) this; - if (player.getRemovalReason() == null) { - PlayerEvents.PLAYER_CHANGED_DIMENSION.invoker().onPlayerChangedDimension(player); - } - } -} diff --git a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/mixin/ThreadedAnvilChunkStorageMixin.java b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/mixin/ThreadedAnvilChunkStorageMixin.java deleted file mode 100644 index 908fd912..00000000 --- a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/mixin/ThreadedAnvilChunkStorageMixin.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.dynmap.fabric_1_19.mixin; - -import net.minecraft.server.world.ChunkHolder; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.server.world.ThreadedAnvilChunkStorage; -import net.minecraft.world.chunk.Chunk; -import org.dynmap.fabric_1_19.access.ProtoChunkAccessor; -import org.dynmap.fabric_1_19.event.CustomServerChunkEvents; -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(value = ThreadedAnvilChunkStorage.class, priority = 666 /* fire before Fabric API CHUNK_LOAD event */) -public abstract class ThreadedAnvilChunkStorageMixin { - @Final - @Shadow - ServerWorld world; - - @Inject( - /* Same place as fabric-lifecycle-events-v1 event CHUNK_LOAD (we will fire before it) */ - method = "method_17227", - at = @At("TAIL") - ) - private void onChunkGenerate(ChunkHolder chunkHolder, Chunk protoChunk, CallbackInfoReturnable callbackInfoReturnable) { - if (((ProtoChunkAccessor)protoChunk).getTouchedByWorldGen()) { - CustomServerChunkEvents.CHUNK_GENERATE.invoker().onChunkGenerate(this.world, callbackInfoReturnable.getReturnValue()); - } - } -} \ No newline at end of file diff --git a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/mixin/WorldChunkMixin.java b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/mixin/WorldChunkMixin.java deleted file mode 100644 index fee76172..00000000 --- a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/mixin/WorldChunkMixin.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.dynmap.fabric_1_19.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_19.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.BLOCK_EVENT.invoker().onBlockEvent(this.getWorld(), pos); - } - } -} diff --git a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/permissions/FabricPermissions.java b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/permissions/FabricPermissions.java deleted file mode 100644 index 270ff000..00000000 --- a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/permissions/FabricPermissions.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.dynmap.fabric_1_19.permissions; - -import me.lucko.fabric.api.permissions.v0.Permissions; -import net.minecraft.entity.player.PlayerEntity; -import org.dynmap.Log; -import org.dynmap.fabric_1_19.DynmapPlugin; -import org.dynmap.json.simple.parser.JSONParser; - -import java.util.Set; -import java.util.stream.Collectors; - -public class FabricPermissions implements PermissionProvider { - - private String permissionKey(String perm) { - return "dynmap." + perm; - } - - @Override - public Set hasOfflinePermissions(String player, Set perms) { - return perms.stream() - .filter(perm -> hasOfflinePermission(player, perm)) - .collect(Collectors.toSet()); - } - - @Override - public boolean hasOfflinePermission(String player, String perm) { - return DynmapPlugin.plugin.isOp(player.toLowerCase()); - } - - @Override - public boolean has(PlayerEntity player, String permission) { - if (player == null) return false; - String name = player.getName().getString().toLowerCase(); - if (DynmapPlugin.plugin.isOp(name)) return true; - return Permissions.check(player, permissionKey(permission)); - } - - @Override - public boolean hasPermissionNode(PlayerEntity player, String permission) { - if (player != null) { - String name = player.getName().getString().toLowerCase(); - return DynmapPlugin.plugin.isOp(name); - } - return false; - } - -} diff --git a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/permissions/FilePermissions.java b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/permissions/FilePermissions.java deleted file mode 100644 index 78f21d3b..00000000 --- a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/permissions/FilePermissions.java +++ /dev/null @@ -1,103 +0,0 @@ -package org.dynmap.fabric_1_19.permissions; - -import net.minecraft.entity.player.PlayerEntity; -import org.dynmap.ConfigurationNode; -import org.dynmap.Log; -import org.dynmap.fabric_1_19.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.19/src/main/java/org/dynmap/fabric_1_19/permissions/LuckPermissions.java b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/permissions/LuckPermissions.java deleted file mode 100644 index 143fa7bf..00000000 --- a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/permissions/LuckPermissions.java +++ /dev/null @@ -1,102 +0,0 @@ -package org.dynmap.fabric_1_19.permissions; - -import me.lucko.fabric.api.permissions.v0.Permissions; -import net.luckperms.api.LuckPerms; -import net.luckperms.api.LuckPermsProvider; -import net.luckperms.api.cacheddata.CachedPermissionData; -import net.luckperms.api.model.user.User; -import net.luckperms.api.util.Tristate; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.server.MinecraftServer; -import org.dynmap.Log; -import org.dynmap.fabric_1_19.DynmapPlugin; -import org.dynmap.json.simple.JSONArray; -import org.dynmap.json.simple.JSONObject; -import org.dynmap.json.simple.parser.JSONParser; -import org.dynmap.json.simple.parser.ParseException; - -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.IOException; -import java.util.Optional; -import java.util.Set; -import java.util.UUID; -import java.util.stream.Collectors; - -public class LuckPermissions implements PermissionProvider { - - private final JSONParser parser = new JSONParser(); - private LuckPerms api = null; - - private Optional getApi() { - if (api != null) return Optional.of(api); - try { - api = LuckPermsProvider.get(); - return Optional.of(api); - } catch (Exception ex) { - Log.warning("Trying to access LuckPerms before it has loaded"); - return Optional.empty(); - } - } - - private Optional cachedUUID(String username) { - try { - BufferedReader reader = new BufferedReader(new FileReader("usercache.json")); - JSONArray cache = (JSONArray) parser.parse(reader); - for (Object it : cache) { - JSONObject user = (JSONObject) it; - if (user.get("name").toString().equalsIgnoreCase(username)) { - String uuid = user.get("uuid").toString(); - return Optional.of(UUID.fromString(uuid)); - } - } - - reader.close(); - } catch (IOException | ParseException ex) { - Log.warning("Unable to read usercache.json"); - } - - return Optional.empty(); - } - - private String permissionKey(String perm) { - return "dynmap." + perm; - } - - @Override - public Set hasOfflinePermissions(String player, Set perms) { - return perms.stream() - .filter(perm -> hasOfflinePermission(player, perm)) - .collect(Collectors.toSet()); - } - - @Override - public boolean hasOfflinePermission(String player, String perm) { - if (DynmapPlugin.plugin.isOp(player.toLowerCase())) return true; - Optional api = getApi(); - Optional uuid = cachedUUID(player); - if (!uuid.isPresent() || !api.isPresent()) return false; - User user = api.get().getUserManager().loadUser(uuid.get()).join(); - CachedPermissionData permissions = user.getCachedData().getPermissionData(); - Tristate state = permissions.checkPermission(permissionKey(perm)); - return state.asBoolean(); - } - - @Override - public boolean has(PlayerEntity player, String permission) { - if (player == null) return false; - String name = player.getName().getString().toLowerCase(); - if (DynmapPlugin.plugin.isOp(name)) return true; - return Permissions.check(player, permissionKey(permission)); - } - - @Override - public boolean hasPermissionNode(PlayerEntity player, String permission) { - if (player != null) { - String name = player.getName().getString().toLowerCase(); - return DynmapPlugin.plugin.isOp(name); - } - return false; - } - -} diff --git a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/permissions/OpPermissions.java b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/permissions/OpPermissions.java deleted file mode 100644 index fdf9369b..00000000 --- a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/permissions/OpPermissions.java +++ /dev/null @@ -1,52 +0,0 @@ -package org.dynmap.fabric_1_19.permissions; - -import net.minecraft.entity.player.PlayerEntity; -import org.dynmap.Log; -import org.dynmap.fabric_1_19.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.19/src/main/java/org/dynmap/fabric_1_19/permissions/PermissionProvider.java b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/permissions/PermissionProvider.java deleted file mode 100644 index 7affe811..00000000 --- a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/permissions/PermissionProvider.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.dynmap.fabric_1_19.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.19/src/main/resources/assets/dynmap/icon.png b/fabric-1.19/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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" - #aws_secret_access_key: "" - #prefix: "" - #override_endpoint: "" - -components: - - class: org.dynmap.ClientConfigurationComponent - - # Remember to change the following class to org.dynmap.JsonFileClientUpdateComponent when using an external web server. - - class: org.dynmap.InternalClientUpdateComponent - sendhealth: true - sendposition: true - allowwebchat: true - webchat-interval: 5 - hidewebchatip: false - trustclientname: false - includehiddenplayers: false - # (optional) if true, color codes in player display names are used - use-name-colors: false - # (optional) if true, player login IDs will be used for web chat when their IPs match - use-player-login-ip: true - # (optional) if use-player-login-ip is true, setting this to true will cause chat messages not matching a known player IP to be ignored - require-player-login-ip: false - # (optional) block player login IDs that are banned from chatting - block-banned-player-chat: true - # Require login for web-to-server chat (requires login-enabled: true) - webchat-requires-login: false - # If set to true, users must have dynmap.webchat permission in order to chat - webchat-permissions: false - # Limit length of single chat messages - chatlengthlimit: 256 - # # Optional - make players hidden when they are inside/underground/in shadows (#=light level: 0=full shadow,15=sky) - # hideifshadow: 4 - # # Optional - make player hidden when they are under cover (#=sky light level,0=underground,15=open to sky) - # hideifundercover: 14 - # # (Optional) if true, players that are crouching/sneaking will be hidden - hideifsneaking: false - # optional, if true, players that are in spectator mode will be hidden - hideifspectator: false - # If true, player positions/status is protected (login with ID with dynmap.playermarkers.seeall permission required for info other than self) - protected-player-info: false - # If true, hide players with invisibility potion effects active - hide-if-invisiblity-potion: true - # If true, player names are not shown on map, chat, list - hidenames: false - #- class: org.dynmap.JsonFileClientUpdateComponent - # writeinterval: 1 - # sendhealth: true - # sendposition: true - # allowwebchat: true - # webchat-interval: 5 - # hidewebchatip: false - # includehiddenplayers: false - # use-name-colors: false - # use-player-login-ip: false - # require-player-login-ip: false - # block-banned-player-chat: true - # hideifshadow: 0 - # hideifundercover: 0 - # hideifsneaking: false - # # Require login for web-to-server chat (requires login-enabled: true) - # webchat-requires-login: false - # # If set to true, users must have dynmap.webchat permission in order to chat - # webchat-permissions: false - # # Limit length of single chat messages - # chatlengthlimit: 256 - # hide-if-invisiblity-potion: true - # hidenames: false - - - class: org.dynmap.SimpleWebChatComponent - allowchat: true - # If true, web UI users can supply name for chat using 'playername' URL parameter. 'trustclientname' must also be set true. - allowurlname: false - - # Note: this component is needed for the dmarker commands, and for the Marker API to be available to other plugins - - class: org.dynmap.MarkersComponent - type: markers - showlabel: false - enablesigns: false - # Default marker set for sign markers - default-sign-set: markers - # (optional) add spawn point markers to standard marker layer - showspawn: true - spawnicon: world - spawnlabel: "Spawn" - # (optional) layer for showing offline player's positions (for 'maxofflinetime' minutes after logoff) - showofflineplayers: false - offlinelabel: "Offline" - offlineicon: offlineuser - offlinehidebydefault: true - offlineminzoom: 0 - maxofflinetime: 30 - # (optional) layer for showing player's spawn beds - showspawnbeds: false - spawnbedlabel: "Spawn Beds" - spawnbedicon: bed - spawnbedhidebydefault: true - spawnbedminzoom: 0 - spawnbedformat: "%name%'s bed" - # (optional) Show world border (vanilla 1.8+) - showworldborder: true - worldborderlabel: "Border" - - - class: org.dynmap.ClientComponent - type: chat - allowurlname: false - - class: org.dynmap.ClientComponent - type: chatballoon - focuschatballoons: false - - class: org.dynmap.ClientComponent - type: chatbox - showplayerfaces: true - messagettl: 5 - # Optional: set number of lines in scrollable message history: if set, messagettl is not used to age out messages - #scrollback: 100 - # Optional: set maximum number of lines visible for chatbox - #visiblelines: 10 - # Optional: send push button - sendbutton: false - - class: org.dynmap.ClientComponent - type: playermarkers - showplayerfaces: true - showplayerhealth: true - # If true, show player body too (only valid if showplayerfaces=true) - showplayerbody: false - # Option to make player faces small - don't use with showplayerhealth or largeplayerfaces - smallplayerfaces: false - # Option to make player faces larger - don't use with showplayerhealth or smallplayerfaces - largeplayerfaces: false - # Optional - make player faces layer hidden by default - hidebydefault: false - # Optional - ordering priority in layer menu (low goes before high - default is 0) - layerprio: 0 - # Optional - label for player marker layer (default is 'Players') - label: "Players" - - #- class: org.dynmap.ClientComponent - # type: digitalclock - - class: org.dynmap.ClientComponent - type: link - - - class: org.dynmap.ClientComponent - type: timeofdayclock - showdigitalclock: true - #showweather: true - # Mouse pointer world coordinate display - - class: org.dynmap.ClientComponent - type: coord - label: "Location" - hidey: false - show-mcr: false - show-chunk: false - - # Note: more than one logo component can be defined - #- class: org.dynmap.ClientComponent - # type: logo - # text: "Dynmap" - # #logourl: "images/block_surface.png" - # linkurl: "http://forums.bukkit.org/threads/dynmap.489/" - # # Valid positions: top-left, top-right, bottom-left, bottom-right - # position: bottom-right - - #- class: org.dynmap.ClientComponent - # type: inactive - # timeout: 1800 # in seconds (1800 seconds = 30 minutes) - # redirecturl: inactive.html - # #showmessage: 'You were inactive for too long.' - - #- class: org.dynmap.TestComponent - # stuff: "This is some configuration-value" - -# Treat hiddenplayers.txt as a whitelist for players to be shown on the map? (Default false) -display-whitelist: false - -# How often a tile gets rendered (in seconds). -renderinterval: 1 - -# How many tiles on update queue before accelerate render interval -renderacceleratethreshold: 60 - -# How often to render tiles when backlog is above renderacceleratethreshold -renderaccelerateinterval: 0.2 - -# How many update tiles to work on at once (if not defined, default is 1/2 the number of cores) -tiles-rendered-at-once: 2 - -# If true, use normal priority threads for rendering (versus low priority) - this can keep rendering -# from starving on busy Windows boxes (Linux JVMs pretty much ignore thread priority), but may result -# in more competition for CPU resources with other processes -usenormalthreadpriority: true - -# Save and restore pending tile renders - prevents their loss on server shutdown or /reload -saverestorepending: true - -# Save period for pending jobs (in seconds): periodic saving for crash recovery of jobs -save-pending-period: 900 - -# Zoom-out tile update period - how often to scan for and process tile updates into zoom-out tiles (in seconds) -zoomoutperiod: 30 - -# Control whether zoom out tiles are validated on startup (can be needed if zoomout processing is interrupted, but can be expensive on large maps) -initial-zoomout-validate: true - -# Default delay on processing of updated tiles, in seconds. This can reduce potentially expensive re-rendering -# of frequently updated tiles (such as due to machines, pistons, quarries or other automation). Values can -# also be set on individual worlds and individual maps. -tileupdatedelay: 30 - -# Tile hashing is used to minimize tile file updates when no changes have occurred - set to false to disable -enabletilehash: true - -# Optional - hide ores: render as normal stone (so that they aren't revealed by maps) -#hideores: true - -# Optional - enabled BetterGrass style rendering of grass and snow block sides -#better-grass: true - -# Optional - enable smooth lighting by default on all maps supporting it (can be set per map as lighting option) -smooth-lighting: true - -# Optional - use world provider lighting table (good for custom worlds with custom lighting curves, like nether) -# false=classic Dynmap lighting curve -use-brightness-table: true - -# Optional - render specific block names using the textures and models of another block name: can be used to hide/disguise specific -# blocks (e.g. make ores look like stone, hide chests) or to provide simple support for rendering unsupported custom blocks -block-alias: -# "minecraft:quartz_ore": "stone" -# "diamond_ore": "coal_ore" - -# Default image format for HDMaps (png, jpg, jpg-q75, jpg-q80, jpg-q85, jpg-q90, jpg-q95, jpg-q100, webp, webp-q75, webp-q80, webp-q85, webp-q90, webp-q95, webp-q100, webp-l), -# Note: any webp format requires the presence of the 'webp command line tools' (cwebp, dwebp) (https://developers.google.com/speed/webp/download) -# -# Has no effect on maps with explicit format settings -image-format: jpg-q90 - -# If cwebp or dwebp are not on the PATH, use these settings to provide their full path. Do not use these settings if the tools are on the PATH -# For Windows, include .exe -# -#cwebpPath: /usr/bin/cwebp -#dwebpPath: /usr/bin/dwebp - -# use-generated-textures: if true, use generated textures (same as client); false is static water/lava textures -# correct-water-lighting: if true, use corrected water lighting (same as client); false is legacy water (darker) -# transparent-leaves: if true, leaves are transparent (lighting-wise): false is needed for some Spout versions that break lighting on leaf blocks -use-generated-textures: true -correct-water-lighting: true -transparent-leaves: true - -# ctm-support: if true, Connected Texture Mod (CTM) in texture packs is enabled (default) -ctm-support: true -# custom-colors-support: if true, Custom Colors in texture packs is enabled (default) -custom-colors-support: true - -# Control loading of player faces (if set to false, skins are never fetched) -#fetchskins: false - -# Control updating of player faces, once loaded (if faces are being managed by other apps or manually) -#refreshskins: false - -# Customize URL used for fetching player skins (%player% is macro for name, %uuid% for UUID) -skin-url: "http://skins.minecraft.net/MinecraftSkins/%player%.png" - -# Control behavior for new (1.0+) compass orientation (sunrise moved 90 degrees: east is now what used to be south) -# default is 'newrose' (preserve pre-1.0 maps, rotate rose) -# 'newnorth' is used to rotate maps and rose (requires fullrender of any HDMap map - same as 'newrose' for FlatMap or KzedMap) -compass-mode: newnorth - -# Triggers for automatic updates : blockupdate-with-id is debug for breaking down updates by ID:meta -# To disable, set just 'none' and comment/delete the rest -render-triggers: - - blockupdate - #- blockupdate-with-id - - chunkgenerate - #- none - -# Title for the web page - if not specified, defaults to the server's name (unless it is the default of 'Unknown Server') -#webpage-title: "My Awesome Server Map" - -# The path where the tile-files are placed. -tilespath: web/tiles - -# The path where the web-files are located. -webpath: web - -# If set to false, disable extraction of webpath content (good if using custom web UI or 3rd party web UI) -# Note: web interface is unsupported in this configuration - you're on your own -update-webpath-files: true - -# The path were the /dynmapexp command exports OBJ ZIP files -exportpath: export - -# The path where files can be imported for /dmarker commands -importpath: import - -# The network-interface the webserver will bind to (0.0.0.0 for all interfaces, 127.0.0.1 for only local access). -# If not set, uses same setting as server in server.properties (or 0.0.0.0 if not specified) -#webserver-bindaddress: 0.0.0.0 - -# The TCP-port the webserver will listen on. -webserver-port: 8123 - -# Maximum concurrent session on internal web server - limits resources used in Bukkit server -max-sessions: 30 - -# Disables Webserver portion of Dynmap (Advanced users only) -disable-webserver: false - -# Enable/disable having the web server allow symbolic links (true=compatible with existing code, false=more secure (default)) -allow-symlinks: true - -# Enable login support -login-enabled: false -# Require login to access website (requires login-enabled: true) -login-required: false - -# Period between tile renders for fullrender, in seconds (non-zero to pace fullrenders, lessen CPU load) -timesliceinterval: 0.0 - -# Maximum chunk loads per server tick (1/20th of a second) - reducing this below 90 will impact render performance, but also will reduce server thread load -maxchunkspertick: 200 - -# Progress report interval for fullrender/radiusrender, in tiles. Must be 100 or greater -progressloginterval: 100 - -# Parallel fullrender: if defined, number of concurrent threads used for fullrender or radiusrender -# Note: setting this will result in much more intensive CPU use, some additional memory use. Caution should be used when -# setting this to equal or exceed the number of physical cores on the system. -#parallelrendercnt: 4 - -# Interval the browser should poll for updates. -updaterate: 2000 - -# If nonzero, server will pause fullrender/radiusrender processing when 'fullrenderplayerlimit' or more users are logged in -fullrenderplayerlimit: 0 -# If nonzero, server will pause update render processing when 'updateplayerlimit' or more users are logged in -updateplayerlimit: 0 -# Target limit on server thread use - msec per tick -per-tick-time-limit: 50 -# If TPS of server is below this setting, update renders processing is paused -update-min-tps: 18.0 -# If TPS of server is below this setting, full/radius renders processing is paused -fullrender-min-tps: 18.0 -# If TPS of server is below this setting, zoom out processing is paused -zoomout-min-tps: 18.0 - -showplayerfacesinmenu: true - -# Control whether players that are hidden or not on current map are grayed out (true=yes) -grayplayerswhenhidden: true - -# Set sidebaropened: 'true' to pin menu sidebar opened permanently, 'pinned' to default the sidebar to pinned, but allow it to unpin -#sidebaropened: true - -# Customized HTTP response headers - add 'id: value' pairs to all HTTP response headers (internal web server only) -#http-response-headers: -# Access-Control-Allow-Origin: "my-domain.com" -# X-Custom-Header-Of-Mine: "MyHeaderValue" - -# Trusted proxies for web server - which proxy addresses are trusted to supply valid X-Forwarded-For fields -# This now supports both IP address, and subnet ranges (e.g. 192.168.1.0/24 or 202.24.0.0/14 ) -trusted-proxies: - - "127.0.0.1" - - "0:0:0:0:0:0:0:1" - -joinmessage: "%playername% joined" -quitmessage: "%playername% quit" -spammessage: "You may only chat once every %interval% seconds." -# format for messages from web: %playername% substitutes sender ID (typically IP), %message% includes text -webmsgformat: "&color;2[WEB] %playername%: &color;f%message%" - -# Control whether layer control is presented on the UI (default is true) -showlayercontrol: true - -# Enable checking for banned IPs via banned-ips.txt (internal web server only) -check-banned-ips: true - -# Default selection when map page is loaded -defaultzoom: 0 -defaultworld: world -defaultmap: flat -# (optional) Zoom level and map to switch to when following a player, if possible -#followzoom: 3 -#followmap: surface - -# If true, make persistent record of IP addresses used by player logins, to support web IP to player matching -persist-ids-by-ip: true - -# If true, map text to cyrillic -cyrillic-support: false - -# Messages to customize -msg: - maptypes: "Map Types" - players: "Players" - chatrequireslogin: "Chat Requires Login" - chatnotallowed: "You are not permitted to send chat messages" - hiddennamejoin: "Player joined" - hiddennamequit: "Player quit" - -# URL for client configuration (only need to be tailored for proxies or other non-standard configurations) -url: - # configuration URL - #configuration: "up/configuration" - # update URL - #update: "up/world/{world}/{timestamp}" - # sendmessage URL - #sendmessage: "up/sendmessage" - # login URL - #login: "up/login" - # register URL - #register: "up/register" - # tiles base URL - #tiles: "tiles/" - # markers base URL - #markers: "tiles/" - # Snapshot cache size, in chunks -snapshotcachesize: 500 -# Snapshot cache uses soft references (true), else weak references (false) -soft-ref-cache: true - -# Player enter/exit title messages for map markers -# -# Processing period - how often to check player positions vs markers - default is 1000ms (1 second) -#enterexitperiod: 1000 -# Title message fade in time, in ticks (0.05 second intervals) - default is 10 (1/2 second) -#titleFadeIn: 10 -# Title message stay time, in ticks (0.05 second intervals) - default is 70 (3.5 seconds) -#titleStay: 70 -# Title message fade out time, in ticks (0.05 seocnd intervals) - default is 20 (1 second) -#titleFadeOut: 20 -# Enter/exit messages use on screen titles (true - default), if false chat messages are sent instead -#enterexitUseTitle: true -# Set true if new enter messages should supercede pending exit messages (vs being queued in order), default false -#enterReplacesExits: true - -# Published public URL for Dynmap server (allows users to use 'dynmap url' command to get public URL usable to access server -# If not set, 'dynmap url' will not return anything. URL should be fully qualified (e.g. https://mc.westeroscraft.com/) -#publicURL: http://my.greatserver.com/dynmap - -# Set to true to enable verbose startup messages - can help with debugging map configuration problems -# Set to false for a much quieter startup log -verbose: false - -# Enables debugging. -#debuggers: -# - class: org.dynmap.debug.LogDebugger -# Debug: dump blocks missing render data -dump-missing-blocks: false - -# Log4J defense: string substituted for attempts to use macros in web chat -hackAttemptBlurb: "(IaM5uchA1337Haxr-Ban Me!)" diff --git a/fabric-1.19/src/main/resources/dynmap.mixins.json b/fabric-1.19/src/main/resources/dynmap.mixins.json deleted file mode 100644 index ea58931e..00000000 --- a/fabric-1.19/src/main/resources/dynmap.mixins.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "required": true, - "minVersion": "0.8", - "package": "org.dynmap.fabric_1_19.mixin", - "compatibilityLevel": "JAVA_17", - "mixins": [ - "BiomeEffectsAccessor", - "MinecraftServerMixin", - "PlayerManagerMixin", - "ProtoChunkMixin", - "ServerPlayerEntityMixin", - "ServerPlayNetworkHandlerMixin", - "ThreadedAnvilChunkStorageMixin", - "WorldChunkMixin" - ], - "injectors": { - "defaultRequire": 1 - } -} diff --git a/fabric-1.19/src/main/resources/fabric.mod.json b/fabric-1.19/src/main/resources/fabric.mod.json deleted file mode 100644 index 074ab540..00000000 --- a/fabric-1.19/src/main/resources/fabric.mod.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "schemaVersion": 1, - "id": "dynmap", - "version": "${version}", - "name": "Dynmap", - "description": "Dynamic, Google-maps style rendered maps for your Minecraft server", - "authors": [ - "mikeprimm", - "LolHens", - "i509VCB" - ], - "contact": { - "homepage": "https://github.com/webbukkit/dynmap", - "sources": "https://github.com/webbukkit/dynmap" - }, - "license": "Apache-2.0", - "icon": "assets/dynmap/icon.png", - "environment": "*", - "entrypoints": { - "main": [ - "org.dynmap.fabric_1_19.DynmapMod" - ] - }, - "mixins": [ - "dynmap.mixins.json" - ], - - "depends": { - "fabricloader": ">=0.14.6", - "fabric": ">=0.55.2", - "minecraft": "1.19" - } -} diff --git a/fabric-1.19/src/main/resources/permissions.yml.example b/fabric-1.19/src/main/resources/permissions.yml.example deleted file mode 100644 index a25f9adc..00000000 --- a/fabric-1.19/src/main/resources/permissions.yml.example +++ /dev/null @@ -1,27 +0,0 @@ -# -# Sample permissions.yml for dynmap - trivial, flat-file based permissions for dynmap features -# To use, copy this file to dynmap/permissions.yml, and edit appropriate. File is YAML format. -# -# All operators have full permissions to all functions. -# All users receive the permissions under the 'defaultuser' section -# Specific users can be given more permissions by defining a section with their name containing their permisssions -# All permissions correspond to those documented here (https://github.com/webbukkit/dynmap/wiki/Permissions), but -# do NOT have the 'dynmap.' prefix when used here (e.g. 'dynmap.fullrender' permission is just 'fullrender' here). -# -defaultuser: - - render - - show.self - - hide.self - - sendtoweb - - stats - - marker.list - - marker.listsets - - marker.icons - - webregister - - webchat - #- marker.sign - -#playername1: -# - fullrender -# - cancelrender -# - radiusrender diff --git a/forge-1.19.2/.gitignore b/forge-1.19.2/.gitignore deleted file mode 100644 index 84c048a7..00000000 --- a/forge-1.19.2/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build/ diff --git a/forge-1.19.2/bin/.gitignore b/forge-1.19.2/bin/.gitignore deleted file mode 100644 index 7eed456b..00000000 --- a/forge-1.19.2/bin/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/main/ -/test/ diff --git a/forge-1.19.2/build.gradle b/forge-1.19.2/build.gradle deleted file mode 100644 index b6e2d63f..00000000 --- a/forge-1.19.2/build.gradle +++ /dev/null @@ -1,92 +0,0 @@ -buildscript { - repositories { - maven { url = 'https://files.minecraftforge.net/maven' } - jcenter() - mavenCentral() - } - dependencies { - classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '5.1.+', changing: true - } -} -apply plugin: 'net.minecraftforge.gradle' -apply plugin: 'com.github.johnrengelman.shadow' -apply plugin: 'eclipse' - -eclipse { - project { - name = "Dynmap(Forge-1.19.2)" - } -} - -sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = JavaLanguageVersion.of(17) // Need this here so eclipse task generates correctly. - -println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getProperty('java.vm.version') + '(' + System.getProperty('java.vendor') + ') Arch: ' + System.getProperty('os.arch')) - -ext.buildNumber = System.getenv().BUILD_NUMBER ?: "Dev" - -minecraft { - mappings channel: 'official', version: '1.19.2' - accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg') - runs { - server { - workingDirectory project.file('run').canonicalPath - } - } -} - -project.archivesBaseName = "${project.archivesBaseName}-forge-1.19.2" - -dependencies { - implementation project(path: ":DynmapCore", configuration: "shadow") - implementation project(path: ':DynmapCoreAPI') - - minecraft 'net.minecraftforge:forge:1.19.2-43.0.0' -} - -processResources -{ - filesMatching('META-INF/mods.toml') { - // replace version and mcversion - expand( - version: project.version + '-' + project.ext.buildNumber, - mcversion: "1.19.2" - ) - } -} - -shadowJar { - dependencies { - include(dependency(':DynmapCore')) - include(dependency("commons-codec:commons-codec:")) - exclude("META-INF/maven/**") - exclude("META-INF/services/**") - } - relocate('org.apache.commons.codec', 'org.dynmap.forge_1_19_2.commons.codec') - - archiveName = "Dynmap-${parent.version}-forge-1.19.2.jar" - destinationDir = file '../target' -} - -shadowJar.doLast { - task -> - ant.checksum file: task.archivePath -} - -afterEvaluate { -reobf { - shadowJar { - mappings = createMcpToSrg.output - } -} -} - -task deobfJar(type: Jar) { - from sourceSets.main.output - classifier = 'dev' -} - -artifacts { - archives deobfJar -} - -build.dependsOn(shadowJar) diff --git a/forge-1.19.2/src/main/java/org/dynmap/forge_1_19_2/ClientProxy.java b/forge-1.19.2/src/main/java/org/dynmap/forge_1_19_2/ClientProxy.java deleted file mode 100644 index a9fd707c..00000000 --- a/forge-1.19.2/src/main/java/org/dynmap/forge_1_19_2/ClientProxy.java +++ /dev/null @@ -1,6 +0,0 @@ -package org.dynmap.forge_1_19_2; - -public class ClientProxy extends Proxy { - public ClientProxy() { - } -} diff --git a/forge-1.19.2/src/main/java/org/dynmap/forge_1_19_2/DynmapMod.java b/forge-1.19.2/src/main/java/org/dynmap/forge_1_19_2/DynmapMod.java deleted file mode 100644 index f355331b..00000000 --- a/forge-1.19.2/src/main/java/org/dynmap/forge_1_19_2/DynmapMod.java +++ /dev/null @@ -1,136 +0,0 @@ -package org.dynmap.forge_1_19_2; - -import java.io.File; - -import org.apache.commons.lang3.tuple.Pair; -import org.dynmap.DynmapCommonAPI; -import org.dynmap.DynmapCommonAPIListener; -import org.dynmap.Log; -import org.dynmap.forge_1_19_2.DynmapPlugin.OurLog; - -import net.minecraft.server.MinecraftServer; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.event.server.ServerAboutToStartEvent; -import net.minecraftforge.event.server.ServerStartedEvent; -import net.minecraftforge.event.server.ServerStartingEvent; -import net.minecraftforge.event.server.ServerStoppingEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.DistExecutor; -import net.minecraftforge.fml.IExtensionPoint; -import net.minecraftforge.fml.ModList; -import net.minecraftforge.fml.ModLoadingContext; -import net.minecraftforge.fml.StartupMessageManager; -import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; -import net.minecraftforge.fml.event.lifecycle.FMLLoadCompleteEvent; -import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; -import net.minecraftforge.network.NetworkConstants;; - -@Mod("dynmap") -public class DynmapMod -{ - // The instance of your mod that Forge uses. - public static DynmapMod instance; - - // Says where the client and server 'proxy' code is loaded. - public static Proxy proxy = DistExecutor.runForDist(() -> ClientProxy::new, () -> Proxy::new); - - public static DynmapPlugin plugin; - public static File jarfile; - public static String ver; - public static boolean useforcedchunks; - - public class APICallback extends DynmapCommonAPIListener { - @Override - public void apiListenerAdded() { - if(plugin == null) { - plugin = proxy.startServer(server); - } - } - @Override - public void apiEnabled(DynmapCommonAPI api) { - } - } - - //TODO - //public class LoadingCallback implements net.minecraftforge.common.ForgeChunkManager.LoadingCallback { - // @Override - // public void ticketsLoaded(List tickets, World world) { - // if(tickets.size() > 0) { - // DynmapPlugin.setBusy(world, tickets.get(0)); - // for(int i = 1; i < tickets.size(); i++) { - // ForgeChunkManager.releaseTicket(tickets.get(i)); - // } - // } - // } - //} - - public DynmapMod() { - instance = this; - FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup); - FMLJavaModLoadingContext.get().getModEventBus().addListener(this::init); - - MinecraftForge.EVENT_BUS.register(this); - - ModLoadingContext.get().registerExtensionPoint(IExtensionPoint.DisplayTest.class, - ()->new IExtensionPoint.DisplayTest(()->NetworkConstants.IGNORESERVERONLY, (remote, isServer)-> true)); - - Log.setLogger(new OurLog()); - org.dynmap.modsupport.ModSupportImpl.init(); - } - - public void setup(final FMLCommonSetupEvent event) - { - //TOOO - jarfile = ModList.get().getModFileById("dynmap").getFile().getFilePath().toFile(); - - ver = ModList.get().getModContainerById("dynmap").get().getModInfo().getVersion().toString(); - - //// Load configuration file - use suggested (config/WesterosBlocks.cfg) - //Configuration cfg = new Configuration(event.getSuggestedConfigurationFile()); - //try { - // cfg.load(); - // - // useforcedchunks = cfg.get("Settings", "UseForcedChunks", true).getBoolean(true); - //} - //finally - //{ - // cfg.save(); - //} - } - - public void init(FMLLoadCompleteEvent event) - { - /* Set up for chunk loading notice from chunk manager */ - //TODO - //if(useforcedchunks) { - // ForgeChunkManager.setForcedChunkLoadingCallback(DynmapMod.instance, new LoadingCallback()); - //} - //else { - // Log.info("[Dynmap] World loading using forced chunks is disabled"); - //} - } - - private MinecraftServer server; - - @SubscribeEvent - public void onServerStarting(ServerAboutToStartEvent event) { - server = event.getServer(); - if(plugin == null) - plugin = proxy.startServer(server); - plugin.onStarting(server.getCommands().getDispatcher()); - } - - @SubscribeEvent - public void onServerStarted(ServerStartedEvent event) { - DynmapCommonAPIListener.register(new APICallback()); - plugin.serverStarted(); - } - - @SubscribeEvent - public void serverStopping(ServerStoppingEvent event) - { - proxy.stopServer(plugin); - plugin = null; - } -} diff --git a/forge-1.19.2/src/main/java/org/dynmap/forge_1_19_2/DynmapPlugin.java b/forge-1.19.2/src/main/java/org/dynmap/forge_1_19_2/DynmapPlugin.java deleted file mode 100644 index 55edc7dc..00000000 --- a/forge-1.19.2/src/main/java/org/dynmap/forge_1_19_2/DynmapPlugin.java +++ /dev/null @@ -1,2039 +0,0 @@ -package org.dynmap.forge_1_19_2; - -import java.io.File; -import java.io.InputStream; -import java.net.InetSocketAddress; -import java.net.SocketAddress; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Base64; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Optional; -import java.util.PriorityQueue; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.Callable; -import java.util.concurrent.CancellationException; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; -import java.util.concurrent.FutureTask; -import java.util.regex.Pattern; - -import net.minecraft.Util; -import net.minecraft.commands.CommandSource; -import net.minecraft.commands.CommandSourceStack; -import net.minecraft.commands.Commands; -import net.minecraft.core.BlockPos; -import net.minecraft.core.IdMapper; -import net.minecraft.core.Registry; -import net.minecraft.network.Connection; -import net.minecraft.network.chat.ChatType; -import net.minecraft.network.chat.Component; -import net.minecraft.network.protocol.game.ClientboundSetSubtitleTextPacket; -import net.minecraft.network.protocol.game.ClientboundSetTitleTextPacket; -import net.minecraft.network.protocol.game.ClientboundSetTitlesAnimationPacket; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.level.ChunkHolder; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.server.network.ServerGamePacketListenerImpl; -import net.minecraft.server.players.GameProfileCache; -import net.minecraft.server.players.UserBanList; -import net.minecraft.world.entity.Pose; -import net.minecraft.world.level.ChunkPos; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.LiquidBlock; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkAccess; -import net.minecraft.world.level.chunk.ChunkStatus; -import net.minecraft.world.level.chunk.LevelChunk; -import net.minecraft.world.level.chunk.LevelChunkSection; -import net.minecraft.world.level.material.Material; -import net.minecraft.world.phys.Vec3; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.event.ServerChatEvent; -import net.minecraftforge.event.TickEvent; -import net.minecraftforge.event.entity.player.PlayerEvent.PlayerChangedDimensionEvent; -import net.minecraftforge.event.entity.player.PlayerEvent.PlayerLoggedInEvent; -import net.minecraftforge.event.entity.player.PlayerEvent.PlayerLoggedOutEvent; -import net.minecraftforge.event.entity.player.PlayerEvent.PlayerRespawnEvent; -import net.minecraftforge.event.level.BlockEvent; -import net.minecraftforge.event.level.ChunkDataEvent; -import net.minecraftforge.event.level.ChunkEvent; -import net.minecraftforge.event.level.LevelEvent; -import net.minecraftforge.fml.ModList; -import net.minecraftforge.fml.ModContainer; -import net.minecraftforge.fml.loading.LoadingModList; -import net.minecraftforge.fml.loading.moddiscovery.ModFileInfo; -import net.minecraftforge.fml.loading.moddiscovery.ModInfo; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.apache.maven.artifact.versioning.ArtifactVersion; -import org.dynmap.ConfigurationNode; -import org.dynmap.DynmapChunk; -import org.dynmap.DynmapCommonAPIListener; -import org.dynmap.DynmapCore; -import org.dynmap.DynmapLocation; -import org.dynmap.DynmapWorld; -import org.dynmap.Log; -import org.dynmap.MapManager; -import org.dynmap.PlayerList; -import org.dynmap.common.BiomeMap; -import org.dynmap.common.DynmapCommandSender; -import org.dynmap.common.DynmapPlayer; -import org.dynmap.common.DynmapServerInterface; -import org.dynmap.common.DynmapListenerManager.EventType; -import org.dynmap.common.chunk.GenericChunkCache; -import org.dynmap.forge_1_19_2.DmapCommand; -import org.dynmap.forge_1_19_2.DmarkerCommand; -import org.dynmap.forge_1_19_2.DynmapCommand; -import org.dynmap.forge_1_19_2.permissions.FilePermissions; -import org.dynmap.forge_1_19_2.permissions.OpPermissions; -import org.dynmap.forge_1_19_2.permissions.PermissionProvider; -import org.dynmap.permissions.PermissionsHandler; -import org.dynmap.renderer.DynmapBlockState; -import org.dynmap.utils.DynmapLogger; -import org.dynmap.utils.MapChunkCache; -import org.dynmap.utils.VisibilityLimit; - -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 com.mojang.brigadier.CommandDispatcher; -import com.mojang.brigadier.arguments.StringArgumentType; -import com.mojang.brigadier.builder.RequiredArgumentBuilder; -import com.mojang.brigadier.exceptions.CommandSyntaxException; - -import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap; -import it.unimi.dsi.fastutil.longs.LongOpenHashSet; -import net.minecraftforge.eventbus.api.EventPriority; -import net.minecraftforge.eventbus.api.SubscribeEvent; - -import net.minecraft.world.level.EmptyBlockGetter; - -public class DynmapPlugin -{ - private DynmapCore core; - private PermissionProvider permissions; - private boolean core_enabled; - public GenericChunkCache sscache; - public PlayerList playerList; - private MapManager mapManager; - private static net.minecraft.server.MinecraftServer server; - public static DynmapPlugin plugin; - private 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 LevelAccessor last_world; - private ForgeWorld last_fworld; - private Map players = new HashMap(); - //TODO private ForgeMetrics metrics; - private HashSet modsused = new HashSet(); - private ForgeServer fserver = new ForgeServer(); - private boolean tickregistered = false; - // TPS calculator - private double tps; - private long lasttick; - private long avgticklen; - // Per tick limit, in nsec - private long perTickLimit = (50000000); // 50 ms - private boolean useSaveFolder = true; - - private static final String[] TRIGGER_DEFAULTS = { "blockupdate", "chunkpopulate", "chunkgenerate" }; - - private static final Pattern patternControlCode = Pattern.compile("(?i)\\u00A7[0-9A-FK-OR]"); - - public static class BlockUpdateRec { - LevelAccessor 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(ForgeWorld 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(ForgeWorld fw, ChunkPos pos) { - LongOpenHashSet cset = knownloadedchunks.get(fw.getName()); - if (cset != null) { - cset.remove(pos.toLong()); - } - } - private boolean checkIfKnownChunk(ForgeWorld fw, ChunkPos pos) { - LongOpenHashSet cset = knownloadedchunks.get(fw.getName()); - if (cset != null) { - return cset.contains(pos.toLong()); - } - return false; - } - - private static Registry reg = null; - - private static Registry getBiomeReg() { - if (reg == null) { - reg = server.registryAccess().ownedRegistryOrThrow(Registry.BIOME_REGISTRY); - } - return reg; - } - - /** - * 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 - - IdMapper bsids = Block.BLOCK_STATE_REGISTRY; - - DynmapBlockState basebs = null; - Block baseb = null; - int baseidx = 0; - - Iterator iter = bsids.iterator(); - DynmapBlockState.Builder bld = new DynmapBlockState.Builder(); - 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; - } - ResourceLocation ui = Registry.BLOCK.getKey(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.world.level.block.state.properties.Property p : bs.getProperties()) { - if (statename.length() > 0) { - statename += ","; - } - statename += p.getName() + "=" + bs.getValue(p).toString(); - } - int lightAtten = 15; - try { // Workaround for mods with broken block state logic... - lightAtten =bs.isSolidRender(EmptyBlockGetter.INSTANCE, BlockPos.ZERO) ? 15 : (bs.propagatesSkylightDown(EmptyBlockGetter.INSTANCE, BlockPos.ZERO) ? 0 : 1); - } catch (Exception x) { - Log.warning(String.format("Exception while checking lighting data for block state: %s[%s]", bn, statename)); - Log.verboseinfo("Exception: " + x.toString()); - } - //Log.info("statename=" + bn + "[" + statename + "], lightAtten=" + lightAtten); - // Fill in base attributes - bld.setBaseState(basebs).setStateIndex(idx - baseidx).setBlockName(bn).setStateName(statename).setMaterial(mat.toString()).setLegacyBlockID(idx).setAttenuatesLight(lightAtten); - if (mat.isSolid()) { bld.setSolid(); } - if (mat == Material.AIR) { bld.setAir(); } - if (mat == Material.WOOD) { bld.setLog(); } - if (mat == Material.LEAVES) { bld.setLeaves(); } - if ((!bs.getFluidState().isEmpty()) && !(bs.getBlock() instanceof LiquidBlock)) { - bld.setWaterlogged(); - } - DynmapBlockState dbs = bld.build(); // Build state - stateByID[idx] = dbs; - if (basebs == null) { basebs = dbs; } - } - } - 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.getItemById(id); - //} - - private static Biome[] biomelist = null; - - public static final Biome[] getBiomeList() { - if (biomelist == null) { - biomelist = new Biome[256]; - Iterator iter = getBiomeReg().iterator(); - while (iter.hasNext()) { - Biome b = iter.next(); - int bidx = getBiomeReg().getId(b); - if (bidx >= biomelist.length) { - biomelist = Arrays.copyOf(biomelist, bidx + biomelist.length); - } - biomelist[bidx] = b; - } - } - return biomelist; - } - //public static final NetworkManager getNetworkManager(ServerPlayNetHandler nh) { - // return nh.netManager; - //} - - private ForgePlayer getOrAddPlayer(ServerPlayer p) { - String name = p.getName().getString(); - ForgePlayer fp = players.get(name); - if(fp != null) { - fp.player = p; - } - else { - fp = new ForgePlayer(p); - players.put(name, fp); - } - return fp; - } - - private static class TaskRecord implements Comparable - { - private long ticktorun; - private long id; - private FutureTask future; - @Override - public int compareTo(Object o) - { - TaskRecord tr = (TaskRecord)o; - - if (this.ticktorun < tr.ticktorun) - { - return -1; - } - else if (this.ticktorun > tr.ticktorun) - { - return 1; - } - else if (this.id < tr.id) - { - return -1; - } - else if (this.id > tr.id) - { - return 1; - } - else - { - return 0; - } - } - } - - private class ChatMessage { - String message; - ServerPlayer sender; - } - private ConcurrentLinkedQueue msgqueue = new ConcurrentLinkedQueue(); - - public class ChatHandler { - @SubscribeEvent - public void handleChat(ServerChatEvent event) { - String msg = event.getMessage().getString(); - if(!msg.startsWith("/")) { - ChatMessage cm = new ChatMessage(); - cm.message = msg; - cm.sender = event.getPlayer(); - msgqueue.add(cm); - } - } - } - - /** TODO: depends on forge chunk manager - private static class WorldBusyRecord { - long last_ts; - Ticket ticket; - } - private static HashMap busy_worlds = new HashMap(); - - private void setBusy(World w) { - setBusy(w, null); - } - static void setBusy(World w, Ticket t) { - if(w == null) return; - if (!DynmapMod.useforcedchunks) return; - WorldBusyRecord wbr = busy_worlds.get(w.provider.getDimension()); - if(wbr == null) { // Not busy, make ticket and keep spawn loaded - Debug.debug("World " + w.getWorldInfo().getWorldName() + "/"+ w.provider.getDimensionType().getName() + " is busy"); - wbr = new WorldBusyRecord(); - if(t != null) - wbr.ticket = t; - else - wbr.ticket = ForgeChunkManager.requestTicket(DynmapMod.instance, w, ForgeChunkManager.Type.NORMAL); - if(wbr.ticket != null) { - BlockPos cc = w.getSpawnPoint(); - ChunkPos ccip = new ChunkPos(cc.getX() >> 4, cc.getZ() >> 4); - ForgeChunkManager.forceChunk(wbr.ticket, ccip); - busy_worlds.put(w.provider.getDimension(), wbr); // Add to busy list - } - } - wbr.last_ts = System.nanoTime(); - } - - private void doIdleOutOfWorlds() { - if (!DynmapMod.useforcedchunks) return; - long ts = System.nanoTime() - worldIdleTimeoutNS; - for(Iterator itr = busy_worlds.values().iterator(); itr.hasNext();) { - WorldBusyRecord wbr = itr.next(); - if(wbr.last_ts < ts) { - World w = wbr.ticket.world; - Debug.debug("World " + w.getWorldInfo().getWorldName() + "/" + wbr.ticket.world.provider.getDimensionType().getName() + " is idle"); - if (wbr.ticket != null) - ForgeChunkManager.releaseTicket(wbr.ticket); // Release hold on world - itr.remove(); - } - } - } - */ - - public static class OurLog implements DynmapLogger { - Logger log; - public static final String DM = "[Dynmap] "; - OurLog() { - 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); - } - } - - public DynmapPlugin(MinecraftServer srv) - { - plugin = this; - this.server = srv; - } - - public boolean isOp(String player) { - String[] ops = server.getPlayerList().getOps().getUserList(); - for (String op : ops) { - if (op.equalsIgnoreCase(player)) { - return true; - } - } - return (server.isSingleplayer() && player.equalsIgnoreCase(server.getSingleplayerProfile().getName())); - } - - private boolean hasPerm(ServerPlayer psender, String permission) { - PermissionsHandler ph = PermissionsHandler.getHandler(); - if ((psender != null) && (ph != null) && ph.hasPermission(psender.getName().getString(), permission)) { - return true; - } - return permissions.has(psender, permission); - } - - private boolean hasPermNode(ServerPlayer psender, String permission) { - PermissionsHandler ph = PermissionsHandler.getHandler(); - if ((psender != null) && (ph != null) && ph.hasPermissionNode(psender.getName().getString(), permission)) { - return true; - } - return permissions.hasPermissionNode(psender, permission); - } - - private 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; - } - private 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); - } - - /** - * Server access abstraction class - */ - public class ForgeServer extends DynmapServerInterface - { - /* Server thread scheduler */ - private Object schedlock = new Object(); - private long cur_tick; - private long next_id; - private long cur_tick_starttime; - private PriorityQueue runqueue = new PriorityQueue(); - - public ForgeServer() { - } - - private GameProfile getProfileByName(String player) { - GameProfileCache cache = server.getProfileCache(); - Optional val = cache.get(player); - return val.isPresent() ? val.get() : null; - } - - @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) - { - TaskRecord tr = new TaskRecord(); - tr.future = new FutureTask(run, null); - - /* Add task record to queue */ - synchronized (schedlock) - { - tr.id = next_id++; - tr.ticktorun = cur_tick + delay; - runqueue.add(tr); - } - } - @Override - public DynmapPlayer[] getOnlinePlayers() - { - if(server.getPlayerList() == null) - return new DynmapPlayer[0]; - List playlist = server.getPlayerList().getPlayers(); - int pcnt = playlist.size(); - DynmapPlayer[] dplay = new DynmapPlayer[pcnt]; - - for (int i = 0; i < pcnt; i++) - { - ServerPlayer p = playlist.get(i); - dplay[i] = getOrAddPlayer(p); - } - - return dplay; - } - @Override - public void reload() - { - plugin.onDisable(); - plugin.onEnable(); - plugin.onStart(); - } - @Override - public DynmapPlayer getPlayer(String name) - { - List players = server.getPlayerList().getPlayers(); - - for (ServerPlayer p : players) - { - if (p.getName().getString().equalsIgnoreCase(name)) - { - return getOrAddPlayer(p); - } - } - - return null; - } - @Override - public Set getIPBans() - { - UserBanList bl = server.getPlayerList().getBans(); - Set ips = new HashSet(); - - for (String s : bl.getUserList()) { - ips.add(s); - } - - return ips; - } - @Override - public Future callSyncMethod(Callable task) { - return callSyncMethod(task, 0); - } - public Future callSyncMethod(Callable task, long delay) - { - TaskRecord tr = new TaskRecord(); - FutureTask ft = new FutureTask(task); - tr.future = ft; - - /* Add task record to queue */ - synchronized (schedlock) - { - tr.id = next_id++; - tr.ticktorun = cur_tick + delay; - runqueue.add(tr); - } - - return ft; - } - @Override - public String getServerName() - { - String sn; - if (server.isSingleplayer()) - sn = "Integrated"; - else - sn = server.getLocalIp(); - if(sn == null) sn = "Unknown Server"; - return sn; - } - @Override - public boolean isPlayerBanned(String pid) - { - UserBanList bl = server.getPlayerList().getBans(); - return bl.isBanned(getProfileByName(pid)); - } - - @Override - public String stripChatColor(String s) - { - return patternControlCode.matcher(s).replaceAll(""); - } - private Set registered = new HashSet(); - @Override - public boolean requestEventNotification(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 (chathandler == null) { - chathandler = new ChatHandler(); - MinecraftForge.EVENT_BUS.register(chathandler); - } - 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) - { - Component component = Component.literal(msg); - server.getPlayerList().broadcastSystemMessage(component, false); - 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(sscache != null) - return sscache.getHitRate(); - return 0.0; - } - @Override - public void resetCacheStats() - { - if(sscache != null) - sscache.resetStats(); - } - @Override - public DynmapWorld getWorldByName(String wname) - { - return DynmapPlugin.this.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) - { - net.minecraft.server.players.PlayerList scm = server.getPlayerList(); - if (scm == null) return Collections.emptySet(); - UserBanList bl = scm.getBans(); - if (bl == null) return Collections.emptySet(); - if(bl.isBanned(getProfileByName(player))) { - return Collections.emptySet(); - } - Set rslt = 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) - { - net.minecraft.server.players.PlayerList scm = server.getPlayerList(); - if (scm == null) return false; - UserBanList bl = scm.getBans(); - if (bl == null) return false; - if(bl.isBanned(getProfileByName(player))) { - return false; - } - return 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) - { - ForgeMapChunkCache c = (ForgeMapChunkCache) 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 (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 ForgeMapChunkCache cc = c; - Future f = this.callSyncMethod(new Callable() { - public Boolean call() throws Exception { - // Update busy state on world - ForgeWorld fw = (ForgeWorld)cc.getWorld(); - //TODO - //setBusy(fw.getWorld()); - cc.getLoadedChunks(); - return true; - } - }, 0); - try { - f.get(); - } - catch (CancellationException cx) { - return null; - } - catch (InterruptedException 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() == false) { - return null; - } - // Now, do rest of chunk reading from calling thread - c.readChunks(chunks.size()); - - return c; - } - @Override - public int getMaxPlayers() - { - return server.getMaxPlayers(); - } - @Override - public int getCurrentPlayers() - { - return server.getPlayerList().getPlayerCount(); - } - - @SubscribeEvent - public void tickEvent(TickEvent.ServerTickEvent event) { - if (event.phase == TickEvent.Phase.START) { - return; - } - cur_tick_starttime = System.nanoTime(); - long elapsed = cur_tick_starttime - lasttick; - lasttick = cur_tick_starttime; - avgticklen = ((avgticklen * 99) / 100) + (elapsed / 100); - tps = (double)1E9 / (double)avgticklen; - // Tick core - if (core != null) { - core.serverTick(tps); - } - - boolean done = false; - TaskRecord tr = null; - - while(!blockupdatequeue.isEmpty()) { - BlockUpdateRec r = blockupdatequeue.remove(); - BlockState bs = r.w.getBlockState(new BlockPos(r.x, r.y, r.z)); - int idx = Block.BLOCK_STATE_REGISTRY.getId(bs); - if((idx >= 0) && (!org.dynmap.hdmap.HDBlockModels.isChangeIgnoredBlock(stateByID[idx]))) { - if(onblockchange_with_id) - mapManager.touch(r.wid, r.x, r.y, r.z, "blockchange[" + idx + "]"); - else - 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.ticktorun > cur_tick) || ((now - cur_tick_starttime) > perTickLimit)) { - done = true; - } - else { - tr = runqueue.poll(); - } - } - while (!done) { - tr.future.run(); - - synchronized(schedlock) { - tr = runqueue.peek(); - now = System.nanoTime(); - /* Nothing due to run */ - if((tr == null) || (tr.ticktorun > cur_tick) || ((now - cur_tick_starttime) > perTickLimit)) { - done = true; - } - else { - tr = runqueue.poll(); - } - } - } - while(!msgqueue.isEmpty()) { - ChatMessage cm = msgqueue.poll(); - DynmapPlayer dp = null; - if(cm.sender != null) - dp = getOrAddPlayer(cm.sender); - else - dp = new ForgePlayer(null); - - core.listenerManager.processChatEvent(EventType.PLAYER_CHAT, dp, cm.message); - } - // Check for generated chunks - if((cur_tick % 20) == 0) { - } - } - - @Override - public boolean isModLoaded(String name) { - boolean loaded = ModList.get().isLoaded(name); - if (loaded) { - modsused.add(name); - } - return loaded; - } - @Override - public String getModVersion(String name) { - Optional mod = ModList.get().getModContainerById(name); // Try case sensitive lookup - if (mod.isPresent()) { - ArtifactVersion vi = mod.get().getModInfo().getVersion(); - return vi.getMajorVersion() + "." + vi.getMinorVersion() + "." + vi.getIncrementalVersion(); - } - return null; - } - @Override - public double getServerTPS() { - return tps; - } - - @Override - public String getServerIP() { - if (server.isSingleplayer()) - return "0.0.0.0"; - else - return server.getLocalIp(); - } - @Override - public File getModContainerFile(String name) { - ModFileInfo mfi = LoadingModList.get().getModFileById(name); // Try case sensitive lookup - if (mfi != null) { - try { - File f = mfi.getFile().getFilePath().toFile(); - return f; - } - catch (UnsupportedOperationException ex) { - //TODO Implement proper jar in jar method for fetching data -/* - Log.info("Searching for: " + name); - for (IModInfo e: ModList.get().getMods()) { - Log.info("in: " + e.getModId().toString()); - Log.info("resource: "+ ModList.get().getModFileById(e.getModId()).getFile().findResource(String.valueOf(mfi.getFile().getFilePath()))); - } -*/ - Log.warning("jar in jar method found, skipping: " + ex.getMessage()); - } - } - return null; - } - @Override - public List getModList() { - List mil = LoadingModList.get().getMods(); - List lst = new ArrayList(); - for (ModInfo mi : mil) { - lst.add(mi.getModId()); - } - return lst; - } - - @Override - public Map getBlockIDMap() { - Map map = new HashMap(); - return map; - } - - @Override - public InputStream openResource(String modid, String rname) { - if (modid == null) modid = "minecraft"; - - Optional mc = ModList.get().getModContainerById(modid); - Object mod = (mc.isPresent()) ? mc.get().getMod() : null; - if (mod != null) { - ClassLoader cl = mod.getClass().getClassLoader(); - if (cl == null) cl = ClassLoader.getSystemClassLoader(); - InputStream is = cl.getResourceAsStream(rname); - if (is != null) { - return is; - } - } - List mcl = LoadingModList.get().getMods(); - for (ModInfo mci : mcl) { - mc = ModList.get().getModContainerById(mci.getModId()); - mod = (mc.isPresent()) ? mc.get().getMod() : null; - if (mod == null) continue; - ClassLoader cl = mod.getClass().getClassLoader(); - if (cl == null) cl = ClassLoader.getSystemClassLoader(); - InputStream is = cl.getResourceAsStream(rname); - if (is != null) { - return is; - } - } - return 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; - } - - } - private static final Gson gson = new GsonBuilder().create(); - - public class TexturesPayload { - public long timestamp; - public String profileId; - public String profileName; - public boolean isPublic; - public Map textures; - - } - public class ProfileTexture { - public String url; - } - - /** - * Player access abstraction class - */ - public class ForgePlayer extends ForgeCommandSender implements DynmapPlayer - { - private ServerPlayer player; - private final String skinurl; - private final UUID uuid; - - - public ForgePlayer(ServerPlayer p) - { - player = p; - String url = null; - if (player != null) { - uuid = player.getUUID(); - GameProfile prof = player.getGameProfile(); - if (prof != null) { - Property textureProperty = Iterables.getFirst(prof.getProperties().get("textures"), null); - - if (textureProperty != null) { - TexturesPayload result = null; - try { - String json = new String(Base64.getDecoder().decode(textureProperty.getValue()), StandardCharsets.UTF_8); - result = gson.fromJson(json, 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; - } - Vec3 v = player.position(); - return toLoc(player.getLevel(), v.x, v.y, v.z); - } - @Override - public String getWorld() - { - if (player == null) - { - return null; - } - - if (player.level != null) - { - return DynmapPlugin.this.getWorld((ServerLevel)player.level).getName(); - } - - return null; - } - public static final Connection getNetworkManager(ServerGamePacketListenerImpl nh) { - return nh.connection; - } - - @Override - public InetSocketAddress getAddress() - { - if((player != null) && (player instanceof ServerPlayer)) { - ServerGamePacketListenerImpl nsh = ((ServerPlayer)player).connection; - if((nsh != null) && (getNetworkManager(nsh) != null)) { - SocketAddress sa = getNetworkManager(nsh).getRemoteAddress(); - if(sa instanceof InetSocketAddress) { - return (InetSocketAddress)sa; - } - } - } - return null; - } - @Override - public boolean isSneaking() - { - if (player != null) - { - return player.getPose() == Pose.CROUCHING; - } - - 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.getArmorValue(); - } - 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 hasPerm(player, privid); - return false; - } - @Override - public boolean isOp() - { - return DynmapPlugin.this.isOp(player.getName().getString()); - } - @Override - public void sendMessage(String msg) - { - Component ichatcomponent = Component.literal(msg); - player.sendSystemMessage(ichatcomponent); - } - @Override - public boolean isInvisible() { - if(player != null) { - return player.isInvisible(); - } - return false; - } - @Override - public boolean isSpectator() { - if(player != null) { - return player.isSpectator(); - } - return false; - } - @Override - public int getSortWeight() { - Integer wt = sortWeights.get(getName()); - if (wt != null) - return wt; - return 0; - } - @Override - public void setSortWeight(int wt) { - if (wt == 0) { - sortWeights.remove(getName()); - } - else { - sortWeights.put(getName(), wt); - } - } - @Override - public boolean hasPermissionNode(String node) { - if(player != null) - return hasPermNode(player, node); - return false; - } - @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 instanceof ServerPlayer) { - ServerPlayer mp = (ServerPlayer) player; - ClientboundSetTitlesAnimationPacket times = new ClientboundSetTitlesAnimationPacket(fadeInTicks, stayTicks, fadeOutTicks); - mp.connection.send(times); - if (title != null) { - ClientboundSetTitleTextPacket titlepkt = new ClientboundSetTitleTextPacket(Component.literal(title)); - mp.connection.send(titlepkt); - } - - if (subtitle != null) { - ClientboundSetSubtitleTextPacket subtitlepkt = new ClientboundSetSubtitleTextPacket(Component.literal(subtitle)); - mp.connection.send(subtitlepkt); - } - } - } - } - /* Handler for generic console command sender */ - public class ForgeCommandSender implements DynmapCommandSender - { - private CommandSourceStack sender; - - protected ForgeCommandSender() { - sender = null; - } - - public ForgeCommandSender(CommandSourceStack send) - { - sender = send; - } - - @Override - public boolean hasPrivilege(String privid) - { - return true; - } - - @Override - public void sendMessage(String msg) - { - if(sender != null) { - Component ichatcomponent = Component.literal(msg); - sender.sendSuccess(ichatcomponent, true); - } - } - - @Override - public boolean isConnected() - { - return false; - } - @Override - public boolean isOp() - { - return true; - } - @Override - public boolean hasPermissionNode(String node) { - return true; - } - } - - 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) { - ResourceLocation regid = getBiomeReg().getKey(bb); - String id = regid.getPath(); - String rl = regid.toString(); - float tmp = bb.getBaseTemperature(), hum = bb.getDownfall(); - int watermult = bb.getWaterColor(); - Log.verboseinfo("biome[" + i + "]: hum=" + hum + ", tmp=" + tmp + ", mult=" + Integer.toHexString(watermult)); - - BiomeMap bmap = BiomeMap.NULL; - if (rl != null) { // If resource location, lookup by this - bmap = BiomeMap.byBiomeResourceLocation(rl); - } - else { - bmap = BiomeMap.byBiomeID(i); - } - if (bmap.isDefault() || (bmap == BiomeMap.NULL)) { - bmap = new BiomeMap((rl != null) ? BiomeMap.NO_INDEX : i, id, tmp, hum, rl); - 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)); - } - bmap.setBiomeObject(bb); - } - } - 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] = bb.toString(); - } - } - return lst; - } - - public void onEnable() - { - /* Get MC version */ - String mcver = server.getServerVersion(); - /* 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() == false) - { - 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); - 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 static int test(CommandSource source) throws CommandSyntaxException - { - Log.warning(source.toString()); - return 1; - } - - private DynmapCommand dynmapCmd; - private DmapCommand dmapCmd; - private DmarkerCommand dmarkerCmd; - private DynmapExpCommand dynmapexpCmd; - - public void onStarting(CommandDispatcher cd) { - /* Register command hander */ - 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) { - MinecraftForge.EVENT_BUS.register(fserver); - tickregistered = true; - } - - playerList = core.playerList; - sscache = new GenericChunkCache(core.getSnapShotCacheSize(), core.useSoftRefInSnapShotCache()); - /* Get map manager from core */ - mapManager = core.getMapManager(); - - /* Load saved world definitions */ - loadWorlds(); - - /* Initialized the currently loaded worlds */ - for (ServerLevel world : server.getAllLevels()) { - ForgeWorld w = this.getWorld(world); - } - for(ForgeWorld 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(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.runqueue.clear(); - - /* Disable core */ - core.disableCore(); - core_enabled = false; - - if (sscache != null) - { - sscache.cleanup(); - sscache = null; - } - - Log.info("Disabled"); - } - - void onCommand(CommandSourceStack commandSourceStack, String cmd, String[] args) - { - DynmapCommandSender dsender; - ServerPlayer psender; - try { - psender = commandSourceStack.getPlayerOrException(); - } catch (com.mojang.brigadier.exceptions.CommandSyntaxException x) { - psender = null; - } - - if (psender != null) - { - dsender = new ForgePlayer(psender); - } - else - { - dsender = new ForgeCommandSender(commandSourceStack); - } - try { - core.processCommand(dsender, cmd, cmd, args); - } catch (Exception x) { - dsender.sendMessage("Command internal error: " + x.getMessage()); - Log.severe("Error with command: " + cmd + Arrays.deepToString(args), x); - } - } - - private DynmapLocation toLoc(ServerLevel level, double x, double y, double z) - { - return new DynmapLocation(DynmapPlugin.this.getWorld(level).getName(), x, y, z); - } - - public class PlayerTracker { - @SubscribeEvent - public void onPlayerLogin(PlayerLoggedInEvent event) { - if(!core_enabled) return; - final DynmapPlayer dp = getOrAddPlayer((ServerPlayer)event.getEntity()); - /* This event can be called from off server thread, so push processing there */ - core.getServer().scheduleServerTask(new Runnable() { - public void run() { - core.listenerManager.processPlayerEvent(EventType.PLAYER_JOIN, dp); - } - }, 2); - } - @SubscribeEvent - public void onPlayerLogout(PlayerLoggedOutEvent event) { - if(!core_enabled) return; - final DynmapPlayer dp = getOrAddPlayer((ServerPlayer)event.getEntity()); - final String name = event.getEntity().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(EventType.PLAYER_QUIT, dp); - players.remove(name); - } - }, 0); - } - @SubscribeEvent - public void onPlayerChangedDimension(PlayerChangedDimensionEvent event) { - if(!core_enabled) return; - getOrAddPlayer((ServerPlayer)event.getEntity()); // Freshen player object reference - } - @SubscribeEvent - public void onPlayerRespawn(PlayerRespawnEvent event) { - if(!core_enabled) return; - getOrAddPlayer((ServerPlayer)event.getEntity()); // Freshen player object reference - } - } - private PlayerTracker playerTracker = null; - - private void registerPlayerLoginListener() - { - if (playerTracker == null) { - playerTracker = new PlayerTracker(); - MinecraftForge.EVENT_BUS.register(playerTracker); - } - } - - public class WorldTracker { - @SubscribeEvent(priority=EventPriority.LOWEST) - public void handleWorldLoad(LevelEvent.Load event) { - if(!core_enabled) return; - LevelAccessor w = event.getLevel(); - if(!(w instanceof ServerLevel)) return; - final ForgeWorld fw = getWorld((ServerLevel)w); - // 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(EventType.WORLD_LOAD, fw); - } - }, 0); - } - @SubscribeEvent(priority=EventPriority.LOWEST) - public void handleWorldUnload(LevelEvent.Unload event) { - if(!core_enabled) return; - LevelAccessor w = event.getLevel(); - if(!(w instanceof ServerLevel)) return; - final ForgeWorld fw = getWorld((ServerLevel)w); - 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(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; - } - } - - @SubscribeEvent(priority=EventPriority.LOWEST) - public void handleChunkLoad(ChunkEvent.Load event) { - if(!onchunkgenerate) return; - - LevelAccessor w = event.getLevel(); - if(!(w instanceof ServerLevel)) return; - ChunkAccess c = event.getChunk(); - if ((c != null) && (c.getStatus() == ChunkStatus.FULL) && (c instanceof LevelChunk)) { - ForgeWorld fw = getWorld((ServerLevel)w, false); - if (fw != null) { - addKnownChunk(fw, c.getPos()); - } - } - } - @SubscribeEvent(priority=EventPriority.LOWEST) - public void handleChunkUnload(ChunkEvent.Unload event) { - if(!onchunkgenerate) return; - - LevelAccessor w = event.getLevel(); - if(!(w instanceof ServerLevel)) return; - ChunkAccess c = event.getChunk(); - if (c != null) { - ForgeWorld fw = getWorld((ServerLevel)w, false); - ChunkPos cp = c.getPos(); - if (fw != null) { - if (!checkIfKnownChunk(fw, cp)) { - int ymax = Integer.MIN_VALUE; - int ymin = Integer.MAX_VALUE; - LevelChunkSection[] sections = c.getSections(); - for(int i = 0; i < sections.length; i++) { - if((sections[i] != null) && (sections[i].hasOnlyAir() == false)) { - int sy = sections[i].bottomBlockY(); - if (sy < ymin) ymin = sy; - if ((sy+16) > ymax) ymax = sy + 16; - } - } - int x = cp.x << 4; - int z = cp.z << 4; - // If not empty AND not initial scan - if (ymax != Integer.MIN_VALUE) { - //Log.info(String.format("chunkkeyerate(unload)(%s,%d,%d,%d,%d,%d,%s)", fw.getName(), x, ymin, z, x+15, ymax, z+15)); - mapManager.touchVolume(fw.getName(), x, ymin, z, x+15, ymax, z+15, "chunkgenerate"); - } - } - removeKnownChunk(fw, cp); - } - } - } - @SubscribeEvent(priority=EventPriority.LOWEST) - public void handleChunkDataSave(ChunkDataEvent.Save event) { - if(!onchunkgenerate) return; - - LevelAccessor w = event.getLevel(); - if(!(w instanceof ServerLevel)) return; - ChunkAccess c = event.getChunk(); - if (c != null) { - ForgeWorld fw = getWorld((ServerLevel)w, false); - ChunkPos cp = c.getPos(); - if (fw != null) { - if (!checkIfKnownChunk(fw, cp)) { - int ymax = Integer.MIN_VALUE; - int ymin = Integer.MAX_VALUE; - LevelChunkSection[] sections = c.getSections(); - for(int i = 0; i < sections.length; i++) { - if((sections[i] != null) && (sections[i].hasOnlyAir() == false)) { - int sy = sections[i].bottomBlockY(); - if (sy < ymin) ymin = sy; - if ((sy+16) > ymax) ymax = sy + 16; - } - } - int x = cp.x << 4; - int z = cp.z << 4; - // If not empty AND not initial scan - if (ymax != Integer.MIN_VALUE) { - //Log.info(String.format("chunkkeyerate(save)(%s,%d,%d,%d,%d,%d,%s)", fw.getName(), x, ymin, z, x+15, ymax, z+15)); - mapManager.touchVolume(fw.getName(), x, ymin, z, x+15, ymax, z+15, "chunkgenerate"); - } - // If cooked, add to known - if ((c.getStatus() == ChunkStatus.FULL) && (c instanceof LevelChunk)) { - addKnownChunk(fw, cp); - } - } - } - } - } - @SubscribeEvent(priority=EventPriority.LOWEST) - public void handleBlockEvent(BlockEvent event) { - if(!core_enabled) return; - if(!onblockchange) return; - BlockUpdateRec r = new BlockUpdateRec(); - r.w = event.getLevel(); - if(!(r.w instanceof ServerLevel)) return; // band-aid to prevent errors in unsupported 'running in client' scenario - ForgeWorld fw = getWorld((ServerLevel)r.w, false); - if (fw == null) return; - r.wid = fw.getName(); - BlockPos p = event.getPos(); - r.x = p.getX(); - r.y = p.getY(); - r.z = p.getZ(); - blockupdatequeue.add(r); - } - } - private WorldTracker worldTracker = null; - private boolean onblockchange = false; - private boolean onchunkpopulate = false; - private boolean onchunkgenerate = false; - private 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(); - MinecraftForge.EVENT_BUS.register(worldTracker); - } - // Prime the known full chunks - if (onchunkgenerate && (server.getAllLevels() != null)) { - for (ServerLevel world : server.getAllLevels()) { - ForgeWorld fw = getWorld(world); - if (fw == null) continue; - Long2ObjectLinkedOpenHashMap chunks = world.getChunkSource().chunkMap.visibleChunkMap; - for (Entry k : chunks.long2ObjectEntrySet()) { - long key = k.getKey().longValue(); - ChunkHolder ch = k.getValue(); - ChunkAccess c = null; - try { - c = ch.getLastAvailable(); - } 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); - } - } - } - } - } - - private ForgeWorld getWorldByName(String name) { - return worlds.get(name); - } - - private ForgeWorld getWorld(ServerLevel w) { - return getWorld(w, true); - } - - private ForgeWorld getWorld(ServerLevel w, boolean add_if_not_found) { - if(last_world == w) { - return last_fworld; - } - String wname = ForgeWorld.getWorldName(w); - - for(ForgeWorld fw : worlds.values()) { - if(fw.getRawName().equals(wname)) { - last_world = w; - last_fworld = fw; - if(fw.isLoaded() == false) { - fw.setWorldLoaded(w); - } - fw.updateWorld(w); - return fw; - } - } - ForgeWorld fw = null; - if(add_if_not_found) { - /* Add to list if not found */ - fw = new ForgeWorld(w); - worlds.put(fw.getName(), fw); - } - last_world = w; - last_fworld = fw; - return fw; - } - - private void saveWorlds() { - File f = new File(core.getDataFolder(), "forgeworlds.yml"); - 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("miny", fw.minY); - vals.put("sealevel", fw.sealevel); - vals.put("nether", fw.isNether()); - vals.put("the_end", ((ForgeWorld)fw).isTheEnd()); - vals.put("title", fw.getTitle()); - lst.add(vals); - } - cn.put("worlds", lst); - cn.put("useSaveFolderAsName", useSaveFolder); - cn.put("maxWorldHeight", ForgeWorld.getMaxWorldHeight()); - - cn.save(); - } - private void loadWorlds() { - File f = new File(core.getDataFolder(), "forgeworlds.yml"); - if(f.canRead() == false) { - useSaveFolder = true; - return; - } - ConfigurationNode cn = new ConfigurationNode(f); - cn.load(); - // If defined, use maxWorldHeight - ForgeWorld.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("Discarding bad forgeworlds.yml"); - return; - } - - for(Map world : lst) { - try { - String name = (String)world.get("name"); - int height = (Integer)world.get("height"); - Integer miny = (Integer) world.get("miny"); - 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) { - ForgeWorld fw = new ForgeWorld(name, height, sealevel, nether, theend, title, (miny != null) ? miny : 0); - fw.setWorldUnloaded(); - core.processWorldLoad(fw); - worlds.put(fw.getName(), fw); - } - } catch (Exception x) { - Log.warning("Unable to load saved worlds from forgeworlds.yml"); - return; - } - } - } - public void serverStarted() { - this.onStart(); - if (core != null) { - core.serverStarted(); - } - } - public MinecraftServer getMCServer() { - return server; - } -} - -class DynmapCommandHandler -{ - private String cmd; - private DynmapPlugin plugin; - - public DynmapCommandHandler(String cmd, DynmapPlugin p) - { - this.cmd = cmd; - this.plugin = p; - } - - public void register(CommandDispatcher cd) { - cd.register(Commands.literal(cmd). - then(RequiredArgumentBuilder. argument("args", StringArgumentType.greedyString()). - executes((ctx) -> this.execute(plugin.getMCServer(), ctx.getSource(), ctx.getInput()))). - executes((ctx) -> this.execute(plugin.getMCServer(), ctx.getSource(), ctx.getInput()))); - } - -// @Override - public int execute(MinecraftServer server, CommandSourceStack commandSourceStack, - String cmdline) { - String[] args = cmdline.split("\\s+"); - plugin.onCommand(commandSourceStack, cmd, Arrays.copyOfRange(args, 1, args.length)); - return 1; - } - -// @Override - public String getUsage(CommandSource arg0) { - return "Run /" + cmd + " help for details on using command"; - } -} - -class DynmapCommand extends DynmapCommandHandler { - DynmapCommand(DynmapPlugin p) { - super("dynmap", p); - } -} -class DmapCommand extends DynmapCommandHandler { - DmapCommand(DynmapPlugin p) { - super("dmap", p); - } -} -class DmarkerCommand extends DynmapCommandHandler { - DmarkerCommand(DynmapPlugin p) { - super("dmarker", p); - } -} -class DynmapExpCommand extends DynmapCommandHandler { - DynmapExpCommand(DynmapPlugin p) { - super("dynmapexp", p); - } -} - diff --git a/forge-1.19.2/src/main/java/org/dynmap/forge_1_19_2/ForgeMapChunkCache.java b/forge-1.19.2/src/main/java/org/dynmap/forge_1_19_2/ForgeMapChunkCache.java deleted file mode 100644 index 8a4a5013..00000000 --- a/forge-1.19.2/src/main/java/org/dynmap/forge_1_19_2/ForgeMapChunkCache.java +++ /dev/null @@ -1,109 +0,0 @@ -package org.dynmap.forge_1_19_2; - -import java.util.List; -import java.util.NoSuchElementException; - -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.biome.BiomeSpecialEffects; -import org.dynmap.DynmapChunk; -import org.dynmap.Log; -import org.dynmap.common.BiomeMap; -import org.dynmap.common.chunk.GenericChunk; -import org.dynmap.common.chunk.GenericChunkCache; -import org.dynmap.common.chunk.GenericMapChunkCache; - -import net.minecraft.nbt.CompoundTag; -import net.minecraft.server.level.ServerChunkCache; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.level.ChunkPos; -import net.minecraft.world.level.chunk.ChunkAccess; -import net.minecraft.world.level.chunk.ChunkStatus; -import net.minecraft.world.level.chunk.storage.ChunkSerializer; - -/** - * Container for managing chunks - dependent upon using chunk snapshots, since - * rendering is off server thread - */ -public class ForgeMapChunkCache extends GenericMapChunkCache { - private ServerLevel w; - private ServerChunkCache cps; - /** - * Construct empty cache - */ - public ForgeMapChunkCache(GenericChunkCache cc) { - super(cc); - } - - // Load generic chunk from existing and already loaded chunk - protected GenericChunk getLoadedChunk(DynmapChunk chunk) { - GenericChunk gc = null; - ChunkAccess ch = cps.getChunk(chunk.x, chunk.z, ChunkStatus.FULL, false); - if (ch != null) { - CompoundTag nbt = ChunkSerializer.write(w, ch); - if (nbt != null) { - gc = parseChunkFromNBT(new NBT.NBTCompound(nbt)); - } - } - return gc; - } - // Load generic chunk from unloaded chunk - protected GenericChunk loadChunk(DynmapChunk chunk) { - GenericChunk gc = null; - CompoundTag nbt = readChunk(chunk.x, chunk.z); - // If read was good - if (nbt != null) { - gc = parseChunkFromNBT(new NBT.NBTCompound(nbt)); - } - return gc; - } - - public void setChunks(ForgeWorld dw, List chunks) { - this.w = dw.getWorld(); - if (dw.isLoaded()) { - /* Check if world's provider is ServerChunkProvider */ - cps = this.w.getChunkSource(); - } - super.setChunks(dw, chunks); - } - - private CompoundTag readChunk(int x, int z) { - try { - CompoundTag rslt = cps.chunkMap.read(new ChunkPos(x, z)).join().get(); - if (rslt != null) { - CompoundTag lev = rslt; - if (lev.contains("Level")) { - lev = lev.getCompound("Level"); - } - // Don't load uncooked chunks - String stat = lev.getString("Status"); - ChunkStatus cs = ChunkStatus.byName(stat); - if ((stat == null) || - // Needs to be at least lighted - (!cs.isOrAfter(ChunkStatus.LIGHT))) { - rslt = null; - } - } - // Log.info(String.format("loadChunk(%d,%d)=%s", x, z, (rslt != null) ? - // rslt.toString() : "null")); - return rslt; - } catch (NoSuchElementException nsex) { - return null; - } catch (Exception exc) { - Log.severe(String.format("Error reading chunk: %s,%d,%d", dw.getName(), x, z), exc); - return null; - } - } - @Override - public int getFoliageColor(BiomeMap bm, int[] colormap, int x, int z) { - return bm.getBiomeObject().map(Biome::getSpecialEffects) - .flatMap(BiomeSpecialEffects::getFoliageColorOverride) - .orElse(colormap[bm.biomeLookup()]); - } - - @Override - public int getGrassColor(BiomeMap bm, int[] colormap, int x, int z) { - BiomeSpecialEffects effects = bm.getBiomeObject().map(Biome::getSpecialEffects).orElse(null); - if (effects == null) return colormap[bm.biomeLookup()]; - return effects.getGrassColorModifier().modifyColor(x, z, effects.getGrassColorOverride().orElse(colormap[bm.biomeLookup()])); - } -} diff --git a/forge-1.19.2/src/main/java/org/dynmap/forge_1_19_2/ForgeWorld.java b/forge-1.19.2/src/main/java/org/dynmap/forge_1_19_2/ForgeWorld.java deleted file mode 100644 index fd3c6de2..00000000 --- a/forge-1.19.2/src/main/java/org/dynmap/forge_1_19_2/ForgeWorld.java +++ /dev/null @@ -1,249 +0,0 @@ -package org.dynmap.forge_1_19_2; -/** - * Forge specific implementation of DynmapWorld - */ -import java.util.List; - -import net.minecraft.world.level.ServerLevelAccessor; -import net.minecraft.world.level.border.WorldBorder; -import net.minecraft.world.level.levelgen.Heightmap; -import net.minecraft.core.BlockPos; -import net.minecraft.resources.ResourceKey; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.LightLayer; - -import org.dynmap.DynmapChunk; -import org.dynmap.DynmapLocation; -import org.dynmap.DynmapWorld; -import org.dynmap.utils.MapChunkCache; -import org.dynmap.utils.Polygon; - -public class ForgeWorld extends DynmapWorld -{ - private ServerLevelAccessor 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 = 320; // Maximum allows world height - - public static int getMaxWorldHeight() { - return maxWorldHeight; - } - public static void setMaxWorldHeight(int h) { - maxWorldHeight = h; - } - - public static String getWorldName(ServerLevelAccessor w) { - ResourceKey rk = w.getLevel().dimension(); - String id = rk.location().getNamespace() + "_" + rk.location().getPath(); - if (id.equals("minecraft_overworld")) { // Overworld? - return w.getLevel().serverLevelData.getLevelName(); - } - else if (id.equals("minecraft_the_end")) { - return "DIM1"; - } - else if (id.equals("minecraft_the_nether")) { - return "DIM-1"; - } - else { - return id; - } - } - - public void updateWorld(ServerLevelAccessor w) { - this.updateWorldHeights(w.getLevel().getHeight(), w.getLevel().dimensionType().minY(), w.getLevel().getSeaLevel()); - } - - public ForgeWorld(ServerLevelAccessor w) - { - this(getWorldName(w), - w.getLevel().getHeight(), - w.getLevel().getSeaLevel(), - w.getLevel().dimension() == Level.NETHER, - w.getLevel().dimension() == Level.END, - getWorldName(w), - w.getLevel().dimensionType().minY()); - setWorldLoaded(w); - } - public ForgeWorld(String name, int height, int sealevel, boolean nether, boolean the_end, String deftitle, int miny) - { - super(name, (height > maxWorldHeight)?maxWorldHeight:height, sealevel, miny); - 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"; - } - //Log.info(getName() + ": skylight=" + skylight + ", height=" + this.worldheight + ", isnether=" + isnether + ", istheend=" + istheend); - } - /* 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) { - BlockPos p = world.getLevel().getSharedSpawnPos(); - spawnloc.x = p.getX(); - spawnloc.y = p.getY(); - spawnloc.z = p.getZ(); - spawnloc.world = this.getName(); - } - return spawnloc; - } - /* Get world time */ - @Override - public long getTime() - { - if(world != null) - return world.getLevel().getDayTime(); - else - return -1; - } - /* World is storming */ - @Override - public boolean hasStorm() - { - if(world != null) - return world.getLevel().isRaining(); - else - return false; - } - /* World is thundering */ - @Override - public boolean isThundering() - { - if(world != null) - return world.getLevel().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(ServerLevelAccessor w) { - world = w; - this.sealevel = w.getLevel().getSeaLevel(); // Read actual current sealevel from world - // Update lighting table - for (int i = 0; i < 16; i++) { - // Algorithm based on LightmapTextureManager.getBrightness() - // We can't call that method because it's client-only. - // This means the code below can stop being correct if Mojang ever - // updates the curve; in that case we should reflect the changes. - float value = (float) i / 15.0f; - float brightness = value / (4.0f - 3.0f * value); - this.setBrightnessTableEntry(i, brightness); - //Log.info(getName() + ": light " + i + " = " + light); - } - } - /* Get light level of block */ - @Override - public int getLightLevel(int x, int y, int z) - { - if(world != null) - return world.getLevel().getLightEngine().getRawBrightness(new BlockPos(x, y, z), 0); - else - return -1; - } - /* Get highest Y coord of given location */ - @Override - public int getHighestBlockYAt(int x, int z) - { - if(world != null) { - return world.getLevel().getChunk(x >> 4, z >> 4).getHeight(Heightmap.Types.MOTION_BLOCKING, 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.getLevel().getBrightness(LightLayer.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) { - ForgeMapChunkCache c = new ForgeMapChunkCache(DynmapPlugin.plugin.sscache); - c.setChunks(this, chunks); - return c; - } - return null; - } - - public ServerLevel getWorld() - { - return world.getLevel(); - } - @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.getMinX(), wb.getMinZ()); - p.addVertex(wb.getMinX(), wb.getMaxZ()); - p.addVertex(wb.getMaxX(), wb.getMaxZ()); - p.addVertex(wb.getMaxX(), wb.getMinZ()); - return p; - } - } - return null; - } -} diff --git a/forge-1.19.2/src/main/java/org/dynmap/forge_1_19_2/NBT.java b/forge-1.19.2/src/main/java/org/dynmap/forge_1_19_2/NBT.java deleted file mode 100644 index 9d4958f0..00000000 --- a/forge-1.19.2/src/main/java/org/dynmap/forge_1_19_2/NBT.java +++ /dev/null @@ -1,126 +0,0 @@ -package org.dynmap.forge_1_19_2; - -import org.dynmap.common.chunk.GenericBitStorage; -import org.dynmap.common.chunk.GenericNBTCompound; -import org.dynmap.common.chunk.GenericNBTList; - -import java.util.Set; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.ListTag; -import net.minecraft.util.SimpleBitStorage; - -public class NBT { - - public static class NBTCompound implements GenericNBTCompound { - private final CompoundTag obj; - public NBTCompound(CompoundTag t) { - this.obj = t; - } - @Override - public Set getAllKeys() { - return obj.getAllKeys(); - } - @Override - public boolean contains(String s) { - return obj.contains(s); - } - @Override - public boolean contains(String s, int i) { - return obj.contains(s, i); - } - @Override - public byte getByte(String s) { - return obj.getByte(s); - } - @Override - public short getShort(String s) { - return obj.getShort(s); - } - @Override - public int getInt(String s) { - return obj.getInt(s); - } - @Override - public long getLong(String s) { - return obj.getLong(s); - } - @Override - public float getFloat(String s) { - return obj.getFloat(s); - } - @Override - public double getDouble(String s) { - return obj.getDouble(s); - } - @Override - public String getString(String s) { - return obj.getString(s); - } - @Override - public byte[] getByteArray(String s) { - return obj.getByteArray(s); - } - @Override - public int[] getIntArray(String s) { - return obj.getIntArray(s); - } - @Override - public long[] getLongArray(String s) { - return obj.getLongArray(s); - } - @Override - public GenericNBTCompound getCompound(String s) { - return new NBTCompound(obj.getCompound(s)); - } - @Override - public GenericNBTList getList(String s, int i) { - return new NBTList(obj.getList(s, i)); - } - @Override - public boolean getBoolean(String s) { - return obj.getBoolean(s); - } - @Override - public String getAsString(String s) { - return obj.get(s).getAsString(); - } - @Override - public GenericBitStorage makeBitStorage(int bits, int count, long[] data) { - return new OurBitStorage(bits, count, data); - } - public String toString() { - return obj.toString(); - } - } - public static class NBTList implements GenericNBTList { - private final ListTag obj; - public NBTList(ListTag t) { - obj = t; - } - @Override - public int size() { - return obj.size(); - } - @Override - public String getString(int idx) { - return obj.getString(idx); - } - @Override - public GenericNBTCompound getCompound(int idx) { - return new NBTCompound(obj.getCompound(idx)); - } - public String toString() { - return obj.toString(); - } - } - public static class OurBitStorage implements GenericBitStorage { - private final SimpleBitStorage bs; - public OurBitStorage(int bits, int count, long[] data) { - bs = new SimpleBitStorage(bits, count, data); - } - @Override - public int get(int idx) { - return bs.get(idx); - } - } -} diff --git a/forge-1.19.2/src/main/java/org/dynmap/forge_1_19_2/Proxy.java b/forge-1.19.2/src/main/java/org/dynmap/forge_1_19_2/Proxy.java deleted file mode 100644 index 52bbf140..00000000 --- a/forge-1.19.2/src/main/java/org/dynmap/forge_1_19_2/Proxy.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.dynmap.forge_1_19_2; - -import net.minecraft.server.MinecraftServer; - -/** - * Server side proxy - methods for creating and cleaning up plugin - */ -public class Proxy -{ - public Proxy() - { - } - public DynmapPlugin startServer(MinecraftServer srv) { - DynmapPlugin plugin = DynmapPlugin.plugin; - if (plugin == null) { - plugin = new DynmapPlugin(srv); - plugin.onEnable(); - } - return plugin; - } - public void stopServer(DynmapPlugin plugin) { - plugin.onDisable(); - } -} diff --git a/forge-1.19.2/src/main/java/org/dynmap/forge_1_19_2/VersionCheck.java b/forge-1.19.2/src/main/java/org/dynmap/forge_1_19_2/VersionCheck.java deleted file mode 100644 index b069fbc7..00000000 --- a/forge-1.19.2/src/main/java/org/dynmap/forge_1_19_2/VersionCheck.java +++ /dev/null @@ -1,97 +0,0 @@ -package org.dynmap.forge_1_19_2; - -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.URL; - -import org.dynmap.DynmapCore; -import org.dynmap.Log; - -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/forge-1.19.2/src/main/java/org/dynmap/forge_1_19_2/permissions/FilePermissions.java b/forge-1.19.2/src/main/java/org/dynmap/forge_1_19_2/permissions/FilePermissions.java deleted file mode 100644 index b8f0c75b..00000000 --- a/forge-1.19.2/src/main/java/org/dynmap/forge_1_19_2/permissions/FilePermissions.java +++ /dev/null @@ -1,103 +0,0 @@ -package org.dynmap.forge_1_19_2.permissions; - -import java.io.File; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.dynmap.ConfigurationNode; -import org.dynmap.Log; -import org.dynmap.forge_1_19_2.DynmapPlugin; - -import net.minecraft.server.level.ServerPlayer; - -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(ServerPlayer psender, String permission) { - if(psender != null) { - String n = psender.getName().getString().toLowerCase(); - return hasPerm(n, permission); - } - return true; - } - @Override - public boolean hasPermissionNode(ServerPlayer psender, String permission) { - if(psender != null) { - String player = psender.getName().getString().toLowerCase(); - return DynmapPlugin.plugin.isOp(player); - } - return false; - } - -} diff --git a/forge-1.19.2/src/main/java/org/dynmap/forge_1_19_2/permissions/OpPermissions.java b/forge-1.19.2/src/main/java/org/dynmap/forge_1_19_2/permissions/OpPermissions.java deleted file mode 100644 index 33c2373c..00000000 --- a/forge-1.19.2/src/main/java/org/dynmap/forge_1_19_2/permissions/OpPermissions.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.dynmap.forge_1_19_2.permissions; - -import java.util.HashSet; -import java.util.Set; - -import org.dynmap.Log; -import org.dynmap.forge_1_19_2.DynmapPlugin; - -import net.minecraft.server.level.ServerPlayer; - -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(ServerPlayer 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(ServerPlayer psender, String permission) { - if(psender != null) { - return DynmapPlugin.plugin.isOp(psender.getName().getString()); - } - return true; - } -} diff --git a/forge-1.19.2/src/main/java/org/dynmap/forge_1_19_2/permissions/PermissionProvider.java b/forge-1.19.2/src/main/java/org/dynmap/forge_1_19_2/permissions/PermissionProvider.java deleted file mode 100644 index 46962227..00000000 --- a/forge-1.19.2/src/main/java/org/dynmap/forge_1_19_2/permissions/PermissionProvider.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.dynmap.forge_1_19_2.permissions; - -import java.util.Set; - -import net.minecraft.server.level.ServerPlayer; - -public interface PermissionProvider { - boolean has(ServerPlayer sender, String permission); - boolean hasPermissionNode(ServerPlayer sender, String permission); - - Set hasOfflinePermissions(String player, Set perms); - - boolean hasOfflinePermission(String player, String perm); - -} diff --git a/forge-1.19.2/src/main/resources/META-INF/accesstransformer.cfg b/forge-1.19.2/src/main/resources/META-INF/accesstransformer.cfg deleted file mode 100644 index 58a91d30..00000000 --- a/forge-1.19.2/src/main/resources/META-INF/accesstransformer.cfg +++ /dev/null @@ -1,4 +0,0 @@ -public net.minecraft.world.level.biome.BiomeSpecialEffects$Builder f_47928_ # waterColor -public net.minecraft.server.level.ServerLevel f_8549_ # serverLevelData -public net.minecraft.server.level.ChunkMap f_140130_ # visibleChunkMap -public net.minecraft.server.level.ChunkMap m_214963_(Lnet/minecraft/world/level/ChunkPos;)Ljava/util/concurrent/CompletableFuture; # readChunk( diff --git a/forge-1.19.2/src/main/resources/META-INF/mods.toml b/forge-1.19.2/src/main/resources/META-INF/mods.toml deleted file mode 100644 index 374c7b8b..00000000 --- a/forge-1.19.2/src/main/resources/META-INF/mods.toml +++ /dev/null @@ -1,26 +0,0 @@ -modLoader="javafml" -loaderVersion="[42,)" -issueTrackerURL="https://github.com/webbukkit/dynmap/issues" -license="Apache Public License v2" -[[mods]] -modId="dynmap" -version="${version}" -displayName="Dynmap" -authors="mikeprimm" -description=''' -Dynamic, Google-maps style rendered maps for your Minecraft server -''' - -[[dependencies.dynmap]] - modId="forge" - mandatory=true - versionRange="[42,)" - ordering="NONE" - # Side this dependency is applied on - BOTH, CLIENT or SERVER - side="SERVER" -[[dependencies.dynmap]] - modId="minecraft" - mandatory=true - versionRange="[1.19.1,1.20)" - ordering="NONE" - side="SERVER" diff --git a/forge-1.19.2/src/main/resources/configuration.txt b/forge-1.19.2/src/main/resources/configuration.txt deleted file mode 100644 index eb4b28da..00000000 --- a/forge-1.19.2/src/main/resources/configuration.txt +++ /dev/null @@ -1,503 +0,0 @@ -# All paths in this configuration file are relative to Dynmap's data-folder: minecraft_server/dynmap/ - -# All map templates are defined in the templates directory -# To use the HDMap very-low-res (2 ppb) map templates as world defaults, set value to vlowres -# The definitions of these templates are in normal-vlowres.txt, nether-vlowres.txt, and the_end-vlowres.txt -# To use the HDMap low-res (4 ppb) map templates as world defaults, set value to lowres -# The definitions of these templates are in normal-lowres.txt, nether-lowres.txt, and the_end-lowres.txt -# To use the HDMap hi-res (16 ppb) map templates (these can take a VERY long time for initial fullrender), set value to hires -# The definitions of these templates are in normal-hires.txt, nether-hires.txt, and the_end-hires.txt -# To use the HDMap low-res (4 ppb) map templates, with support for boosting resolution selectively to hi-res (16 ppb), set value to low_boost_hi -# The definitions of these templates are in normal-low_boost_hi.txt, nether-low_boost_hi.txt, and the_end-low_boost_hi.txt -# To use the HDMap hi-res (16 ppb) map templates, with support for boosting resolution selectively to vhi-res (32 ppb), set value to hi_boost_vhi -# The definitions of these templates are in normal-hi_boost_vhi.txt, nether-hi_boost_vhi.txt, and the_end-hi_boost_vhi.txt -# To use the HDMap hi-res (16 ppb) map templates, with support for boosting resolution selectively to xhi-res (64 ppb), set value to hi_boost_xhi -# The definitions of these templates are in normal-hi_boost_xhi.txt, nether-hi_boost_xhi.txt, and the_end-hi_boost_xhi.txt -deftemplatesuffix: hires - -# Set default tile scale (0 = 128px x 128x, 1 = 256px x 256px, 2 = 512px x 512px, 3 = 1024px x 1024px, 4 = 2048px x 2048px) - 0 is default -# Note: changing this value will result in all maps that use the default value being required to be fully rendered -#defaulttilescale: 0 - -# Map storage scheme: only uncommoent one 'type' value -# filetree: classic and default scheme: tree of files, with all map data under the directory indicated by 'tilespath' setting -# sqlite: single SQLite database file (this can get VERY BIG), located at 'dbfile' setting (default is file dynmap.db in data directory) -# mysql: MySQL database, at hostname:port in database, accessed via userid with password -# mariadb: MariaDB database, at hostname:port in database, accessed via userid with password -# postgres: PostgreSQL database, at hostname:port in database, accessed via userid with password -storage: - # Filetree storage (standard tree of image files for maps) - type: filetree - # SQLite db for map storage (uses dbfile as storage location) - #type: sqlite - #dbfile: dynmap.db - # MySQL DB for map storage (at 'hostname':'port' in database 'database' using user 'userid' password 'password' and table prefix 'prefix' - #type: mysql - #hostname: localhost - #port: 3306 - #database: dynmap - #userid: dynmap - #password: dynmap - #prefix: "" - # - # AWS S3 backet web site - #type: aws_s3 - #bucketname: "dynmap-bucket-name" - #region: us-east-1 - #aws_access_key_id: "" - #aws_secret_access_key: "" - #prefix: "" - #override_endpoint: "" - -components: - - class: org.dynmap.ClientConfigurationComponent - - # Remember to change the following class to org.dynmap.JsonFileClientUpdateComponent when using an external web server. - - class: org.dynmap.InternalClientUpdateComponent - sendhealth: true - sendposition: true - allowwebchat: true - webchat-interval: 5 - hidewebchatip: false - trustclientname: false - includehiddenplayers: false - # (optional) if true, color codes in player display names are used - use-name-colors: false - # (optional) if true, player login IDs will be used for web chat when their IPs match - use-player-login-ip: true - # (optional) if use-player-login-ip is true, setting this to true will cause chat messages not matching a known player IP to be ignored - require-player-login-ip: false - # (optional) block player login IDs that are banned from chatting - block-banned-player-chat: true - # Require login for web-to-server chat (requires login-enabled: true) - webchat-requires-login: false - # If set to true, users must have dynmap.webchat permission in order to chat - webchat-permissions: false - # Limit length of single chat messages - chatlengthlimit: 256 - # # Optional - make players hidden when they are inside/underground/in shadows (#=light level: 0=full shadow,15=sky) - # hideifshadow: 4 - # # Optional - make player hidden when they are under cover (#=sky light level,0=underground,15=open to sky) - # hideifundercover: 14 - # # (Optional) if true, players that are crouching/sneaking will be hidden - hideifsneaking: false - # optional, if true, players that are in spectator mode will be hidden - hideifspectator: false - # If true, player positions/status is protected (login with ID with dynmap.playermarkers.seeall permission required for info other than self) - protected-player-info: false - # If true, hide players with invisibility potion effects active - hide-if-invisiblity-potion: true - # If true, player names are not shown on map, chat, list - hidenames: false - #- class: org.dynmap.JsonFileClientUpdateComponent - # writeinterval: 1 - # sendhealth: true - # sendposition: true - # allowwebchat: true - # webchat-interval: 5 - # hidewebchatip: false - # includehiddenplayers: false - # use-name-colors: false - # use-player-login-ip: false - # require-player-login-ip: false - # block-banned-player-chat: true - # hideifshadow: 0 - # hideifundercover: 0 - # hideifsneaking: false - # # Require login for web-to-server chat (requires login-enabled: true) - # webchat-requires-login: false - # # If set to true, users must have dynmap.webchat permission in order to chat - # webchat-permissions: false - # # Limit length of single chat messages - # chatlengthlimit: 256 - # hide-if-invisiblity-potion: true - # hidenames: false - - - class: org.dynmap.SimpleWebChatComponent - allowchat: true - # If true, web UI users can supply name for chat using 'playername' URL parameter. 'trustclientname' must also be set true. - allowurlname: false - - # Note: this component is needed for the dmarker commands, and for the Marker API to be available to other plugins - - class: org.dynmap.MarkersComponent - type: markers - showlabel: false - enablesigns: false - # Default marker set for sign markers - default-sign-set: markers - # (optional) add spawn point markers to standard marker layer - showspawn: true - spawnicon: world - spawnlabel: "Spawn" - # (optional) layer for showing offline player's positions (for 'maxofflinetime' minutes after logoff) - showofflineplayers: false - offlinelabel: "Offline" - offlineicon: offlineuser - offlinehidebydefault: true - offlineminzoom: 0 - maxofflinetime: 30 - # (optional) layer for showing player's spawn beds - showspawnbeds: false - spawnbedlabel: "Spawn Beds" - spawnbedicon: bed - spawnbedhidebydefault: true - spawnbedminzoom: 0 - spawnbedformat: "%name%'s bed" - # (optional) Show world border (vanilla 1.8+) - showworldborder: true - worldborderlabel: "Border" - - - class: org.dynmap.ClientComponent - type: chat - allowurlname: false - - class: org.dynmap.ClientComponent - type: chatballoon - focuschatballoons: false - - class: org.dynmap.ClientComponent - type: chatbox - showplayerfaces: true - messagettl: 5 - # Optional: set number of lines in scrollable message history: if set, messagettl is not used to age out messages - #scrollback: 100 - # Optional: set maximum number of lines visible for chatbox - #visiblelines: 10 - # Optional: send push button - sendbutton: false - - class: org.dynmap.ClientComponent - type: playermarkers - showplayerfaces: true - showplayerhealth: true - # If true, show player body too (only valid if showplayerfaces=true) - showplayerbody: false - # Option to make player faces small - don't use with showplayerhealth or largeplayerfaces - smallplayerfaces: false - # Option to make player faces larger - don't use with showplayerhealth or smallplayerfaces - largeplayerfaces: false - # Optional - make player faces layer hidden by default - hidebydefault: false - # Optional - ordering priority in layer menu (low goes before high - default is 0) - layerprio: 0 - # Optional - label for player marker layer (default is 'Players') - label: "Players" - - #- class: org.dynmap.ClientComponent - # type: digitalclock - - class: org.dynmap.ClientComponent - type: link - - - class: org.dynmap.ClientComponent - type: timeofdayclock - showdigitalclock: true - #showweather: true - # Mouse pointer world coordinate display - - class: org.dynmap.ClientComponent - type: coord - label: "Location" - hidey: false - show-mcr: false - show-chunk: false - - # Note: more than one logo component can be defined - #- class: org.dynmap.ClientComponent - # type: logo - # text: "Dynmap" - # #logourl: "images/block_surface.png" - # linkurl: "http://forums.bukkit.org/threads/dynmap.489/" - # # Valid positions: top-left, top-right, bottom-left, bottom-right - # position: bottom-right - - #- class: org.dynmap.ClientComponent - # type: inactive - # timeout: 1800 # in seconds (1800 seconds = 30 minutes) - # redirecturl: inactive.html - # #showmessage: 'You were inactive for too long.' - - #- class: org.dynmap.TestComponent - # stuff: "This is some configuration-value" - -# Treat hiddenplayers.txt as a whitelist for players to be shown on the map? (Default false) -display-whitelist: false - -# How often a tile gets rendered (in seconds). -renderinterval: 1 - -# How many tiles on update queue before accelerate render interval -renderacceleratethreshold: 60 - -# How often to render tiles when backlog is above renderacceleratethreshold -renderaccelerateinterval: 0.2 - -# How many update tiles to work on at once (if not defined, default is 1/2 the number of cores) -tiles-rendered-at-once: 2 - -# If true, use normal priority threads for rendering (versus low priority) - this can keep rendering -# from starving on busy Windows boxes (Linux JVMs pretty much ignore thread priority), but may result -# in more competition for CPU resources with other processes -usenormalthreadpriority: true - -# Save and restore pending tile renders - prevents their loss on server shutdown or /reload -saverestorepending: true - -# Save period for pending jobs (in seconds): periodic saving for crash recovery of jobs -save-pending-period: 900 - -# Zoom-out tile update period - how often to scan for and process tile updates into zoom-out tiles (in seconds) -zoomoutperiod: 30 - -# Control whether zoom out tiles are validated on startup (can be needed if zoomout processing is interrupted, but can be expensive on large maps) -initial-zoomout-validate: true - -# Default delay on processing of updated tiles, in seconds. This can reduce potentially expensive re-rendering -# of frequently updated tiles (such as due to machines, pistons, quarries or other automation). Values can -# also be set on individual worlds and individual maps. -tileupdatedelay: 30 - -# Tile hashing is used to minimize tile file updates when no changes have occurred - set to false to disable -enabletilehash: true - -# Optional - hide ores: render as normal stone (so that they aren't revealed by maps) -#hideores: true - -# Optional - enabled BetterGrass style rendering of grass and snow block sides -#better-grass: true - -# Optional - enable smooth lighting by default on all maps supporting it (can be set per map as lighting option) -smooth-lighting: true - -# Optional - use world provider lighting table (good for custom worlds with custom lighting curves, like nether) -# false=classic Dynmap lighting curve -use-brightness-table: true - -# Optional - render specific block names using the textures and models of another block name: can be used to hide/disguise specific -# blocks (e.g. make ores look like stone, hide chests) or to provide simple support for rendering unsupported custom blocks -block-alias: -# "minecraft:quartz_ore": "stone" -# "diamond_ore": "coal_ore" - -# Default image format for HDMaps (png, jpg, jpg-q75, jpg-q80, jpg-q85, jpg-q90, jpg-q95, jpg-q100, webp, webp-q75, webp-q80, webp-q85, webp-q90, webp-q95, webp-q100), -# Note: any webp format requires the presence of the 'webp command line tools' (cwebp, dwebp) (https://developers.google.com/speed/webp/download) -# -# Has no effect on maps with explicit format settings -image-format: jpg-q90 - -# If cwebp or dwebp are not on the PATH, use these settings to provide their full path. Do not use these settings if the tools are on the PATH -# For Windows, include .exe -# -#cwebpPath: /usr/bin/cwebp -#dwebpPath: /usr/bin/dwebp - -# use-generated-textures: if true, use generated textures (same as client); false is static water/lava textures -# correct-water-lighting: if true, use corrected water lighting (same as client); false is legacy water (darker) -# transparent-leaves: if true, leaves are transparent (lighting-wise): false is needed for some Spout versions that break lighting on leaf blocks -use-generated-textures: true -correct-water-lighting: true -transparent-leaves: true - -# ctm-support: if true, Connected Texture Mod (CTM) in texture packs is enabled (default) -ctm-support: true -# custom-colors-support: if true, Custom Colors in texture packs is enabled (default) -custom-colors-support: true - -# Control loading of player faces (if set to false, skins are never fetched) -#fetchskins: false - -# Control updating of player faces, once loaded (if faces are being managed by other apps or manually) -#refreshskins: false - -# Customize URL used for fetching player skins (%player% is macro for name, %uuid% for UUID) -skin-url: "http://skins.minecraft.net/MinecraftSkins/%player%.png" - -# Control behavior for new (1.0+) compass orientation (sunrise moved 90 degrees: east is now what used to be south) -# default is 'newrose' (preserve pre-1.0 maps, rotate rose) -# 'newnorth' is used to rotate maps and rose (requires fullrender of any HDMap map - same as 'newrose' for FlatMap or KzedMap) -compass-mode: newnorth - -# Triggers for automatic updates : blockupdate-with-id is debug for breaking down updates by ID:meta -# To disable, set just 'none' and comment/delete the rest -render-triggers: - - blockupdate - #- blockupdate-with-id - #- lightingupdate - - chunkpopulate - - chunkgenerate - #- none - -# Title for the web page - if not specified, defaults to the server's name (unless it is the default of 'Unknown Server') -#webpage-title: "My Awesome Server Map" - -# The path where the tile-files are placed. -tilespath: web/tiles - -# The path where the web-files are located. -webpath: web - -# If set to false, disable extraction of webpath content (good if using custom web UI or 3rd party web UI) -# Note: web interface is unsupported in this configuration - you're on your own -update-webpath-files: true - -# The path were the /dynmapexp command exports OBJ ZIP files -exportpath: export - -# The path where files can be imported for /dmarker commands -importpath: import - -# The network-interface the webserver will bind to (0.0.0.0 for all interfaces, 127.0.0.1 for only local access). -# If not set, uses same setting as server in server.properties (or 0.0.0.0 if not specified) -#webserver-bindaddress: 0.0.0.0 - -# The TCP-port the webserver will listen on. -webserver-port: 8123 - -# Maximum concurrent session on internal web server - limits resources used in Bukkit server -max-sessions: 30 - -# Disables Webserver portion of Dynmap (Advanced users only) -disable-webserver: false - -# Enable/disable having the web server allow symbolic links (true=compatible with existing code, false=more secure (default)) -allow-symlinks: true - -# Enable login support -login-enabled: false -# Require login to access website (requires login-enabled: true) -login-required: false - -# Period between tile renders for fullrender, in seconds (non-zero to pace fullrenders, lessen CPU load) -timesliceinterval: 0.0 - -# Maximum chunk loads per server tick (1/20th of a second) - reducing this below 90 will impact render performance, but also will reduce server thread load -maxchunkspertick: 200 - -# Progress report interval for fullrender/radiusrender, in tiles. Must be 100 or greater -progressloginterval: 100 - -# Parallel fullrender: if defined, number of concurrent threads used for fullrender or radiusrender -# Note: setting this will result in much more intensive CPU use, some additional memory use. Caution should be used when -# setting this to equal or exceed the number of physical cores on the system. -#parallelrendercnt: 4 - -# Interval the browser should poll for updates. -updaterate: 2000 - -# If nonzero, server will pause fullrender/radiusrender processing when 'fullrenderplayerlimit' or more users are logged in -fullrenderplayerlimit: 0 -# If nonzero, server will pause update render processing when 'updateplayerlimit' or more users are logged in -updateplayerlimit: 0 -# Target limit on server thread use - msec per tick -per-tick-time-limit: 50 -# If TPS of server is below this setting, update renders processing is paused -update-min-tps: 18.0 -# If TPS of server is below this setting, full/radius renders processing is paused -fullrender-min-tps: 18.0 -# If TPS of server is below this setting, zoom out processing is paused -zoomout-min-tps: 18.0 - -showplayerfacesinmenu: true - -# Control whether players that are hidden or not on current map are grayed out (true=yes) -grayplayerswhenhidden: true - -# Set sidebaropened: 'true' to pin menu sidebar opened permanently, 'pinned' to default the sidebar to pinned, but allow it to unpin -#sidebaropened: true - -# Customized HTTP response headers - add 'id: value' pairs to all HTTP response headers (internal web server only) -#http-response-headers: -# Access-Control-Allow-Origin: "my-domain.com" -# X-Custom-Header-Of-Mine: "MyHeaderValue" - -# Trusted proxies for web server - which proxy addresses are trusted to supply valid X-Forwarded-For fields -# This now supports both IP address, and subnet ranges (e.g. 192.168.1.0/24 or 202.24.0.0/14 ) -trusted-proxies: - - "127.0.0.1" - - "0:0:0:0:0:0:0:1" - -joinmessage: "%playername% joined" -quitmessage: "%playername% quit" -spammessage: "You may only chat once every %interval% seconds." -# format for messages from web: %playername% substitutes sender ID (typically IP), %message% includes text -webmsgformat: "&color;2[WEB] %playername%: &color;f%message%" - -# Control whether layer control is presented on the UI (default is true) -showlayercontrol: true - -# Enable checking for banned IPs via banned-ips.txt (internal web server only) -check-banned-ips: true - -# Default selection when map page is loaded -defaultzoom: 0 -defaultworld: world -defaultmap: flat -# (optional) Zoom level and map to switch to when following a player, if possible -#followzoom: 3 -#followmap: surface - -# If true, make persistent record of IP addresses used by player logins, to support web IP to player matching -persist-ids-by-ip: true - -# If true, map text to cyrillic -cyrillic-support: false - -# Messages to customize -msg: - maptypes: "Map Types" - players: "Players" - chatrequireslogin: "Chat Requires Login" - chatnotallowed: "You are not permitted to send chat messages" - hiddennamejoin: "Player joined" - hiddennamequit: "Player quit" - -# URL for client configuration (only need to be tailored for proxies or other non-standard configurations) -url: - # configuration URL - #configuration: "up/configuration" - # update URL - #update: "up/world/{world}/{timestamp}" - # sendmessage URL - #sendmessage: "up/sendmessage" - # login URL - #login: "up/login" - # register URL - #register: "up/register" - # tiles base URL - #tiles: "tiles/" - # markers base URL - #markers: "tiles/" - # Snapshot cache size, in chunks -snapshotcachesize: 500 -# Snapshot cache uses soft references (true), else weak references (false) -soft-ref-cache: true - -# Player enter/exit title messages for map markers -# -# Processing period - how often to check player positions vs markers - default is 1000ms (1 second) -#enterexitperiod: 1000 -# Title message fade in time, in ticks (0.05 second intervals) - default is 10 (1/2 second) -#titleFadeIn: 10 -# Title message stay time, in ticks (0.05 second intervals) - default is 70 (3.5 seconds) -#titleStay: 70 -# Title message fade out time, in ticks (0.05 seocnd intervals) - default is 20 (1 second) -#titleFadeOut: 20 -# Enter/exit messages use on screen titles (true - default), if false chat messages are sent instead -#enterexitUseTitle: true -# Set true if new enter messages should supercede pending exit messages (vs being queued in order), default false -#enterReplacesExits: true - -# Published public URL for Dynmap server (allows users to use 'dynmap url' command to get public URL usable to access server -# If not set, 'dynmap url' will not return anything. URL should be fully qualified (e.g. https://mc.westeroscraft.com/) -#publicURL: http://my.greatserver.com/dynmap - -# Send this message if the player does not have permission to use the command -noPermissionMsg: "You don't have permission to use this command!" - -# Set to true to enable verbose startup messages - can help with debugging map configuration problems -# Set to false for a much quieter startup log -verbose: false - -# Enables debugging. -#debuggers: -# - class: org.dynmap.debug.LogDebugger -# Debug: dump blocks missing render data -dump-missing-blocks: false - -# Log4J defense: string substituted for attempts to use macros in web chat -hackAttemptBlurb: "(IaM5uchA1337Haxr-Ban Me!)" diff --git a/forge-1.19.2/src/main/resources/pack.mcmeta b/forge-1.19.2/src/main/resources/pack.mcmeta deleted file mode 100644 index 8ae5db1a..00000000 --- a/forge-1.19.2/src/main/resources/pack.mcmeta +++ /dev/null @@ -1,6 +0,0 @@ -{ - "pack": { - "description": "Dynmap resources", - "pack_format": 8 - } -} diff --git a/forge-1.19.2/src/main/resources/permissions.yml.example b/forge-1.19.2/src/main/resources/permissions.yml.example deleted file mode 100644 index a25f9adc..00000000 --- a/forge-1.19.2/src/main/resources/permissions.yml.example +++ /dev/null @@ -1,27 +0,0 @@ -# -# Sample permissions.yml for dynmap - trivial, flat-file based permissions for dynmap features -# To use, copy this file to dynmap/permissions.yml, and edit appropriate. File is YAML format. -# -# All operators have full permissions to all functions. -# All users receive the permissions under the 'defaultuser' section -# Specific users can be given more permissions by defining a section with their name containing their permisssions -# All permissions correspond to those documented here (https://github.com/webbukkit/dynmap/wiki/Permissions), but -# do NOT have the 'dynmap.' prefix when used here (e.g. 'dynmap.fullrender' permission is just 'fullrender' here). -# -defaultuser: - - render - - show.self - - hide.self - - sendtoweb - - stats - - marker.list - - marker.listsets - - marker.icons - - webregister - - webchat - #- marker.sign - -#playername1: -# - fullrender -# - cancelrender -# - radiusrender diff --git a/forge-1.19/.gitignore b/forge-1.19/.gitignore deleted file mode 100644 index 84c048a7..00000000 --- a/forge-1.19/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build/ diff --git a/forge-1.19/bin/.gitignore b/forge-1.19/bin/.gitignore deleted file mode 100644 index 7eed456b..00000000 --- a/forge-1.19/bin/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/main/ -/test/ diff --git a/forge-1.19/build.gradle b/forge-1.19/build.gradle deleted file mode 100644 index 78fd7c5c..00000000 --- a/forge-1.19/build.gradle +++ /dev/null @@ -1,92 +0,0 @@ -buildscript { - repositories { - maven { url = 'https://files.minecraftforge.net/maven' } - jcenter() - mavenCentral() - } - dependencies { - classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '5.1.+', changing: true - } -} -apply plugin: 'net.minecraftforge.gradle' -apply plugin: 'com.github.johnrengelman.shadow' -apply plugin: 'eclipse' - -eclipse { - project { - name = "Dynmap(Forge-1.19)" - } -} - -sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = JavaLanguageVersion.of(17) // Need this here so eclipse task generates correctly. - -println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getProperty('java.vm.version') + '(' + System.getProperty('java.vendor') + ') Arch: ' + System.getProperty('os.arch')) - -ext.buildNumber = System.getenv().BUILD_NUMBER ?: "Dev" - -minecraft { - mappings channel: 'official', version: '1.19' - accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg') - runs { - server { - workingDirectory project.file('run').canonicalPath - } - } -} - -project.archivesBaseName = "${project.archivesBaseName}-forge-1.19" - -dependencies { - implementation project(path: ":DynmapCore", configuration: "shadow") - implementation project(path: ':DynmapCoreAPI') - - minecraft 'net.minecraftforge:forge:1.19-41.0.100' -} - -processResources -{ - filesMatching('META-INF/mods.toml') { - // replace version and mcversion - expand( - version: project.version + '-' + project.ext.buildNumber, - mcversion: "1.19" - ) - } -} - -shadowJar { - dependencies { - include(dependency(':DynmapCore')) - include(dependency("commons-codec:commons-codec:")) - exclude("META-INF/maven/**") - exclude("META-INF/services/**") - } - relocate('org.apache.commons.codec', 'org.dynmap.forge_1_19.commons.codec') - - archiveName = "Dynmap-${parent.version}-forge-1.19.jar" - destinationDir = file '../target' -} - -shadowJar.doLast { - task -> - ant.checksum file: task.archivePath -} - -afterEvaluate { -reobf { - shadowJar { - mappings = createMcpToSrg.output - } -} -} - -task deobfJar(type: Jar) { - from sourceSets.main.output - classifier = 'dev' -} - -artifacts { - archives deobfJar -} - -build.dependsOn(shadowJar) diff --git a/forge-1.19/src/main/java/org/dynmap/forge_1_19/ClientProxy.java b/forge-1.19/src/main/java/org/dynmap/forge_1_19/ClientProxy.java deleted file mode 100644 index a467dc70..00000000 --- a/forge-1.19/src/main/java/org/dynmap/forge_1_19/ClientProxy.java +++ /dev/null @@ -1,6 +0,0 @@ -package org.dynmap.forge_1_19; - -public class ClientProxy extends Proxy { - public ClientProxy() { - } -} diff --git a/forge-1.19/src/main/java/org/dynmap/forge_1_19/DynmapMod.java b/forge-1.19/src/main/java/org/dynmap/forge_1_19/DynmapMod.java deleted file mode 100644 index c9355651..00000000 --- a/forge-1.19/src/main/java/org/dynmap/forge_1_19/DynmapMod.java +++ /dev/null @@ -1,136 +0,0 @@ -package org.dynmap.forge_1_19; - -import java.io.File; - -import org.apache.commons.lang3.tuple.Pair; -import org.dynmap.DynmapCommonAPI; -import org.dynmap.DynmapCommonAPIListener; -import org.dynmap.Log; -import org.dynmap.forge_1_19.DynmapPlugin.OurLog; - -import net.minecraft.server.MinecraftServer; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.event.server.ServerAboutToStartEvent; -import net.minecraftforge.event.server.ServerStartedEvent; -import net.minecraftforge.event.server.ServerStartingEvent; -import net.minecraftforge.event.server.ServerStoppingEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.DistExecutor; -import net.minecraftforge.fml.IExtensionPoint; -import net.minecraftforge.fml.ModList; -import net.minecraftforge.fml.ModLoadingContext; -import net.minecraftforge.fml.StartupMessageManager; -import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; -import net.minecraftforge.fml.event.lifecycle.FMLLoadCompleteEvent; -import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; -import net.minecraftforge.network.NetworkConstants;; - -@Mod("dynmap") -public class DynmapMod -{ - // The instance of your mod that Forge uses. - public static DynmapMod instance; - - // Says where the client and server 'proxy' code is loaded. - public static Proxy proxy = DistExecutor.runForDist(() -> ClientProxy::new, () -> Proxy::new); - - public static DynmapPlugin plugin; - public static File jarfile; - public static String ver; - public static boolean useforcedchunks; - - public class APICallback extends DynmapCommonAPIListener { - @Override - public void apiListenerAdded() { - if(plugin == null) { - plugin = proxy.startServer(server); - } - } - @Override - public void apiEnabled(DynmapCommonAPI api) { - } - } - - //TODO - //public class LoadingCallback implements net.minecraftforge.common.ForgeChunkManager.LoadingCallback { - // @Override - // public void ticketsLoaded(List tickets, World world) { - // if(tickets.size() > 0) { - // DynmapPlugin.setBusy(world, tickets.get(0)); - // for(int i = 1; i < tickets.size(); i++) { - // ForgeChunkManager.releaseTicket(tickets.get(i)); - // } - // } - // } - //} - - public DynmapMod() { - instance = this; - FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup); - FMLJavaModLoadingContext.get().getModEventBus().addListener(this::init); - - MinecraftForge.EVENT_BUS.register(this); - - ModLoadingContext.get().registerExtensionPoint(IExtensionPoint.DisplayTest.class, - ()->new IExtensionPoint.DisplayTest(()->NetworkConstants.IGNORESERVERONLY, (remote, isServer)-> true)); - - Log.setLogger(new OurLog()); - org.dynmap.modsupport.ModSupportImpl.init(); - } - - public void setup(final FMLCommonSetupEvent event) - { - //TOOO - jarfile = ModList.get().getModFileById("dynmap").getFile().getFilePath().toFile(); - - ver = ModList.get().getModContainerById("dynmap").get().getModInfo().getVersion().toString(); - - //// Load configuration file - use suggested (config/WesterosBlocks.cfg) - //Configuration cfg = new Configuration(event.getSuggestedConfigurationFile()); - //try { - // cfg.load(); - // - // useforcedchunks = cfg.get("Settings", "UseForcedChunks", true).getBoolean(true); - //} - //finally - //{ - // cfg.save(); - //} - } - - public void init(FMLLoadCompleteEvent event) - { - /* Set up for chunk loading notice from chunk manager */ - //TODO - //if(useforcedchunks) { - // ForgeChunkManager.setForcedChunkLoadingCallback(DynmapMod.instance, new LoadingCallback()); - //} - //else { - // Log.info("[Dynmap] World loading using forced chunks is disabled"); - //} - } - - private MinecraftServer server; - - @SubscribeEvent - public void onServerStarting(ServerAboutToStartEvent event) { - server = event.getServer(); - if(plugin == null) - plugin = proxy.startServer(server); - plugin.onStarting(server.getCommands().getDispatcher()); - } - - @SubscribeEvent - public void onServerStarted(ServerStartedEvent event) { - DynmapCommonAPIListener.register(new APICallback()); - plugin.serverStarted(); - } - - @SubscribeEvent - public void serverStopping(ServerStoppingEvent event) - { - proxy.stopServer(plugin); - plugin = null; - } -} diff --git a/forge-1.19/src/main/java/org/dynmap/forge_1_19/DynmapPlugin.java b/forge-1.19/src/main/java/org/dynmap/forge_1_19/DynmapPlugin.java deleted file mode 100644 index 3b3605b0..00000000 --- a/forge-1.19/src/main/java/org/dynmap/forge_1_19/DynmapPlugin.java +++ /dev/null @@ -1,2039 +0,0 @@ -package org.dynmap.forge_1_19; - -import java.io.File; -import java.io.InputStream; -import java.net.InetSocketAddress; -import java.net.SocketAddress; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Base64; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Optional; -import java.util.PriorityQueue; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.Callable; -import java.util.concurrent.CancellationException; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; -import java.util.concurrent.FutureTask; -import java.util.regex.Pattern; - -import net.minecraft.Util; -import net.minecraft.commands.CommandSource; -import net.minecraft.commands.CommandSourceStack; -import net.minecraft.commands.Commands; -import net.minecraft.core.BlockPos; -import net.minecraft.core.IdMapper; -import net.minecraft.core.Registry; -import net.minecraft.network.Connection; -import net.minecraft.network.chat.ChatType; -import net.minecraft.network.chat.Component; -import net.minecraft.network.protocol.game.ClientboundSetSubtitleTextPacket; -import net.minecraft.network.protocol.game.ClientboundSetTitleTextPacket; -import net.minecraft.network.protocol.game.ClientboundSetTitlesAnimationPacket; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.level.ChunkHolder; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.server.network.ServerGamePacketListenerImpl; -import net.minecraft.server.players.GameProfileCache; -import net.minecraft.server.players.UserBanList; -import net.minecraft.world.entity.Pose; -import net.minecraft.world.level.ChunkPos; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.LiquidBlock; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkAccess; -import net.minecraft.world.level.chunk.ChunkStatus; -import net.minecraft.world.level.chunk.LevelChunk; -import net.minecraft.world.level.chunk.LevelChunkSection; -import net.minecraft.world.level.material.Material; -import net.minecraft.world.phys.Vec3; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.event.ServerChatEvent; -import net.minecraftforge.event.TickEvent; -import net.minecraftforge.event.entity.player.PlayerEvent.PlayerChangedDimensionEvent; -import net.minecraftforge.event.entity.player.PlayerEvent.PlayerLoggedInEvent; -import net.minecraftforge.event.entity.player.PlayerEvent.PlayerLoggedOutEvent; -import net.minecraftforge.event.entity.player.PlayerEvent.PlayerRespawnEvent; -import net.minecraftforge.event.level.BlockEvent; -import net.minecraftforge.event.level.ChunkDataEvent; -import net.minecraftforge.event.level.ChunkEvent; -import net.minecraftforge.event.level.LevelEvent; -import net.minecraftforge.fml.ModList; -import net.minecraftforge.fml.ModContainer; -import net.minecraftforge.fml.loading.LoadingModList; -import net.minecraftforge.fml.loading.moddiscovery.ModFileInfo; -import net.minecraftforge.fml.loading.moddiscovery.ModInfo; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.apache.maven.artifact.versioning.ArtifactVersion; -import org.dynmap.ConfigurationNode; -import org.dynmap.DynmapChunk; -import org.dynmap.DynmapCommonAPIListener; -import org.dynmap.DynmapCore; -import org.dynmap.DynmapLocation; -import org.dynmap.DynmapWorld; -import org.dynmap.Log; -import org.dynmap.MapManager; -import org.dynmap.PlayerList; -import org.dynmap.common.BiomeMap; -import org.dynmap.common.DynmapCommandSender; -import org.dynmap.common.DynmapPlayer; -import org.dynmap.common.DynmapServerInterface; -import org.dynmap.common.DynmapListenerManager.EventType; -import org.dynmap.common.chunk.GenericChunkCache; -import org.dynmap.forge_1_19.DmapCommand; -import org.dynmap.forge_1_19.DmarkerCommand; -import org.dynmap.forge_1_19.DynmapCommand; -import org.dynmap.forge_1_19.permissions.FilePermissions; -import org.dynmap.forge_1_19.permissions.OpPermissions; -import org.dynmap.forge_1_19.permissions.PermissionProvider; -import org.dynmap.permissions.PermissionsHandler; -import org.dynmap.renderer.DynmapBlockState; -import org.dynmap.utils.DynmapLogger; -import org.dynmap.utils.MapChunkCache; -import org.dynmap.utils.VisibilityLimit; - -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 com.mojang.brigadier.CommandDispatcher; -import com.mojang.brigadier.arguments.StringArgumentType; -import com.mojang.brigadier.builder.RequiredArgumentBuilder; -import com.mojang.brigadier.exceptions.CommandSyntaxException; - -import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap; -import it.unimi.dsi.fastutil.longs.LongOpenHashSet; -import net.minecraftforge.eventbus.api.EventPriority; -import net.minecraftforge.eventbus.api.SubscribeEvent; - -import net.minecraft.world.level.EmptyBlockGetter; - -public class DynmapPlugin -{ - private DynmapCore core; - private PermissionProvider permissions; - private boolean core_enabled; - public GenericChunkCache sscache; - public PlayerList playerList; - private MapManager mapManager; - private static net.minecraft.server.MinecraftServer server; - public static DynmapPlugin plugin; - private 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 LevelAccessor last_world; - private ForgeWorld last_fworld; - private Map players = new HashMap(); - //TODO private ForgeMetrics metrics; - private HashSet modsused = new HashSet(); - private ForgeServer fserver = new ForgeServer(); - private boolean tickregistered = false; - // TPS calculator - private double tps; - private long lasttick; - private long avgticklen; - // Per tick limit, in nsec - private long perTickLimit = (50000000); // 50 ms - private boolean useSaveFolder = true; - - private static final String[] TRIGGER_DEFAULTS = { "blockupdate", "chunkpopulate", "chunkgenerate" }; - - private static final Pattern patternControlCode = Pattern.compile("(?i)\\u00A7[0-9A-FK-OR]"); - - public static class BlockUpdateRec { - LevelAccessor 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(ForgeWorld 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(ForgeWorld fw, ChunkPos pos) { - LongOpenHashSet cset = knownloadedchunks.get(fw.getName()); - if (cset != null) { - cset.remove(pos.toLong()); - } - } - private boolean checkIfKnownChunk(ForgeWorld fw, ChunkPos pos) { - LongOpenHashSet cset = knownloadedchunks.get(fw.getName()); - if (cset != null) { - return cset.contains(pos.toLong()); - } - return false; - } - - private static Registry reg = null; - - private static Registry getBiomeReg() { - if (reg == null) { - reg = server.registryAccess().ownedRegistryOrThrow(Registry.BIOME_REGISTRY); - } - return reg; - } - - /** - * 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 - - IdMapper bsids = Block.BLOCK_STATE_REGISTRY; - - DynmapBlockState basebs = null; - Block baseb = null; - int baseidx = 0; - - Iterator iter = bsids.iterator(); - DynmapBlockState.Builder bld = new DynmapBlockState.Builder(); - 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; - } - ResourceLocation ui = Registry.BLOCK.getKey(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.world.level.block.state.properties.Property p : bs.getProperties()) { - if (statename.length() > 0) { - statename += ","; - } - statename += p.getName() + "=" + bs.getValue(p).toString(); - } - int lightAtten = 15; - try { // Workaround for mods with broken block state logic... - lightAtten =bs.isSolidRender(EmptyBlockGetter.INSTANCE, BlockPos.ZERO) ? 15 : (bs.propagatesSkylightDown(EmptyBlockGetter.INSTANCE, BlockPos.ZERO) ? 0 : 1); - } catch (Exception x) { - Log.warning(String.format("Exception while checking lighting data for block state: %s[%s]", bn, statename)); - Log.verboseinfo("Exception: " + x.toString()); - } - //Log.info("statename=" + bn + "[" + statename + "], lightAtten=" + lightAtten); - // Fill in base attributes - bld.setBaseState(basebs).setStateIndex(idx - baseidx).setBlockName(bn).setStateName(statename).setMaterial(mat.toString()).setLegacyBlockID(idx).setAttenuatesLight(lightAtten); - if (mat.isSolid()) { bld.setSolid(); } - if (mat == Material.AIR) { bld.setAir(); } - if (mat == Material.WOOD) { bld.setLog(); } - if (mat == Material.LEAVES) { bld.setLeaves(); } - if ((!bs.getFluidState().isEmpty()) && !(bs.getBlock() instanceof LiquidBlock)) { - bld.setWaterlogged(); - } - DynmapBlockState dbs = bld.build(); // Build state - stateByID[idx] = dbs; - if (basebs == null) { basebs = dbs; } - } - } - 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.getItemById(id); - //} - - private static Biome[] biomelist = null; - - public static final Biome[] getBiomeList() { - if (biomelist == null) { - biomelist = new Biome[256]; - Iterator iter = getBiomeReg().iterator(); - while (iter.hasNext()) { - Biome b = iter.next(); - int bidx = getBiomeReg().getId(b); - if (bidx >= biomelist.length) { - biomelist = Arrays.copyOf(biomelist, bidx + biomelist.length); - } - biomelist[bidx] = b; - } - } - return biomelist; - } - //public static final NetworkManager getNetworkManager(ServerPlayNetHandler nh) { - // return nh.netManager; - //} - - private ForgePlayer getOrAddPlayer(ServerPlayer p) { - String name = p.getName().getString(); - ForgePlayer fp = players.get(name); - if(fp != null) { - fp.player = p; - } - else { - fp = new ForgePlayer(p); - players.put(name, fp); - } - return fp; - } - - private static class TaskRecord implements Comparable - { - private long ticktorun; - private long id; - private FutureTask future; - @Override - public int compareTo(Object o) - { - TaskRecord tr = (TaskRecord)o; - - if (this.ticktorun < tr.ticktorun) - { - return -1; - } - else if (this.ticktorun > tr.ticktorun) - { - return 1; - } - else if (this.id < tr.id) - { - return -1; - } - else if (this.id > tr.id) - { - return 1; - } - else - { - return 0; - } - } - } - - private class ChatMessage { - String message; - ServerPlayer sender; - } - private ConcurrentLinkedQueue msgqueue = new ConcurrentLinkedQueue(); - - public class ChatHandler { - @SubscribeEvent - public void handleChat(ServerChatEvent event) { - String msg = event.getMessage(); - if(!msg.startsWith("/")) { - ChatMessage cm = new ChatMessage(); - cm.message = msg; - cm.sender = event.getPlayer(); - msgqueue.add(cm); - } - } - } - - /** TODO: depends on forge chunk manager - private static class WorldBusyRecord { - long last_ts; - Ticket ticket; - } - private static HashMap busy_worlds = new HashMap(); - - private void setBusy(World w) { - setBusy(w, null); - } - static void setBusy(World w, Ticket t) { - if(w == null) return; - if (!DynmapMod.useforcedchunks) return; - WorldBusyRecord wbr = busy_worlds.get(w.provider.getDimension()); - if(wbr == null) { // Not busy, make ticket and keep spawn loaded - Debug.debug("World " + w.getWorldInfo().getWorldName() + "/"+ w.provider.getDimensionType().getName() + " is busy"); - wbr = new WorldBusyRecord(); - if(t != null) - wbr.ticket = t; - else - wbr.ticket = ForgeChunkManager.requestTicket(DynmapMod.instance, w, ForgeChunkManager.Type.NORMAL); - if(wbr.ticket != null) { - BlockPos cc = w.getSpawnPoint(); - ChunkPos ccip = new ChunkPos(cc.getX() >> 4, cc.getZ() >> 4); - ForgeChunkManager.forceChunk(wbr.ticket, ccip); - busy_worlds.put(w.provider.getDimension(), wbr); // Add to busy list - } - } - wbr.last_ts = System.nanoTime(); - } - - private void doIdleOutOfWorlds() { - if (!DynmapMod.useforcedchunks) return; - long ts = System.nanoTime() - worldIdleTimeoutNS; - for(Iterator itr = busy_worlds.values().iterator(); itr.hasNext();) { - WorldBusyRecord wbr = itr.next(); - if(wbr.last_ts < ts) { - World w = wbr.ticket.world; - Debug.debug("World " + w.getWorldInfo().getWorldName() + "/" + wbr.ticket.world.provider.getDimensionType().getName() + " is idle"); - if (wbr.ticket != null) - ForgeChunkManager.releaseTicket(wbr.ticket); // Release hold on world - itr.remove(); - } - } - } - */ - - public static class OurLog implements DynmapLogger { - Logger log; - public static final String DM = "[Dynmap] "; - OurLog() { - 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); - } - } - - public DynmapPlugin(MinecraftServer srv) - { - plugin = this; - this.server = srv; - } - - public boolean isOp(String player) { - String[] ops = server.getPlayerList().getOps().getUserList(); - for (String op : ops) { - if (op.equalsIgnoreCase(player)) { - return true; - } - } - return (server.isSingleplayer() && player.equalsIgnoreCase(server.getSingleplayerProfile().getName())); - } - - private boolean hasPerm(ServerPlayer psender, String permission) { - PermissionsHandler ph = PermissionsHandler.getHandler(); - if ((psender != null) && (ph != null) && ph.hasPermission(psender.getName().getString(), permission)) { - return true; - } - return permissions.has(psender, permission); - } - - private boolean hasPermNode(ServerPlayer psender, String permission) { - PermissionsHandler ph = PermissionsHandler.getHandler(); - if ((psender != null) && (ph != null) && ph.hasPermissionNode(psender.getName().getString(), permission)) { - return true; - } - return permissions.hasPermissionNode(psender, permission); - } - - private 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; - } - private 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); - } - - /** - * Server access abstraction class - */ - public class ForgeServer extends DynmapServerInterface - { - /* Server thread scheduler */ - private Object schedlock = new Object(); - private long cur_tick; - private long next_id; - private long cur_tick_starttime; - private PriorityQueue runqueue = new PriorityQueue(); - - public ForgeServer() { - } - - private GameProfile getProfileByName(String player) { - GameProfileCache cache = server.getProfileCache(); - Optional val = cache.get(player); - return val.isPresent() ? val.get() : null; - } - - @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) - { - TaskRecord tr = new TaskRecord(); - tr.future = new FutureTask(run, null); - - /* Add task record to queue */ - synchronized (schedlock) - { - tr.id = next_id++; - tr.ticktorun = cur_tick + delay; - runqueue.add(tr); - } - } - @Override - public DynmapPlayer[] getOnlinePlayers() - { - if(server.getPlayerList() == null) - return new DynmapPlayer[0]; - List playlist = server.getPlayerList().getPlayers(); - int pcnt = playlist.size(); - DynmapPlayer[] dplay = new DynmapPlayer[pcnt]; - - for (int i = 0; i < pcnt; i++) - { - ServerPlayer p = playlist.get(i); - dplay[i] = getOrAddPlayer(p); - } - - return dplay; - } - @Override - public void reload() - { - plugin.onDisable(); - plugin.onEnable(); - plugin.onStart(); - } - @Override - public DynmapPlayer getPlayer(String name) - { - List players = server.getPlayerList().getPlayers(); - - for (ServerPlayer p : players) - { - if (p.getName().getString().equalsIgnoreCase(name)) - { - return getOrAddPlayer(p); - } - } - - return null; - } - @Override - public Set getIPBans() - { - UserBanList bl = server.getPlayerList().getBans(); - Set ips = new HashSet(); - - for (String s : bl.getUserList()) { - ips.add(s); - } - - return ips; - } - @Override - public Future callSyncMethod(Callable task) { - return callSyncMethod(task, 0); - } - public Future callSyncMethod(Callable task, long delay) - { - TaskRecord tr = new TaskRecord(); - FutureTask ft = new FutureTask(task); - tr.future = ft; - - /* Add task record to queue */ - synchronized (schedlock) - { - tr.id = next_id++; - tr.ticktorun = cur_tick + delay; - runqueue.add(tr); - } - - return ft; - } - @Override - public String getServerName() - { - String sn; - if (server.isSingleplayer()) - sn = "Integrated"; - else - sn = server.getLocalIp(); - if(sn == null) sn = "Unknown Server"; - return sn; - } - @Override - public boolean isPlayerBanned(String pid) - { - UserBanList bl = server.getPlayerList().getBans(); - return bl.isBanned(getProfileByName(pid)); - } - - @Override - public String stripChatColor(String s) - { - return patternControlCode.matcher(s).replaceAll(""); - } - private Set registered = new HashSet(); - @Override - public boolean requestEventNotification(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 (chathandler == null) { - chathandler = new ChatHandler(); - MinecraftForge.EVENT_BUS.register(chathandler); - } - 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) - { - Component component = Component.literal(msg); - server.getPlayerList().broadcastSystemMessage(component, ChatType.SYSTEM); - 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(sscache != null) - return sscache.getHitRate(); - return 0.0; - } - @Override - public void resetCacheStats() - { - if(sscache != null) - sscache.resetStats(); - } - @Override - public DynmapWorld getWorldByName(String wname) - { - return DynmapPlugin.this.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) - { - net.minecraft.server.players.PlayerList scm = server.getPlayerList(); - if (scm == null) return Collections.emptySet(); - UserBanList bl = scm.getBans(); - if (bl == null) return Collections.emptySet(); - if(bl.isBanned(getProfileByName(player))) { - return Collections.emptySet(); - } - Set rslt = 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) - { - net.minecraft.server.players.PlayerList scm = server.getPlayerList(); - if (scm == null) return false; - UserBanList bl = scm.getBans(); - if (bl == null) return false; - if(bl.isBanned(getProfileByName(player))) { - return false; - } - return 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) - { - ForgeMapChunkCache c = (ForgeMapChunkCache) 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 (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 ForgeMapChunkCache cc = c; - Future f = this.callSyncMethod(new Callable() { - public Boolean call() throws Exception { - // Update busy state on world - ForgeWorld fw = (ForgeWorld)cc.getWorld(); - //TODO - //setBusy(fw.getWorld()); - cc.getLoadedChunks(); - return true; - } - }, 0); - try { - f.get(); - } - catch (CancellationException cx) { - return null; - } - catch (InterruptedException 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() == false) { - return null; - } - // Now, do rest of chunk reading from calling thread - c.readChunks(chunks.size()); - - return c; - } - @Override - public int getMaxPlayers() - { - return server.getMaxPlayers(); - } - @Override - public int getCurrentPlayers() - { - return server.getPlayerList().getPlayerCount(); - } - - @SubscribeEvent - public void tickEvent(TickEvent.ServerTickEvent event) { - if (event.phase == TickEvent.Phase.START) { - return; - } - cur_tick_starttime = System.nanoTime(); - long elapsed = cur_tick_starttime - lasttick; - lasttick = cur_tick_starttime; - avgticklen = ((avgticklen * 99) / 100) + (elapsed / 100); - tps = (double)1E9 / (double)avgticklen; - // Tick core - if (core != null) { - core.serverTick(tps); - } - - boolean done = false; - TaskRecord tr = null; - - while(!blockupdatequeue.isEmpty()) { - BlockUpdateRec r = blockupdatequeue.remove(); - BlockState bs = r.w.getBlockState(new BlockPos(r.x, r.y, r.z)); - int idx = Block.BLOCK_STATE_REGISTRY.getId(bs); - if((idx >= 0) && (!org.dynmap.hdmap.HDBlockModels.isChangeIgnoredBlock(stateByID[idx]))) { - if(onblockchange_with_id) - mapManager.touch(r.wid, r.x, r.y, r.z, "blockchange[" + idx + "]"); - else - 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.ticktorun > cur_tick) || ((now - cur_tick_starttime) > perTickLimit)) { - done = true; - } - else { - tr = runqueue.poll(); - } - } - while (!done) { - tr.future.run(); - - synchronized(schedlock) { - tr = runqueue.peek(); - now = System.nanoTime(); - /* Nothing due to run */ - if((tr == null) || (tr.ticktorun > cur_tick) || ((now - cur_tick_starttime) > perTickLimit)) { - done = true; - } - else { - tr = runqueue.poll(); - } - } - } - while(!msgqueue.isEmpty()) { - ChatMessage cm = msgqueue.poll(); - DynmapPlayer dp = null; - if(cm.sender != null) - dp = getOrAddPlayer(cm.sender); - else - dp = new ForgePlayer(null); - - core.listenerManager.processChatEvent(EventType.PLAYER_CHAT, dp, cm.message); - } - // Check for generated chunks - if((cur_tick % 20) == 0) { - } - } - - @Override - public boolean isModLoaded(String name) { - boolean loaded = ModList.get().isLoaded(name); - if (loaded) { - modsused.add(name); - } - return loaded; - } - @Override - public String getModVersion(String name) { - Optional mod = ModList.get().getModContainerById(name); // Try case sensitive lookup - if (mod.isPresent()) { - ArtifactVersion vi = mod.get().getModInfo().getVersion(); - return vi.getMajorVersion() + "." + vi.getMinorVersion() + "." + vi.getIncrementalVersion(); - } - return null; - } - @Override - public double getServerTPS() { - return tps; - } - - @Override - public String getServerIP() { - if (server.isSingleplayer()) - return "0.0.0.0"; - else - return server.getLocalIp(); - } - @Override - public File getModContainerFile(String name) { - ModFileInfo mfi = LoadingModList.get().getModFileById(name); // Try case sensitive lookup - if (mfi != null) { - try { - File f = mfi.getFile().getFilePath().toFile(); - return f; - } - catch (UnsupportedOperationException ex) { - //TODO Implement proper jar in jar method for fetching data -/* - Log.info("Searching for: " + name); - for (IModInfo e: ModList.get().getMods()) { - Log.info("in: " + e.getModId().toString()); - Log.info("resource: "+ ModList.get().getModFileById(e.getModId()).getFile().findResource(String.valueOf(mfi.getFile().getFilePath()))); - } -*/ - Log.warning("jar in jar method found, skipping: " + ex.getMessage()); - } - } - return null; - } - @Override - public List getModList() { - List mil = LoadingModList.get().getMods(); - List lst = new ArrayList(); - for (ModInfo mi : mil) { - lst.add(mi.getModId()); - } - return lst; - } - - @Override - public Map getBlockIDMap() { - Map map = new HashMap(); - return map; - } - - @Override - public InputStream openResource(String modid, String rname) { - if (modid == null) modid = "minecraft"; - - Optional mc = ModList.get().getModContainerById(modid); - Object mod = (mc.isPresent()) ? mc.get().getMod() : null; - if (mod != null) { - ClassLoader cl = mod.getClass().getClassLoader(); - if (cl == null) cl = ClassLoader.getSystemClassLoader(); - InputStream is = cl.getResourceAsStream(rname); - if (is != null) { - return is; - } - } - List mcl = LoadingModList.get().getMods(); - for (ModInfo mci : mcl) { - mc = ModList.get().getModContainerById(mci.getModId()); - mod = (mc.isPresent()) ? mc.get().getMod() : null; - if (mod == null) continue; - ClassLoader cl = mod.getClass().getClassLoader(); - if (cl == null) cl = ClassLoader.getSystemClassLoader(); - InputStream is = cl.getResourceAsStream(rname); - if (is != null) { - return is; - } - } - return 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; - } - - } - private static final Gson gson = new GsonBuilder().create(); - - public class TexturesPayload { - public long timestamp; - public String profileId; - public String profileName; - public boolean isPublic; - public Map textures; - - } - public class ProfileTexture { - public String url; - } - - /** - * Player access abstraction class - */ - public class ForgePlayer extends ForgeCommandSender implements DynmapPlayer - { - private ServerPlayer player; - private final String skinurl; - private final UUID uuid; - - - public ForgePlayer(ServerPlayer p) - { - player = p; - String url = null; - if (player != null) { - uuid = player.getUUID(); - GameProfile prof = player.getGameProfile(); - if (prof != null) { - Property textureProperty = Iterables.getFirst(prof.getProperties().get("textures"), null); - - if (textureProperty != null) { - TexturesPayload result = null; - try { - String json = new String(Base64.getDecoder().decode(textureProperty.getValue()), StandardCharsets.UTF_8); - result = gson.fromJson(json, 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; - } - Vec3 v = player.position(); - return toLoc(player.getLevel(), v.x, v.y, v.z); - } - @Override - public String getWorld() - { - if (player == null) - { - return null; - } - - if (player.level != null) - { - return DynmapPlugin.this.getWorld((ServerLevel)player.level).getName(); - } - - return null; - } - public static final Connection getNetworkManager(ServerGamePacketListenerImpl nh) { - return nh.connection; - } - - @Override - public InetSocketAddress getAddress() - { - if((player != null) && (player instanceof ServerPlayer)) { - ServerGamePacketListenerImpl nsh = ((ServerPlayer)player).connection; - if((nsh != null) && (getNetworkManager(nsh) != null)) { - SocketAddress sa = getNetworkManager(nsh).getRemoteAddress(); - if(sa instanceof InetSocketAddress) { - return (InetSocketAddress)sa; - } - } - } - return null; - } - @Override - public boolean isSneaking() - { - if (player != null) - { - return player.getPose() == Pose.CROUCHING; - } - - 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.getArmorValue(); - } - 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 hasPerm(player, privid); - return false; - } - @Override - public boolean isOp() - { - return DynmapPlugin.this.isOp(player.getName().getString()); - } - @Override - public void sendMessage(String msg) - { - Component ichatcomponent = Component.literal(msg); - player.sendSystemMessage(ichatcomponent); - } - @Override - public boolean isInvisible() { - if(player != null) { - return player.isInvisible(); - } - return false; - } - @Override - public boolean isSpectator() { - if(player != null) { - return player.isSpectator(); - } - return false; - } - @Override - public int getSortWeight() { - Integer wt = sortWeights.get(getName()); - if (wt != null) - return wt; - return 0; - } - @Override - public void setSortWeight(int wt) { - if (wt == 0) { - sortWeights.remove(getName()); - } - else { - sortWeights.put(getName(), wt); - } - } - @Override - public boolean hasPermissionNode(String node) { - if(player != null) - return hasPermNode(player, node); - return false; - } - @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 instanceof ServerPlayer) { - ServerPlayer mp = (ServerPlayer) player; - ClientboundSetTitlesAnimationPacket times = new ClientboundSetTitlesAnimationPacket(fadeInTicks, stayTicks, fadeOutTicks); - mp.connection.send(times); - if (title != null) { - ClientboundSetTitleTextPacket titlepkt = new ClientboundSetTitleTextPacket(Component.literal(title)); - mp.connection.send(titlepkt); - } - - if (subtitle != null) { - ClientboundSetSubtitleTextPacket subtitlepkt = new ClientboundSetSubtitleTextPacket(Component.literal(subtitle)); - mp.connection.send(subtitlepkt); - } - } - } - } - /* Handler for generic console command sender */ - public class ForgeCommandSender implements DynmapCommandSender - { - private CommandSourceStack sender; - - protected ForgeCommandSender() { - sender = null; - } - - public ForgeCommandSender(CommandSourceStack send) - { - sender = send; - } - - @Override - public boolean hasPrivilege(String privid) - { - return true; - } - - @Override - public void sendMessage(String msg) - { - if(sender != null) { - Component ichatcomponent = Component.literal(msg); - sender.sendSuccess(ichatcomponent, true); - } - } - - @Override - public boolean isConnected() - { - return false; - } - @Override - public boolean isOp() - { - return true; - } - @Override - public boolean hasPermissionNode(String node) { - return true; - } - } - - 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) { - ResourceLocation regid = getBiomeReg().getKey(bb); - String id = regid.getPath(); - String rl = regid.toString(); - float tmp = bb.getBaseTemperature(), hum = bb.getDownfall(); - int watermult = bb.getWaterColor(); - Log.verboseinfo("biome[" + i + "]: hum=" + hum + ", tmp=" + tmp + ", mult=" + Integer.toHexString(watermult)); - - BiomeMap bmap = BiomeMap.NULL; - if (rl != null) { // If resource location, lookup by this - bmap = BiomeMap.byBiomeResourceLocation(rl); - } - else { - bmap = BiomeMap.byBiomeID(i); - } - if (bmap.isDefault() || (bmap == BiomeMap.NULL)) { - bmap = new BiomeMap((rl != null) ? BiomeMap.NO_INDEX : i, id, tmp, hum, rl); - 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)); - } - bmap.setBiomeObject(bb); - } - } - 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] = bb.toString(); - } - } - return lst; - } - - public void onEnable() - { - /* Get MC version */ - String mcver = server.getServerVersion(); - /* 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() == false) - { - 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); - 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 static int test(CommandSource source) throws CommandSyntaxException - { - Log.warning(source.toString()); - return 1; - } - - private DynmapCommand dynmapCmd; - private DmapCommand dmapCmd; - private DmarkerCommand dmarkerCmd; - private DynmapExpCommand dynmapexpCmd; - - public void onStarting(CommandDispatcher cd) { - /* Register command hander */ - 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) { - MinecraftForge.EVENT_BUS.register(fserver); - tickregistered = true; - } - - playerList = core.playerList; - sscache = new GenericChunkCache(core.getSnapShotCacheSize(), core.useSoftRefInSnapShotCache()); - /* Get map manager from core */ - mapManager = core.getMapManager(); - - /* Load saved world definitions */ - loadWorlds(); - - /* Initialized the currently loaded worlds */ - for (ServerLevel world : server.getAllLevels()) { - ForgeWorld w = this.getWorld(world); - } - for(ForgeWorld 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(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.runqueue.clear(); - - /* Disable core */ - core.disableCore(); - core_enabled = false; - - if (sscache != null) - { - sscache.cleanup(); - sscache = null; - } - - Log.info("Disabled"); - } - - void onCommand(CommandSourceStack commandSourceStack, String cmd, String[] args) - { - DynmapCommandSender dsender; - ServerPlayer psender; - try { - psender = commandSourceStack.getPlayerOrException(); - } catch (com.mojang.brigadier.exceptions.CommandSyntaxException x) { - psender = null; - } - - if (psender != null) - { - dsender = new ForgePlayer(psender); - } - else - { - dsender = new ForgeCommandSender(commandSourceStack); - } - try { - core.processCommand(dsender, cmd, cmd, args); - } catch (Exception x) { - dsender.sendMessage("Command internal error: " + x.getMessage()); - Log.severe("Error with command: " + cmd + Arrays.deepToString(args), x); - } - } - - private DynmapLocation toLoc(ServerLevel level, double x, double y, double z) - { - return new DynmapLocation(DynmapPlugin.this.getWorld(level).getName(), x, y, z); - } - - public class PlayerTracker { - @SubscribeEvent - public void onPlayerLogin(PlayerLoggedInEvent event) { - if(!core_enabled) return; - final DynmapPlayer dp = getOrAddPlayer((ServerPlayer)event.getEntity()); - /* This event can be called from off server thread, so push processing there */ - core.getServer().scheduleServerTask(new Runnable() { - public void run() { - core.listenerManager.processPlayerEvent(EventType.PLAYER_JOIN, dp); - } - }, 2); - } - @SubscribeEvent - public void onPlayerLogout(PlayerLoggedOutEvent event) { - if(!core_enabled) return; - final DynmapPlayer dp = getOrAddPlayer((ServerPlayer)event.getEntity()); - final String name = event.getEntity().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(EventType.PLAYER_QUIT, dp); - players.remove(name); - } - }, 0); - } - @SubscribeEvent - public void onPlayerChangedDimension(PlayerChangedDimensionEvent event) { - if(!core_enabled) return; - getOrAddPlayer((ServerPlayer)event.getEntity()); // Freshen player object reference - } - @SubscribeEvent - public void onPlayerRespawn(PlayerRespawnEvent event) { - if(!core_enabled) return; - getOrAddPlayer((ServerPlayer)event.getEntity()); // Freshen player object reference - } - } - private PlayerTracker playerTracker = null; - - private void registerPlayerLoginListener() - { - if (playerTracker == null) { - playerTracker = new PlayerTracker(); - MinecraftForge.EVENT_BUS.register(playerTracker); - } - } - - public class WorldTracker { - @SubscribeEvent(priority=EventPriority.LOWEST) - public void handleWorldLoad(LevelEvent.Load event) { - if(!core_enabled) return; - LevelAccessor w = event.getLevel(); - if(!(w instanceof ServerLevel)) return; - final ForgeWorld fw = getWorld((ServerLevel)w); - // 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(EventType.WORLD_LOAD, fw); - } - }, 0); - } - @SubscribeEvent(priority=EventPriority.LOWEST) - public void handleWorldUnload(LevelEvent.Unload event) { - if(!core_enabled) return; - LevelAccessor w = event.getLevel(); - if(!(w instanceof ServerLevel)) return; - final ForgeWorld fw = getWorld((ServerLevel)w); - 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(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; - } - } - - @SubscribeEvent(priority=EventPriority.LOWEST) - public void handleChunkLoad(ChunkEvent.Load event) { - if(!onchunkgenerate) return; - - LevelAccessor w = event.getLevel(); - if(!(w instanceof ServerLevel)) return; - ChunkAccess c = event.getChunk(); - if ((c != null) && (c.getStatus() == ChunkStatus.FULL) && (c instanceof LevelChunk)) { - ForgeWorld fw = getWorld((ServerLevel)w, false); - if (fw != null) { - addKnownChunk(fw, c.getPos()); - } - } - } - @SubscribeEvent(priority=EventPriority.LOWEST) - public void handleChunkUnload(ChunkEvent.Unload event) { - if(!onchunkgenerate) return; - - LevelAccessor w = event.getLevel(); - if(!(w instanceof ServerLevel)) return; - ChunkAccess c = event.getChunk(); - if (c != null) { - ForgeWorld fw = getWorld((ServerLevel)w, false); - ChunkPos cp = c.getPos(); - if (fw != null) { - if (!checkIfKnownChunk(fw, cp)) { - int ymax = Integer.MIN_VALUE; - int ymin = Integer.MAX_VALUE; - LevelChunkSection[] sections = c.getSections(); - for(int i = 0; i < sections.length; i++) { - if((sections[i] != null) && (sections[i].hasOnlyAir() == false)) { - int sy = sections[i].bottomBlockY(); - if (sy < ymin) ymin = sy; - if ((sy+16) > ymax) ymax = sy + 16; - } - } - int x = cp.x << 4; - int z = cp.z << 4; - // If not empty AND not initial scan - if (ymax != Integer.MIN_VALUE) { - //Log.info(String.format("chunkkeyerate(unload)(%s,%d,%d,%d,%d,%d,%s)", fw.getName(), x, ymin, z, x+15, ymax, z+15)); - mapManager.touchVolume(fw.getName(), x, ymin, z, x+15, ymax, z+15, "chunkgenerate"); - } - } - removeKnownChunk(fw, cp); - } - } - } - @SubscribeEvent(priority=EventPriority.LOWEST) - public void handleChunkDataSave(ChunkDataEvent.Save event) { - if(!onchunkgenerate) return; - - LevelAccessor w = event.getLevel(); - if(!(w instanceof ServerLevel)) return; - ChunkAccess c = event.getChunk(); - if (c != null) { - ForgeWorld fw = getWorld((ServerLevel)w, false); - ChunkPos cp = c.getPos(); - if (fw != null) { - if (!checkIfKnownChunk(fw, cp)) { - int ymax = Integer.MIN_VALUE; - int ymin = Integer.MAX_VALUE; - LevelChunkSection[] sections = c.getSections(); - for(int i = 0; i < sections.length; i++) { - if((sections[i] != null) && (sections[i].hasOnlyAir() == false)) { - int sy = sections[i].bottomBlockY(); - if (sy < ymin) ymin = sy; - if ((sy+16) > ymax) ymax = sy + 16; - } - } - int x = cp.x << 4; - int z = cp.z << 4; - // If not empty AND not initial scan - if (ymax != Integer.MIN_VALUE) { - //Log.info(String.format("chunkkeyerate(save)(%s,%d,%d,%d,%d,%d,%s)", fw.getName(), x, ymin, z, x+15, ymax, z+15)); - mapManager.touchVolume(fw.getName(), x, ymin, z, x+15, ymax, z+15, "chunkgenerate"); - } - // If cooked, add to known - if ((c.getStatus() == ChunkStatus.FULL) && (c instanceof LevelChunk)) { - addKnownChunk(fw, cp); - } - } - } - } - } - @SubscribeEvent(priority=EventPriority.LOWEST) - public void handleBlockEvent(BlockEvent event) { - if(!core_enabled) return; - if(!onblockchange) return; - BlockUpdateRec r = new BlockUpdateRec(); - r.w = event.getLevel(); - if(!(r.w instanceof ServerLevel)) return; // band-aid to prevent errors in unsupported 'running in client' scenario - ForgeWorld fw = getWorld((ServerLevel)r.w, false); - if (fw == null) return; - r.wid = fw.getName(); - BlockPos p = event.getPos(); - r.x = p.getX(); - r.y = p.getY(); - r.z = p.getZ(); - blockupdatequeue.add(r); - } - } - private WorldTracker worldTracker = null; - private boolean onblockchange = false; - private boolean onchunkpopulate = false; - private boolean onchunkgenerate = false; - private 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(); - MinecraftForge.EVENT_BUS.register(worldTracker); - } - // Prime the known full chunks - if (onchunkgenerate && (server.getAllLevels() != null)) { - for (ServerLevel world : server.getAllLevels()) { - ForgeWorld fw = getWorld(world); - if (fw == null) continue; - Long2ObjectLinkedOpenHashMap chunks = world.getChunkSource().chunkMap.visibleChunkMap; - for (Entry k : chunks.long2ObjectEntrySet()) { - long key = k.getKey().longValue(); - ChunkHolder ch = k.getValue(); - ChunkAccess c = null; - try { - c = ch.getLastAvailable(); - } 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); - } - } - } - } - } - - private ForgeWorld getWorldByName(String name) { - return worlds.get(name); - } - - private ForgeWorld getWorld(ServerLevel w) { - return getWorld(w, true); - } - - private ForgeWorld getWorld(ServerLevel w, boolean add_if_not_found) { - if(last_world == w) { - return last_fworld; - } - String wname = ForgeWorld.getWorldName(w); - - for(ForgeWorld fw : worlds.values()) { - if(fw.getRawName().equals(wname)) { - last_world = w; - last_fworld = fw; - if(fw.isLoaded() == false) { - fw.setWorldLoaded(w); - } - fw.updateWorld(w); - return fw; - } - } - ForgeWorld fw = null; - if(add_if_not_found) { - /* Add to list if not found */ - fw = new ForgeWorld(w); - worlds.put(fw.getName(), fw); - } - last_world = w; - last_fworld = fw; - return fw; - } - - private void saveWorlds() { - File f = new File(core.getDataFolder(), "forgeworlds.yml"); - 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("miny", fw.minY); - vals.put("sealevel", fw.sealevel); - vals.put("nether", fw.isNether()); - vals.put("the_end", ((ForgeWorld)fw).isTheEnd()); - vals.put("title", fw.getTitle()); - lst.add(vals); - } - cn.put("worlds", lst); - cn.put("useSaveFolderAsName", useSaveFolder); - cn.put("maxWorldHeight", ForgeWorld.getMaxWorldHeight()); - - cn.save(); - } - private void loadWorlds() { - File f = new File(core.getDataFolder(), "forgeworlds.yml"); - if(f.canRead() == false) { - useSaveFolder = true; - return; - } - ConfigurationNode cn = new ConfigurationNode(f); - cn.load(); - // If defined, use maxWorldHeight - ForgeWorld.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("Discarding bad forgeworlds.yml"); - return; - } - - for(Map world : lst) { - try { - String name = (String)world.get("name"); - int height = (Integer)world.get("height"); - Integer miny = (Integer) world.get("miny"); - 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) { - ForgeWorld fw = new ForgeWorld(name, height, sealevel, nether, theend, title, (miny != null) ? miny : 0); - fw.setWorldUnloaded(); - core.processWorldLoad(fw); - worlds.put(fw.getName(), fw); - } - } catch (Exception x) { - Log.warning("Unable to load saved worlds from forgeworlds.yml"); - return; - } - } - } - public void serverStarted() { - this.onStart(); - if (core != null) { - core.serverStarted(); - } - } - public MinecraftServer getMCServer() { - return server; - } -} - -class DynmapCommandHandler -{ - private String cmd; - private DynmapPlugin plugin; - - public DynmapCommandHandler(String cmd, DynmapPlugin p) - { - this.cmd = cmd; - this.plugin = p; - } - - public void register(CommandDispatcher cd) { - cd.register(Commands.literal(cmd). - then(RequiredArgumentBuilder. argument("args", StringArgumentType.greedyString()). - executes((ctx) -> this.execute(plugin.getMCServer(), ctx.getSource(), ctx.getInput()))). - executes((ctx) -> this.execute(plugin.getMCServer(), ctx.getSource(), ctx.getInput()))); - } - -// @Override - public int execute(MinecraftServer server, CommandSourceStack commandSourceStack, - String cmdline) { - String[] args = cmdline.split("\\s+"); - plugin.onCommand(commandSourceStack, cmd, Arrays.copyOfRange(args, 1, args.length)); - return 1; - } - -// @Override - public String getUsage(CommandSource arg0) { - return "Run /" + cmd + " help for details on using command"; - } -} - -class DynmapCommand extends DynmapCommandHandler { - DynmapCommand(DynmapPlugin p) { - super("dynmap", p); - } -} -class DmapCommand extends DynmapCommandHandler { - DmapCommand(DynmapPlugin p) { - super("dmap", p); - } -} -class DmarkerCommand extends DynmapCommandHandler { - DmarkerCommand(DynmapPlugin p) { - super("dmarker", p); - } -} -class DynmapExpCommand extends DynmapCommandHandler { - DynmapExpCommand(DynmapPlugin p) { - super("dynmapexp", p); - } -} - diff --git a/forge-1.19/src/main/java/org/dynmap/forge_1_19/ForgeMapChunkCache.java b/forge-1.19/src/main/java/org/dynmap/forge_1_19/ForgeMapChunkCache.java deleted file mode 100644 index 80f96e0e..00000000 --- a/forge-1.19/src/main/java/org/dynmap/forge_1_19/ForgeMapChunkCache.java +++ /dev/null @@ -1,109 +0,0 @@ -package org.dynmap.forge_1_19; - -import java.util.List; -import java.util.NoSuchElementException; - -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.biome.BiomeSpecialEffects; -import org.dynmap.DynmapChunk; -import org.dynmap.Log; -import org.dynmap.common.BiomeMap; -import org.dynmap.common.chunk.GenericChunk; -import org.dynmap.common.chunk.GenericChunkCache; -import org.dynmap.common.chunk.GenericMapChunkCache; - -import net.minecraft.nbt.CompoundTag; -import net.minecraft.server.level.ServerChunkCache; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.level.ChunkPos; -import net.minecraft.world.level.chunk.ChunkAccess; -import net.minecraft.world.level.chunk.ChunkStatus; -import net.minecraft.world.level.chunk.storage.ChunkSerializer; - -/** - * Container for managing chunks - dependent upon using chunk snapshots, since - * rendering is off server thread - */ -public class ForgeMapChunkCache extends GenericMapChunkCache { - private ServerLevel w; - private ServerChunkCache cps; - /** - * Construct empty cache - */ - public ForgeMapChunkCache(GenericChunkCache cc) { - super(cc); - } - - // Load generic chunk from existing and already loaded chunk - protected GenericChunk getLoadedChunk(DynmapChunk chunk) { - GenericChunk gc = null; - ChunkAccess ch = cps.getChunk(chunk.x, chunk.z, ChunkStatus.FULL, false); - if (ch != null) { - CompoundTag nbt = ChunkSerializer.write(w, ch); - if (nbt != null) { - gc = parseChunkFromNBT(new NBT.NBTCompound(nbt)); - } - } - return gc; - } - // Load generic chunk from unloaded chunk - protected GenericChunk loadChunk(DynmapChunk chunk) { - GenericChunk gc = null; - CompoundTag nbt = readChunk(chunk.x, chunk.z); - // If read was good - if (nbt != null) { - gc = parseChunkFromNBT(new NBT.NBTCompound(nbt)); - } - return gc; - } - - public void setChunks(ForgeWorld dw, List chunks) { - this.w = dw.getWorld(); - if (dw.isLoaded()) { - /* Check if world's provider is ServerChunkProvider */ - cps = this.w.getChunkSource(); - } - super.setChunks(dw, chunks); - } - - private CompoundTag readChunk(int x, int z) { - try { - CompoundTag rslt = cps.chunkMap.read(new ChunkPos(x, z)).join().get(); - if (rslt != null) { - CompoundTag lev = rslt; - if (lev.contains("Level")) { - lev = lev.getCompound("Level"); - } - // Don't load uncooked chunks - String stat = lev.getString("Status"); - ChunkStatus cs = ChunkStatus.byName(stat); - if ((stat == null) || - // Needs to be at least lighted - (!cs.isOrAfter(ChunkStatus.LIGHT))) { - rslt = null; - } - } - // Log.info(String.format("loadChunk(%d,%d)=%s", x, z, (rslt != null) ? - // rslt.toString() : "null")); - return rslt; - } catch (NoSuchElementException nsex) { - return null; - } catch (Exception exc) { - Log.severe(String.format("Error reading chunk: %s,%d,%d", dw.getName(), x, z), exc); - return null; - } - } - @Override - public int getFoliageColor(BiomeMap bm, int[] colormap, int x, int z) { - return bm.getBiomeObject().map(Biome::getSpecialEffects) - .flatMap(BiomeSpecialEffects::getFoliageColorOverride) - .orElse(colormap[bm.biomeLookup()]); - } - - @Override - public int getGrassColor(BiomeMap bm, int[] colormap, int x, int z) { - BiomeSpecialEffects effects = bm.getBiomeObject().map(Biome::getSpecialEffects).orElse(null); - if (effects == null) return colormap[bm.biomeLookup()]; - return effects.getGrassColorModifier().modifyColor(x, z, effects.getGrassColorOverride().orElse(colormap[bm.biomeLookup()])); - } -} diff --git a/forge-1.19/src/main/java/org/dynmap/forge_1_19/ForgeWorld.java b/forge-1.19/src/main/java/org/dynmap/forge_1_19/ForgeWorld.java deleted file mode 100644 index 02ea2f64..00000000 --- a/forge-1.19/src/main/java/org/dynmap/forge_1_19/ForgeWorld.java +++ /dev/null @@ -1,249 +0,0 @@ -package org.dynmap.forge_1_19; -/** - * Forge specific implementation of DynmapWorld - */ -import java.util.List; - -import net.minecraft.world.level.ServerLevelAccessor; -import net.minecraft.world.level.border.WorldBorder; -import net.minecraft.world.level.levelgen.Heightmap; -import net.minecraft.core.BlockPos; -import net.minecraft.resources.ResourceKey; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.LightLayer; - -import org.dynmap.DynmapChunk; -import org.dynmap.DynmapLocation; -import org.dynmap.DynmapWorld; -import org.dynmap.utils.MapChunkCache; -import org.dynmap.utils.Polygon; - -public class ForgeWorld extends DynmapWorld -{ - private ServerLevelAccessor 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 = 320; // Maximum allows world height - - public static int getMaxWorldHeight() { - return maxWorldHeight; - } - public static void setMaxWorldHeight(int h) { - maxWorldHeight = h; - } - - public static String getWorldName(ServerLevelAccessor w) { - ResourceKey rk = w.getLevel().dimension(); - String id = rk.location().getNamespace() + "_" + rk.location().getPath(); - if (id.equals("minecraft_overworld")) { // Overworld? - return w.getLevel().serverLevelData.getLevelName(); - } - else if (id.equals("minecraft_the_end")) { - return "DIM1"; - } - else if (id.equals("minecraft_the_nether")) { - return "DIM-1"; - } - else { - return id; - } - } - - public void updateWorld(ServerLevelAccessor w) { - this.updateWorldHeights(w.getLevel().getHeight(), w.getLevel().dimensionType().minY(), w.getLevel().getSeaLevel()); - } - - public ForgeWorld(ServerLevelAccessor w) - { - this(getWorldName(w), - w.getLevel().getHeight(), - w.getLevel().getSeaLevel(), - w.getLevel().dimension() == Level.NETHER, - w.getLevel().dimension() == Level.END, - getWorldName(w), - w.getLevel().dimensionType().minY()); - setWorldLoaded(w); - } - public ForgeWorld(String name, int height, int sealevel, boolean nether, boolean the_end, String deftitle, int miny) - { - super(name, (height > maxWorldHeight)?maxWorldHeight:height, sealevel, miny); - 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"; - } - //Log.info(getName() + ": skylight=" + skylight + ", height=" + this.worldheight + ", isnether=" + isnether + ", istheend=" + istheend); - } - /* 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) { - BlockPos p = world.getLevel().getSharedSpawnPos(); - spawnloc.x = p.getX(); - spawnloc.y = p.getY(); - spawnloc.z = p.getZ(); - spawnloc.world = this.getName(); - } - return spawnloc; - } - /* Get world time */ - @Override - public long getTime() - { - if(world != null) - return world.getLevel().getDayTime(); - else - return -1; - } - /* World is storming */ - @Override - public boolean hasStorm() - { - if(world != null) - return world.getLevel().isRaining(); - else - return false; - } - /* World is thundering */ - @Override - public boolean isThundering() - { - if(world != null) - return world.getLevel().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(ServerLevelAccessor w) { - world = w; - this.sealevel = w.getLevel().getSeaLevel(); // Read actual current sealevel from world - // Update lighting table - for (int i = 0; i < 16; i++) { - // Algorithm based on LightmapTextureManager.getBrightness() - // We can't call that method because it's client-only. - // This means the code below can stop being correct if Mojang ever - // updates the curve; in that case we should reflect the changes. - float value = (float) i / 15.0f; - float brightness = value / (4.0f - 3.0f * value); - this.setBrightnessTableEntry(i, brightness); - //Log.info(getName() + ": light " + i + " = " + light); - } - } - /* Get light level of block */ - @Override - public int getLightLevel(int x, int y, int z) - { - if(world != null) - return world.getLevel().getLightEngine().getRawBrightness(new BlockPos(x, y, z), 0); - else - return -1; - } - /* Get highest Y coord of given location */ - @Override - public int getHighestBlockYAt(int x, int z) - { - if(world != null) { - return world.getLevel().getChunk(x >> 4, z >> 4).getHeight(Heightmap.Types.MOTION_BLOCKING, 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.getLevel().getBrightness(LightLayer.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) { - ForgeMapChunkCache c = new ForgeMapChunkCache(DynmapPlugin.plugin.sscache); - c.setChunks(this, chunks); - return c; - } - return null; - } - - public ServerLevel getWorld() - { - return world.getLevel(); - } - @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.getMinX(), wb.getMinZ()); - p.addVertex(wb.getMinX(), wb.getMaxZ()); - p.addVertex(wb.getMaxX(), wb.getMaxZ()); - p.addVertex(wb.getMaxX(), wb.getMinZ()); - return p; - } - } - return null; - } -} diff --git a/forge-1.19/src/main/java/org/dynmap/forge_1_19/NBT.java b/forge-1.19/src/main/java/org/dynmap/forge_1_19/NBT.java deleted file mode 100644 index aad82091..00000000 --- a/forge-1.19/src/main/java/org/dynmap/forge_1_19/NBT.java +++ /dev/null @@ -1,126 +0,0 @@ -package org.dynmap.forge_1_19; - -import org.dynmap.common.chunk.GenericBitStorage; -import org.dynmap.common.chunk.GenericNBTCompound; -import org.dynmap.common.chunk.GenericNBTList; - -import java.util.Set; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.ListTag; -import net.minecraft.util.SimpleBitStorage; - -public class NBT { - - public static class NBTCompound implements GenericNBTCompound { - private final CompoundTag obj; - public NBTCompound(CompoundTag t) { - this.obj = t; - } - @Override - public Set getAllKeys() { - return obj.getAllKeys(); - } - @Override - public boolean contains(String s) { - return obj.contains(s); - } - @Override - public boolean contains(String s, int i) { - return obj.contains(s, i); - } - @Override - public byte getByte(String s) { - return obj.getByte(s); - } - @Override - public short getShort(String s) { - return obj.getShort(s); - } - @Override - public int getInt(String s) { - return obj.getInt(s); - } - @Override - public long getLong(String s) { - return obj.getLong(s); - } - @Override - public float getFloat(String s) { - return obj.getFloat(s); - } - @Override - public double getDouble(String s) { - return obj.getDouble(s); - } - @Override - public String getString(String s) { - return obj.getString(s); - } - @Override - public byte[] getByteArray(String s) { - return obj.getByteArray(s); - } - @Override - public int[] getIntArray(String s) { - return obj.getIntArray(s); - } - @Override - public long[] getLongArray(String s) { - return obj.getLongArray(s); - } - @Override - public GenericNBTCompound getCompound(String s) { - return new NBTCompound(obj.getCompound(s)); - } - @Override - public GenericNBTList getList(String s, int i) { - return new NBTList(obj.getList(s, i)); - } - @Override - public boolean getBoolean(String s) { - return obj.getBoolean(s); - } - @Override - public String getAsString(String s) { - return obj.get(s).getAsString(); - } - @Override - public GenericBitStorage makeBitStorage(int bits, int count, long[] data) { - return new OurBitStorage(bits, count, data); - } - public String toString() { - return obj.toString(); - } - } - public static class NBTList implements GenericNBTList { - private final ListTag obj; - public NBTList(ListTag t) { - obj = t; - } - @Override - public int size() { - return obj.size(); - } - @Override - public String getString(int idx) { - return obj.getString(idx); - } - @Override - public GenericNBTCompound getCompound(int idx) { - return new NBTCompound(obj.getCompound(idx)); - } - public String toString() { - return obj.toString(); - } - } - public static class OurBitStorage implements GenericBitStorage { - private final SimpleBitStorage bs; - public OurBitStorage(int bits, int count, long[] data) { - bs = new SimpleBitStorage(bits, count, data); - } - @Override - public int get(int idx) { - return bs.get(idx); - } - } -} diff --git a/forge-1.19/src/main/java/org/dynmap/forge_1_19/Proxy.java b/forge-1.19/src/main/java/org/dynmap/forge_1_19/Proxy.java deleted file mode 100644 index c2b6ee29..00000000 --- a/forge-1.19/src/main/java/org/dynmap/forge_1_19/Proxy.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.dynmap.forge_1_19; - -import net.minecraft.server.MinecraftServer; - -/** - * Server side proxy - methods for creating and cleaning up plugin - */ -public class Proxy -{ - public Proxy() - { - } - public DynmapPlugin startServer(MinecraftServer srv) { - DynmapPlugin plugin = DynmapPlugin.plugin; - if (plugin == null) { - plugin = new DynmapPlugin(srv); - plugin.onEnable(); - } - return plugin; - } - public void stopServer(DynmapPlugin plugin) { - plugin.onDisable(); - } -} diff --git a/forge-1.19/src/main/java/org/dynmap/forge_1_19/VersionCheck.java b/forge-1.19/src/main/java/org/dynmap/forge_1_19/VersionCheck.java deleted file mode 100644 index 044e2df3..00000000 --- a/forge-1.19/src/main/java/org/dynmap/forge_1_19/VersionCheck.java +++ /dev/null @@ -1,97 +0,0 @@ -package org.dynmap.forge_1_19; - -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.URL; - -import org.dynmap.DynmapCore; -import org.dynmap.Log; - -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/forge-1.19/src/main/java/org/dynmap/forge_1_19/permissions/FilePermissions.java b/forge-1.19/src/main/java/org/dynmap/forge_1_19/permissions/FilePermissions.java deleted file mode 100644 index c3121bd3..00000000 --- a/forge-1.19/src/main/java/org/dynmap/forge_1_19/permissions/FilePermissions.java +++ /dev/null @@ -1,103 +0,0 @@ -package org.dynmap.forge_1_19.permissions; - -import java.io.File; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.dynmap.ConfigurationNode; -import org.dynmap.Log; -import org.dynmap.forge_1_19.DynmapPlugin; - -import net.minecraft.server.level.ServerPlayer; - -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(ServerPlayer psender, String permission) { - if(psender != null) { - String n = psender.getName().getString().toLowerCase(); - return hasPerm(n, permission); - } - return true; - } - @Override - public boolean hasPermissionNode(ServerPlayer psender, String permission) { - if(psender != null) { - String player = psender.getName().getString().toLowerCase(); - return DynmapPlugin.plugin.isOp(player); - } - return false; - } - -} diff --git a/forge-1.19/src/main/java/org/dynmap/forge_1_19/permissions/OpPermissions.java b/forge-1.19/src/main/java/org/dynmap/forge_1_19/permissions/OpPermissions.java deleted file mode 100644 index ddbe5c78..00000000 --- a/forge-1.19/src/main/java/org/dynmap/forge_1_19/permissions/OpPermissions.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.dynmap.forge_1_19.permissions; - -import java.util.HashSet; -import java.util.Set; - -import org.dynmap.Log; -import org.dynmap.forge_1_19.DynmapPlugin; - -import net.minecraft.server.level.ServerPlayer; - -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(ServerPlayer 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(ServerPlayer psender, String permission) { - if(psender != null) { - return DynmapPlugin.plugin.isOp(psender.getName().getString()); - } - return true; - } -} diff --git a/forge-1.19/src/main/java/org/dynmap/forge_1_19/permissions/PermissionProvider.java b/forge-1.19/src/main/java/org/dynmap/forge_1_19/permissions/PermissionProvider.java deleted file mode 100644 index d41a772d..00000000 --- a/forge-1.19/src/main/java/org/dynmap/forge_1_19/permissions/PermissionProvider.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.dynmap.forge_1_19.permissions; - -import java.util.Set; - -import net.minecraft.server.level.ServerPlayer; - -public interface PermissionProvider { - boolean has(ServerPlayer sender, String permission); - boolean hasPermissionNode(ServerPlayer sender, String permission); - - Set hasOfflinePermissions(String player, Set perms); - - boolean hasOfflinePermission(String player, String perm); - -} diff --git a/forge-1.19/src/main/resources/META-INF/accesstransformer.cfg b/forge-1.19/src/main/resources/META-INF/accesstransformer.cfg deleted file mode 100644 index 58a91d30..00000000 --- a/forge-1.19/src/main/resources/META-INF/accesstransformer.cfg +++ /dev/null @@ -1,4 +0,0 @@ -public net.minecraft.world.level.biome.BiomeSpecialEffects$Builder f_47928_ # waterColor -public net.minecraft.server.level.ServerLevel f_8549_ # serverLevelData -public net.minecraft.server.level.ChunkMap f_140130_ # visibleChunkMap -public net.minecraft.server.level.ChunkMap m_214963_(Lnet/minecraft/world/level/ChunkPos;)Ljava/util/concurrent/CompletableFuture; # readChunk( diff --git a/forge-1.19/src/main/resources/META-INF/mods.toml b/forge-1.19/src/main/resources/META-INF/mods.toml deleted file mode 100644 index 17241af4..00000000 --- a/forge-1.19/src/main/resources/META-INF/mods.toml +++ /dev/null @@ -1,26 +0,0 @@ -modLoader="javafml" -loaderVersion="[41,)" -issueTrackerURL="https://github.com/webbukkit/dynmap/issues" -license="Apache Public License v2" -[[mods]] -modId="dynmap" -version="${version}" -displayName="Dynmap" -authors="mikeprimm" -description=''' -Dynamic, Google-maps style rendered maps for your Minecraft server -''' - -[[dependencies.dynmap]] - modId="forge" - mandatory=true - versionRange="[41,)" - ordering="NONE" - # Side this dependency is applied on - BOTH, CLIENT or SERVER - side="SERVER" -[[dependencies.dynmap]] - modId="minecraft" - mandatory=true - versionRange="[1.19,1.20)" - ordering="NONE" - side="SERVER" diff --git a/forge-1.19/src/main/resources/configuration.txt b/forge-1.19/src/main/resources/configuration.txt deleted file mode 100644 index eb4b28da..00000000 --- a/forge-1.19/src/main/resources/configuration.txt +++ /dev/null @@ -1,503 +0,0 @@ -# All paths in this configuration file are relative to Dynmap's data-folder: minecraft_server/dynmap/ - -# All map templates are defined in the templates directory -# To use the HDMap very-low-res (2 ppb) map templates as world defaults, set value to vlowres -# The definitions of these templates are in normal-vlowres.txt, nether-vlowres.txt, and the_end-vlowres.txt -# To use the HDMap low-res (4 ppb) map templates as world defaults, set value to lowres -# The definitions of these templates are in normal-lowres.txt, nether-lowres.txt, and the_end-lowres.txt -# To use the HDMap hi-res (16 ppb) map templates (these can take a VERY long time for initial fullrender), set value to hires -# The definitions of these templates are in normal-hires.txt, nether-hires.txt, and the_end-hires.txt -# To use the HDMap low-res (4 ppb) map templates, with support for boosting resolution selectively to hi-res (16 ppb), set value to low_boost_hi -# The definitions of these templates are in normal-low_boost_hi.txt, nether-low_boost_hi.txt, and the_end-low_boost_hi.txt -# To use the HDMap hi-res (16 ppb) map templates, with support for boosting resolution selectively to vhi-res (32 ppb), set value to hi_boost_vhi -# The definitions of these templates are in normal-hi_boost_vhi.txt, nether-hi_boost_vhi.txt, and the_end-hi_boost_vhi.txt -# To use the HDMap hi-res (16 ppb) map templates, with support for boosting resolution selectively to xhi-res (64 ppb), set value to hi_boost_xhi -# The definitions of these templates are in normal-hi_boost_xhi.txt, nether-hi_boost_xhi.txt, and the_end-hi_boost_xhi.txt -deftemplatesuffix: hires - -# Set default tile scale (0 = 128px x 128x, 1 = 256px x 256px, 2 = 512px x 512px, 3 = 1024px x 1024px, 4 = 2048px x 2048px) - 0 is default -# Note: changing this value will result in all maps that use the default value being required to be fully rendered -#defaulttilescale: 0 - -# Map storage scheme: only uncommoent one 'type' value -# filetree: classic and default scheme: tree of files, with all map data under the directory indicated by 'tilespath' setting -# sqlite: single SQLite database file (this can get VERY BIG), located at 'dbfile' setting (default is file dynmap.db in data directory) -# mysql: MySQL database, at hostname:port in database, accessed via userid with password -# mariadb: MariaDB database, at hostname:port in database, accessed via userid with password -# postgres: PostgreSQL database, at hostname:port in database, accessed via userid with password -storage: - # Filetree storage (standard tree of image files for maps) - type: filetree - # SQLite db for map storage (uses dbfile as storage location) - #type: sqlite - #dbfile: dynmap.db - # MySQL DB for map storage (at 'hostname':'port' in database 'database' using user 'userid' password 'password' and table prefix 'prefix' - #type: mysql - #hostname: localhost - #port: 3306 - #database: dynmap - #userid: dynmap - #password: dynmap - #prefix: "" - # - # AWS S3 backet web site - #type: aws_s3 - #bucketname: "dynmap-bucket-name" - #region: us-east-1 - #aws_access_key_id: "" - #aws_secret_access_key: "" - #prefix: "" - #override_endpoint: "" - -components: - - class: org.dynmap.ClientConfigurationComponent - - # Remember to change the following class to org.dynmap.JsonFileClientUpdateComponent when using an external web server. - - class: org.dynmap.InternalClientUpdateComponent - sendhealth: true - sendposition: true - allowwebchat: true - webchat-interval: 5 - hidewebchatip: false - trustclientname: false - includehiddenplayers: false - # (optional) if true, color codes in player display names are used - use-name-colors: false - # (optional) if true, player login IDs will be used for web chat when their IPs match - use-player-login-ip: true - # (optional) if use-player-login-ip is true, setting this to true will cause chat messages not matching a known player IP to be ignored - require-player-login-ip: false - # (optional) block player login IDs that are banned from chatting - block-banned-player-chat: true - # Require login for web-to-server chat (requires login-enabled: true) - webchat-requires-login: false - # If set to true, users must have dynmap.webchat permission in order to chat - webchat-permissions: false - # Limit length of single chat messages - chatlengthlimit: 256 - # # Optional - make players hidden when they are inside/underground/in shadows (#=light level: 0=full shadow,15=sky) - # hideifshadow: 4 - # # Optional - make player hidden when they are under cover (#=sky light level,0=underground,15=open to sky) - # hideifundercover: 14 - # # (Optional) if true, players that are crouching/sneaking will be hidden - hideifsneaking: false - # optional, if true, players that are in spectator mode will be hidden - hideifspectator: false - # If true, player positions/status is protected (login with ID with dynmap.playermarkers.seeall permission required for info other than self) - protected-player-info: false - # If true, hide players with invisibility potion effects active - hide-if-invisiblity-potion: true - # If true, player names are not shown on map, chat, list - hidenames: false - #- class: org.dynmap.JsonFileClientUpdateComponent - # writeinterval: 1 - # sendhealth: true - # sendposition: true - # allowwebchat: true - # webchat-interval: 5 - # hidewebchatip: false - # includehiddenplayers: false - # use-name-colors: false - # use-player-login-ip: false - # require-player-login-ip: false - # block-banned-player-chat: true - # hideifshadow: 0 - # hideifundercover: 0 - # hideifsneaking: false - # # Require login for web-to-server chat (requires login-enabled: true) - # webchat-requires-login: false - # # If set to true, users must have dynmap.webchat permission in order to chat - # webchat-permissions: false - # # Limit length of single chat messages - # chatlengthlimit: 256 - # hide-if-invisiblity-potion: true - # hidenames: false - - - class: org.dynmap.SimpleWebChatComponent - allowchat: true - # If true, web UI users can supply name for chat using 'playername' URL parameter. 'trustclientname' must also be set true. - allowurlname: false - - # Note: this component is needed for the dmarker commands, and for the Marker API to be available to other plugins - - class: org.dynmap.MarkersComponent - type: markers - showlabel: false - enablesigns: false - # Default marker set for sign markers - default-sign-set: markers - # (optional) add spawn point markers to standard marker layer - showspawn: true - spawnicon: world - spawnlabel: "Spawn" - # (optional) layer for showing offline player's positions (for 'maxofflinetime' minutes after logoff) - showofflineplayers: false - offlinelabel: "Offline" - offlineicon: offlineuser - offlinehidebydefault: true - offlineminzoom: 0 - maxofflinetime: 30 - # (optional) layer for showing player's spawn beds - showspawnbeds: false - spawnbedlabel: "Spawn Beds" - spawnbedicon: bed - spawnbedhidebydefault: true - spawnbedminzoom: 0 - spawnbedformat: "%name%'s bed" - # (optional) Show world border (vanilla 1.8+) - showworldborder: true - worldborderlabel: "Border" - - - class: org.dynmap.ClientComponent - type: chat - allowurlname: false - - class: org.dynmap.ClientComponent - type: chatballoon - focuschatballoons: false - - class: org.dynmap.ClientComponent - type: chatbox - showplayerfaces: true - messagettl: 5 - # Optional: set number of lines in scrollable message history: if set, messagettl is not used to age out messages - #scrollback: 100 - # Optional: set maximum number of lines visible for chatbox - #visiblelines: 10 - # Optional: send push button - sendbutton: false - - class: org.dynmap.ClientComponent - type: playermarkers - showplayerfaces: true - showplayerhealth: true - # If true, show player body too (only valid if showplayerfaces=true) - showplayerbody: false - # Option to make player faces small - don't use with showplayerhealth or largeplayerfaces - smallplayerfaces: false - # Option to make player faces larger - don't use with showplayerhealth or smallplayerfaces - largeplayerfaces: false - # Optional - make player faces layer hidden by default - hidebydefault: false - # Optional - ordering priority in layer menu (low goes before high - default is 0) - layerprio: 0 - # Optional - label for player marker layer (default is 'Players') - label: "Players" - - #- class: org.dynmap.ClientComponent - # type: digitalclock - - class: org.dynmap.ClientComponent - type: link - - - class: org.dynmap.ClientComponent - type: timeofdayclock - showdigitalclock: true - #showweather: true - # Mouse pointer world coordinate display - - class: org.dynmap.ClientComponent - type: coord - label: "Location" - hidey: false - show-mcr: false - show-chunk: false - - # Note: more than one logo component can be defined - #- class: org.dynmap.ClientComponent - # type: logo - # text: "Dynmap" - # #logourl: "images/block_surface.png" - # linkurl: "http://forums.bukkit.org/threads/dynmap.489/" - # # Valid positions: top-left, top-right, bottom-left, bottom-right - # position: bottom-right - - #- class: org.dynmap.ClientComponent - # type: inactive - # timeout: 1800 # in seconds (1800 seconds = 30 minutes) - # redirecturl: inactive.html - # #showmessage: 'You were inactive for too long.' - - #- class: org.dynmap.TestComponent - # stuff: "This is some configuration-value" - -# Treat hiddenplayers.txt as a whitelist for players to be shown on the map? (Default false) -display-whitelist: false - -# How often a tile gets rendered (in seconds). -renderinterval: 1 - -# How many tiles on update queue before accelerate render interval -renderacceleratethreshold: 60 - -# How often to render tiles when backlog is above renderacceleratethreshold -renderaccelerateinterval: 0.2 - -# How many update tiles to work on at once (if not defined, default is 1/2 the number of cores) -tiles-rendered-at-once: 2 - -# If true, use normal priority threads for rendering (versus low priority) - this can keep rendering -# from starving on busy Windows boxes (Linux JVMs pretty much ignore thread priority), but may result -# in more competition for CPU resources with other processes -usenormalthreadpriority: true - -# Save and restore pending tile renders - prevents their loss on server shutdown or /reload -saverestorepending: true - -# Save period for pending jobs (in seconds): periodic saving for crash recovery of jobs -save-pending-period: 900 - -# Zoom-out tile update period - how often to scan for and process tile updates into zoom-out tiles (in seconds) -zoomoutperiod: 30 - -# Control whether zoom out tiles are validated on startup (can be needed if zoomout processing is interrupted, but can be expensive on large maps) -initial-zoomout-validate: true - -# Default delay on processing of updated tiles, in seconds. This can reduce potentially expensive re-rendering -# of frequently updated tiles (such as due to machines, pistons, quarries or other automation). Values can -# also be set on individual worlds and individual maps. -tileupdatedelay: 30 - -# Tile hashing is used to minimize tile file updates when no changes have occurred - set to false to disable -enabletilehash: true - -# Optional - hide ores: render as normal stone (so that they aren't revealed by maps) -#hideores: true - -# Optional - enabled BetterGrass style rendering of grass and snow block sides -#better-grass: true - -# Optional - enable smooth lighting by default on all maps supporting it (can be set per map as lighting option) -smooth-lighting: true - -# Optional - use world provider lighting table (good for custom worlds with custom lighting curves, like nether) -# false=classic Dynmap lighting curve -use-brightness-table: true - -# Optional - render specific block names using the textures and models of another block name: can be used to hide/disguise specific -# blocks (e.g. make ores look like stone, hide chests) or to provide simple support for rendering unsupported custom blocks -block-alias: -# "minecraft:quartz_ore": "stone" -# "diamond_ore": "coal_ore" - -# Default image format for HDMaps (png, jpg, jpg-q75, jpg-q80, jpg-q85, jpg-q90, jpg-q95, jpg-q100, webp, webp-q75, webp-q80, webp-q85, webp-q90, webp-q95, webp-q100), -# Note: any webp format requires the presence of the 'webp command line tools' (cwebp, dwebp) (https://developers.google.com/speed/webp/download) -# -# Has no effect on maps with explicit format settings -image-format: jpg-q90 - -# If cwebp or dwebp are not on the PATH, use these settings to provide their full path. Do not use these settings if the tools are on the PATH -# For Windows, include .exe -# -#cwebpPath: /usr/bin/cwebp -#dwebpPath: /usr/bin/dwebp - -# use-generated-textures: if true, use generated textures (same as client); false is static water/lava textures -# correct-water-lighting: if true, use corrected water lighting (same as client); false is legacy water (darker) -# transparent-leaves: if true, leaves are transparent (lighting-wise): false is needed for some Spout versions that break lighting on leaf blocks -use-generated-textures: true -correct-water-lighting: true -transparent-leaves: true - -# ctm-support: if true, Connected Texture Mod (CTM) in texture packs is enabled (default) -ctm-support: true -# custom-colors-support: if true, Custom Colors in texture packs is enabled (default) -custom-colors-support: true - -# Control loading of player faces (if set to false, skins are never fetched) -#fetchskins: false - -# Control updating of player faces, once loaded (if faces are being managed by other apps or manually) -#refreshskins: false - -# Customize URL used for fetching player skins (%player% is macro for name, %uuid% for UUID) -skin-url: "http://skins.minecraft.net/MinecraftSkins/%player%.png" - -# Control behavior for new (1.0+) compass orientation (sunrise moved 90 degrees: east is now what used to be south) -# default is 'newrose' (preserve pre-1.0 maps, rotate rose) -# 'newnorth' is used to rotate maps and rose (requires fullrender of any HDMap map - same as 'newrose' for FlatMap or KzedMap) -compass-mode: newnorth - -# Triggers for automatic updates : blockupdate-with-id is debug for breaking down updates by ID:meta -# To disable, set just 'none' and comment/delete the rest -render-triggers: - - blockupdate - #- blockupdate-with-id - #- lightingupdate - - chunkpopulate - - chunkgenerate - #- none - -# Title for the web page - if not specified, defaults to the server's name (unless it is the default of 'Unknown Server') -#webpage-title: "My Awesome Server Map" - -# The path where the tile-files are placed. -tilespath: web/tiles - -# The path where the web-files are located. -webpath: web - -# If set to false, disable extraction of webpath content (good if using custom web UI or 3rd party web UI) -# Note: web interface is unsupported in this configuration - you're on your own -update-webpath-files: true - -# The path were the /dynmapexp command exports OBJ ZIP files -exportpath: export - -# The path where files can be imported for /dmarker commands -importpath: import - -# The network-interface the webserver will bind to (0.0.0.0 for all interfaces, 127.0.0.1 for only local access). -# If not set, uses same setting as server in server.properties (or 0.0.0.0 if not specified) -#webserver-bindaddress: 0.0.0.0 - -# The TCP-port the webserver will listen on. -webserver-port: 8123 - -# Maximum concurrent session on internal web server - limits resources used in Bukkit server -max-sessions: 30 - -# Disables Webserver portion of Dynmap (Advanced users only) -disable-webserver: false - -# Enable/disable having the web server allow symbolic links (true=compatible with existing code, false=more secure (default)) -allow-symlinks: true - -# Enable login support -login-enabled: false -# Require login to access website (requires login-enabled: true) -login-required: false - -# Period between tile renders for fullrender, in seconds (non-zero to pace fullrenders, lessen CPU load) -timesliceinterval: 0.0 - -# Maximum chunk loads per server tick (1/20th of a second) - reducing this below 90 will impact render performance, but also will reduce server thread load -maxchunkspertick: 200 - -# Progress report interval for fullrender/radiusrender, in tiles. Must be 100 or greater -progressloginterval: 100 - -# Parallel fullrender: if defined, number of concurrent threads used for fullrender or radiusrender -# Note: setting this will result in much more intensive CPU use, some additional memory use. Caution should be used when -# setting this to equal or exceed the number of physical cores on the system. -#parallelrendercnt: 4 - -# Interval the browser should poll for updates. -updaterate: 2000 - -# If nonzero, server will pause fullrender/radiusrender processing when 'fullrenderplayerlimit' or more users are logged in -fullrenderplayerlimit: 0 -# If nonzero, server will pause update render processing when 'updateplayerlimit' or more users are logged in -updateplayerlimit: 0 -# Target limit on server thread use - msec per tick -per-tick-time-limit: 50 -# If TPS of server is below this setting, update renders processing is paused -update-min-tps: 18.0 -# If TPS of server is below this setting, full/radius renders processing is paused -fullrender-min-tps: 18.0 -# If TPS of server is below this setting, zoom out processing is paused -zoomout-min-tps: 18.0 - -showplayerfacesinmenu: true - -# Control whether players that are hidden or not on current map are grayed out (true=yes) -grayplayerswhenhidden: true - -# Set sidebaropened: 'true' to pin menu sidebar opened permanently, 'pinned' to default the sidebar to pinned, but allow it to unpin -#sidebaropened: true - -# Customized HTTP response headers - add 'id: value' pairs to all HTTP response headers (internal web server only) -#http-response-headers: -# Access-Control-Allow-Origin: "my-domain.com" -# X-Custom-Header-Of-Mine: "MyHeaderValue" - -# Trusted proxies for web server - which proxy addresses are trusted to supply valid X-Forwarded-For fields -# This now supports both IP address, and subnet ranges (e.g. 192.168.1.0/24 or 202.24.0.0/14 ) -trusted-proxies: - - "127.0.0.1" - - "0:0:0:0:0:0:0:1" - -joinmessage: "%playername% joined" -quitmessage: "%playername% quit" -spammessage: "You may only chat once every %interval% seconds." -# format for messages from web: %playername% substitutes sender ID (typically IP), %message% includes text -webmsgformat: "&color;2[WEB] %playername%: &color;f%message%" - -# Control whether layer control is presented on the UI (default is true) -showlayercontrol: true - -# Enable checking for banned IPs via banned-ips.txt (internal web server only) -check-banned-ips: true - -# Default selection when map page is loaded -defaultzoom: 0 -defaultworld: world -defaultmap: flat -# (optional) Zoom level and map to switch to when following a player, if possible -#followzoom: 3 -#followmap: surface - -# If true, make persistent record of IP addresses used by player logins, to support web IP to player matching -persist-ids-by-ip: true - -# If true, map text to cyrillic -cyrillic-support: false - -# Messages to customize -msg: - maptypes: "Map Types" - players: "Players" - chatrequireslogin: "Chat Requires Login" - chatnotallowed: "You are not permitted to send chat messages" - hiddennamejoin: "Player joined" - hiddennamequit: "Player quit" - -# URL for client configuration (only need to be tailored for proxies or other non-standard configurations) -url: - # configuration URL - #configuration: "up/configuration" - # update URL - #update: "up/world/{world}/{timestamp}" - # sendmessage URL - #sendmessage: "up/sendmessage" - # login URL - #login: "up/login" - # register URL - #register: "up/register" - # tiles base URL - #tiles: "tiles/" - # markers base URL - #markers: "tiles/" - # Snapshot cache size, in chunks -snapshotcachesize: 500 -# Snapshot cache uses soft references (true), else weak references (false) -soft-ref-cache: true - -# Player enter/exit title messages for map markers -# -# Processing period - how often to check player positions vs markers - default is 1000ms (1 second) -#enterexitperiod: 1000 -# Title message fade in time, in ticks (0.05 second intervals) - default is 10 (1/2 second) -#titleFadeIn: 10 -# Title message stay time, in ticks (0.05 second intervals) - default is 70 (3.5 seconds) -#titleStay: 70 -# Title message fade out time, in ticks (0.05 seocnd intervals) - default is 20 (1 second) -#titleFadeOut: 20 -# Enter/exit messages use on screen titles (true - default), if false chat messages are sent instead -#enterexitUseTitle: true -# Set true if new enter messages should supercede pending exit messages (vs being queued in order), default false -#enterReplacesExits: true - -# Published public URL for Dynmap server (allows users to use 'dynmap url' command to get public URL usable to access server -# If not set, 'dynmap url' will not return anything. URL should be fully qualified (e.g. https://mc.westeroscraft.com/) -#publicURL: http://my.greatserver.com/dynmap - -# Send this message if the player does not have permission to use the command -noPermissionMsg: "You don't have permission to use this command!" - -# Set to true to enable verbose startup messages - can help with debugging map configuration problems -# Set to false for a much quieter startup log -verbose: false - -# Enables debugging. -#debuggers: -# - class: org.dynmap.debug.LogDebugger -# Debug: dump blocks missing render data -dump-missing-blocks: false - -# Log4J defense: string substituted for attempts to use macros in web chat -hackAttemptBlurb: "(IaM5uchA1337Haxr-Ban Me!)" diff --git a/forge-1.19/src/main/resources/pack.mcmeta b/forge-1.19/src/main/resources/pack.mcmeta deleted file mode 100644 index 8ae5db1a..00000000 --- a/forge-1.19/src/main/resources/pack.mcmeta +++ /dev/null @@ -1,6 +0,0 @@ -{ - "pack": { - "description": "Dynmap resources", - "pack_format": 8 - } -} diff --git a/forge-1.19/src/main/resources/permissions.yml.example b/forge-1.19/src/main/resources/permissions.yml.example deleted file mode 100644 index a25f9adc..00000000 --- a/forge-1.19/src/main/resources/permissions.yml.example +++ /dev/null @@ -1,27 +0,0 @@ -# -# Sample permissions.yml for dynmap - trivial, flat-file based permissions for dynmap features -# To use, copy this file to dynmap/permissions.yml, and edit appropriate. File is YAML format. -# -# All operators have full permissions to all functions. -# All users receive the permissions under the 'defaultuser' section -# Specific users can be given more permissions by defining a section with their name containing their permisssions -# All permissions correspond to those documented here (https://github.com/webbukkit/dynmap/wiki/Permissions), but -# do NOT have the 'dynmap.' prefix when used here (e.g. 'dynmap.fullrender' permission is just 'fullrender' here). -# -defaultuser: - - render - - show.self - - hide.self - - sendtoweb - - stats - - marker.list - - marker.listsets - - marker.icons - - webregister - - webchat - #- marker.sign - -#playername1: -# - fullrender -# - cancelrender -# - radiusrender diff --git a/settings.gradle b/settings.gradle index 7915eada..b333ed49 100644 --- a/settings.gradle +++ b/settings.gradle @@ -33,9 +33,6 @@ include ':fabric-1.20.4' include ':fabric-1.20.2' include ':fabric-1.20' include ':fabric-1.19.4' -include ':fabric-1.19.3' -include ':fabric-1.19.1' -include ':fabric-1.19' include ':fabric-1.18.2' include ':fabric-1.17.1' include ':fabric-1.16.4' @@ -44,8 +41,6 @@ include ':fabric-1.14.4' include ':forge-1.20.2' include ':forge-1.20' include ':forge-1.19.3' -include ':forge-1.19.2' -include ':forge-1.19' include ':forge-1.18.2' include ':forge-1.17.1' include ':forge-1.16.5' @@ -77,9 +72,6 @@ project(':fabric-1.20.4').projectDir = "$rootDir/fabric-1.20.4" as File project(':fabric-1.20.2').projectDir = "$rootDir/fabric-1.20.2" as File project(':fabric-1.20').projectDir = "$rootDir/fabric-1.20" as File project(':fabric-1.19.4').projectDir = "$rootDir/fabric-1.19.4" as File -project(':fabric-1.19.3').projectDir = "$rootDir/fabric-1.19.3" as File -project(':fabric-1.19.1').projectDir = "$rootDir/fabric-1.19.1" as File -project(':fabric-1.19').projectDir = "$rootDir/fabric-1.19" as File project(':fabric-1.18.2').projectDir = "$rootDir/fabric-1.18.2" as File project(':fabric-1.17.1').projectDir = "$rootDir/fabric-1.17.1" as File project(':fabric-1.16.4').projectDir = "$rootDir/fabric-1.16.4" as File @@ -88,7 +80,6 @@ project(':fabric-1.14.4').projectDir = "$rootDir/fabric-1.14.4" as File project(':forge-1.20.2').projectDir = "$rootDir/forge-1.20.2" as File project(':forge-1.20').projectDir = "$rootDir/forge-1.20" as File project(':forge-1.19.3').projectDir = "$rootDir/forge-1.19.3" as File -project(':forge-1.19.2').projectDir = "$rootDir/forge-1.19.2" as File project(':forge-1.18.2').projectDir = "$rootDir/forge-1.18.2" as File project(':forge-1.17.1').projectDir = "$rootDir/forge-1.17.1" as File project(':forge-1.16.5').projectDir = "$rootDir/forge-1.16.5" as File