From 78deaf4a9e77c3cee0016b4a675fe1739cc92f35 Mon Sep 17 00:00:00 2001 From: Awakened-Redstone <40528665+Awakened-Redstone@users.noreply.github.com> Date: Sun, 14 Apr 2024 21:45:48 -0300 Subject: [PATCH] Update branch Signed-off-by: Awakened-Redstone <40528665+Awakened-Redstone@users.noreply.github.com> --- .editorconfig | 3 + .gitignore | 130 ++++- README.md | 56 ++- build.gradle | 87 ++-- gradle.properties | 42 +- gradle/wrapper/gradle-wrapper.jar | Bin 60756 -> 63721 bytes gradle/wrapper/gradle-wrapper.properties | 4 +- gradlew | 25 +- gradlew.bat | 1 + .../neoskies}/api/SkylandsAPI.java | 38 +- .../neoskies}/api/events/IslandEvents.java | 4 +- .../api/island/DefaultPermissionLevel.java | 2 +- .../neoskies}/api/island/IslandSettings.java | 2 +- .../api/island/IslandSettingsList.java | 2 +- .../neoskies}/api/island/PermissionLevel.java | 22 +- .../neoskies}/api/island/SettingsManager.java | 21 +- .../neoskies}/command/SkylandsCommands.java | 26 +- .../command/admin/BallanceCommand.java | 30 +- .../command/admin/DeleteIslandCommand.java | 16 +- .../command/admin/IslandDataCommand.java | 26 +- .../command/admin/SettingsCommand.java | 19 +- .../command/island/AcceptCommand.java | 53 +- .../neoskies}/command/island/BanCommands.java | 37 +- .../command/island/CreateCommand.java | 22 +- .../command/island/DeleteCommand.java | 43 +- .../neoskies}/command/island/HelpCommand.java | 10 +- .../neoskies}/command/island/HubCommands.java | 42 +- .../neoskies}/command/island/KickCommand.java | 27 +- .../command/island/LevelCommand.java | 167 +++++-- .../command/island/MemberCommands.java | 56 ++- .../neoskies}/command/island/MenuCommand.java | 66 +-- .../command/island/SettingCommands.java | 41 +- .../command/island/VisitCommand.java | 27 +- .../neoskies}/command/utils/CommandUtils.java | 40 +- .../neoskies/config/IslandRanking.java | 27 + .../neoskies/config/MainConfig.java | 73 +++ .../neoskies/config/source/Config.java | 108 ++++ .../config/source/JanksonBuilder.java | 191 +++++++ .../annotation/PredicateConstraint.java | 12 + .../source/annotation/RangeConstraint.java | 16 + .../source/annotation/RegexConstraint.java | 12 + .../config/source/jankson/Marshaller.java | 471 ++++++++++++++++++ .../neoskies}/data/PlayerComponent.java | 2 +- .../neoskies}/data/SkylandComponents.java | 15 +- .../neoskies}/data/WorldComponent.java | 11 +- .../datagen/NeoSkiesBlockTagProvider.java | 76 +++ .../neoskies/datagen/NeoSkiesDatagen.java | 14 + .../datagen/NeoSkiesEntityTagProvider.java | 24 + .../datagen/NeoSkiesItemTagProvider.java | 71 +++ .../neoskies}/duck/ExtendedChunk.java | 2 +- .../neoskies/duck/ExtendedPlayerManager.java | 7 + .../duck/ExtendedServerPlayerEntity.java | 7 + .../neoskies}/event/PlayerConnectEvent.java | 19 +- .../neoskies}/event/PlayerEvents.java | 3 +- .../neoskies/event/ServerEventListener.java | 85 ++++ .../neoskies}/font/FontManager.java | 10 +- .../neoskies}/font/FontProvider.java | 7 +- .../neoskies/gui/CommonGuiElements.java | 41 ++ .../neoskies}/gui/IslandSettingsGui.java | 31 +- .../neoskies/gui/PagedGui.java | 231 +++++++++ .../neoskies/gui/SkinEncoder.java | 29 ++ .../neoskies/gui/polymer/CBGuiElement.java | 25 + .../gui/polymer/CBGuiElementBuilder.java | 341 +++++++++++++ .../gui/polymer/CBSimpleGuiBuilder.java | 269 ++++++++++ .../awakenedredstone/neoskies}/logic/Hub.java | 33 +- .../neoskies}/logic/Invites.java | 12 +- .../neoskies}/logic/Island.java | 119 +++-- .../neoskies}/logic/IslandStuck.java | 78 ++- .../neoskies}/logic/Member.java | 4 +- .../neoskies}/logic/Skylands.java | 47 +- .../neoskies}/logic/SkylandsRegistries.java | 8 +- .../neoskies}/logic/economy/Economy.java | 4 +- .../logic/economy/SkylandsEconomyAccount.java | 10 +- .../economy/SkylandsEconomyCurrency.java | 8 +- .../economy/SkylandsEconomyProvider.java | 16 +- .../SkylandsProtectionProvider.java | 78 +++ .../registry/NeoSkiesIslandSettings.java | 100 ++++ .../logic/tags/NeoSkiesBlockTags.java | 21 + .../logic/tags/NeoSkiesEntityTags.java | 13 + .../neoskies/logic/tags/NeoSkiesItemTags.java | 11 + .../neoskies}/logic/util/ChunkScanQueue.java | 2 +- .../mixin/block/EndPortalBlockMixin.java | 11 +- .../neoskies}/mixin/block/FireBlockMixin.java | 4 +- .../block/accessor/WorldBorderAccessor.java | 2 +- .../entity/EndGatewayBlockEntityMixin.java | 4 +- .../neoskies/mixin/compat/JanksonAcessor.java | 17 + .../compat/POJODeserializerAccessor.java | 14 + .../neoskies}/mixin/entity/EntityMixin.java | 11 +- .../mixin/entity/PlayerManagerMixin.java | 175 +++++++ .../mixin/entity/ServerPlayerEntityMixin.java | 67 ++- .../mixin/item/ArmorStandItemMixin.java | 11 +- .../neoskies}/mixin/item/BlockItemMixin.java | 19 +- .../neoskies}/mixin/item/BoatItemMixin.java | 6 +- .../neoskies/mixin/item/ItemStackMixin.java} | 27 +- .../mixin/item/MinecartItemMixin.java | 11 +- .../neoskies}/mixin/world/ChunkMixin.java | 4 +- .../mixin/world/PlayerEntityMixin.java | 49 +- .../mixin/world/PortalForcerMixin.java | 6 +- .../mixin/world/ServerWorldMixin.java | 21 +- .../protection/AbstractBlockStateMixin.java | 4 +- .../protection/AbstractCandleBlockMixin.java | 11 +- .../world/protection/AnvilBlockMixin.java | 11 +- .../world/protection/ArmorStandMixin.java | 25 +- .../mixin/world/protection/AxeItemMixin.java | 11 +- .../world/protection/BeaconBlockMixin.java | 11 +- .../world/protection/BigDripLeafMixin.java | 13 +- .../mixin/world/protection/BoatMixin.java | 21 +- .../world/protection/BoneMealItemMixin.java | 11 +- .../protection/BrewingStandBlockMixin.java | 11 +- .../world/protection/BucketItemMixin.java | 11 +- .../mixin/world/protection/ButtonMixin.java | 13 +- .../world/protection/CampfireBlockMixin.java | 15 +- .../world/protection/CandleBlockMixin.java | 11 +- .../protection/CandleCakeBlockMixin.java | 11 +- .../world/protection/CauldronBlockMixin.java | 11 +- .../world/protection/ChestBlockMixin.java | 11 +- .../world/protection/ChestBoatMixin.java | 13 +- .../world/protection/ComparatorMixin.java | 11 +- .../world/protection/CompassItemMixin.java | 13 +- .../world/protection/ComposterBlockMixin.java | 11 +- .../DaylightDetectorBlockMixin.java | 11 +- .../protection/DecorationEntityMixin.java | 13 +- .../world/protection/DecorationItemMixin.java | 11 +- .../world/protection/DispenserBlockMixin.java | 15 +- .../world/protection/DoorBlockMixin.java | 11 +- .../world/protection/DropperBlockMixin.java | 9 +- .../world/protection/EnderEyeItemMixin.java | 11 +- .../world/protection/FarmlandBlockMixin.java | 11 +- .../world/protection/FenceBlockMixin.java | 11 +- .../world/protection/FenceGateBlockMixin.java | 11 +- .../world/protection/FilledMapItemMixin.java | 11 +- .../world/protection/FireChargeItemMixin.java | 11 +- .../world/protection/FlintAndSteelMixin.java | 11 +- .../world/protection/FlowerPotBlockMixin.java | 11 +- .../world/protection/FurnaceBlockMixin.java | 11 +- .../mixin/world/protection/HoeItemMixin.java | 11 +- .../world/protection/HoneycombItemMixin.java | 11 +- .../protection/HopperBlockEntityMixin.java | 4 +- .../world/protection/HopperBlockMixin.java | 18 +- .../protection/HopperMinecartEntityMixin.java | 6 +- .../protection/ItemFrameEntityMixin.java | 19 +- .../mixin/world/protection/LeadItemMixin.java | 11 +- .../protection/LeashKnotEntityMixin.java | 13 +- .../world/protection/LecternBlockMixin.java | 11 +- .../mixin/world/protection/LeverMixin.java | 13 +- .../world/protection/LivingEntityMixin.java | 19 +- .../mixin/world/protection/MinecartMixin.java | 17 +- .../world/protection/NoteBlockMixin.java | 11 +- .../world/protection/PistonBlockMixin.java | 4 +- .../world/protection/PlayerEntityMixin.java | 15 +- .../world/protection/PotionEntityMixin.java | 17 +- .../protection/PressurePlateBlockMixin.java | 11 +- .../world/protection/PumpkinBlockMixin.java | 13 +- .../world/protection/RedstoneWireMixin.java | 15 +- .../mixin/world/protection/RepeaterMixin.java | 11 +- .../protection/RespawnAnchorBlockMixin.java | 12 +- .../SculkCatalystBlockEntityMixin.java | 40 ++ .../SculkSensorBlockEntityMixin.java | 14 +- .../protection/SculkSensorBlockMixin.java | 15 +- .../SculkShriekerBlockEntityMixin.java | 14 +- .../protection/SculkShriekerBlockMixin.java | 9 +- .../protection/SculkSpreadCursorMixin.java | 4 +- .../world/protection/ShearsItemMixin.java | 11 +- .../world/protection/ShovelItemMixin.java | 11 +- .../protection/ShulkerBoxBlockMixin.java | 11 +- .../protection/StorageMinecartMixin.java | 13 +- .../protection/SweetBerryBushBlockMixin.java | 11 +- .../world/protection/TargetBlockMixin.java | 11 +- .../mixin/world/protection/TntBlockMixin.java | 29 +- .../world/protection/TrapdoorBlockMixin.java | 11 +- .../protection/VibrationListenerMixin.java | 23 +- .../world/protection/VillagerEntityMixin.java | 13 +- .../mixin/world/protection/WorldMixin.java | 9 +- .../protection/WritableBookItemMixin.java | 11 +- .../protection/WrittenBookItemMixin.java | 11 +- .../neoskies/util/AutoRegister.java | 6 + .../neoskies}/util/Constants.java | 4 +- .../neoskies}/util/DynamicPlaceholders.java | 4 +- .../neoskies}/util/FontUtils.java | 6 +- .../neoskies}/util/IslandUtils.java | 4 +- .../neoskies/util/MapBuilder.java | 36 ++ .../neoskies}/util/NbtMigrator.java | 2 +- .../neoskies}/util/Players.java | 6 +- .../neoskies}/util/PreInitData.java | 13 +- .../neoskies}/util/Scheduler.java | 4 +- .../neoskies}/util/ServerUtils.java | 8 +- .../neoskies}/util/Texts.java | 10 +- .../neoskies/util/UIUtils.java | 30 ++ .../neoskies}/util/UnitConvertions.java | 2 +- .../neoskies}/util/WorldProtection.java | 81 ++- .../neoskies}/util/Worlds.java | 20 +- src/main/java/skylands/config/MainConfig.java | 30 -- .../skylands/data/reloadable/SongsData.java | 45 -- .../java/skylands/event/BlockBreakEvent.java | 29 -- .../skylands/event/ServerEventListener.java | 43 -- .../java/skylands/event/UseBlockEvent.java | 52 -- .../java/skylands/event/UseEntityEvent.java | 22 - .../java/skylands/event/UseItemEvent.java | 16 - .../registry/SkylandsIslandSettings.java | 34 -- .../mixin/entity/PlayerManagerMixin.java | 46 -- .../world/protection/BarrelBlockMixin.java | 31 -- .../SculkCatalystBlockEntityMixin.java | 32 -- .../protection/SculkCatalystBlockMixin.java | 25 - .../assets/{skylands => neoskies}/icon.png | Bin .../font/default.glyphs.json | 0 .../{skylands => neoskies}/font/default.json | 2 +- .../font/glyph_sizes.bin | Bin .../songs/heads-will-roll.nbs | Bin .../{skylands => neoskies}/songs/home.nbs | Bin .../songs/merry_go_round_of_life.nbs | Bin .../songs/our_great_mikado.nbs | Bin .../structures/end_island.nbt | Bin .../structures/nether_island.nbt | Bin .../structures/start_island.nbt | Bin src/main/resources/fabric.mod.json | 34 +- ...s.accesswidener => neoskies.accesswidener} | 8 + 216 files changed, 4381 insertions(+), 1706 deletions(-) mode change 100644 => 100755 gradlew rename src/main/java/{skylands => com/awakenedredstone/neoskies}/api/SkylandsAPI.java (63%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/api/events/IslandEvents.java (94%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/api/island/DefaultPermissionLevel.java (73%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/api/island/IslandSettings.java (79%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/api/island/IslandSettingsList.java (69%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/api/island/PermissionLevel.java (56%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/api/island/SettingsManager.java (87%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/command/SkylandsCommands.java (61%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/command/admin/BallanceCommand.java (83%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/command/admin/DeleteIslandCommand.java (64%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/command/admin/IslandDataCommand.java (80%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/command/admin/SettingsCommand.java (56%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/command/island/AcceptCommand.java (50%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/command/island/BanCommands.java (76%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/command/island/CreateCommand.java (60%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/command/island/DeleteCommand.java (56%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/command/island/HelpCommand.java (81%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/command/island/HubCommands.java (57%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/command/island/KickCommand.java (67%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/command/island/LevelCommand.java (72%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/command/island/MemberCommands.java (57%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/command/island/MenuCommand.java (72%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/command/island/SettingCommands.java (74%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/command/island/VisitCommand.java (66%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/command/utils/CommandUtils.java (61%) create mode 100644 src/main/java/com/awakenedredstone/neoskies/config/IslandRanking.java create mode 100644 src/main/java/com/awakenedredstone/neoskies/config/MainConfig.java create mode 100644 src/main/java/com/awakenedredstone/neoskies/config/source/Config.java create mode 100644 src/main/java/com/awakenedredstone/neoskies/config/source/JanksonBuilder.java create mode 100644 src/main/java/com/awakenedredstone/neoskies/config/source/annotation/PredicateConstraint.java create mode 100644 src/main/java/com/awakenedredstone/neoskies/config/source/annotation/RangeConstraint.java create mode 100644 src/main/java/com/awakenedredstone/neoskies/config/source/annotation/RegexConstraint.java create mode 100644 src/main/java/com/awakenedredstone/neoskies/config/source/jankson/Marshaller.java rename src/main/java/{skylands => com/awakenedredstone/neoskies}/data/PlayerComponent.java (97%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/data/SkylandComponents.java (64%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/data/WorldComponent.java (73%) create mode 100644 src/main/java/com/awakenedredstone/neoskies/datagen/NeoSkiesBlockTagProvider.java create mode 100644 src/main/java/com/awakenedredstone/neoskies/datagen/NeoSkiesDatagen.java create mode 100644 src/main/java/com/awakenedredstone/neoskies/datagen/NeoSkiesEntityTagProvider.java create mode 100644 src/main/java/com/awakenedredstone/neoskies/datagen/NeoSkiesItemTagProvider.java rename src/main/java/{skylands => com/awakenedredstone/neoskies}/duck/ExtendedChunk.java (77%) create mode 100644 src/main/java/com/awakenedredstone/neoskies/duck/ExtendedPlayerManager.java create mode 100644 src/main/java/com/awakenedredstone/neoskies/duck/ExtendedServerPlayerEntity.java rename src/main/java/{skylands => com/awakenedredstone/neoskies}/event/PlayerConnectEvent.java (73%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/event/PlayerEvents.java (94%) create mode 100644 src/main/java/com/awakenedredstone/neoskies/event/ServerEventListener.java rename src/main/java/{skylands => com/awakenedredstone/neoskies}/font/FontManager.java (88%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/font/FontProvider.java (96%) create mode 100644 src/main/java/com/awakenedredstone/neoskies/gui/CommonGuiElements.java rename src/main/java/{skylands => com/awakenedredstone/neoskies}/gui/IslandSettingsGui.java (78%) create mode 100644 src/main/java/com/awakenedredstone/neoskies/gui/PagedGui.java create mode 100644 src/main/java/com/awakenedredstone/neoskies/gui/SkinEncoder.java create mode 100644 src/main/java/com/awakenedredstone/neoskies/gui/polymer/CBGuiElement.java create mode 100644 src/main/java/com/awakenedredstone/neoskies/gui/polymer/CBGuiElementBuilder.java create mode 100644 src/main/java/com/awakenedredstone/neoskies/gui/polymer/CBSimpleGuiBuilder.java rename src/main/java/{skylands => com/awakenedredstone/neoskies}/logic/Hub.java (66%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/logic/Invites.java (83%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/logic/Island.java (80%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/logic/IslandStuck.java (52%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/logic/Member.java (90%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/logic/Skylands.java (59%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/logic/SkylandsRegistries.java (76%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/logic/economy/Economy.java (81%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/logic/economy/SkylandsEconomyAccount.java (88%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/logic/economy/SkylandsEconomyCurrency.java (80%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/logic/economy/SkylandsEconomyProvider.java (86%) create mode 100644 src/main/java/com/awakenedredstone/neoskies/logic/protection/SkylandsProtectionProvider.java create mode 100644 src/main/java/com/awakenedredstone/neoskies/logic/registry/NeoSkiesIslandSettings.java create mode 100644 src/main/java/com/awakenedredstone/neoskies/logic/tags/NeoSkiesBlockTags.java create mode 100644 src/main/java/com/awakenedredstone/neoskies/logic/tags/NeoSkiesEntityTags.java create mode 100644 src/main/java/com/awakenedredstone/neoskies/logic/tags/NeoSkiesItemTags.java rename src/main/java/{skylands => com/awakenedredstone/neoskies}/logic/util/ChunkScanQueue.java (97%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/block/EndPortalBlockMixin.java (83%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/block/FireBlockMixin.java (88%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/block/accessor/WorldBorderAccessor.java (83%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/block/entity/EndGatewayBlockEntityMixin.java (86%) create mode 100644 src/main/java/com/awakenedredstone/neoskies/mixin/compat/JanksonAcessor.java create mode 100644 src/main/java/com/awakenedredstone/neoskies/mixin/compat/POJODeserializerAccessor.java rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/entity/EntityMixin.java (94%) create mode 100644 src/main/java/com/awakenedredstone/neoskies/mixin/entity/PlayerManagerMixin.java rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/entity/ServerPlayerEntityMixin.java (56%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/item/ArmorStandItemMixin.java (78%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/item/BlockItemMixin.java (77%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/item/BoatItemMixin.java (91%) rename src/main/java/{skylands/mixin/item/ItemMixin.java => com/awakenedredstone/neoskies/mixin/item/ItemStackMixin.java} (61%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/item/MinecartItemMixin.java (78%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/ChunkMixin.java (87%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/PlayerEntityMixin.java (66%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/PortalForcerMixin.java (88%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/ServerWorldMixin.java (81%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/AbstractBlockStateMixin.java (90%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/AbstractCandleBlockMixin.java (79%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/AnvilBlockMixin.java (78%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/ArmorStandMixin.java (66%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/AxeItemMixin.java (75%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/BeaconBlockMixin.java (78%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/BigDripLeafMixin.java (82%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/BoatMixin.java (63%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/BoneMealItemMixin.java (75%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/BrewingStandBlockMixin.java (78%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/BucketItemMixin.java (85%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/ButtonMixin.java (76%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/CampfireBlockMixin.java (81%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/CandleBlockMixin.java (79%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/CandleCakeBlockMixin.java (80%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/CauldronBlockMixin.java (78%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/ChestBlockMixin.java (77%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/ChestBoatMixin.java (73%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/ComparatorMixin.java (80%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/CompassItemMixin.java (76%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/ComposterBlockMixin.java (78%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/DaylightDetectorBlockMixin.java (78%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/DecorationEntityMixin.java (71%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/DecorationItemMixin.java (78%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/DispenserBlockMixin.java (79%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/DoorBlockMixin.java (77%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/DropperBlockMixin.java (71%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/EnderEyeItemMixin.java (75%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/FarmlandBlockMixin.java (72%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/FenceBlockMixin.java (78%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/FenceGateBlockMixin.java (77%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/FilledMapItemMixin.java (75%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/FireChargeItemMixin.java (77%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/FlintAndSteelMixin.java (78%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/FlowerPotBlockMixin.java (77%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/FurnaceBlockMixin.java (78%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/HoeItemMixin.java (75%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/HoneycombItemMixin.java (77%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/HopperBlockEntityMixin.java (91%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/HopperBlockMixin.java (85%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/HopperMinecartEntityMixin.java (81%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/ItemFrameEntityMixin.java (68%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/LeadItemMixin.java (76%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/LeashKnotEntityMixin.java (72%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/LecternBlockMixin.java (81%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/LeverMixin.java (76%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/LivingEntityMixin.java (63%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/MinecartMixin.java (62%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/NoteBlockMixin.java (77%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/PistonBlockMixin.java (92%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/PlayerEntityMixin.java (78%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/PotionEntityMixin.java (73%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/PressurePlateBlockMixin.java (78%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/PumpkinBlockMixin.java (77%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/RedstoneWireMixin.java (88%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/RepeaterMixin.java (80%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/RespawnAnchorBlockMixin.java (75%) create mode 100644 src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/SculkCatalystBlockEntityMixin.java rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/SculkSensorBlockEntityMixin.java (58%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/SculkSensorBlockMixin.java (60%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/SculkShriekerBlockEntityMixin.java (58%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/SculkShriekerBlockMixin.java (72%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/SculkSpreadCursorMixin.java (88%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/ShearsItemMixin.java (75%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/ShovelItemMixin.java (75%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/ShulkerBoxBlockMixin.java (77%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/StorageMinecartMixin.java (66%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/SweetBerryBushBlockMixin.java (78%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/TargetBlockMixin.java (80%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/TntBlockMixin.java (83%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/TrapdoorBlockMixin.java (77%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/VibrationListenerMixin.java (59%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/VillagerEntityMixin.java (66%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/WorldMixin.java (72%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/WritableBookItemMixin.java (77%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/mixin/world/protection/WrittenBookItemMixin.java (77%) create mode 100644 src/main/java/com/awakenedredstone/neoskies/util/AutoRegister.java rename src/main/java/{skylands => com/awakenedredstone/neoskies}/util/Constants.java (72%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/util/DynamicPlaceholders.java (91%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/util/FontUtils.java (94%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/util/IslandUtils.java (70%) create mode 100644 src/main/java/com/awakenedredstone/neoskies/util/MapBuilder.java rename src/main/java/{skylands => com/awakenedredstone/neoskies}/util/NbtMigrator.java (79%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/util/Players.java (72%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/util/PreInitData.java (63%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/util/Scheduler.java (95%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/util/ServerUtils.java (68%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/util/Texts.java (93%) create mode 100644 src/main/java/com/awakenedredstone/neoskies/util/UIUtils.java rename src/main/java/{skylands => com/awakenedredstone/neoskies}/util/UnitConvertions.java (89%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/util/WorldProtection.java (51%) rename src/main/java/{skylands => com/awakenedredstone/neoskies}/util/Worlds.java (77%) delete mode 100644 src/main/java/skylands/config/MainConfig.java delete mode 100644 src/main/java/skylands/data/reloadable/SongsData.java delete mode 100644 src/main/java/skylands/event/BlockBreakEvent.java delete mode 100644 src/main/java/skylands/event/ServerEventListener.java delete mode 100644 src/main/java/skylands/event/UseBlockEvent.java delete mode 100644 src/main/java/skylands/event/UseEntityEvent.java delete mode 100644 src/main/java/skylands/event/UseItemEvent.java delete mode 100644 src/main/java/skylands/logic/registry/SkylandsIslandSettings.java delete mode 100644 src/main/java/skylands/mixin/entity/PlayerManagerMixin.java delete mode 100644 src/main/java/skylands/mixin/world/protection/BarrelBlockMixin.java delete mode 100644 src/main/java/skylands/mixin/world/protection/SculkCatalystBlockEntityMixin.java delete mode 100644 src/main/java/skylands/mixin/world/protection/SculkCatalystBlockMixin.java rename src/main/resources/assets/{skylands => neoskies}/icon.png (100%) rename src/main/resources/data/{skylands => neoskies}/font/default.glyphs.json (100%) rename src/main/resources/data/{skylands => neoskies}/font/default.json (99%) rename src/main/resources/data/{skylands => neoskies}/font/glyph_sizes.bin (100%) rename src/main/resources/data/{skylands => neoskies}/songs/heads-will-roll.nbs (100%) rename src/main/resources/data/{skylands => neoskies}/songs/home.nbs (100%) rename src/main/resources/data/{skylands => neoskies}/songs/merry_go_round_of_life.nbs (100%) rename src/main/resources/data/{skylands => neoskies}/songs/our_great_mikado.nbs (100%) rename src/main/resources/data/{skylands => neoskies}/structures/end_island.nbt (100%) rename src/main/resources/data/{skylands => neoskies}/structures/nether_island.nbt (100%) rename src/main/resources/data/{skylands => neoskies}/structures/start_island.nbt (100%) rename src/main/resources/{skylands.accesswidener => neoskies.accesswidener} (50%) diff --git a/.editorconfig b/.editorconfig index 58cc925..d273b0d 100644 --- a/.editorconfig +++ b/.editorconfig @@ -6,6 +6,9 @@ charset = utf-8 end_of_line = lf insert_final_newline = true tab_width = 4 +indent_size = 4 +ij_continuation_indent_size = 2 + trim_trailing_whitespace = true [*.json] diff --git a/.gitignore b/.gitignore index 8f65d28..98f2b81 100644 --- a/.gitignore +++ b/.gitignore @@ -1,34 +1,124 @@ -# gradle +# User-specific stuff +.idea/ -.gradle/ -build/ +*.iml +*.ipr +*.iws + +# IntelliJ out/ -classes/ +# mpeltonen/sbt-idea plugin +.idea_modules/ -# eclipse +# JIRA plugin +atlassian-ide-plugin.xml -*.launch +# Compiled class file +*.class -# idea +# Log file +*.log -.idea/ -*.iml -*.ipr -*.iws +# BlueJ files +*.ctxt + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory -# vscode +# Linux trash folder which might appear on any partition or disk +.Trash-* -.settings/ -.vscode/ -bin/ -.classpath -.project +# .nfs files are created when an open file is removed but is still being accessed +.nfs* -# macos +# General +.DS_Store +.AppleDouble +.LSOverride -*.DS_Store +# Icon must end with two \r +Icon -# fabric +# Thumbnails +._* +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +.gradle +build/ + +# Ignore Gradle GUI config +gradle-app.setting + +# Cache of project +.gradletasknamecache + +**/build/ + +# Common working directory run/ + +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) +!gradle-wrapper.jar +/config.json +/users.db +/auto-whitelist.json +/remappedSrc/ +/CHANGELOG.md /.run/ diff --git a/README.md b/README.md index 973cf4a..dcc6036 100644 --- a/README.md +++ b/README.md @@ -1,40 +1,42 @@ -## This costom version is still in development! - ## About -Skylands is a Minecraft mod/plugin for fabric loader. Simple skyblock islands generator and manager allowing your -server's players create and visit islands. The mod can be used server-side only, however it's compatible with singleplayer -and modpacks. This mod is not complete and still in active development. +NeoSkies is a skyblock Minecraft mod, with island settings, teams, island upgrades, dedicated worlds for each island, economy integration (with Common Economy API) and more! +This is a server-side mod, fully compatible with **vanilla** clients -[![Discord Server](https://raw.githubusercontent.com/intergrav/devins-badges/v2/assets/cozy/social/discord-plural_64h.png)](https://discord.gg/DcemWeskeZ) -[![Modrinth Page](https://raw.githubusercontent.com/intergrav/devins-badges/v2/assets/cozy/available/modrinth_64h.png)](https://modrinth.com/mod/skylands) +[//]: # ([![Modrinth Page](https://raw.githubusercontent.com/intergrav/devins-badges/v2/assets/cozy/available/modrinth_64h.png)](https://modrinth.com/mod/neoskies)) ### User Commands -- **/sl hub** -> Teleport to the Hub. -- **/sl create** -> Creates an Island. -- **/sl home** -> Teleport to your Island. -- **/sl visit ** -> Visit someone's Island. -- **/sl home ** -> Teleport to an Island you are member of. -- **/sl members invite ** -> Invite player to your Island. -- **/sl members remove ** -> Remove player from your Island. -- **/sl accept ** -> Accept Island join invite request. -- **/sl kick ** -> Kick player from your Island. -- **/sl ban ** -> Ban player from visiting your Island. -- **/sl unban ** -> Unban player to allow visiting your Island. -- **/sl delete** -> Deletes your Island. -- **/sl settings set-spawn-pos** -> Changes home position. -- **/sl settings set-visits-pos** -> Changes visits position. -- **/sl settings toggle-visits** -> Enables/disables ability to visit your Island. -- **/sl help** -> Sends this list. +- **/is home** -> Open the mod GUI +- **/is hub** -> Teleport to the Hub. +- **/is create** -> Creates an Island. +- **/is home** -> Teleport to your Island. +- **/is visit ** -> Visit someone's Island. +- **/is home ** -> Teleport to an Island you are member of. +- **/is members invite ** -> Invite player to your Island. +- **/is members remove ** -> Remove player from your Island. +- **/is accept ** -> Accept Island join invite request. +- **/is kick ** -> Kick player from your Island. +- **/is ban ** -> Ban player from visiting your Island. +- **/is unban ** -> Unban player to allow visiting your Island. +- **/is delete** -> Deletes your Island. +- **/is settings set-spawn-pos** -> Changes home position. +- **/is settings set-visits-pos** -> Changes visits position. +- **/is settings toggle-visits** -> Enables/disables ability to visit your Island. +- **/is help** -> Sends this list. ### Admin Commands -- **/force-sl set-hub-pos** -> Changes position of the hub. -- **/force-sl delete-island ** -> Deletes player's Island. -- **/force-sl toggle-hub-protection** -> Enables/disables hub protection. -- **/force-sl toggle-hub-music** -> Enables/disables hub background music. +- **/sba hub \(pos|protection)** -> Modify the hub settings. +- **/sba delete-island \** -> Delete a player's island +- **/sba settings** -> Change the mod settings (WIP) +- **/sba balance \(get|set|add|remove)** -> Modify an island's balance +- **/sba island-data \(find|get)** -> Get the data of an island +- **/sba modify \(size|gamerule)** -> Modify an island property +- **/sba reload** -> Reload the mod data + +This mod is a fork of [Skylands](https://modrinth.com/mod/skylands), made to have more feature parity with skyblock plugins like [bSkyblock](https://modrinth.com/plugin/bskyblock) and [ASkyblock](https://www.spigotmc.org/resources/askyblock.1220/) diff --git a/build.gradle b/build.gradle index d81f859..7d9082d 100644 --- a/build.gradle +++ b/build.gradle @@ -1,10 +1,32 @@ plugins { - id "fabric-loom" version "1.1-SNAPSHOT" - id 'io.freefair.lombok' version '6.6.2' + id "fabric-loom" version "1.6-SNAPSHOT" +} + +sourceSets { + main { + resources { + srcDirs += [ + 'src/main/generated' + ] + } + } } loom { - accessWidenerPath = file("src/main/resources/skylands.accesswidener") + accessWidenerPath = file("src/main/resources/neoskies.accesswidener") + + runs { + datagenServer { + server() + name "Data Generation" + vmArg "-Dfabric-api.datagen" + vmArg "-Dfabric-api.datagen.output-dir=${file("src/main/generated")}" + vmArg "-Dfabric-api.datagen.modid=neoskies" + + ideConfigGenerated = true + runDir "build/datagen" + } + } } archivesBaseName = project.archives_base_name @@ -12,47 +34,48 @@ version = project.mod_version group = project.maven_group repositories { - //mavenLocal() - maven { - url "https://api.modrinth.com/maven" - content { includeGroup "maven.modrinth" } - } maven { url "https://maven.nucleoid.xyz" } maven { url "https://maven.awakenedredstone.com" } maven { url "https://oss.sonatype.org/content/repositories/snapshots" } - maven { url "https://ladysnake.jfrog.io/artifactory/mods" } - maven { url = "https://jitpack.io" } - - maven { url "https://maven.wispforest.io" } //Temporary + maven { url "https://maven.ladysnake.org/releases" } + maven { url "https://maven.isxander.dev/releases" } + maven { url "https://jitpack.io" } } dependencies { + //region Fabric minecraft "com.mojang:minecraft:${project.minecraft_version}" mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" - modImplementation "net.fabricmc:fabric-loader:${project.fabric_loader}" modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_api}" - modImplementation "dev.onyxstudios.cardinal-components-api:cardinal-components-api:${project.cca}" - include "dev.onyxstudios.cardinal-components-api:cardinal-components-base:${project.cca}" - include "dev.onyxstudios.cardinal-components-api:cardinal-components-world:${project.cca}" - include "dev.onyxstudios.cardinal-components-api:cardinal-components-entity:${project.cca}" - - modImplementation include("eu.pb4:sgui:${project.sgui}") - modImplementation include("xyz.nucleoid:fantasy:${project.fantasy}") - modImplementation include("maven.modrinth:nota:${project.nota}") - modImplementation include("eu.pb4:placeholder-api:${project.papi}") - modImplementation include("xyz.nucleoid:server-translations-api:${project.sta}") + //endregion + // region Cardinal Components + modImplementation "dev.onyxstudios.cardinal-components-api:cardinal-components-api:${project.cardinal_components_api}" + include "dev.onyxstudios.cardinal-components-api:cardinal-components-base:${project.cardinal_components_api}" + include "dev.onyxstudios.cardinal-components-api:cardinal-components-world:${project.cardinal_components_api}" + // endregion + // region Nucleoid + modImplementation include("xyz.nucleoid:fantasy:${project.fantasy}") modImplementation include("xyz.nucleoid:stimuli:${project.stimuli}") - modImplementation include("me.lucko:fabric-permissions-api:${project.fpa}") - modImplementation include("eu.pb4:common-protection-api:${project.cpa}") - modImplementation include("eu.pb4:common-economy-api:${project.cea}") - + modImplementation include("xyz.nucleoid:server-translations-api:${project.server_translations_api}") + //endregion + // region Patbox + modImplementation include("eu.pb4:sgui:${project.server_gui}") + modImplementation include("eu.pb4:placeholder-api:${project.placeholder_api}") + modImplementation include("eu.pb4:common-economy-api:${project.common_economy_api}") + modImplementation include("eu.pb4:common-protection-api:${project.common_protection_api}") + //region Polymer + modImplementation include("eu.pb4:polymer-core:${project.polymer}") + modImplementation include("eu.pb4:polymer-resource-pack:${project.polymer}") modImplementation include("eu.pb4:polymer-virtual-entity:${project.polymer}") - - modImplementation "com.awakenedredstone:cbserverconfig:${project.cbsc}" - annotationProcessor(modCompileOnly "io.wispforest:owo-lib:0.10.3+1.19.4") //Temporary - - include(implementation(annotationProcessor("com.github.llamalad7.mixinextras:mixinextras-fabric:${project.mixin_extras}"))) + //endregion + //endregion + // region Others + modImplementation include("me.lucko:fabric-permissions-api:${project.fabric_permission_api}") + //endregion + // region Non mod dependencies + include api("blue.endless:jankson:${project.jankson_version}") + //endregion } processResources { diff --git a/gradle.properties b/gradle.properties index 852e5f6..9547c59 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,25 +2,29 @@ org.gradle.jvmargs = -Xmx2G # Mod Properties -maven_group = ru.pinkgoosik -archives_base_name = skylands-custom +maven_group = com.awakenedredstone +archives_base_name = neoskies mod_version = 1.0.0-alpha.1 # Dependencies | Check these on https://fabricmc.net/develop -minecraft_version = 1.19.4 -yarn_mappings = 1.19.4+build.1 -fabric_loader = 0.14.18 -fabric_api = 0.76.0+1.19.4 -cca = 5.1.0 -sgui = 1.2.1+1.19.3 -fantasy = 0.4.9+1.19.4-rc2 -nota = 0.1.0+1.19 -papi = 2.0.0-rc.1+1.19.3 -sta = 2.0.0-beta.2+1.19.4-pre2 -fpa = 0.2-SNAPSHOT -stimuli = 0.4.4+1.19.4-rc2 -cbsc = 0.1.0-alpha.5 -cpa = 1.0.0 -cea = 1.0.0 -polymer = 0.4.9+1.19.4 -mixin_extras = 0.2.0-beta.8 +minecraft_version = 1.20.4 +yarn_mappings = 1.20.4+build.3 +fabric_loader = 0.15.7 + +fabric_api = 0.96.11+1.20.4 + +cardinal_components_api = 5.4.0 + +server_gui = 1.4.2+1.20.4 +placeholder_api = 2.3.0+1.20.3 +common_protection_api = 1.0.0 +common_economy_api = 1.1.1 +polymer = 0.7.7+1.20.4 + +fantasy = 0.5.0+1.20.4 +server_translations_api = 2.2.0+1.20.3-rc1 +stimuli = 0.4.10+1.20.4 + +fabric_permission_api = 0.2-SNAPSHOT + +jankson_version=1.2.2 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 249e5832f090a2944b7473328c07c9755baa3196..7f93135c49b765f8051ef9d0a6055ff8e46073d8 100644 GIT binary patch delta 44091 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 F{tsc4gtPzv delta 41205 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 jFA#1K+D2e>Q|zP /dev/null && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -133,22 +131,29 @@ location of your Java installation." fi else JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac case $MAX_FD in #( '' | soft) :;; #( *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -193,6 +198,10 @@ if "$cygwin" || "$msys" ; then done fi + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + # Collect all arguments for the java command; # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of # shell script including quotes and variable substitutions, so put them in diff --git a/gradlew.bat b/gradlew.bat index f127cfd..93e3f59 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -26,6 +26,7 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% diff --git a/src/main/java/skylands/api/SkylandsAPI.java b/src/main/java/com/awakenedredstone/neoskies/api/SkylandsAPI.java similarity index 63% rename from src/main/java/skylands/api/SkylandsAPI.java rename to src/main/java/com/awakenedredstone/neoskies/api/SkylandsAPI.java index 3139070..b8ce1fa 100644 --- a/src/main/java/skylands/api/SkylandsAPI.java +++ b/src/main/java/com/awakenedredstone/neoskies/api/SkylandsAPI.java @@ -1,25 +1,29 @@ -package skylands.api; +package com.awakenedredstone.neoskies.api; import eu.pb4.common.economy.api.EconomyAccount; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.registry.RegistryKey; import net.minecraft.world.World; import org.jetbrains.annotations.Nullable; -import skylands.SkylandsMain; -import skylands.logic.Island; -import skylands.logic.Skylands; -import skylands.util.Constants; +import com.awakenedredstone.neoskies.SkylandsMain; +import com.awakenedredstone.neoskies.logic.Island; +import com.awakenedredstone.neoskies.logic.Skylands; +import com.awakenedredstone.neoskies.util.Constants; import java.util.Optional; import java.util.UUID; public class SkylandsAPI { - static Skylands skylands = Skylands.getInstance(); + public static final Skylands SKYLANDS = Skylands.getInstance(); public static boolean isHub(World world) { return world.getRegistryKey() == World.OVERWORLD; } + public static boolean isProtectedArea(World world) { + return isHub(world) || isIsland(world); + } + public static boolean isIsland(World world) { return isIsland(world.getRegistryKey()); } @@ -31,7 +35,7 @@ public static boolean isIsland(RegistryKey registryKey) { public static boolean isOverworld(RegistryKey registryKey) { var namespace = registryKey.getValue().getNamespace(); - return namespace.equals(SkylandsMain.MOD_ID) || registryKey == World.OVERWORLD; + return namespace.equals(Constants.NAMESPACE) || registryKey == World.OVERWORLD; } public static boolean isNether(RegistryKey registryKey) { @@ -45,24 +49,28 @@ public static boolean isEnd(RegistryKey registryKey) { } public static Optional getIslandByPlayer(PlayerEntity player) { - return skylands.islands.getFromMember(player); + return SKYLANDS.islands.getFromMember(player); } public static Optional getIslandByPlayer(String playerName) { - return skylands.islands.getByPlayer(playerName); + return SKYLANDS.islands.getByPlayer(playerName); } public static Optional getIslandByPlayer(UUID playerUuid) { - return skylands.islands.getByPlayer(playerUuid); + return SKYLANDS.islands.getByPlayer(playerUuid); } public static Optional getIsland(UUID islandId) { - return skylands.islands.get(islandId); + return SKYLANDS.islands.get(islandId); } public static Optional getIsland(World world) { - if (SkylandsAPI.isIsland(world)) { - return skylands.islands.getByPlayer(UUID.fromString(world.getRegistryKey().getValue().getPath())); + return getIsland(world.getRegistryKey()); + } + + public static Optional getIsland(RegistryKey registryKey) { + if (SkylandsAPI.isIsland(registryKey)) { + return SKYLANDS.islands.getByPlayer(UUID.fromString(registryKey.getValue().getPath())); } return Optional.empty(); } @@ -71,6 +79,10 @@ public static boolean hasIsland(PlayerEntity player) { return getIslandByPlayer(player).isPresent(); } + public static boolean isIslandOwner(PlayerEntity player) { + return getIslandByPlayer(player).isPresent() && getIslandByPlayer(player).get().owner.uuid.equals(player.getUuid()); + } + public static @Nullable EconomyAccount getIslandWallet(Island island) { return island.getWallet(); } diff --git a/src/main/java/skylands/api/events/IslandEvents.java b/src/main/java/com/awakenedredstone/neoskies/api/events/IslandEvents.java similarity index 94% rename from src/main/java/skylands/api/events/IslandEvents.java rename to src/main/java/com/awakenedredstone/neoskies/api/events/IslandEvents.java index e125b90..e39ac13 100644 --- a/src/main/java/skylands/api/events/IslandEvents.java +++ b/src/main/java/com/awakenedredstone/neoskies/api/events/IslandEvents.java @@ -1,10 +1,10 @@ -package skylands.api.events; +package com.awakenedredstone.neoskies.api.events; import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.api.event.EventFactory; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.world.World; -import skylands.logic.Island; +import com.awakenedredstone.neoskies.logic.Island; public interface IslandEvents { Event ON_HUB_VISIT = EventFactory.createArrayBacked(HubVisitEvent.class, callbacks -> (player, world) -> { diff --git a/src/main/java/skylands/api/island/DefaultPermissionLevel.java b/src/main/java/com/awakenedredstone/neoskies/api/island/DefaultPermissionLevel.java similarity index 73% rename from src/main/java/skylands/api/island/DefaultPermissionLevel.java rename to src/main/java/com/awakenedredstone/neoskies/api/island/DefaultPermissionLevel.java index 15f63d4..dbb8152 100644 --- a/src/main/java/skylands/api/island/DefaultPermissionLevel.java +++ b/src/main/java/com/awakenedredstone/neoskies/api/island/DefaultPermissionLevel.java @@ -1,4 +1,4 @@ -package skylands.api.island; +package com.awakenedredstone.neoskies.api.island; public class DefaultPermissionLevel extends PermissionLevel { diff --git a/src/main/java/skylands/api/island/IslandSettings.java b/src/main/java/com/awakenedredstone/neoskies/api/island/IslandSettings.java similarity index 79% rename from src/main/java/skylands/api/island/IslandSettings.java rename to src/main/java/com/awakenedredstone/neoskies/api/island/IslandSettings.java index a737720..e032721 100644 --- a/src/main/java/skylands/api/island/IslandSettings.java +++ b/src/main/java/com/awakenedredstone/neoskies/api/island/IslandSettings.java @@ -1,4 +1,4 @@ -package skylands.api.island; +package com.awakenedredstone.neoskies.api.island; public class IslandSettings { public PermissionLevel permissionLevel; diff --git a/src/main/java/skylands/api/island/IslandSettingsList.java b/src/main/java/com/awakenedredstone/neoskies/api/island/IslandSettingsList.java similarity index 69% rename from src/main/java/skylands/api/island/IslandSettingsList.java rename to src/main/java/com/awakenedredstone/neoskies/api/island/IslandSettingsList.java index 33f9c83..f87bc11 100644 --- a/src/main/java/skylands/api/island/IslandSettingsList.java +++ b/src/main/java/com/awakenedredstone/neoskies/api/island/IslandSettingsList.java @@ -1,4 +1,4 @@ -package skylands.api.island; +package com.awakenedredstone.neoskies.api.island; import net.minecraft.util.Identifier; diff --git a/src/main/java/skylands/api/island/PermissionLevel.java b/src/main/java/com/awakenedredstone/neoskies/api/island/PermissionLevel.java similarity index 56% rename from src/main/java/skylands/api/island/PermissionLevel.java rename to src/main/java/com/awakenedredstone/neoskies/api/island/PermissionLevel.java index b8821e9..6bbd9a9 100644 --- a/src/main/java/skylands/api/island/PermissionLevel.java +++ b/src/main/java/com/awakenedredstone/neoskies/api/island/PermissionLevel.java @@ -1,19 +1,29 @@ -package skylands.api.island; +package com.awakenedredstone.neoskies.api.island; -import lombok.Getter; +import com.awakenedredstone.neoskies.logic.SkylandsRegistries; import net.minecraft.util.Identifier; -import skylands.logic.SkylandsRegistries; + +import java.util.concurrent.atomic.AtomicReference; public abstract class PermissionLevel { - @Getter(lazy = true) - private final Identifier id = getIdentifierFromRegistry(); - @Getter + private final AtomicReference id = new AtomicReference<>(); private final int level; public PermissionLevel(int level) { this.level = level; } + public Identifier getId() { + if (id.get() == null) { + id.set(getIdentifierFromRegistry()); + } + return id.get(); + } + + public int getLevel() { + return level; + } + private Identifier getIdentifierFromRegistry() { return SkylandsRegistries.PERMISSION_LEVELS.getId(this); } diff --git a/src/main/java/skylands/api/island/SettingsManager.java b/src/main/java/com/awakenedredstone/neoskies/api/island/SettingsManager.java similarity index 87% rename from src/main/java/skylands/api/island/SettingsManager.java rename to src/main/java/com/awakenedredstone/neoskies/api/island/SettingsManager.java index 68dac00..a01c118 100644 --- a/src/main/java/skylands/api/island/SettingsManager.java +++ b/src/main/java/com/awakenedredstone/neoskies/api/island/SettingsManager.java @@ -1,8 +1,8 @@ -package skylands.api.island; +package com.awakenedredstone.neoskies.api.island; -import com.awakenedredstone.cbserverconfig.polymer.CBGuiElement; -import com.awakenedredstone.cbserverconfig.polymer.CBGuiElementBuilder; -import com.awakenedredstone.cbserverconfig.util.MapBuilder; +import com.awakenedredstone.neoskies.gui.polymer.CBGuiElement; +import com.awakenedredstone.neoskies.gui.polymer.CBGuiElementBuilder; +import com.awakenedredstone.neoskies.util.MapBuilder; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; import net.minecraft.registry.RegistryKey; @@ -11,12 +11,13 @@ import net.minecraft.sound.SoundEvents; import net.minecraft.text.Text; import net.minecraft.util.Identifier; -import skylands.logic.Island; -import skylands.logic.SkylandsRegistries; -import skylands.util.Texts; +import com.awakenedredstone.neoskies.logic.Island; +import com.awakenedredstone.neoskies.logic.SkylandsRegistries; +import com.awakenedredstone.neoskies.util.Texts; import java.util.*; +@Deprecated //TODO: Replace with just registry public class SettingsManager { private static final Map defaultSettings = new HashMap<>(); private static final Map icons = new HashMap<>(); @@ -93,15 +94,15 @@ private static List buildLore(Island island, Identifier identifier) { for (Integer level : levels) { - Text levelText = Texts.of("text.skylands.island_settings.level." + level); + Text levelText = Texts.of("text.neoskies.island_settings.level." + level); Map placeholders = new MapBuilder() .put("level", levelText) .build(); if (value == level) { - lore.add(Texts.of(Text.translatable("text.skylands.island_settings.selected"), placeholders)); + lore.add(Texts.of(Text.translatable("text.neoskies.island_settings.selected"), placeholders)); } else { - lore.add(Texts.of(Text.translatable("text.skylands.island_settings.unselected"), placeholders)); + lore.add(Texts.of(Text.translatable("text.neoskies.island_settings.unselected"), placeholders)); } } diff --git a/src/main/java/skylands/command/SkylandsCommands.java b/src/main/java/com/awakenedredstone/neoskies/command/SkylandsCommands.java similarity index 61% rename from src/main/java/skylands/command/SkylandsCommands.java rename to src/main/java/com/awakenedredstone/neoskies/command/SkylandsCommands.java index 97383f5..5e52d34 100644 --- a/src/main/java/skylands/command/SkylandsCommands.java +++ b/src/main/java/com/awakenedredstone/neoskies/command/SkylandsCommands.java @@ -1,11 +1,18 @@ -package skylands.command; +package com.awakenedredstone.neoskies.command; +import com.awakenedredstone.neoskies.config.MainConfig; +import com.awakenedredstone.neoskies.logic.Skylands; import com.mojang.brigadier.CommandDispatcher; import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; +import net.minecraft.server.command.CommandManager; import net.minecraft.server.command.ServerCommandSource; -import skylands.SkylandsMain; -import skylands.command.admin.*; -import skylands.command.island.*; +import com.awakenedredstone.neoskies.SkylandsMain; +import com.awakenedredstone.neoskies.command.admin.*; +import com.awakenedredstone.neoskies.command.island.*; +import net.minecraft.text.Text; + +import static com.awakenedredstone.neoskies.command.utils.CommandUtils.adminNode; +import static com.awakenedredstone.neoskies.command.utils.CommandUtils.registerAdmin; public class SkylandsCommands { @@ -20,6 +27,7 @@ private static void register(CommandDispatcher dispatcher) } private static void registerPublicCommands(CommandDispatcher dispatcher) { + //TODO: Fix soft-lock on "/help is" MenuCommand.init(dispatcher); CreateCommand.init(dispatcher); HubCommands.init(dispatcher); @@ -41,5 +49,15 @@ private static void registerAdminCommands(CommandDispatcher BallanceCommand.init(dispatcher); IslandDataCommand.init(dispatcher); ModifyCommand.init(dispatcher); + + registerAdmin(dispatcher, adminNode() + .then(CommandManager.literal("reload") + .executes(context -> { + context.getSource().sendFeedback(() -> Text.translatable("message.neoskies.reload"), true); + Skylands.getConfig().load(); + return 1; + }) + ) + ); } } diff --git a/src/main/java/skylands/command/admin/BallanceCommand.java b/src/main/java/com/awakenedredstone/neoskies/command/admin/BallanceCommand.java similarity index 83% rename from src/main/java/skylands/command/admin/BallanceCommand.java rename to src/main/java/com/awakenedredstone/neoskies/command/admin/BallanceCommand.java index f897eb7..b18587c 100644 --- a/src/main/java/skylands/command/admin/BallanceCommand.java +++ b/src/main/java/com/awakenedredstone/neoskies/command/admin/BallanceCommand.java @@ -1,6 +1,6 @@ -package skylands.command.admin; +package com.awakenedredstone.neoskies.command.admin; -import com.awakenedredstone.cbserverconfig.util.MapBuilder; +import com.awakenedredstone.neoskies.util.MapBuilder; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.arguments.LongArgumentType; import com.mojang.brigadier.arguments.StringArgumentType; @@ -9,22 +9,22 @@ import me.lucko.fabric.api.permissions.v0.Permissions; import net.minecraft.server.command.ServerCommandSource; import org.jetbrains.annotations.Nullable; -import skylands.api.SkylandsAPI; -import skylands.command.utils.CommandUtils; -import skylands.logic.Island; -import skylands.util.Texts; +import com.awakenedredstone.neoskies.api.SkylandsAPI; +import com.awakenedredstone.neoskies.command.utils.CommandUtils; +import com.awakenedredstone.neoskies.logic.Island; +import com.awakenedredstone.neoskies.util.Texts; import java.util.UUID; import static net.minecraft.server.command.CommandManager.argument; import static net.minecraft.server.command.CommandManager.literal; -import static skylands.command.utils.CommandUtils.adminNode; -import static skylands.command.utils.CommandUtils.registerAdmin; +import static com.awakenedredstone.neoskies.command.utils.CommandUtils.adminNode; +import static com.awakenedredstone.neoskies.command.utils.CommandUtils.registerAdmin; public class BallanceCommand { public static void init(CommandDispatcher dispatcher) { registerAdmin(dispatcher, adminNode() - .then(literal("balance").requires(Permissions.require("skylands.admin.economy.modify", 4)) + .then(literal("balance").requires(Permissions.require("neoskies.admin.economy.modify", 4)) .then(argument("island", StringArgumentType.word()) .suggests(CommandUtils.ISLAND_SUGGESTIONS) .then(literal("get") @@ -64,12 +64,12 @@ public static void init(CommandDispatcher dispatcher) { private static @Nullable EconomyAccount getWallet(ServerCommandSource source, Island island) { if (island == null) { - source.sendError(Texts.of("message.skylands.error.island_not_found")); + source.sendError(Texts.of("message.neoskies.error.island_not_found")); return null; } EconomyAccount islandWallet = SkylandsAPI.getIslandWallet(island); if (islandWallet == null) { - source.sendError(Texts.of("message.skylands.error.island_wallet_not_found")); + source.sendError(Texts.of("message.neoskies.error.island_wallet_not_found")); return null; } return islandWallet; @@ -78,7 +78,7 @@ public static void init(CommandDispatcher dispatcher) { private static int getBalance(ServerCommandSource source, @Nullable Island island) { EconomyAccount wallet = getWallet(source, island); if (wallet == null) return 0; - source.sendFeedback(Texts.of("message.skylands.balance.get", map -> new MapBuilder.StringMap() + source.sendFeedback(() -> Texts.of("message.neoskies.balance.get", map -> new MapBuilder.StringMap() .put("island", island.getIslandId().toString()) .putAny("amount", wallet.balance())), true); return 1; @@ -88,7 +88,7 @@ private static int setBalance(ServerCommandSource source, @Nullable Island islan EconomyAccount wallet = getWallet(source, island); if (wallet == null) return 0; wallet.setBalance(amount); - source.sendFeedback(Texts.of("message.skylands.balance.set", map -> new MapBuilder.StringMap() + source.sendFeedback(() -> Texts.of("message.neoskies.balance.set", map -> new MapBuilder.StringMap() .put("island", island.getIslandId().toString()) .putAny("amount", amount)), true); return 1; @@ -99,7 +99,7 @@ private static int addBalance(ServerCommandSource source, @Nullable Island islan if (wallet == null) return 0; EconomyTransaction transaction = wallet.canIncreaseBalance(amount); - source.sendFeedback(transaction.message(), true); + source.sendFeedback(transaction::message, true); if (!transaction.isSuccessful()) return 0; wallet.increaseBalance(amount); return 1; @@ -110,7 +110,7 @@ private static int removeBalance(ServerCommandSource source, @Nullable Island is if (wallet == null) return 0; EconomyTransaction transaction = wallet.canDecreaseBalance(amount); - source.sendFeedback(transaction.message(), true); + source.sendFeedback(transaction::message, true); if (!transaction.isSuccessful()) return 0; wallet.decreaseBalance(amount); return 1; diff --git a/src/main/java/skylands/command/admin/DeleteIslandCommand.java b/src/main/java/com/awakenedredstone/neoskies/command/admin/DeleteIslandCommand.java similarity index 64% rename from src/main/java/skylands/command/admin/DeleteIslandCommand.java rename to src/main/java/com/awakenedredstone/neoskies/command/admin/DeleteIslandCommand.java index b912f81..475857f 100644 --- a/src/main/java/skylands/command/admin/DeleteIslandCommand.java +++ b/src/main/java/com/awakenedredstone/neoskies/command/admin/DeleteIslandCommand.java @@ -1,22 +1,22 @@ -package skylands.command.admin; +package com.awakenedredstone.neoskies.command.admin; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.arguments.StringArgumentType; import me.lucko.fabric.api.permissions.v0.Permissions; import net.minecraft.server.command.ServerCommandSource; -import skylands.logic.Skylands; -import skylands.util.Texts; +import com.awakenedredstone.neoskies.logic.Skylands; +import com.awakenedredstone.neoskies.util.Texts; import static com.mojang.brigadier.arguments.StringArgumentType.word; import static net.minecraft.server.command.CommandManager.argument; import static net.minecraft.server.command.CommandManager.literal; -import static skylands.command.utils.CommandUtils.adminNode; -import static skylands.command.utils.CommandUtils.registerAdmin; +import static com.awakenedredstone.neoskies.command.utils.CommandUtils.adminNode; +import static com.awakenedredstone.neoskies.command.utils.CommandUtils.registerAdmin; public class DeleteIslandCommand { public static void init(CommandDispatcher dispatcher) { registerAdmin(dispatcher, adminNode() - .then(literal("delete-island").requires(Permissions.require("skylands.admin.delete", 4)) + .then(literal("delete-island").requires(Permissions.require("neoskies.admin.delete", 4)) .then(argument("player", word()) .executes(context -> { var playerName = StringArgumentType.getString(context, "player"); @@ -24,9 +24,9 @@ public static void init(CommandDispatcher dispatcher) { if (island.isPresent()) { Skylands.getInstance().islands.delete(playerName); - context.getSource().sendFeedback(Texts.of("message.skylands.force_delete.success", map -> map.put("player", playerName)), true); + context.getSource().sendFeedback(() -> Texts.of("message.neoskies.force_delete.success", map -> map.put("player", playerName)), true); } else { - context.getSource().sendFeedback(Texts.of("message.skylands.force_delete.fail", map -> map.put("player", playerName)), true); + context.getSource().sendFeedback(() -> Texts.of("message.neoskies.force_delete.fail", map -> map.put("player", playerName)), true); } return 1; diff --git a/src/main/java/skylands/command/admin/IslandDataCommand.java b/src/main/java/com/awakenedredstone/neoskies/command/admin/IslandDataCommand.java similarity index 80% rename from src/main/java/skylands/command/admin/IslandDataCommand.java rename to src/main/java/com/awakenedredstone/neoskies/command/admin/IslandDataCommand.java index 4bb2923..9012c20 100644 --- a/src/main/java/skylands/command/admin/IslandDataCommand.java +++ b/src/main/java/com/awakenedredstone/neoskies/command/admin/IslandDataCommand.java @@ -1,16 +1,16 @@ -package skylands.command.admin; +package com.awakenedredstone.neoskies.command.admin; -import com.awakenedredstone.cbserverconfig.util.MapBuilder; +import com.awakenedredstone.neoskies.util.MapBuilder; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.arguments.StringArgumentType; import me.lucko.fabric.api.permissions.v0.Permissions; import net.minecraft.server.command.ServerCommandSource; import org.jetbrains.annotations.Nullable; -import skylands.api.SkylandsAPI; -import skylands.command.utils.CommandUtils; -import skylands.logic.Island; -import skylands.logic.Skylands; -import skylands.util.Texts; +import com.awakenedredstone.neoskies.api.SkylandsAPI; +import com.awakenedredstone.neoskies.command.utils.CommandUtils; +import com.awakenedredstone.neoskies.logic.Island; +import com.awakenedredstone.neoskies.logic.Skylands; +import com.awakenedredstone.neoskies.util.Texts; import java.util.List; import java.util.Optional; @@ -18,15 +18,15 @@ import static net.minecraft.server.command.CommandManager.argument; import static net.minecraft.server.command.CommandManager.literal; -import static skylands.command.utils.CommandUtils.adminNode; -import static skylands.command.utils.CommandUtils.registerAdmin; +import static com.awakenedredstone.neoskies.command.utils.CommandUtils.adminNode; +import static com.awakenedredstone.neoskies.command.utils.CommandUtils.registerAdmin; public class IslandDataCommand { public static void init(CommandDispatcher dispatcher) { registerAdmin(dispatcher, adminNode() .then(literal("island-data") .then(literal("find") - .requires(Permissions.require("skylands.admin.island.data.find", 4)) + .requires(Permissions.require("neoskies.admin.island.data.find", 4)) .then(argument("player", StringArgumentType.word()) .suggests((context, builder) -> { List islands = Skylands.getInstance().islands.stuck; @@ -59,7 +59,7 @@ public static void init(CommandDispatcher dispatcher) { private static int getIslandData(ServerCommandSource source, @Nullable Island island) { if (island == null) { - source.sendError(Texts.of("message.skylands.error.island_not_found")); + source.sendError(Texts.of("message.neoskies.error.island_not_found")); return 0; } @@ -83,8 +83,8 @@ private static int getIslandData(ServerCommandSource source, @Nullable Island is .putAny("visit_pos", island.visitsPos) .putAny("radius", island.radius) .putAny("locked", island.locked) - .putAny("created", island.created.toEpochMilli()); - source.sendFeedback(Texts.of("message.skylands.island_data", map.build()), false); + .putAny("created", island.getCreated().toEpochMilli()); + source.sendFeedback(() -> Texts.of("message.neoskies.island_data", map.build()), false); return 1; } } diff --git a/src/main/java/skylands/command/admin/SettingsCommand.java b/src/main/java/com/awakenedredstone/neoskies/command/admin/SettingsCommand.java similarity index 56% rename from src/main/java/skylands/command/admin/SettingsCommand.java rename to src/main/java/com/awakenedredstone/neoskies/command/admin/SettingsCommand.java index 6a293f0..d5293f3 100644 --- a/src/main/java/skylands/command/admin/SettingsCommand.java +++ b/src/main/java/com/awakenedredstone/neoskies/command/admin/SettingsCommand.java @@ -1,28 +1,29 @@ -package skylands.command.admin; +package com.awakenedredstone.neoskies.command.admin; -import com.awakenedredstone.cbserverconfig.ui.ConfigScreen; import com.mojang.brigadier.CommandDispatcher; import me.lucko.fabric.api.permissions.v0.Permissions; import net.minecraft.server.command.ServerCommandSource; -import skylands.SkylandsMain; -import skylands.util.Texts; +import com.awakenedredstone.neoskies.SkylandsMain; +import com.awakenedredstone.neoskies.util.Texts; +import net.minecraft.text.Text; import static net.minecraft.server.command.CommandManager.literal; -import static skylands.command.utils.CommandUtils.adminNode; -import static skylands.command.utils.CommandUtils.registerAdmin; +import static com.awakenedredstone.neoskies.command.utils.CommandUtils.adminNode; +import static com.awakenedredstone.neoskies.command.utils.CommandUtils.registerAdmin; public class SettingsCommand { public static void init(CommandDispatcher dispatcher) { registerAdmin(dispatcher, adminNode() - .then(literal("settings").requires(Permissions.require("skylands.admin.settings", 4)) + .then(literal("settings").requires(Permissions.require("neoskies.admin.settings", 4)) .executes(context -> { ServerCommandSource source = context.getSource(); if (!source.isExecutedByPlayer()) { - source.sendError(Texts.prefixed("message.skylands.error.player_only")); + source.sendError(Texts.prefixed("message.neoskies.error.player_only")); return 0; } - new ConfigScreen(source.getPlayer(), SkylandsMain.MAIN_CONFIG, null, null); + //new ConfigScreen(source.getPlayer(), SkylandsMain.MAIN_CONFIG, null, null); + source.sendFeedback(() -> Text.literal("In development, they will likely require the client mod"), false); return 1; }) diff --git a/src/main/java/skylands/command/island/AcceptCommand.java b/src/main/java/com/awakenedredstone/neoskies/command/island/AcceptCommand.java similarity index 50% rename from src/main/java/skylands/command/island/AcceptCommand.java rename to src/main/java/com/awakenedredstone/neoskies/command/island/AcceptCommand.java index 0848948..60ee9d2 100644 --- a/src/main/java/skylands/command/island/AcceptCommand.java +++ b/src/main/java/com/awakenedredstone/neoskies/command/island/AcceptCommand.java @@ -1,24 +1,24 @@ -package skylands.command.island; +package com.awakenedredstone.neoskies.command.island; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.arguments.StringArgumentType; import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.network.ServerPlayerEntity; -import skylands.data.SkylandComponents; -import skylands.logic.Skylands; -import skylands.util.Players; -import skylands.util.Texts; +import com.awakenedredstone.neoskies.logic.Skylands; +import com.awakenedredstone.neoskies.util.Players; +import com.awakenedredstone.neoskies.util.Texts; +import static com.awakenedredstone.neoskies.command.utils.CommandUtils.*; import static com.mojang.brigadier.arguments.StringArgumentType.word; import static net.minecraft.server.command.CommandManager.argument; import static net.minecraft.server.command.CommandManager.literal; -import static skylands.command.utils.CommandUtils.*; +import static net.minecraft.server.command.CommandManager.literal; public class AcceptCommand { public static void init(CommandDispatcher dispatcher) { register(dispatcher, node() .then(literal("accept") - .requires(requiresIsland("skylands.command.accept", true)) + .requires(requiresIsland("neoskies.command.accept", true)) .then(argument("player", word()) .executes(context -> { String inviter = StringArgumentType.getString(context, "player"); @@ -36,24 +36,27 @@ public static void init(CommandDispatcher dispatcher) { static void run(ServerPlayerEntity player, String ownerName) { var inviter = Players.get(ownerName); - if (inviter.isPresent()) { - var island = Skylands.getInstance().islands.getByPlayer(inviter.get()); - if (island.isPresent()) { - var invite = Skylands.getInstance().invites.get(island.get(), player); - if (invite.isPresent()) { - if (!invite.get().accepted) { - invite.get().accept(player); - player.sendMessage(Texts.prefixed("message.skylands.accept.success", map -> map.put("owner", ownerName))); - SkylandComponents.PLAYER_DATA.get(player).addIsland(ownerName); - } - } else { - player.sendMessage(Texts.prefixed("message.skylands.accept.fail")); - } - } else { - player.sendMessage(Texts.prefixed("message.skylands.accept.no_island")); - } - } else { - player.sendMessage(Texts.prefixed("message.skylands.accept.no_player")); + if (inviter.isEmpty()) { + player.sendMessage(Texts.prefixed("message.neoskies.accept.no_player")); + return; + } + + var island = Skylands.getInstance().islands.getByPlayer(inviter.get()); + if (island.isEmpty()) { + player.sendMessage(Texts.prefixed("message.neoskies.accept.no_island")); + return; + } + + var invite = Skylands.getInstance().invites.get(island.get(), player); + if (invite.isEmpty()) { + player.sendMessage(Texts.prefixed("message.neoskies.accept.fail")); + return; + } + + if (!invite.get().accepted) { + invite.get().accept(player); + player.sendMessage(Texts.prefixed("message.neoskies.accept.success", map -> map.put("owner", ownerName))); } + } } diff --git a/src/main/java/skylands/command/island/BanCommands.java b/src/main/java/com/awakenedredstone/neoskies/command/island/BanCommands.java similarity index 76% rename from src/main/java/skylands/command/island/BanCommands.java rename to src/main/java/com/awakenedredstone/neoskies/command/island/BanCommands.java index b3c18f8..9251636 100644 --- a/src/main/java/skylands/command/island/BanCommands.java +++ b/src/main/java/com/awakenedredstone/neoskies/command/island/BanCommands.java @@ -1,4 +1,4 @@ -package skylands.command.island; +package com.awakenedredstone.neoskies.command.island; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.arguments.StringArgumentType; @@ -6,22 +6,23 @@ import net.minecraft.command.argument.EntityArgumentType; import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.network.ServerPlayerEntity; -import skylands.api.SkylandsAPI; -import skylands.logic.Member; -import skylands.logic.Skylands; -import skylands.util.Texts; +import com.awakenedredstone.neoskies.api.SkylandsAPI; +import com.awakenedredstone.neoskies.logic.Member; +import com.awakenedredstone.neoskies.logic.Skylands; +import com.awakenedredstone.neoskies.util.Texts; +import static com.awakenedredstone.neoskies.command.utils.CommandUtils.*; import static com.mojang.brigadier.arguments.StringArgumentType.word; import static net.minecraft.command.argument.EntityArgumentType.player; import static net.minecraft.server.command.CommandManager.argument; import static net.minecraft.server.command.CommandManager.literal; -import static skylands.command.utils.CommandUtils.*; +import static net.minecraft.server.command.CommandManager.literal; public class BanCommands { public static void init(CommandDispatcher dispatcher) { register(dispatcher, node() .then(literal("ban") - .requires(requiresIsland("skylands.command.ban", true)) + .requires(requiresIsland("neoskies.command.ban", true)) .then(argument("player", player()) .executes(context -> { var player = context.getSource().getPlayer(); @@ -37,7 +38,7 @@ public static void init(CommandDispatcher dispatcher) { register(dispatcher, node(). then(literal("unban") - .requires(Permissions.require("skylands.command.unban", true)) + .requires(Permissions.require("neoskies.command.unban", true)) .then(argument("player", word()) .suggests((context, builder) -> { var player = context.getSource().getPlayer(); @@ -75,37 +76,37 @@ public static void init(CommandDispatcher dispatcher) { static void ban(ServerPlayerEntity player, ServerPlayerEntity banned) { Skylands.getInstance().islands.getByPlayer(player).ifPresentOrElse(island -> { if (player.getName().getString().equals(banned.getName().getString())) { - player.sendMessage(Texts.prefixed("message.skylands.ban_player.yourself")); + player.sendMessage(Texts.prefixed("message.neoskies.ban_player.yourself")); } else { if (island.isMember(banned)) { - player.sendMessage(Texts.prefixed("message.skylands.ban_player.member")); + player.sendMessage(Texts.prefixed("message.neoskies.ban_player.member")); } else { if (island.isBanned(banned)) { - player.sendMessage(Texts.prefixed("message.skylands.ban_player.fail")); + player.sendMessage(Texts.prefixed("message.neoskies.ban_player.fail")); } else { island.bans.add(new Member(banned)); - player.sendMessage(Texts.prefixed("message.skylands.ban_player.success", map -> map.put("player", banned.getName().getString()))); - banned.sendMessage(Texts.prefixed("message.skylands.ban_player.ban", map -> map.put("owner", island.owner.name))); + player.sendMessage(Texts.prefixed("message.neoskies.ban_player.success", map -> map.put("player", banned.getName().getString()))); + banned.sendMessage(Texts.prefixed("message.neoskies.ban_player.ban", map -> map.put("owner", island.owner.name))); SkylandsAPI.getIsland(banned.getWorld()).ifPresent(isl -> { if (isl.owner.uuid.equals(island.owner.uuid)) { - Skylands.getInstance().hub.visit(player); + Skylands.getInstance().hub.visit(banned); } }); } } } - }, () -> player.sendMessage(Texts.prefixed("message.skylands.ban_player.no_island"))); + }, () -> player.sendMessage(Texts.prefixed("message.neoskies.ban_player.no_island"))); } static void unban(ServerPlayerEntity player, String unbanned) { Skylands.getInstance().islands.getByPlayer(player).ifPresentOrElse(island -> { if (!island.isBanned(unbanned)) { - player.sendMessage(Texts.prefixed("message.skylands.unban_player.fail")); + player.sendMessage(Texts.prefixed("message.neoskies.unban_player.fail")); } else { island.bans.removeIf(member -> member.name.equals(unbanned)); - player.sendMessage(Texts.prefixed("message.skylands.unban_player.success", map -> map.put("player", unbanned))); + player.sendMessage(Texts.prefixed("message.neoskies.unban_player.success", map -> map.put("player", unbanned))); } - }, () -> player.sendMessage(Texts.prefixed("message.skylands.unban_player.no_island"))); + }, () -> player.sendMessage(Texts.prefixed("message.neoskies.unban_player.no_island"))); } } diff --git a/src/main/java/skylands/command/island/CreateCommand.java b/src/main/java/com/awakenedredstone/neoskies/command/island/CreateCommand.java similarity index 60% rename from src/main/java/skylands/command/island/CreateCommand.java rename to src/main/java/com/awakenedredstone/neoskies/command/island/CreateCommand.java index 5ce4ad7..6c284d7 100644 --- a/src/main/java/skylands/command/island/CreateCommand.java +++ b/src/main/java/com/awakenedredstone/neoskies/command/island/CreateCommand.java @@ -1,24 +1,24 @@ -package skylands.command.island; +package com.awakenedredstone.neoskies.command.island; import com.mojang.brigadier.CommandDispatcher; -import me.lucko.fabric.api.permissions.v0.Permissions; import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.network.ServerPlayerEntity; -import skylands.logic.Island; -import skylands.logic.IslandStuck; -import skylands.logic.Skylands; -import skylands.util.Texts; +import com.awakenedredstone.neoskies.logic.Island; +import com.awakenedredstone.neoskies.logic.IslandStuck; +import com.awakenedredstone.neoskies.logic.Skylands; +import com.awakenedredstone.neoskies.util.Texts; +import static com.awakenedredstone.neoskies.command.utils.CommandUtils.node; +import static com.awakenedredstone.neoskies.command.utils.CommandUtils.register; +import static com.awakenedredstone.neoskies.command.utils.CommandUtils.requiresNoIsland; import static net.minecraft.server.command.CommandManager.literal; -import static skylands.command.utils.CommandUtils.node; -import static skylands.command.utils.CommandUtils.register; public class CreateCommand { public static void init(CommandDispatcher dispatcher) { register(dispatcher, node() .then(literal("create") - .requires(Permissions.require("skylands.island.create", true)) + .requires(requiresNoIsland("neoskies.island.create", true)) .executes(context -> { var source = context.getSource(); var player = source.getPlayer(); @@ -35,11 +35,11 @@ static void run(ServerPlayerEntity player) { IslandStuck islands = Skylands.getInstance().islands; if (islands.getByPlayer(player).isPresent()) { - player.sendMessage(Texts.prefixed("message.skylands.island_create.fail")); + player.sendMessage(Texts.prefixed("message.neoskies.island_create.fail")); } else { Island island = islands.create(player); island.onFirstLoad(player); - player.sendMessage(Texts.prefixed("message.skylands.island_create.success")); + player.sendMessage(Texts.prefixed("message.neoskies.island_create.success")); } } } diff --git a/src/main/java/skylands/command/island/DeleteCommand.java b/src/main/java/com/awakenedredstone/neoskies/command/island/DeleteCommand.java similarity index 56% rename from src/main/java/skylands/command/island/DeleteCommand.java rename to src/main/java/com/awakenedredstone/neoskies/command/island/DeleteCommand.java index ebac116..edc9bd6 100644 --- a/src/main/java/skylands/command/island/DeleteCommand.java +++ b/src/main/java/com/awakenedredstone/neoskies/command/island/DeleteCommand.java @@ -1,27 +1,30 @@ -package skylands.command.island; +package com.awakenedredstone.neoskies.command.island; +import com.awakenedredstone.neoskies.command.utils.CommandUtils; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.arguments.StringArgumentType; import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.network.ServerPlayerEntity; -import skylands.logic.IslandStuck; -import skylands.logic.Skylands; -import skylands.util.Texts; +import com.awakenedredstone.neoskies.logic.IslandStuck; +import com.awakenedredstone.neoskies.logic.Skylands; +import com.awakenedredstone.neoskies.util.Texts; import java.time.Instant; import java.time.temporal.ChronoUnit; +import static com.awakenedredstone.neoskies.command.utils.CommandUtils.mustBeIslandOwner; +import static com.awakenedredstone.neoskies.command.utils.CommandUtils.node; +import static com.awakenedredstone.neoskies.command.utils.CommandUtils.register; import static com.mojang.brigadier.arguments.StringArgumentType.word; import static net.minecraft.server.command.CommandManager.argument; import static net.minecraft.server.command.CommandManager.literal; -import static skylands.command.utils.CommandUtils.*; public class DeleteCommand { public static void init(CommandDispatcher dispatcher) { register(dispatcher, node() .then(literal("delete") - .requires(requiresIsland("skylands.island.delete", true)) + .requires(mustBeIslandOwner("neoskies.island.delete", true)) .executes(context -> { var player = context.getSource().getPlayer(); if (player != null) DeleteCommand.warn(player); @@ -42,23 +45,22 @@ static void run(ServerPlayerEntity player, String confirmWord) { IslandStuck islands = Skylands.getInstance().islands; islands.getByPlayer(player).ifPresentOrElse(island -> { - var created = island.created; + var created = island.getCreated(); var now = Instant.now(); - var hours = ChronoUnit.HOURS.between(created, now); + var seconds = ChronoUnit.SECONDS.between(created, now); - //TODO: undo this - if (25 >= 24) { + if (seconds >= Skylands.getConfig().deletionCooldown) { islands.delete(player); - player.sendMessage(Texts.prefixed("message.skylands.island_delete.success")); + player.sendMessage(Texts.prefixed("message.neoskies.island_delete.success")); } else { - player.sendMessage(Texts.prefixed("message.skylands.island_delete.too_often")); + player.sendMessage(Texts.prefixed("message.neoskies.island_delete.too_often")); } }, () -> { - player.sendMessage(Texts.prefixed("message.skylands.island_delete.fail")); + player.sendMessage(Texts.prefixed("message.neoskies.island_delete.fail")); }); } else { - player.sendMessage(Texts.prefixed("message.skylands.island_delete.warning")); + player.sendMessage(Texts.prefixed("message.neoskies.island_delete.warning")); } } @@ -66,19 +68,18 @@ static void warn(ServerPlayerEntity player) { IslandStuck islands = Skylands.getInstance().islands; islands.getByPlayer(player).ifPresentOrElse(island -> { - var created = island.created; + var created = island.getCreated(); var now = Instant.now(); - var hours = ChronoUnit.HOURS.between(created, now); + var seconds = ChronoUnit.SECONDS.between(created, now); - //TODO: undo this - if (25 >= 24) { - player.sendMessage(Texts.prefixed("message.skylands.island_delete.warning")); + if (seconds >= Skylands.getConfig().deletionCooldown) { + player.sendMessage(Texts.prefixed("message.neoskies.island_delete.warning")); } else { - player.sendMessage(Texts.prefixed("message.skylands.island_delete.too_often")); + player.sendMessage(Texts.prefixed("message.neoskies.island_delete.too_often")); } }, () -> { - player.sendMessage(Texts.prefixed("message.skylands.island_delete.fail")); + player.sendMessage(Texts.prefixed("message.neoskies.island_delete.fail")); }); } } diff --git a/src/main/java/skylands/command/island/HelpCommand.java b/src/main/java/com/awakenedredstone/neoskies/command/island/HelpCommand.java similarity index 81% rename from src/main/java/skylands/command/island/HelpCommand.java rename to src/main/java/com/awakenedredstone/neoskies/command/island/HelpCommand.java index bbd7906..a31a9b2 100644 --- a/src/main/java/skylands/command/island/HelpCommand.java +++ b/src/main/java/com/awakenedredstone/neoskies/command/island/HelpCommand.java @@ -1,4 +1,4 @@ -package skylands.command.island; +package com.awakenedredstone.neoskies.command.island; import com.mojang.brigadier.CommandDispatcher; import eu.pb4.placeholders.api.TextParserUtils; @@ -8,15 +8,15 @@ import net.minecraft.util.Language; import static net.minecraft.server.command.CommandManager.literal; -import static skylands.command.utils.CommandUtils.node; -import static skylands.command.utils.CommandUtils.register; +import static com.awakenedredstone.neoskies.command.utils.CommandUtils.node; +import static com.awakenedredstone.neoskies.command.utils.CommandUtils.register; public class HelpCommand { public static void init(CommandDispatcher dispatcher) { register(dispatcher, node() .then(literal("help") - .requires(Permissions.require("skylands.command.help", true)) + .requires(Permissions.require("neoskies.command.help", true)) .executes(context -> { ServerPlayerEntity player = context.getSource().getPlayer(); if (player != null) { @@ -31,7 +31,7 @@ public static void init(CommandDispatcher dispatcher) { static void run(ServerPlayerEntity player) { Language lang = Language.getInstance(); StringBuilder text = new StringBuilder(); - String key = "message.skylands.help."; + String key = "message.neoskies.help."; for (int i = 0; i <= 32; i++) { if (lang.hasTranslation(key + i)) { diff --git a/src/main/java/skylands/command/island/HubCommands.java b/src/main/java/com/awakenedredstone/neoskies/command/island/HubCommands.java similarity index 57% rename from src/main/java/skylands/command/island/HubCommands.java rename to src/main/java/com/awakenedredstone/neoskies/command/island/HubCommands.java index 5c7b218..1cabf5f 100644 --- a/src/main/java/skylands/command/island/HubCommands.java +++ b/src/main/java/com/awakenedredstone/neoskies/command/island/HubCommands.java @@ -1,30 +1,27 @@ -package skylands.command.island; +package com.awakenedredstone.neoskies.command.island; import com.mojang.brigadier.CommandDispatcher; import me.lucko.fabric.api.permissions.v0.Permissions; -import net.fabricmc.fabric.api.dimension.v1.FabricDimensions; import net.minecraft.command.argument.BlockPosArgumentType; import net.minecraft.server.MinecraftServer; import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; -import net.minecraft.world.TeleportTarget; -import nota.player.SongPlayer; -import skylands.logic.Skylands; -import skylands.util.Texts; +import com.awakenedredstone.neoskies.logic.Skylands; +import com.awakenedredstone.neoskies.util.Texts; +import static com.awakenedredstone.neoskies.command.utils.CommandUtils.*; import static net.minecraft.command.argument.BlockPosArgumentType.blockPos; import static net.minecraft.server.command.CommandManager.argument; import static net.minecraft.server.command.CommandManager.literal; -import static skylands.command.utils.CommandUtils.*; public class HubCommands { public static void init(CommandDispatcher dispatcher) { register(dispatcher, node() .then(literal("hub") - .requires(Permissions.require("skylands.teleport.hub", true)) + .requires(Permissions.require("neoskies.teleport.hub", true)) .executes(context -> { var source = context.getSource(); var player = source.getPlayer(); @@ -38,57 +35,42 @@ public static void init(CommandDispatcher dispatcher) { ); registerAdmin(dispatcher, adminNode() - .then(literal("hub").requires(Permissions.require("skylands.admin.hub", 4)) - .then(literal("pos").requires(Permissions.require("skylands.admin.hub.pos", 4)) + .then(literal("hub").requires(Permissions.require("neoskies.admin.hub", 4)) + .then(literal("pos").requires(Permissions.require("neoskies.admin.hub.pos", 4)) .then(argument("position", blockPos()).executes(context -> { var pos = BlockPosArgumentType.getBlockPos(context, "position"); var source = context.getSource(); HubCommands.setPos(pos, source); return 1; }))) - .then(literal("protection").requires(Permissions.require("skylands.admin.hub.protection", 4)) + .then(literal("protection").requires(Permissions.require("neoskies.admin.hub.protection", 4)) .executes(context -> { HubCommands.toggleProtection(context.getSource()); return 1; }) - ).then(literal("music").requires(Permissions.require("skylands.admin.hub.music", 4)) - .executes(context -> { - MinecraftServer server = context.getSource().getServer(); - Skylands skylands = Skylands.getInstance(); - SongPlayer sp = skylands.hub.songPlayer; - if (sp != null) { - sp.setPlaying(!sp.playing); - } else { - skylands.hub.initSongPlayer(server); - server.getPlayerManager().getPlayerList().forEach(player -> skylands.hub.songPlayer.addPlayer(player)); - skylands.hub.songPlayer.setPlaying(true); - } - return 1; - }) ) ) ); } static void visit(ServerPlayerEntity player, MinecraftServer server) { - player.sendMessage(Texts.prefixed("message.skylands.hub_visit")); - FabricDimensions.teleport(player, server.getOverworld(), new TeleportTarget(Skylands.getInstance().hub.pos, new Vec3d(0, 0, 0), 0, 0)); + Skylands.getInstance().hub.visit(player); } static void setPos(BlockPos pos, ServerCommandSource source) { Skylands.getInstance().hub.pos = new Vec3d(pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5); String posText = pos.getX() + " " + pos.getY() + " " + pos.getZ(); - source.sendFeedback(Texts.prefixed("message.skylands.hub_pos_change", map -> map.put("pos", posText)), true); + source.sendFeedback(() -> Texts.prefixed("message.neoskies.hub_pos_change", map -> map.put("pos", posText)), true); } static void toggleProtection(ServerCommandSource source) { var hub = Skylands.getInstance().hub; if (hub.hasProtection) { hub.hasProtection = false; - source.sendFeedback(Texts.prefixed("message.skylands.hub_protection.disable"), true); + source.sendFeedback(() -> Texts.prefixed("message.neoskies.hub_protection.disable"), true); } else { hub.hasProtection = true; - source.sendFeedback(Texts.prefixed("message.skylands.hub_protection.enable"), true); + source.sendFeedback(() -> Texts.prefixed("message.neoskies.hub_protection.enable"), true); } } } diff --git a/src/main/java/skylands/command/island/KickCommand.java b/src/main/java/com/awakenedredstone/neoskies/command/island/KickCommand.java similarity index 67% rename from src/main/java/skylands/command/island/KickCommand.java rename to src/main/java/com/awakenedredstone/neoskies/command/island/KickCommand.java index e6add2b..e3bfa06 100644 --- a/src/main/java/skylands/command/island/KickCommand.java +++ b/src/main/java/com/awakenedredstone/neoskies/command/island/KickCommand.java @@ -1,24 +1,25 @@ -package skylands.command.island; +package com.awakenedredstone.neoskies.command.island; import com.mojang.brigadier.CommandDispatcher; import net.minecraft.command.argument.EntityArgumentType; import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.network.ServerPlayerEntity; -import skylands.api.SkylandsAPI; -import skylands.logic.Skylands; -import skylands.util.Texts; +import com.awakenedredstone.neoskies.api.SkylandsAPI; +import com.awakenedredstone.neoskies.logic.Skylands; +import com.awakenedredstone.neoskies.util.Texts; +import static com.awakenedredstone.neoskies.command.utils.CommandUtils.*; import static net.minecraft.command.argument.EntityArgumentType.player; import static net.minecraft.server.command.CommandManager.argument; import static net.minecraft.server.command.CommandManager.literal; -import static skylands.command.utils.CommandUtils.*; +import static net.minecraft.server.command.CommandManager.literal; public class KickCommand { public static void init(CommandDispatcher dispatcher) { register(dispatcher, node() .then(literal("kick") - .requires(requiresIsland("skylands.command.kick", true)) + .requires(requiresIsland("neoskies.command.kick", true)) .then(argument("player", player()) .executes(context -> { var player = context.getSource().getPlayer(); @@ -36,23 +37,23 @@ public static void init(CommandDispatcher dispatcher) { static void run(ServerPlayerEntity player, ServerPlayerEntity kicked) { Skylands.getInstance().islands.getByPlayer(player).ifPresentOrElse(island -> { if (player.getName().getString().equals(kicked.getName().getString())) { - player.sendMessage(Texts.prefixed("message.skylands.kick_visitor.yourself")); + player.sendMessage(Texts.prefixed("message.neoskies.kick_visitor.yourself")); } else { if (island.isMember(kicked)) { - player.sendMessage(Texts.prefixed("message.skylands.kick_visitor.member")); + player.sendMessage(Texts.prefixed("message.neoskies.kick_visitor.member")); } else { SkylandsAPI.getIsland(kicked.getWorld()).ifPresent(isl -> { if (isl.owner.uuid.equals(island.owner.uuid)) { - player.sendMessage(Texts.prefixed("message.skylands.kick_visitor.success", map -> map.put("player", kicked.getName().getString()))); + player.sendMessage(Texts.prefixed("message.neoskies.kick_visitor.success", map -> map.put("player", kicked.getName().getString()))); - kicked.sendMessage(Texts.prefixed("message.skylands.kick_visitor.kick", map -> map.put("owner", player.getName().getString()))); - Skylands.getInstance().hub.visit(player); + kicked.sendMessage(Texts.prefixed("message.neoskies.kick_visitor.kick", map -> map.put("owner", player.getName().getString()))); + Skylands.getInstance().hub.visit(kicked); } else { - player.sendMessage(Texts.prefixed("message.skylands.kick_visitor.fail", map -> map.put("player", kicked.getName().getString()))); + player.sendMessage(Texts.prefixed("message.neoskies.kick_visitor.fail", map -> map.put("player", kicked.getName().getString()))); } }); } } - }, () -> player.sendMessage(Texts.prefixed("message.skylands.kick_visitor.no_island"))); + }, () -> player.sendMessage(Texts.prefixed("message.neoskies.kick_visitor.no_island"))); } } diff --git a/src/main/java/skylands/command/island/LevelCommand.java b/src/main/java/com/awakenedredstone/neoskies/command/island/LevelCommand.java similarity index 72% rename from src/main/java/skylands/command/island/LevelCommand.java rename to src/main/java/com/awakenedredstone/neoskies/command/island/LevelCommand.java index 33fc3e3..04ced68 100644 --- a/src/main/java/skylands/command/island/LevelCommand.java +++ b/src/main/java/com/awakenedredstone/neoskies/command/island/LevelCommand.java @@ -1,6 +1,7 @@ -package skylands.command.island; +package com.awakenedredstone.neoskies.command.island; -import com.awakenedredstone.cbserverconfig.util.MapBuilder; +import com.awakenedredstone.neoskies.gui.PagedGui; +import com.awakenedredstone.neoskies.util.MapBuilder; import com.mojang.brigadier.CommandDispatcher; import eu.pb4.polymer.virtualentity.api.ElementHolder; import eu.pb4.polymer.virtualentity.api.attachment.ChunkAttachment; @@ -8,9 +9,16 @@ import eu.pb4.polymer.virtualentity.api.elements.InteractionElement; import eu.pb4.polymer.virtualentity.api.elements.TextDisplayElement; import eu.pb4.polymer.virtualentity.api.elements.VirtualElement; +import eu.pb4.sgui.api.elements.GuiElement; +import eu.pb4.sgui.api.elements.GuiElementBuilder; +import eu.pb4.sgui.api.elements.GuiElementInterface; +import eu.pb4.sgui.api.gui.SimpleGui; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.entity.decoration.Brightness; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.registry.Registries; import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.world.ChunkHolder; @@ -29,14 +37,15 @@ import net.minecraft.world.chunk.PalettedContainer; import net.minecraft.world.chunk.WorldChunk; import org.jetbrains.annotations.Nullable; -import skylands.api.SkylandsAPI; -import skylands.duck.ExtendedChunk; -import skylands.logic.Island; -import skylands.logic.Skylands; -import skylands.logic.util.ChunkScanQueue; -import skylands.util.FontUtils; -import skylands.util.Texts; -import skylands.util.UnitConvertions; +import com.awakenedredstone.neoskies.SkylandsMain; +import com.awakenedredstone.neoskies.api.SkylandsAPI; +import com.awakenedredstone.neoskies.duck.ExtendedChunk; +import com.awakenedredstone.neoskies.logic.Island; +import com.awakenedredstone.neoskies.logic.Skylands; +import com.awakenedredstone.neoskies.logic.util.ChunkScanQueue; +import com.awakenedredstone.neoskies.util.FontUtils; +import com.awakenedredstone.neoskies.util.Texts; +import com.awakenedredstone.neoskies.util.UnitConvertions; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; @@ -44,36 +53,83 @@ import java.util.function.BiConsumer; import java.util.function.Consumer; +import static com.awakenedredstone.neoskies.command.utils.CommandUtils.assertIsland; +import static com.awakenedredstone.neoskies.command.utils.CommandUtils.assertPlayer; +import static com.awakenedredstone.neoskies.command.utils.CommandUtils.node; +import static com.awakenedredstone.neoskies.command.utils.CommandUtils.register; +import static com.awakenedredstone.neoskies.command.utils.CommandUtils.requiresIsland; import static net.minecraft.server.command.CommandManager.literal; -import static skylands.command.utils.CommandUtils.*; public class LevelCommand { private static ElementHolder holder; public static void init(CommandDispatcher dispatcher) { register(dispatcher, node() - .then(literal("level") - .requires(requiresIsland("skylands.command.level", true)) - .then(literal("scan") - .executes(context -> LevelCommand.run(context.getSource())) - ) + .then(literal("level") + .requires(requiresIsland("neoskies.command.level", true)) + .then(literal("scan") + .executes(context -> LevelCommand.runScan(context.getSource())) + ).then(literal("view") + .executes(context -> LevelCommand.view(context.getSource())) ) + ) ); } - private static int run(ServerCommandSource source) { + private static int view(ServerCommandSource source) { + AtomicInteger sum = new AtomicInteger(); + if (!assertPlayer(source)) return 0; ServerPlayerEntity player = source.getPlayer(); Island island = SkylandsAPI.getIslandByPlayer(player).orElse(null); if (!assertIsland(source, island)) return 0; if (island.isScanning()) { - source.sendError(Texts.of("message.skylands.island.level.scan.running")); + source.sendError(Texts.of("message.neoskies.island.error.scanning")); + return 0; + } + + List elements = new ArrayList<>(); + + island.getBlocks().forEach((block, count) -> { + Integer points = Skylands.getRankingConfig().points.getOrDefault(block, 1); + sum.addAndGet(points * count); + + Block block1 = Registries.BLOCK.get(block); + ItemStack stack = block1.asItem().getDefaultStack(); + GuiElementBuilder builder = GuiElementBuilder.from(stack.isEmpty() ? new ItemStack(Items.BARRIER) : stack) + .hideFlags() + .addLoreLine(Texts.of("x%d blocks".formatted(count))) + .addLoreLine(Texts.of("%d points".formatted(points * count))); + + if (stack.isEmpty()) { + builder.setName(block1.getName()); + } + elements.add(builder.build()); + }); + + SimpleGui gui = PagedGui.of(player, elements); + gui.setTitle(Texts.of("Island points")); + gui.open(); + + source.sendFeedback(() -> Texts.of(sum.get() + " points"), false); + + return sum.get(); + } + + private static int runScan(ServerCommandSource source) { + if (!assertPlayer(source)) return 0; + ServerPlayerEntity player = source.getPlayer(); + + Island island = SkylandsAPI.getIslandByPlayer(player).orElse(null); + if (!assertIsland(source, island)) return 0; + if (island.isScanning()) { + source.sendError(Texts.of("message.neoskies.island.error.scanning")); return 0; } BlockPos blockPos = player.getBlockPos(); - World world = player.world; + World world = player.getWorld(); Vec3d pos = player.getPos(); Vec3d look = player.getRotationVector(); @@ -86,10 +142,10 @@ private static int run(ServerCommandSource source) { holder = new ElementHolder(); new ChunkAttachment(holder, (WorldChunk) world.getChunk(blockPos), pos, true); - MutableText text = Texts.of("message.skylands.island.level.scan.background").copy(); + MutableText text = Texts.of("message.neoskies.island.level.scan.background").copy(); - Text startScanText = Texts.of("message.skylands.island.level.scan.start"); - Text cancelText = Texts.of("message.skylands.island.level.scan.cancel"); + Text startScanText = Texts.of("message.neoskies.island.level.scan.start"); + Text cancelText = Texts.of("message.neoskies.island.level.scan.cancel"); TextDisplayElement textDisplay = new TextDisplayElement(); textDisplay.setText(text); @@ -125,7 +181,7 @@ private static int run(ServerCommandSource source) { TextDisplayElement display = createDisplay(Texts.of(""), yaw, new Vec3d(0, 0, 0)); VirtualElement.InteractionHandler startScan = createHandler((interactor, hand) -> { if (island.isScanning()) { - source.sendError(Texts.of("message.skylands.island.level.scan.running")); + source.sendError(Texts.of("message.neoskies.island.level.scan.running")); return; } scanChunks(island, () -> { @@ -134,13 +190,13 @@ private static int run(ServerCommandSource source) { removeDisplay(message.get()); display.setTranslation(new Vec3d(0, 0.25 * (lines / 2d) + 0.0625 + 0.5, 0).toVector3f()); - display.setText(Texts.of("message.skylands.island.level.scan.preparing")); + display.setText(Texts.of("message.neoskies.island.level.scan.preparing")); }, total -> { if (total > 200) { - display.setText(Texts.of("message.skylands.island.level.scan.progress", new MapBuilder.StringMap() - .putAny("progress", 0) - .putAny("total", total) - .build())); + display.setText(Texts.of("message.neoskies.island.level.scan.progress", new MapBuilder.StringMap() + .putAny("progress", 0) + .putAny("total", total) + .build())); return; } MutableText visualization = Text.empty(); @@ -153,16 +209,16 @@ private static int run(ServerCommandSource source) { } display.setText(visualization); //charsWidth * scale = 3; charsWidth = (9/80d) * size; scale = ?; so I must calculate the scale - double scale = 1.5 / ((9/80d) * size); - display.setTranslation(new Vec3d(0, -(9/35d) * scale, 0).toVector3f()); + double scale = 1.5 / ((9 / 80d) * size); + display.setTranslation(new Vec3d(0, -(9 / 35d) * scale, 0).toVector3f()); display.setScale(new Vec3d(scale, scale, 1).toVector3f()); }, (total, current) -> { if (total > 200) { - Text progress = Texts.of("message.skylands.island.level.scan.progress", new MapBuilder.StringMap() - .putAny("progress", current) - .putAny("total", total) - .build()); - Skylands.getInstance().scheduler.scheduleDelayed(new Identifier("skylands", "island-scan/" + island.getIslandId().toString()), Skylands.getServer(), 0, () -> display.setText(progress)); + Text progress = Texts.of("message.neoskies.island.level.scan.progress", new MapBuilder.StringMap() + .putAny("progress", current) + .putAny("total", total) + .build()); + Skylands.getInstance().scheduler.schedule(new Identifier("neoskies", "island-scan/" + island.getIslandId().toString()), 0, () -> display.setText(progress)); return; } @@ -176,19 +232,20 @@ private static int run(ServerCommandSource source) { } visualization.append(Text.of("\n")); } - Skylands.getInstance().scheduler.scheduleDelayed(new Identifier("skylands", "island-scan/" + island.getIslandId().toString()), Skylands.getServer(), 0, () -> display.setText(visualization)); + Skylands.getInstance().scheduler.schedule(new Identifier("neoskies", "island-scan/" + island.getIslandId().toString()), 0, () -> display.setText(visualization)); }, (timeTaken, scannedBlocks) -> { - Skylands.getInstance().scheduler.scheduleDelayed(Skylands.getServer(), 0, () -> { - source.sendFeedback(Texts.of("message.skylands.island.level.scan.time_taken", new MapBuilder.StringMap() - .put("time", UnitConvertions.formatTimings(timeTaken)) - .build()), false); + Skylands.syncWithTick(() -> { + source.sendFeedback(() -> Texts.of("message.neoskies.island.level.scan.time_taken", new MapBuilder.StringMap() + .put("time", UnitConvertions.formatTimings(timeTaken)) + .build()), false); removeDisplay(display); float width = getTextWidth(text); AtomicInteger i = new AtomicInteger(); List blockDisplays = new ArrayList<>(); List labels = new ArrayList<>(); - scannedBlocks.forEach((block, amount) -> { + scannedBlocks.forEach((id, amount) -> { if (i.get() > 8) return; + Block block = Registries.BLOCK.get(id); BlockDisplayElement blockDisplay = new BlockDisplayElement(); blockDisplay.setBlockState(block.getDefaultState()); blockDisplay.setYaw(yaw + 180); @@ -197,7 +254,10 @@ private static int run(ServerCommandSource source) { blockDisplay.setBrightness(Brightness.FULL); holder.addElement(blockDisplay); blockDisplays.add(blockDisplay); - Text amountText = Texts.of(amount + "x " + block.getName().getString()); + Text amountText = Texts.of("message.neoskies.island.level.scan.block_info", new MapBuilder.StringMap() + .putAny("amount", amount) + .put("block", block.getName().getString()) + .build()); labels.add(createDisplay(amountText, yaw, new Vec3d(-width + 0.7 + (getTextWidth(amountText)), 0.25 * (lines) + 0.0625 - (i.get()) * 0.3 - 0.03125, 0))); i.getAndIncrement(); }); @@ -211,7 +271,7 @@ private static int run(ServerCommandSource source) { removeInteraction(ref.closeButton); }; - ref.closeButton = createInteraction(Texts.of("message.skylands.island.level.scan.close"), createHandler((player1, hand1) -> { + ref.closeButton = createInteraction(Texts.of("message.neoskies.island.level.scan.close"), createHandler((player1, hand1) -> { removeBlocksView.run(); closeBackground.run(); }), yaw); @@ -246,7 +306,7 @@ private static int run(ServerCommandSource source) { }); Skylands.getInstance().scheduler.scheduleDelayed(Skylands.getServer(), 15, () -> { - message.set(createDisplay(Texts.of("message.skylands.island.level.scan.confirm"), yaw, new Vec3d(0, 0.25 * (lines / 2d) + 0.0625 + 0.5, 0))); + message.set(createDisplay(Texts.of("message.neoskies.island.level.scan.confirm"), yaw, new Vec3d(0, 0.25 * (lines / 2d) + 0.0625 + 0.5, 0))); startScanPair.set(createInteraction(startScanText, startScan, yaw, new Vec3d(-2 + getTextWidth(startScanText), 0.25 * (lines / 2d) + 0.0625, 0))); cancalScanPair.set(createInteraction(cancelText, cancelScan, yaw, new Vec3d(2 - getTextWidth(startScanText), 0.25 * (lines / 2d) + 0.0625, 0))); }); @@ -259,7 +319,7 @@ private static int run(ServerCommandSource source) { closeBackground.run(); } }); - source.sendFeedback(Texts.of("message.skylands.island.level.scan.opening"), false); + source.sendFeedback(() -> Texts.of("message.neoskies.island.level.scan.opening"), false); return 1; } @@ -272,7 +332,7 @@ private static void scanChunks(Island island, Runnable preparing, Consumer 0) { //get all chunks in radius, the island center always is at 0, 0 BlockPos center = new BlockPos(0, 0, 0); for (int x = -radius; x <= radius; x += 16) { @@ -288,15 +348,13 @@ private static void scanChunks(Island island, Runnable preparing, Consumer chunkHolders = anvilChunkStorage.chunkHolders.values().stream().filter(ChunkHolder::isAccessible).peek(ChunkHolder::updateAccessibleStatus).toList(); - chunkHolders.forEach(chunkHolder -> { - chunks.add(chunkHolder.getCurrentChunk()); - }); + chunkHolders.forEach(chunkHolder -> chunks.add(chunkHolder.getCurrentChunk())); } informTotal.accept(chunks.size()); //scan all chunks - LinkedHashMap blocks = new LinkedHashMap<>(); + LinkedHashMap blocks = new LinkedHashMap<>(); long start = System.nanoTime() / 1000; while (!chunks.finished()) { updater.accept(chunks.size(), chunks.getPos()); @@ -306,7 +364,8 @@ private static void scanChunks(Island island, Runnable preparing, Consumer stateContainer = section.getBlockStateContainer(); stateContainer.count((blockState, amount) -> { if (blockState.isAir()) return; - blocks.compute(blockState.getBlock(), (state, count) -> count == null ? amount : count + amount); + Identifier id = Registries.BLOCK.getId(blockState.getBlock()); + blocks.compute(id, (state, count) -> count == null ? amount : count + amount); }); } } @@ -314,14 +373,14 @@ private static void scanChunks(Island island, Runnable preparing, Consumer> entries = new LinkedList<>(blocks.entrySet()); + List> entries = new LinkedList<>(blocks.entrySet()); entries.sort(Comparator.comparingInt(Map.Entry::getValue)); Collections.reverse(entries); blocks.clear(); entries.forEach(entry -> blocks.put(entry.getKey(), entry.getValue())); finisher.finish(end - start, blocks); - island.blocks = blocks; + island.updateBlocks(blocks); island.setScanning(false); }); @@ -410,6 +469,6 @@ interface Interaction { @FunctionalInterface interface ScanFinish { - void finish(long timeTaken, Map scannedBlocks); + void finish(long timeTaken, Map scannedBlocks); } } diff --git a/src/main/java/skylands/command/island/MemberCommands.java b/src/main/java/com/awakenedredstone/neoskies/command/island/MemberCommands.java similarity index 57% rename from src/main/java/skylands/command/island/MemberCommands.java rename to src/main/java/com/awakenedredstone/neoskies/command/island/MemberCommands.java index 4e3c6bc..5a14356 100644 --- a/src/main/java/skylands/command/island/MemberCommands.java +++ b/src/main/java/com/awakenedredstone/neoskies/command/island/MemberCommands.java @@ -1,4 +1,4 @@ -package skylands.command.island; +package com.awakenedredstone.neoskies.command.island; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.arguments.StringArgumentType; @@ -8,20 +8,22 @@ import net.minecraft.text.ClickEvent; import net.minecraft.text.HoverEvent; import net.minecraft.text.Style; -import skylands.logic.Skylands; -import skylands.util.Texts; +import com.awakenedredstone.neoskies.api.SkylandsAPI; +import com.awakenedredstone.neoskies.logic.Skylands; +import com.awakenedredstone.neoskies.util.Texts; +import static com.awakenedredstone.neoskies.command.utils.CommandUtils.*; import static com.mojang.brigadier.arguments.StringArgumentType.word; import static net.minecraft.command.argument.EntityArgumentType.player; import static net.minecraft.server.command.CommandManager.argument; import static net.minecraft.server.command.CommandManager.literal; -import static skylands.command.utils.CommandUtils.*; +import static net.minecraft.server.command.CommandManager.literal; public class MemberCommands { public static void init(CommandDispatcher dispatcher) { register(dispatcher, node().then(literal("members") - .then(literal("invite").requires(requiresIsland("skylands.command.members.invite", true)) + .then(literal("invite").requires(requiresIsland("neoskies.command.members.invite", true)) .then(argument("player", player()) .executes(context -> { var player = context.getSource().getPlayer(); @@ -32,7 +34,7 @@ public static void init(CommandDispatcher dispatcher) { return 1; }) ) - ).then(literal("remove").requires(requiresIsland("skylands.command.members.remove", true)) + ).then(literal("remove").requires(requiresIsland("neoskies.command.members.remove", true)) .then(argument("player", word()) .suggests((context, builder) -> { var player = context.getSource().getPlayer(); @@ -67,41 +69,47 @@ public static void init(CommandDispatcher dispatcher) { } static void invite(ServerPlayerEntity inviter, ServerPlayerEntity newcomer) { + if (SkylandsAPI.getIslandByPlayer(newcomer).isPresent()) { + inviter.sendMessage(Texts.prefixed("message.neoskies.invite_member.already_has_island")); + return; + } + Skylands.getInstance().islands.getByPlayer(inviter).ifPresentOrElse(island -> { if (island.isMember(newcomer)) { - inviter.sendMessage(Texts.prefixed("message.skylands.invite_member.already_member")); + inviter.sendMessage(Texts.prefixed("message.neoskies.invite_member.already_member")); + return; + } + + if (Skylands.getInstance().invites.hasInvite(island, newcomer)) { + inviter.sendMessage(Texts.prefixed("message.neoskies.invite_member.already_invited")); } else { - if (Skylands.getInstance().invites.hasInvite(island, newcomer)) { - inviter.sendMessage(Texts.prefixed("message.skylands.invite_member.already_invited")); - } else { - inviter.sendMessage(Texts.prefixed("message.skylands.invite_member.success", (map) -> map.put("newcomer", newcomer.getName().getString()))); + inviter.sendMessage(Texts.prefixed("message.neoskies.invite_member.success", (map) -> map.put("newcomer", newcomer.getName().getString()))); - var hoverText = Texts.prefixed("hover_event.skylands.invite_member.accept", (map) -> map.put("inviter", inviter.getName().getString())); - Style style = Style.EMPTY.withClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/sl accept " + inviter.getName().getString())); - style = style.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, hoverText)); + var hoverText = Texts.prefixed("hover_event.neoskies.invite_member.accept", (map) -> map.put("inviter", inviter.getName().getString())); + Style style = Style.EMPTY.withClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/sl accept " + inviter.getName().getString())); + style = style.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, hoverText)); - var inviteText = Texts.prefixed("message.skylands.invite_member.invite", (map) -> map.put("inviter", inviter.getName().getString())); + var inviteText = Texts.prefixed("message.neoskies.invite_member.invite", (map) -> map.put("inviter", inviter.getName().getString())); - newcomer.sendMessage(inviteText.getWithStyle(style).get(0)); - newcomer.sendMessage(Texts.prefixed("message.skylands.invite_member.accept").getWithStyle(style).get(0)); - Skylands.getInstance().invites.create(island, newcomer); - } + newcomer.sendMessage(inviteText.getWithStyle(style).get(0)); + newcomer.sendMessage(Texts.prefixed("message.neoskies.invite_member.accept").getWithStyle(style).get(0)); + Skylands.getInstance().invites.create(island, newcomer); } - }, () -> inviter.sendMessage(Texts.prefixed("message.skylands.invite_member.no_island"))); + }, () -> inviter.sendMessage(Texts.prefixed("message.neoskies.invite_member.no_island"))); } static void remove(ServerPlayerEntity player, String removed) { Skylands.getInstance().islands.getByPlayer(player).ifPresentOrElse(island -> { if (player.getName().getString().equals(removed)) { - player.sendMessage(Texts.prefixed("message.skylands.remove_member.yourself")); + player.sendMessage(Texts.prefixed("message.neoskies.remove_member.yourself")); } else { if (island.isMember(removed)) { island.members.removeIf(member -> member.name.equals(removed)); - player.sendMessage(Texts.prefixed("message.skylands.remove_member.success", (map) -> map.put("member", removed))); + player.sendMessage(Texts.prefixed("message.neoskies.remove_member.success", (map) -> map.put("member", removed))); } else { - player.sendMessage(Texts.prefixed("message.skylands.remove_member.not_member")); + player.sendMessage(Texts.prefixed("message.neoskies.remove_member.not_member")); } } - }, () -> player.sendMessage(Texts.prefixed("message.skylands.remove_member.no_island"))); + }, () -> player.sendMessage(Texts.prefixed("message.neoskies.remove_member.no_island"))); } } diff --git a/src/main/java/skylands/command/island/MenuCommand.java b/src/main/java/com/awakenedredstone/neoskies/command/island/MenuCommand.java similarity index 72% rename from src/main/java/skylands/command/island/MenuCommand.java rename to src/main/java/com/awakenedredstone/neoskies/command/island/MenuCommand.java index 998923d..cce4f59 100644 --- a/src/main/java/skylands/command/island/MenuCommand.java +++ b/src/main/java/com/awakenedredstone/neoskies/command/island/MenuCommand.java @@ -1,9 +1,8 @@ -package skylands.command.island; +package com.awakenedredstone.neoskies.command.island; -import com.awakenedredstone.cbserverconfig.polymer.CBGuiElementBuilder; -import com.awakenedredstone.cbserverconfig.polymer.CBSimpleGuiBuilder; -import com.awakenedredstone.cbserverconfig.ui.ConfigScreen; -import com.awakenedredstone.cbserverconfig.util.Utils; +import com.awakenedredstone.neoskies.gui.polymer.CBGuiElementBuilder; +import com.awakenedredstone.neoskies.gui.polymer.CBSimpleGuiBuilder; +import com.awakenedredstone.neoskies.util.UIUtils; import com.mojang.brigadier.CommandDispatcher; import eu.pb4.sgui.api.SlotHolder; import me.lucko.fabric.api.permissions.v0.Permissions; @@ -17,37 +16,37 @@ import net.minecraft.sound.SoundCategory; import net.minecraft.sound.SoundEvents; import net.minecraft.text.Text; -import skylands.SkylandsMain; -import skylands.api.SkylandsAPI; -import skylands.gui.IslandSettingsGui; -import skylands.logic.Island; -import skylands.logic.Skylands; -import skylands.util.Texts; +import com.awakenedredstone.neoskies.SkylandsMain; +import com.awakenedredstone.neoskies.api.SkylandsAPI; +import com.awakenedredstone.neoskies.gui.IslandSettingsGui; +import com.awakenedredstone.neoskies.logic.Island; +import com.awakenedredstone.neoskies.logic.Skylands; +import com.awakenedredstone.neoskies.util.Texts; import java.util.Optional; import java.util.Set; import java.util.function.Consumer; import static net.minecraft.server.command.CommandManager.literal; -import static skylands.command.utils.CommandUtils.node; -import static skylands.command.utils.CommandUtils.register; +import static com.awakenedredstone.neoskies.command.utils.CommandUtils.node; +import static com.awakenedredstone.neoskies.command.utils.CommandUtils.register; public class MenuCommand { public static void init(CommandDispatcher dispatcher) { register(dispatcher, node().then(literal("menu") - .requires(Permissions.require("skylands.command.menu", true)) + .requires(Permissions.require("neoskies.command.menu", true)) .executes(context -> MenuCommand.execute(context.getSource())) ) ); - for (String alias : SkylandsMain.MAIN_CONFIG.commandAliases()) { + for (String alias : Skylands.getConfig().commandAliases) { dispatcher.register(CommandManager.literal(alias).executes(context -> MenuCommand.execute(context.getSource()))); } } private static int execute(ServerCommandSource source) { if (!source.isExecutedByPlayer()) { - source.sendError(Texts.prefixed("message.skylands.error.player_only")); + source.sendError(Texts.prefixed("message.neoskies.error.player_only")); return 0; } @@ -57,16 +56,16 @@ private static int execute(ServerCommandSource source) { int permissionLevel = player.getPermissionLevel(); CBSimpleGuiBuilder guiBuilder = new CBSimpleGuiBuilder(ScreenHandlerType.GENERIC_9X3, false); - guiBuilder.setTitle(Texts.of("gui.skylands.menu")); + guiBuilder.setTitle(Texts.of("gui.neoskies.menu")); var ref = new Object() { boolean dirty = false; }; final Consumer consumer = slotHolder -> { Optional islandOptional = SkylandsAPI.getIslandByPlayer(player); - Utils.fillGui(slotHolder, new CBGuiElementBuilder(Items.BLACK_STAINED_GLASS_PANE).setName(Text.empty()).build()); - if (Permissions.check(player, "skylands.teleport.hub", true)) { - slotHolder.setSlot(10, new CBGuiElementBuilder(Items.BEACON).setName(Texts.of("item_name.skylands.hub")) + UIUtils.fillGui(slotHolder, new CBGuiElementBuilder(Items.BLACK_STAINED_GLASS_PANE).setName(Text.empty()).build()); + if (Permissions.check(player, "neoskies.teleport.hub", true)) { + slotHolder.setSlot(10, new CBGuiElementBuilder(Items.BEACON).setName(Texts.of("item_name.neoskies.hub")) .setCallback((index, type, action, gui) -> { //gui.getPlayer().playSound(SoundEvents.UI_BUTTON_CLICK, SoundCategory.MASTER, 0.3f, 1); Skylands.getInstance().hub.visit(player); @@ -75,8 +74,8 @@ private static int execute(ServerCommandSource source) { .build()); } if (islandOptional.isPresent()) { - if (Permissions.check(player, "skylands.teleport.home", true)) { - slotHolder.setSlot(11, new CBGuiElementBuilder(Items.GRASS_BLOCK).setName(Texts.of("item_name.skylands.home")) + if (Permissions.check(player, "neoskies.teleport.home", true)) { + slotHolder.setSlot(11, new CBGuiElementBuilder(Items.GRASS_BLOCK).setName(Texts.of("item_name.neoskies.home")) .setCallback((index, type, action, gui) -> { //gui.getPlayer().playSound(SoundEvents.UI_BUTTON_CLICK, SoundCategory.MASTER, 0.3f, 1); HomeCommand.run(player); @@ -84,28 +83,29 @@ private static int execute(ServerCommandSource source) { }) .build()); } - if (Permissions.check(player, "skylands.island.settings", true)) { - slotHolder.setSlot(12, new CBGuiElementBuilder(Items.REDSTONE).setName(Texts.of("item_name.skylands.island_settings")) + if (Permissions.check(player, "neoskies.island.settings", true)) { + slotHolder.setSlot(12, new CBGuiElementBuilder(Items.REDSTONE).setName(Texts.of("item_name.neoskies.island_settings")) .setCallback((index, type, action, gui) -> { gui.getPlayer().playSound(SoundEvents.UI_BUTTON_CLICK.value(), SoundCategory.MASTER, 0.3f, 1); new IslandSettingsGui(islandOptional.get(), gui).openGui(player); }) .build()); } - } else if (Permissions.check(player, "skylands.island.create", true)) { - slotHolder.setSlot(11, new CBGuiElementBuilder(Items.OAK_SAPLING).setName(Texts.of("item_name.skylands.create")) + } else if (Permissions.check(player, "neoskies.island.create", true)) { + slotHolder.setSlot(11, new CBGuiElementBuilder(Items.OAK_SAPLING).setName(Texts.of("item_name.neoskies.create")) .setCallback((index, type, action, gui) -> { gui.getPlayer().playSound(SoundEvents.UI_BUTTON_CLICK.value(), SoundCategory.MASTER, 0.3f, 1); CreateCommand.run(player); + ref.dirty = true; }) .build()); } - if (Permissions.check(player, "skylands.admin.protection.bypass", 4)) { + if (Permissions.check(player, "neoskies.admin.protection.bypass", 4)) { Set protectionBypass = SkylandsMain.PROTECTION_BYPASS; boolean overrideMode = protectionBypass.contains(player); Item item = overrideMode ? Items.OAK_CHEST_BOAT : Items.OAK_BOAT; - slotHolder.setSlot(slotHolder.getSize() - 2, new CBGuiElementBuilder(item).setName(Texts.of("item_name.skylands.protection_bypass")) - .addLoreLine(Texts.of("text.skylands.protection_bypass", map -> map.put("value", String.valueOf(overrideMode)))) + slotHolder.setSlot(slotHolder.getSize() - 2, new CBGuiElementBuilder(item).setName(Texts.of("item_name.neoskies.protection_bypass")) + .addLoreLine(Texts.of("text.neoskies.protection_bypass", map -> map.put("value", String.valueOf(overrideMode)))) .setCallback((index, type, action, gui) -> { gui.getPlayer().playSound(SoundEvents.UI_BUTTON_CLICK.value(), SoundCategory.MASTER, 0.3f, 1); if (overrideMode) protectionBypass.remove(player); @@ -113,14 +113,14 @@ private static int execute(ServerCommandSource source) { ref.dirty = true; }).build()); } - if (Permissions.check(player, "skylands.admin.settings", 4)) { - slotHolder.setSlot(slotHolder.getSize() - 1, new CBGuiElementBuilder(Items.COMMAND_BLOCK_MINECART).setName(Texts.of("item_name.skylands.mod_settings")) + /*if (Permissions.check(player, "neoskies.admin.settings", 4)) { + slotHolder.setSlot(slotHolder.getSize() - 1, new CBGuiElementBuilder(Items.COMMAND_BLOCK_MINECART).setName(Texts.of("item_name.neoskies.mod_settings")) .setCallback((index, type, action, gui) -> { gui.getPlayer().playSound(SoundEvents.UI_BUTTON_CLICK.value(), SoundCategory.MASTER, 0.3f, 1); new ConfigScreen(source.getPlayer(), SkylandsMain.MAIN_CONFIG, null, null); }) .build()); - } + }*/ }; consumer.accept(guiBuilder); @@ -128,7 +128,7 @@ private static int execute(ServerCommandSource source) { if (gui.getPlayer().getPermissionLevel() != permissionLevel || ref.dirty) { ref.dirty = false; consumer.accept(gui); - if (!Permissions.check(player, "skylands.admin.protection.bypass", 4)) { + if (!Permissions.check(player, "neoskies.admin.protection.bypass", 4)) { SkylandsMain.PROTECTION_BYPASS.remove(player); } } diff --git a/src/main/java/skylands/command/island/SettingCommands.java b/src/main/java/com/awakenedredstone/neoskies/command/island/SettingCommands.java similarity index 74% rename from src/main/java/skylands/command/island/SettingCommands.java rename to src/main/java/com/awakenedredstone/neoskies/command/island/SettingCommands.java index 1f42351..6b14fad 100644 --- a/src/main/java/skylands/command/island/SettingCommands.java +++ b/src/main/java/com/awakenedredstone/neoskies/command/island/SettingCommands.java @@ -1,4 +1,4 @@ -package skylands.command.island; +package com.awakenedredstone.neoskies.command.island; import com.mojang.brigadier.CommandDispatcher; import net.minecraft.command.argument.BlockPosArgumentType; @@ -8,28 +8,29 @@ import net.minecraft.sound.SoundEvents; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; -import skylands.api.SkylandsAPI; -import skylands.gui.IslandSettingsGui; -import skylands.logic.Island; -import skylands.logic.Skylands; -import skylands.util.Texts; +import com.awakenedredstone.neoskies.api.SkylandsAPI; +import com.awakenedredstone.neoskies.gui.IslandSettingsGui; +import com.awakenedredstone.neoskies.logic.Island; +import com.awakenedredstone.neoskies.logic.Skylands; +import com.awakenedredstone.neoskies.util.Texts; import java.util.Optional; +import static com.awakenedredstone.neoskies.command.utils.CommandUtils.*; import static net.minecraft.command.argument.BlockPosArgumentType.blockPos; import static net.minecraft.server.command.CommandManager.argument; import static net.minecraft.server.command.CommandManager.literal; -import static skylands.command.utils.CommandUtils.*; +import static net.minecraft.server.command.CommandManager.literal; public class SettingCommands { public static void init(CommandDispatcher dispatcher) { register(dispatcher, node() .then(literal("settings") - .requires(requiresIsland("skylands.island.settings", true)) + .requires(requiresIsland("neoskies.island.settings", true)) .executes(context -> settingsGui(context.getSource())) .then(literal("lock") - .requires(requiresIsland("skylands.island.lock", true)) + .requires(requiresIsland("neoskies.island.lock", true)) .executes(context -> { var player = context.getSource().getPlayer(); if (player != null) { @@ -39,7 +40,7 @@ public static void init(CommandDispatcher dispatcher) { }) ).then(literal("position") .then(literal("spawn") - .requires(requiresIsland("skylands.island.settings.position.spawn", true)) + .requires(requiresIsland("neoskies.island.settings.position.spawn", true)) .then(argument("position", blockPos()) .executes(context -> { var player = context.getSource().getPlayer(); @@ -51,7 +52,7 @@ public static void init(CommandDispatcher dispatcher) { }) ) ).then(literal("visit") - .requires(requiresIsland("skylands.island.settings.position.visit", true)) + .requires(requiresIsland("neoskies.island.settings.position.visit", true)) .then(argument("position", blockPos()) .executes(context -> { var player = context.getSource().getPlayer(); @@ -71,37 +72,37 @@ public static void init(CommandDispatcher dispatcher) { static void toggleVisits(ServerPlayerEntity player) { Skylands.getInstance().islands.getByPlayer(player).ifPresentOrElse(island -> { if (island.locked) { - player.sendMessage(Texts.prefixed("message.skylands.settings.unlock")); + player.sendMessage(Texts.prefixed("message.neoskies.settings.unlock")); island.locked = false; } else { - player.sendMessage(Texts.prefixed("message.skylands.settings.lock")); + player.sendMessage(Texts.prefixed("message.neoskies.settings.lock")); island.locked = true; } - }, () -> player.sendMessage(Texts.prefixed("message.skylands.settings.no_island"))); + }, () -> player.sendMessage(Texts.prefixed("message.neoskies.settings.no_island"))); } static void setSpawnPos(ServerPlayerEntity player, BlockPos pos) { Skylands.getInstance().islands.getByPlayer(player).ifPresentOrElse(island -> { island.spawnPos = new Vec3d(pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5); String posText = pos.getX() + " " + pos.getY() + " " + pos.getZ(); - player.sendMessage(Texts.prefixed("message.skylands.settings.spawn_pos_change", map -> map.put("pos", posText))); + player.sendMessage(Texts.prefixed("message.neoskies.settings.spawn_pos_change", map -> map.put("pos", posText))); - }, () -> player.sendMessage(Texts.prefixed("message.skylands.settings.no_island"))); + }, () -> player.sendMessage(Texts.prefixed("message.neoskies.settings.no_island"))); } static void setVisitsPos(ServerPlayerEntity player, BlockPos pos) { Skylands.getInstance().islands.getByPlayer(player).ifPresentOrElse(island -> { island.visitsPos = new Vec3d(pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5); String posText = pos.getX() + " " + pos.getY() + " " + pos.getZ(); - player.sendMessage(Texts.prefixed("message.skylands.settings.visits_pos_change", map -> map.put("pos", posText))); + player.sendMessage(Texts.prefixed("message.neoskies.settings.visits_pos_change", map -> map.put("pos", posText))); - }, () -> player.sendMessage(Texts.prefixed("message.skylands.settings.no_island"))); + }, () -> player.sendMessage(Texts.prefixed("message.neoskies.settings.no_island"))); } private static int settingsGui(ServerCommandSource source) { if (!source.isExecutedByPlayer()) { - source.sendError(Texts.prefixed("message.skylands.error.player_only")); + source.sendError(Texts.prefixed("message.neoskies.error.player_only")); return 0; } @@ -112,7 +113,7 @@ private static int settingsGui(ServerCommandSource source) { //noinspection DataFlowIssue player.playSound(SoundEvents.ENTITY_HORSE_SADDLE, SoundCategory.MASTER, 0.4f, 1); new IslandSettingsGui(island, null).openGui(player); - }, () -> source.sendError(Texts.prefixed("message.skylands.error.missing_island"))); + }, () -> source.sendError(Texts.prefixed("message.neoskies.error.missing_island"))); return 1; } diff --git a/src/main/java/skylands/command/island/VisitCommand.java b/src/main/java/com/awakenedredstone/neoskies/command/island/VisitCommand.java similarity index 66% rename from src/main/java/skylands/command/island/VisitCommand.java rename to src/main/java/com/awakenedredstone/neoskies/command/island/VisitCommand.java index 34bf246..85251ed 100644 --- a/src/main/java/skylands/command/island/VisitCommand.java +++ b/src/main/java/com/awakenedredstone/neoskies/command/island/VisitCommand.java @@ -1,25 +1,26 @@ -package skylands.command.island; +package com.awakenedredstone.neoskies.command.island; +import com.awakenedredstone.neoskies.logic.Skylands; import com.mojang.brigadier.CommandDispatcher; import me.lucko.fabric.api.permissions.v0.Permissions; import net.minecraft.command.argument.EntityArgumentType; import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.network.ServerPlayerEntity; -import skylands.SkylandsMain; -import skylands.util.Texts; +import com.awakenedredstone.neoskies.SkylandsMain; +import com.awakenedredstone.neoskies.util.Texts; import static net.minecraft.command.argument.EntityArgumentType.player; import static net.minecraft.server.command.CommandManager.argument; import static net.minecraft.server.command.CommandManager.literal; -import static skylands.command.utils.CommandUtils.node; -import static skylands.command.utils.CommandUtils.register; +import static com.awakenedredstone.neoskies.command.utils.CommandUtils.node; +import static com.awakenedredstone.neoskies.command.utils.CommandUtils.register; public class VisitCommand { public static void init(CommandDispatcher dispatcher) { register(dispatcher, node() .then(literal("visit") - .requires(Permissions.require("skylands.island.visit", true)) + .requires(Permissions.require("neoskies.island.visit", true)) .then(argument("player", player()) .executes(context -> { var visitor = context.getSource().getPlayer(); @@ -37,22 +38,22 @@ public static void init(CommandDispatcher dispatcher) { static void run(ServerPlayerEntity visitor, ServerPlayerEntity owner) { String ownerName = owner.getName().getString(); - skylands.logic.Skylands.getInstance().islands.getByPlayer(owner).ifPresentOrElse(island -> { + Skylands.getInstance().islands.getByPlayer(owner).ifPresentOrElse(island -> { if (!island.isMember(visitor) && island.isBanned(visitor)) { - visitor.sendMessage(Texts.prefixed("message.skylands.island_visit.ban", map -> map.put("owner", ownerName))); + visitor.sendMessage(Texts.prefixed("message.neoskies.island_visit.ban", map -> map.put("owner", ownerName))); } else { if (!island.locked) { - if (visitor.getWorld().getRegistryKey().getValue().equals(SkylandsMain.id(island.owner.uuid.toString())) && !SkylandsMain.MAIN_CONFIG.allowVisitCurrentIsland()) { - visitor.sendMessage(Texts.prefixed("message.skylands.island_visit.fail", map -> map.put("owner", ownerName))); + if (visitor.getWorld().getRegistryKey().getValue().equals(SkylandsMain.id(island.owner.uuid.toString())) && !Skylands.getConfig().allowVisitCurrentIsland) { + visitor.sendMessage(Texts.prefixed("message.neoskies.island_visit.fail", map -> map.put("owner", ownerName))); } else { - visitor.sendMessage(Texts.prefixed("message.skylands.island_visit.success", map -> map.put("owner", ownerName))); + visitor.sendMessage(Texts.prefixed("message.neoskies.island_visit.success", map -> map.put("owner", ownerName))); island.visitAsVisitor(visitor); } } else { - visitor.sendMessage(Texts.prefixed("message.skylands.island_visit.no_visits", map -> map.put("owner", ownerName))); + visitor.sendMessage(Texts.prefixed("message.neoskies.island_visit.no_visits", map -> map.put("owner", ownerName))); } } - }, () -> visitor.sendMessage(Texts.prefixed("message.skylands.island_visit.no_island", map -> map.put("owner", ownerName)))); + }, () -> visitor.sendMessage(Texts.prefixed("message.neoskies.island_visit.no_island", map -> map.put("owner", ownerName)))); } } diff --git a/src/main/java/skylands/command/utils/CommandUtils.java b/src/main/java/com/awakenedredstone/neoskies/command/utils/CommandUtils.java similarity index 61% rename from src/main/java/skylands/command/utils/CommandUtils.java rename to src/main/java/com/awakenedredstone/neoskies/command/utils/CommandUtils.java index 103c5fa..f512685 100644 --- a/src/main/java/skylands/command/utils/CommandUtils.java +++ b/src/main/java/com/awakenedredstone/neoskies/command/utils/CommandUtils.java @@ -1,4 +1,4 @@ -package skylands.command.utils; +package com.awakenedredstone.neoskies.command.utils; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.builder.LiteralArgumentBuilder; @@ -9,11 +9,11 @@ import net.minecraft.server.command.ServerCommandSource; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import skylands.SkylandsMain; -import skylands.api.SkylandsAPI; -import skylands.logic.Island; -import skylands.logic.Skylands; -import skylands.util.Texts; +import com.awakenedredstone.neoskies.SkylandsMain; +import com.awakenedredstone.neoskies.api.SkylandsAPI; +import com.awakenedredstone.neoskies.logic.Island; +import com.awakenedredstone.neoskies.logic.Skylands; +import com.awakenedredstone.neoskies.util.Texts; import java.util.List; import java.util.function.Predicate; @@ -29,38 +29,52 @@ public class CommandUtils { return builder.buildFuture(); }; + @SuppressWarnings("BooleanMethodIsAlwaysInverted") public static boolean assertIsland(ServerCommandSource source, @Nullable Island island) { if (island == null) { - source.sendError(Texts.of("message.skylands.error.island_not_found")); + source.sendError(Texts.of("message.neoskies.error.island_not_found")); return false; } return true; } + @SuppressWarnings("BooleanMethodIsAlwaysInverted") public static boolean assertPlayer(ServerCommandSource source) { if (!source.isExecutedByPlayer()) { - source.sendError(Texts.of("message.skylands.error.player_olny")); + source.sendError(Texts.of("message.neoskies.error.player_olny")); return false; } return true; } + public static Predicate playerOnly(@NotNull String permission, boolean defaultValue) { + return source -> Permissions.check(source, permission, defaultValue) && source.isExecutedByPlayer() ; + } + public static Predicate requiresIsland(@NotNull String permission, boolean defaultValue) { - return source -> Permissions.check(source, permission, defaultValue) && source.isExecutedByPlayer() && SkylandsAPI.hasIsland(source.getPlayer()); + return source -> playerOnly(permission, defaultValue).test(source) && SkylandsAPI.hasIsland(source.getPlayer()); + } + + public static Predicate requiresNoIsland(@NotNull String permission, boolean defaultValue) { + return source -> playerOnly(permission, defaultValue).test(source) && !SkylandsAPI.hasIsland(source.getPlayer()); + } + + public static Predicate mustBeIslandOwner(@NotNull String permission, boolean defaultValue) { + return source -> requiresIsland(permission, defaultValue).test(source) && SkylandsAPI.isIslandOwner(source.getPlayer()); } public static LiteralArgumentBuilder node() { - return literal(SkylandsMain.MAIN_CONFIG.command()); + return literal(Skylands.getConfig().command); } public static LiteralArgumentBuilder adminNode() { - return literal(SkylandsMain.MAIN_CONFIG.adminCommand()); + return literal(Skylands.getConfig().adminCommand); } public static LiteralCommandNode register(CommandDispatcher dispatcher, final LiteralArgumentBuilder command) { LiteralCommandNode node = dispatcher.register(command); - for (String alias : SkylandsMain.MAIN_CONFIG.commandAliases()) { + for (String alias : Skylands.getConfig().commandAliases) { dispatcher.register(CommandManager.literal(alias).redirect(node)); } @@ -70,7 +84,7 @@ public static LiteralCommandNode register(CommandDispatcher public static LiteralCommandNode registerAdmin(CommandDispatcher dispatcher, final LiteralArgumentBuilder command) { LiteralCommandNode node = dispatcher.register(command); - for (String alias : SkylandsMain.MAIN_CONFIG.adminCommandAliases()) { + for (String alias : Skylands.getConfig().adminCommandAliases) { dispatcher.register(CommandManager.literal(alias).redirect(node)); } diff --git a/src/main/java/com/awakenedredstone/neoskies/config/IslandRanking.java b/src/main/java/com/awakenedredstone/neoskies/config/IslandRanking.java new file mode 100644 index 0000000..6eaaea5 --- /dev/null +++ b/src/main/java/com/awakenedredstone/neoskies/config/IslandRanking.java @@ -0,0 +1,27 @@ +package com.awakenedredstone.neoskies.config; + +import blue.endless.jankson.Comment; +import com.awakenedredstone.neoskies.config.source.Config; +import com.awakenedredstone.neoskies.config.source.JanksonBuilder; +import com.awakenedredstone.neoskies.config.source.annotation.PredicateConstraint; +import net.minecraft.util.Identifier; + +import java.util.LinkedHashMap; +import java.util.Map; + +public class IslandRanking extends Config { + public IslandRanking() { + super("neoskies/ranking", JanksonBuilder.buildJankson()); + } + + @PredicateConstraint("pointConstraint") + @Comment("The value of each block for the island ranking") + public Map points = new LinkedHashMap<>(); + + public static boolean pointConstraint(Map points) { + for (Integer value : points.values()) { + if (value < 0) return false; + } + return true; + } +} diff --git a/src/main/java/com/awakenedredstone/neoskies/config/MainConfig.java b/src/main/java/com/awakenedredstone/neoskies/config/MainConfig.java new file mode 100644 index 0000000..37fe721 --- /dev/null +++ b/src/main/java/com/awakenedredstone/neoskies/config/MainConfig.java @@ -0,0 +1,73 @@ +package com.awakenedredstone.neoskies.config; + +import blue.endless.jankson.Comment; +import com.awakenedredstone.neoskies.config.source.JanksonBuilder; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.Vec3d; +import com.awakenedredstone.neoskies.config.source.Config; + +import java.util.*; + +public class MainConfig extends Config { + public MainConfig() { + super("neoskies/config", JanksonBuilder.buildJankson()); + } + + @Comment("The mod language") + public String language = "en_us"; + + @Comment("The mod main command") + public String command = "sb"; + + @Comment("The mod main command aliases") + public List commandAliases = new ArrayList<>(List.of("skyblock")); + + @Comment("The mod admin command") + public String adminCommand = "sba"; + + @Comment("The mod admin command aliases") + public List adminCommandAliases = new ArrayList<>(List.of("skyblockadmin")); + + @Comment("Allow the player to visit their own island") + public boolean allowVisitCurrentIsland = false; + + @Comment("The default island radius") + public int defaultIslandRadius = -1; + + @Comment("The cooldown before the player can delete their island (in seconds)") + public int deletionCooldown = -1; + + @Comment("The maximum amount of islands a player can create") + public int islandLimit = -1; + + @Comment("Whenever it should clear the player data when they reset their island") + public boolean resetPlayerWithIsland = false; + + @Comment("The default island location") + public Vec3d defaultIslandLocation = new Vec3d(0.5d, 75d, 0.5d); + + @Comment("Disable blocks outside the islands") + public boolean disableBlocksOutsideIslands = false; + + @Comment("Disable entities outside the islands") + public boolean disableEntitiesOutsideIslands = false; + + @Comment("Enable end islands") + public boolean enableEndIsland = false; + + @Comment("Whenever the player is protected from falling into the void") + public boolean safeVoid = false; + + @Comment("Whenever the player is protected from fall damage when being recovered from the void") + public boolean safeVoidFallDamage = true; + + @Comment("The amount of blocks the player is protected from falling into the void") + public byte safeVoidBlocksBelow = 16; + + @Comment("Whenever the player gets the island protection messages") + public boolean showProtectionMessages = true; + + @Deprecated + @Comment("The value of each block for the island ranking") + public Map blockPoints = new LinkedHashMap<>(); +} diff --git a/src/main/java/com/awakenedredstone/neoskies/config/source/Config.java b/src/main/java/com/awakenedredstone/neoskies/config/source/Config.java new file mode 100644 index 0000000..2777239 --- /dev/null +++ b/src/main/java/com/awakenedredstone/neoskies/config/source/Config.java @@ -0,0 +1,108 @@ +package com.awakenedredstone.neoskies.config.source; + +import blue.endless.jankson.Jankson; +import blue.endless.jankson.JsonGrammar; +import blue.endless.jankson.api.SyntaxError; +import com.awakenedredstone.neoskies.SkylandsMain; +import net.fabricmc.loader.api.FabricLoader; + +import java.io.IOException; +import java.lang.reflect.Modifier; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.function.Consumer; + +public abstract class Config { + private final Map> listeners = new HashMap<>(); + private final Jankson interpreter; + protected final Path fileLocation; + protected boolean loading = false; + + public Config(String configFile, Jankson interpreter) { + this.fileLocation = FabricLoader.getInstance().getConfigDir().resolve(configFile + ".json5"); + this.interpreter = interpreter; + } + + public Path getFileLocation() { + return fileLocation; + } + + public void save() { + if (this.loading) return; + + try { + this.getFileLocation().getParent().toFile().mkdirs(); + Files.writeString(this.getFileLocation(), this.interpreter.toJson(this).toJson(JsonGrammar.JANKSON), StandardCharsets.UTF_8); + } catch (IOException e) { + SkylandsMain.LOGGER.warn("Could not save config!", e); + } + } + + /** + * Load the config represented by this wrapper from + * its associated file, or create it if it does not exist + */ + public void load() { + if (!configExists()) { + this.save(); + return; + } + + try { + this.loading = true; + Config newValues = this.interpreter.fromJson(Files.readString(this.getFileLocation(), StandardCharsets.UTF_8), this.getClass()); + + //Update values with new values + for (var field : this.getClass().getDeclaredFields()) { + int modifiers = field.getModifiers(); + if (Modifier.isStatic(modifiers) || Modifier.isFinal(modifiers) || Modifier.isTransient(modifiers) || !Modifier.isPublic(modifiers)) continue; + + Object newValue = field.get(newValues); + if (listeners.containsKey(field.getName()) && !Objects.equals(newValue, field.get(this))) { + listeners.get(field.getName()).accept(newValue); + } + + field.set(this, newValue); + } + + } catch (IOException | SyntaxError | IllegalAccessException e) { + SkylandsMain.LOGGER.warn("Could not load config!", e); + } finally { + this.loading = false; + } + } + + public boolean tryLoad() { + if (!configExists()) { + return false; + } + + try { + this.interpreter.fromJson(Files.readString(this.getFileLocation(), StandardCharsets.UTF_8), this.getClass()); + } catch (IOException | SyntaxError e) { + return false; + } + return true; + } + + public boolean configExists() { + return Files.exists(this.getFileLocation()); + } + + public void registerListener(String key, Consumer listener) { + //noinspection unchecked + this.listeners.put(key, (Consumer) listener); + } + + public String toString() { + return this.interpreter.toJson(this).toJson(JsonGrammar.JANKSON); + } + + public Jankson getInterpreter() { + return interpreter; + } +} diff --git a/src/main/java/com/awakenedredstone/neoskies/config/source/JanksonBuilder.java b/src/main/java/com/awakenedredstone/neoskies/config/source/JanksonBuilder.java new file mode 100644 index 0000000..a30c068 --- /dev/null +++ b/src/main/java/com/awakenedredstone/neoskies/config/source/JanksonBuilder.java @@ -0,0 +1,191 @@ +package com.awakenedredstone.neoskies.config.source; + +import blue.endless.jankson.*; +import blue.endless.jankson.api.DeserializerFunction; +import com.awakenedredstone.neoskies.config.source.annotation.PredicateConstraint; +import com.awakenedredstone.neoskies.config.source.annotation.RangeConstraint; +import com.awakenedredstone.neoskies.config.source.annotation.RegexConstraint; +import com.awakenedredstone.neoskies.config.source.jankson.Marshaller; +import com.awakenedredstone.neoskies.mixin.compat.JanksonAcessor; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; +import java.util.function.BiFunction; +import java.util.function.Consumer; +import java.util.function.Supplier; + +public class JanksonBuilder { + public static final Logger LOGGER = LoggerFactory.getLogger("Jankson Marshaller"); + public static final Jankson JANKSON; + + /** + * Creates a Jankson instance with the default serializers and deserializers, it takes a consumer as parameter + * that can be used to add custom serializers and deserializers. + * + * @return A Jankson instance with the default and provided custom serializers and deserializers + */ + public static Jankson buildJankson() { + return buildJankson(builder -> { + }); + } + + /** + * Creates a Jankson instance with the default serializers and deserializers, it takes a consumer as parameter + * that can be used to add custom serializers and deserializers. + * + * @param janksonBuilder A consumer that can be used to add custom serializers and deserializers. + * @return A Jankson instance with the default and provided custom serializers and deserializers + */ + public static Jankson buildJankson(Consumer janksonBuilder) { + Builder builder = new Builder() + //Identifier + .registerSerializer(Identifier.class, (identifier, marshaller) -> new JsonPrimitive(identifier.toString())) + .registerDeserializer(JsonPrimitive.class, Identifier.class, (primitive, m) -> Identifier.tryParse(primitive.asString())) + + //UUID + .registerSerializer(UUID.class, (uuid, marshaller) -> { + JsonArray array = new JsonArray(); + array.add(new JsonPrimitive(uuid.getMostSignificantBits())); + array.add(new JsonPrimitive(uuid.getLeastSignificantBits())); + return array; + }) + .registerDeserializer(JsonArray.class, UUID.class, (json, m) -> new UUID(json.getLong(0, 0), json.getLong(1, 0))) + + //BlockPos + .registerSerializer(BlockPos.class, (blockPos, marshaller) -> { + JsonArray array = new JsonArray(); + array.add(new JsonPrimitive(blockPos.getX())); + array.add(new JsonPrimitive(blockPos.getY())); + array.add(new JsonPrimitive(blockPos.getZ())); + return array; + }) + .registerDeserializer(JsonArray.class, BlockPos.class, (json, m) -> new BlockPos(json.getInt(0, 0), json.getInt(1, 0), json.getInt(2, 0))) + + //Vec3d + .registerSerializer(Vec3d.class, (vec3d, marshaller) -> { + JsonArray array = new JsonArray(); + array.add(new JsonPrimitive(vec3d.getX())); + array.add(new JsonPrimitive(vec3d.getY())); + array.add(new JsonPrimitive(vec3d.getZ())); + return array; + }) + .registerDeserializer(JsonArray.class, Vec3d.class, (json, m) -> new Vec3d(json.getDouble(0, 0), json.getDouble(1, 0), json.getDouble(2, 0))) + //Annotation + .registerAnnotationProcessor(PredicateConstraint.class, (annotation, object, clazz, fieldName) -> { + List methods = Arrays.stream(clazz.getMethods()).filter(method -> method.getName().equals(annotation.value())).toList(); + Method method; + if (methods.size() > 1) { + LOGGER.warn("Multiple methods found with the same name, trying to find the most suitable one"); + method = methods.stream().filter(m -> m.getParameterCount() == 1 && m.getParameterTypes()[0].isAssignableFrom(object.getClass())).findFirst().orElse(null); + if (method == null) { + throw new IllegalStateException("No suitable " + annotation.value() + " method found for " + fieldName); + } + } else if (methods.size() == 1) { + method = methods.get(0); + } else { + throw new IllegalStateException("No " + annotation.value() + " method found for " + fieldName); + } + + if (method.getReturnType() != boolean.class) { + throw new IllegalStateException("The method " + method.getName() + " must return a " + boolean.class.getSimpleName()); + } else if (method.getParameterCount() != 1) { + throw new IllegalStateException("The method " + method.getName() + " must have only one parameter"); + } else if (!method.getParameterTypes()[0].isAssignableFrom(object.getClass())) { + throw new IllegalStateException("The method " + method.getName() + " must have a parameter of type " + object.getClass().getSimpleName()); + } + + try { + return (boolean) method.invoke(null, object); + } catch (Exception e) { + throw new IllegalStateException("Failed to invoke " + method.getName() + " for " + fieldName, e); + } + }) + .registerAnnotationProcessor(RegexConstraint.class, (annotation, object, clazz, fieldName) -> object.toString().matches(annotation.value())) + .registerAnnotationProcessor(RangeConstraint.class, (annotation, object, clazz, fieldName) -> { + if (object instanceof Number number) { + boolean minValid = annotation.minInclusive() ? number.doubleValue() >= annotation.min() : number.doubleValue() > annotation.min(); + boolean maxValid = annotation.maxInclusive() ? number.doubleValue() <= annotation.max() : number.doubleValue() < annotation.max(); + boolean minusOneValid = !annotation.minusOne() || number.doubleValue() != -1; + return minValid && maxValid && minusOneValid; + } else { + throw new IllegalStateException("The field " + fieldName + " must be a number to use the " + annotation.annotationType().getSimpleName()); + } + }); + + janksonBuilder.accept(builder); + return builder.build(); + } + + static { + JANKSON = buildJankson(); + } + + public static class Builder extends Jankson.Builder { + protected Marshaller marshaller = new Marshaller(); + boolean allowBareRootObject = false; + + /** + * Registers a function to serialize an object into json. This can be useful if a class's serialized form is not + * meant to resemble its live-memory form. + * + * @param clazz The class to register a serializer for + * @param serializer A function which takes the object and a Marshaller, and produces a serialized JsonElement + * @return This Builder for further modificaton. + */ + public Builder registerSerializer(Class clazz, BiFunction serializer) { + marshaller.registerSerializer(clazz, serializer); + return this; + } + + public Builder registerDeserializer(Class sourceClass, Class targetClass, DeserializerFunction function) { + marshaller.registerDeserializer(sourceClass, targetClass, function); + return this; + } + + public Builder registerAnnotationProcessor(Class annotation, Marshaller.AnnotationProcessor processor) { + marshaller.registerAnnotationProcessor(annotation, processor); + return this; + } + + /** + * Registers a factory that can generate empty objects of the specified type. Sometimes it's not practical + * to have a no-arg constructor available on an object, so the function to create blanks can be specified + * here. + * + * @param clazz The class to use an alternate factory for + * @param factory A Supplier which can create blank objects of class `clazz` for deserialization + * @return This Builder for further modification. + */ + public Builder registerTypeFactory(Class clazz, Supplier factory) { + marshaller.registerTypeFactory(clazz, factory); + return this; + } + + /** + * Allows loading JSON files that do not contain root braces, as generated with + * {@link JsonGrammar.Builder#bareRootObject(boolean) bareRootObject}. + * + * @return This Builder for further modification. + */ + public Builder allowBareRootObject() { + allowBareRootObject = true; + return this; + } + + public Jankson build() { + Jankson result = JanksonAcessor.createJankson(this); + JanksonAcessor accessor = (JanksonAcessor) result; + accessor.setMarshaller(marshaller); + accessor.setAllowBareRootObject(allowBareRootObject); + return result; + } + } +} diff --git a/src/main/java/com/awakenedredstone/neoskies/config/source/annotation/PredicateConstraint.java b/src/main/java/com/awakenedredstone/neoskies/config/source/annotation/PredicateConstraint.java new file mode 100644 index 0000000..f01b269 --- /dev/null +++ b/src/main/java/com/awakenedredstone/neoskies/config/source/annotation/PredicateConstraint.java @@ -0,0 +1,12 @@ +package com.awakenedredstone.neoskies.config.source.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface PredicateConstraint { + String value(); +} diff --git a/src/main/java/com/awakenedredstone/neoskies/config/source/annotation/RangeConstraint.java b/src/main/java/com/awakenedredstone/neoskies/config/source/annotation/RangeConstraint.java new file mode 100644 index 0000000..d569952 --- /dev/null +++ b/src/main/java/com/awakenedredstone/neoskies/config/source/annotation/RangeConstraint.java @@ -0,0 +1,16 @@ +package com.awakenedredstone.neoskies.config.source.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface RangeConstraint { + double min(); + double max(); + boolean minInclusive() default true; + boolean maxInclusive() default true; + boolean minusOne() default false; +} diff --git a/src/main/java/com/awakenedredstone/neoskies/config/source/annotation/RegexConstraint.java b/src/main/java/com/awakenedredstone/neoskies/config/source/annotation/RegexConstraint.java new file mode 100644 index 0000000..188f949 --- /dev/null +++ b/src/main/java/com/awakenedredstone/neoskies/config/source/annotation/RegexConstraint.java @@ -0,0 +1,12 @@ +package com.awakenedredstone.neoskies.config.source.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface RegexConstraint { + String value(); +} diff --git a/src/main/java/com/awakenedredstone/neoskies/config/source/jankson/Marshaller.java b/src/main/java/com/awakenedredstone/neoskies/config/source/jankson/Marshaller.java new file mode 100644 index 0000000..307e342 --- /dev/null +++ b/src/main/java/com/awakenedredstone/neoskies/config/source/jankson/Marshaller.java @@ -0,0 +1,471 @@ +package com.awakenedredstone.neoskies.config.source.jankson; + +import blue.endless.jankson.*; +import blue.endless.jankson.annotation.SerializedName; +import blue.endless.jankson.annotation.Serializer; +import blue.endless.jankson.api.DeserializationException; +import blue.endless.jankson.api.DeserializerFunction; +import blue.endless.jankson.impl.POJODeserializer; +import blue.endless.jankson.impl.serializer.DeserializerFunctionPool; +import blue.endless.jankson.magic.TypeMagic; +import com.awakenedredstone.neoskies.mixin.compat.POJODeserializerAccessor; +import org.jetbrains.annotations.Nullable; + +import java.lang.annotation.Annotation; +import java.lang.reflect.*; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.function.Supplier; + +public class Marshaller implements blue.endless.jankson.api.Marshaller { + private static final Marshaller INSTANCE = new Marshaller(); + + public static blue.endless.jankson.api.Marshaller getFallback() { + return INSTANCE; + } + + private final Map, Function> primitiveMarshallers = new HashMap<>(); + protected final Map, Function> typeAdapters = new HashMap<>(); + + private final Map, BiFunction> serializers = new HashMap<>(); + private final Map, DeserializerFunctionPool> deserializers = new HashMap<>(); + private final Map, Supplier> typeFactories = new HashMap<>(); + + public void register(Class clazz, Function marshaller) { + primitiveMarshallers.put(clazz, marshaller); + } + + public void registerTypeAdapter(Class clazz, Function adapter) { + typeAdapters.put(clazz, adapter); + } + + @SuppressWarnings("unchecked") + public void registerSerializer(Class clazz, Function serializer) { + serializers.put(clazz, (it, marshaller) -> serializer.apply((T) it)); + } + + @SuppressWarnings("unchecked") + public void registerSerializer(Class clazz, BiFunction serializer) { + serializers.put(clazz, (BiFunction) serializer); + } + + public void registerTypeFactory(Class clazz, Supplier supplier) { + typeFactories.put(clazz, supplier); + } + + public void registerDeserializer(Class sourceClass, Class targetClass, DeserializerFunction function) { + @SuppressWarnings("unchecked") + DeserializerFunctionPool pool = (DeserializerFunctionPool) deserializers.get(targetClass); + if (pool == null) { + pool = new DeserializerFunctionPool<>(targetClass); + deserializers.put(targetClass, pool); + } + pool.registerUnsafe(sourceClass, function); + } + + public Marshaller() { + register(Void.class, (it) -> null); + + register(String.class, Object::toString); + + register(Byte.class, (it) -> (it instanceof Number) ? ((Number) it).byteValue() : null); + register(Character.class, (it) -> (it instanceof Number) ? (char) ((Number) it).shortValue() : it.toString().charAt(0)); + register(Short.class, (it) -> (it instanceof Number) ? ((Number) it).shortValue() : null); + register(Integer.class, (it) -> (it instanceof Number) ? ((Number) it).intValue() : null); + register(Long.class, (it) -> (it instanceof Number) ? ((Number) it).longValue() : null); + register(Float.class, (it) -> (it instanceof Number) ? ((Number) it).floatValue() : null); + register(Double.class, (it) -> (it instanceof Number) ? ((Number) it).doubleValue() : null); + register(Boolean.class, (it) -> (it instanceof Boolean) ? (Boolean) it : null); + + register(Void.TYPE, (it) -> null); + register(Byte.TYPE, (it) -> (it instanceof Number) ? ((Number) it).byteValue() : null); + register(Character.TYPE, (it) -> (it instanceof Number) ? (char) ((Number) it).shortValue() : it.toString().charAt(0)); + register(Short.TYPE, (it) -> (it instanceof Number) ? ((Number) it).shortValue() : null); + register(Integer.TYPE, (it) -> (it instanceof Number) ? ((Number) it).intValue() : null); + register(Long.TYPE, (it) -> (it instanceof Number) ? ((Number) it).longValue() : null); + register(Float.TYPE, (it) -> (it instanceof Number) ? ((Number) it).floatValue() : null); + register(Double.TYPE, (it) -> (it instanceof Number) ? ((Number) it).doubleValue() : null); + register(Boolean.TYPE, (it) -> (it instanceof Boolean) ? (Boolean) it : null); + + + registerSerializer(Void.class, (it) -> JsonNull.INSTANCE); + registerSerializer(Character.class, (it) -> new JsonPrimitive("" + it)); + registerSerializer(String.class, JsonPrimitive::new); + registerSerializer(Byte.class, (it) -> new JsonPrimitive(Long.valueOf(it))); + registerSerializer(Short.class, (it) -> new JsonPrimitive(Long.valueOf(it))); + registerSerializer(Integer.class, (it) -> new JsonPrimitive(Long.valueOf(it))); + registerSerializer(Long.class, JsonPrimitive::new); + registerSerializer(Float.class, (it) -> new JsonPrimitive(Double.valueOf(it))); + registerSerializer(Double.class, JsonPrimitive::new); + registerSerializer(Boolean.class, JsonPrimitive::new); + + registerSerializer(Void.TYPE, (it) -> JsonNull.INSTANCE); + registerSerializer(Character.TYPE, (it) -> new JsonPrimitive("" + it)); + registerSerializer(Byte.TYPE, (it) -> new JsonPrimitive(Long.valueOf(it))); + registerSerializer(Short.TYPE, (it) -> new JsonPrimitive(Long.valueOf(it))); + registerSerializer(Integer.TYPE, (it) -> new JsonPrimitive(Long.valueOf(it))); + registerSerializer(Long.TYPE, JsonPrimitive::new); + registerSerializer(Float.TYPE, (it) -> new JsonPrimitive(Double.valueOf(it))); + registerSerializer(Double.TYPE, JsonPrimitive::new); + registerSerializer(Boolean.TYPE, JsonPrimitive::new); + + registerSerializer(UUID.class, (uuid, marshaller) -> { + JsonArray array = new JsonArray(); + array.add(new JsonPrimitive(uuid.getMostSignificantBits())); + array.add(new JsonPrimitive(uuid.getLeastSignificantBits())); + return array; + }); + registerDeserializer(JsonArray.class, UUID.class, (json, m) -> new UUID(json.getLong(0, 0), json.getLong(1, 0))); + } + + /** + * EXPERIMENTAL. Marshalls elem into a very specific parameterized type, honoring generic type arguments. + */ + @SuppressWarnings("unchecked") + @Nullable + public T marshall(Type type, JsonElement elem) { + if (elem == null) return null; + if (elem == JsonNull.INSTANCE) return null; + + if (type instanceof Class) { + try { + return marshall((Class) type, elem); + } catch (ClassCastException t) { + return null; + } + } + + if (type instanceof ParameterizedType) { + try { + Class clazz = (Class) TypeMagic.classForType(type); + + return marshall(clazz, elem); + } catch (ClassCastException t) { + return null; + } + } + + return null; + } + + public T marshall(Class clazz, JsonElement elem) { + try { + return marshall(clazz, elem, false); + } catch (Throwable t) { + return null; + } + } + + public T marshallCarefully(Class clazz, JsonElement elem) throws DeserializationException { + return marshall(clazz, elem, true); + } + + @SuppressWarnings("unchecked") + @Nullable + public T marshall(Class clazz, JsonElement elem, boolean failFast) throws DeserializationException { + if (elem == null) return null; + if (elem == JsonNull.INSTANCE) return null; + if (clazz.isAssignableFrom(elem.getClass())) return (T) elem; //Already the correct type + + //Externally registered deserializers + DeserializerFunctionPool pool = (DeserializerFunctionPool) deserializers.get(clazz); + if (pool != null) { + try { + return pool.apply(elem, this); + } catch (DeserializerFunctionPool.FunctionMatchFailedException e) { + //Don't return the result, but continue + } + } + + //Internally annotated deserializers + pool = POJODeserializerAccessor.callDeserializersFor(clazz); + T poolResult; + try { + poolResult = pool.apply(elem, this); + return poolResult; + } catch (DeserializerFunctionPool.FunctionMatchFailedException e) { + //Don't return the result, but continue + } + + + if (Enum.class.isAssignableFrom(clazz)) { + if (!(elem instanceof JsonPrimitive)) return null; + String name = ((JsonPrimitive) elem).getValue().toString(); + + T[] constants = clazz.getEnumConstants(); + if (constants == null) return null; + for (T t : constants) { + if (((Enum) t).name().equals(name)) return t; + } + } + + if (clazz.equals(String.class)) { + //Almost everything has a String representation + if (elem instanceof JsonObject) return (T) elem.toJson(false, false); + if (elem instanceof JsonArray) return (T) elem.toJson(false, false); + if (elem instanceof JsonPrimitive) { + return (T) ((JsonPrimitive) elem).asString(); + } + if (elem instanceof JsonNull) return (T) "null"; + + if (failFast) + throw new DeserializationException("Encountered unexpected JsonElement type while deserializing to string: " + elem.getClass().getCanonicalName()); + return null; + } + + if (elem instanceof JsonPrimitive) { + Function func = primitiveMarshallers.get(clazz); + if (func != null) { + return (T) func.apply(((JsonPrimitive) elem).getValue()); + } else { + if (failFast) + throw new DeserializationException("Don't know how to unpack value '" + elem.toString() + "' into target type '" + clazz.getCanonicalName() + "'"); + return null; + } + } else if (elem instanceof JsonObject obj) { + + + if (clazz.isPrimitive()) + throw new DeserializationException("Can't marshall json object into primitive type " + clazz.getCanonicalName()); + if (JsonPrimitive.class.isAssignableFrom(clazz)) { + if (failFast) throw new DeserializationException("Can't marshall json object into a json primitive"); + return null; + } + + obj.setMarshaller(this); + + if (typeAdapters.containsKey(clazz)) { + return (T) typeAdapters.get(clazz).apply((JsonObject) elem); + } + + if (typeFactories.containsKey(clazz)) { + T result = (T) typeFactories.get(clazz).get(); + try { + POJODeserializer.unpackObject(result, obj, failFast); + return result; + } catch (Throwable t) { + if (failFast) throw t; + return null; + } + } else { + + try { + T result = TypeMagic.createAndCast(clazz, failFast); + T resultDefault = TypeMagic.createAndCast(clazz, failFast); + POJODeserializer.unpackObject(result, obj, failFast); + parseAnnotations(clazz, result, resultDefault); + + return result; + } catch (Throwable t) { + if (failFast) throw t; + return null; + } + } + + } else if (elem instanceof JsonArray) { + if (clazz.isPrimitive()) return null; + if (clazz.isArray()) { + Class componentType = clazz.getComponentType(); + JsonArray array = (JsonArray) elem; + + T result = (T) Array.newInstance(componentType, array.size()); + for (int i = 0; i < array.size(); i++) { + Array.set(result, i, marshall(componentType, array.get(i))); + } + return result; + } + } + + return null; + } + + public JsonElement serialize(Object obj) { + if (obj == null) return JsonNull.INSTANCE; + + //Prefer exact match + BiFunction serializer = serializers.get(obj.getClass()); + if (serializer != null) { + JsonElement result = serializer.apply(obj, this); + if (result instanceof JsonObject) ((JsonObject) result).setMarshaller(this); + if (result instanceof JsonArray) ((JsonArray) result).setMarshaller(this); + return result; + } else { + //Detailed match + for (Map.Entry, BiFunction> entry : serializers.entrySet()) { + if (entry.getKey().isAssignableFrom(obj.getClass())) { + JsonElement result = entry.getValue().apply(obj, this); + if (result instanceof JsonObject) ((JsonObject) result).setMarshaller(this); + if (result instanceof JsonArray) ((JsonArray) result).setMarshaller(this); + return result; + } + } + } + + //Check for annotations + for (Method m : obj.getClass().getDeclaredMethods()) { + if (m.isAnnotationPresent(Serializer.class) && !Modifier.isStatic(m.getModifiers())) { + Class clazz = m.getReturnType(); + if (JsonElement.class.isAssignableFrom(clazz)) { + //This is probably the method we're looking for! Let's figure out its method signature! + Parameter[] params = m.getParameters(); + if (params.length == 0) { + try { + boolean access = m.canAccess(obj); + if (!access) m.setAccessible(true); + JsonElement result = (JsonElement) m.invoke(obj); + if (!access) m.setAccessible(false); + if (result instanceof JsonObject) ((JsonObject) result).setMarshaller(this); + if (result instanceof JsonArray) ((JsonArray) result).setMarshaller(this); + return result; + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + return JsonNull.INSTANCE; //TODO: This is a very real and important error case. We need a SerializationException and a way to expose exceptions proactively. + } + } else if (params.length == 1) { + if (blue.endless.jankson.api.Marshaller.class.isAssignableFrom(params[0].getType())) { + try { + boolean access = m.canAccess(obj); + if (!access) m.setAccessible(true); + JsonElement result = (JsonElement) m.invoke(obj, this); + if (!access) m.setAccessible(false); + if (result instanceof JsonObject) ((JsonObject) result).setMarshaller(this); + if (result instanceof JsonArray) ((JsonArray) result).setMarshaller(this); + return result; + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + return JsonNull.INSTANCE; //TODO: Same failure case that needs expressing + } + } + } + } + } + } + + if (obj instanceof Enum) { + return new JsonPrimitive(((Enum) obj).name()); + } + + if (obj.getClass().isArray()) { + + JsonArray array = new JsonArray(); + array.setMarshaller(this); + //Class component = obj.getClass().getComponentType(); + for (int i = 0; i < Array.getLength(obj); i++) { + Object elem = Array.get(obj, i); + JsonElement parsed = serialize(elem); + array.add(parsed); + } + return array; + } + + if (obj instanceof Collection) { + JsonArray array = new JsonArray(); + array.setMarshaller(this); + for (Object elem : (Collection) obj) { + JsonElement parsed = serialize(elem); + array.add(parsed); + } + return array; + } + + if (obj instanceof Map) { + JsonObject result = new JsonObject(); + for (Map.Entry entry : ((Map) obj).entrySet()) { + String k = entry.getKey().toString(); + Object v = entry.getValue(); + result.put(k, serialize(v)); + } + return result; + } + + JsonObject result = new JsonObject(); + //Pull in public fields first + for (Field f : obj.getClass().getFields()) { + if ( + Modifier.isStatic(f.getModifiers()) || // Not part of the object + Modifier.isTransient(f.getModifiers())) continue; //Never serialize + f.setAccessible(true); + + try { + Object child = f.get(obj); + String name = f.getName(); + SerializedName nameAnnotation = f.getAnnotation(SerializedName.class); + if (nameAnnotation != null) name = nameAnnotation.value(); + + Comment comment = f.getAnnotation(Comment.class); + if (comment == null) { + result.put(name, serialize(child)); + } else { + result.put(name, serialize(child), comment.value()); + } + } catch (IllegalArgumentException | IllegalAccessException ignored) { + } + } + + //Add in what private fields we can reach + for (Field field : obj.getClass().getDeclaredFields()) { + if ( + Modifier.isPublic(field.getModifiers()) || // Already serialized + Modifier.isStatic(field.getModifiers()) || // Not part of the object + Modifier.isTransient(field.getModifiers())) continue; //Never serialize + field.setAccessible(true); + + try { + Object child = field.get(obj); + String name = field.getName(); + SerializedName nameAnnotation = field.getAnnotation(SerializedName.class); + if (nameAnnotation != null) name = nameAnnotation.value(); + + try { + Object instance = TypeMagic.createAndCast(obj.getClass(), true); + parseAnnotations(obj.getClass(), obj, instance); + } catch (DeserializationException e) { + throw new AssertionError("Failed to create instance of " + obj.getClass().getCanonicalName(), e); + } + + Comment comment = field.getAnnotation(Comment.class); + if (comment == null) { + result.put(name, serialize(child)); + } else { + result.put(name, serialize(child), comment.value()); + } + } catch (IllegalArgumentException | IllegalAccessException ignored) {} + } + + return result; + } + + protected void parseAnnotations(Class clazz, Object obj, Object objDefault) { + for (Field field : clazz.getDeclaredFields()) { + try { + Object fieldValue = field.get(obj); + + for (Annotation annotation : field.getAnnotations()) { + //noinspection rawtypes + AnnotationProcessor processor = annotationProcessors.get(annotation.annotationType()); + if (processor != null) { + //noinspection unchecked + boolean valid = processor.process(annotation, fieldValue, obj.getClass(), field.getName()); + if (!valid) { + //Reset the field to its default value + field.set(obj, field.get(objDefault)); + } + } + } + } catch (IllegalAccessException ignored) {} + } + } + + private final Map, AnnotationProcessor> annotationProcessors = new HashMap<>(); + + public void registerAnnotationProcessor(Class annotation, AnnotationProcessor processor) { + annotationProcessors.put(annotation, processor); + } + + @FunctionalInterface + public interface AnnotationProcessor { + boolean process(A annotation, V object, Class clazz, String fieldName); + } +} diff --git a/src/main/java/skylands/data/PlayerComponent.java b/src/main/java/com/awakenedredstone/neoskies/data/PlayerComponent.java similarity index 97% rename from src/main/java/skylands/data/PlayerComponent.java rename to src/main/java/com/awakenedredstone/neoskies/data/PlayerComponent.java index 4c62cbd..fb27727 100644 --- a/src/main/java/skylands/data/PlayerComponent.java +++ b/src/main/java/com/awakenedredstone/neoskies/data/PlayerComponent.java @@ -1,4 +1,4 @@ -package skylands.data; +package com.awakenedredstone.neoskies.data; import dev.onyxstudios.cca.api.v3.component.ComponentV3; import net.minecraft.entity.player.PlayerEntity; diff --git a/src/main/java/skylands/data/SkylandComponents.java b/src/main/java/com/awakenedredstone/neoskies/data/SkylandComponents.java similarity index 64% rename from src/main/java/skylands/data/SkylandComponents.java rename to src/main/java/com/awakenedredstone/neoskies/data/SkylandComponents.java index 1d3dcbb..d1c326b 100644 --- a/src/main/java/skylands/data/SkylandComponents.java +++ b/src/main/java/com/awakenedredstone/neoskies/data/SkylandComponents.java @@ -1,25 +1,22 @@ -package skylands.data; +package com.awakenedredstone.neoskies.data; import dev.onyxstudios.cca.api.v3.component.ComponentKey; import dev.onyxstudios.cca.api.v3.component.ComponentRegistryV3; -import dev.onyxstudios.cca.api.v3.entity.EntityComponentFactoryRegistry; -import dev.onyxstudios.cca.api.v3.entity.EntityComponentInitializer; -import dev.onyxstudios.cca.api.v3.entity.RespawnCopyStrategy; import dev.onyxstudios.cca.api.v3.world.WorldComponentFactoryRegistry; import dev.onyxstudios.cca.api.v3.world.WorldComponentInitializer; -import skylands.SkylandsMain; +import com.awakenedredstone.neoskies.SkylandsMain; -public class SkylandComponents implements WorldComponentInitializer, EntityComponentInitializer { +public class SkylandComponents implements WorldComponentInitializer/*, EntityComponentInitializer*/ { public static final ComponentKey WORLD_DATA = ComponentRegistryV3.INSTANCE.getOrCreate(SkylandsMain.id("world_data"), WorldComponent.class); - public static final ComponentKey PLAYER_DATA = ComponentRegistryV3.INSTANCE.getOrCreate(SkylandsMain.id("player_data"), PlayerComponent.class); + //public static final ComponentKey PLAYER_DATA = ComponentRegistryV3.INSTANCE.getOrCreate(SkylandsMain.id("player_data"), PlayerComponent.class); @Override public void registerWorldComponentFactories(WorldComponentFactoryRegistry registry) { registry.register(WORLD_DATA, WorldComponent::new); } - @Override + /*@Override public void registerEntityComponentFactories(EntityComponentFactoryRegistry registry) { registry.registerForPlayers(PLAYER_DATA, PlayerComponent::new, RespawnCopyStrategy.ALWAYS_COPY); - } + }*/ } diff --git a/src/main/java/skylands/data/WorldComponent.java b/src/main/java/com/awakenedredstone/neoskies/data/WorldComponent.java similarity index 73% rename from src/main/java/skylands/data/WorldComponent.java rename to src/main/java/com/awakenedredstone/neoskies/data/WorldComponent.java index 186b712..c5a3068 100644 --- a/src/main/java/skylands/data/WorldComponent.java +++ b/src/main/java/com/awakenedredstone/neoskies/data/WorldComponent.java @@ -1,17 +1,12 @@ -package skylands.data; +package com.awakenedredstone.neoskies.data; import dev.onyxstudios.cca.api.v3.component.ComponentV3; import net.minecraft.nbt.NbtCompound; import net.minecraft.world.World; import org.jetbrains.annotations.NotNull; -import skylands.logic.Skylands; +import com.awakenedredstone.neoskies.logic.Skylands; -public class WorldComponent implements ComponentV3 { - public World world; - - public WorldComponent(World world) { - this.world = world; - } +public record WorldComponent(World world) implements ComponentV3 { @Override public void readFromNbt(@NotNull NbtCompound nbt) { diff --git a/src/main/java/com/awakenedredstone/neoskies/datagen/NeoSkiesBlockTagProvider.java b/src/main/java/com/awakenedredstone/neoskies/datagen/NeoSkiesBlockTagProvider.java new file mode 100644 index 0000000..2a30851 --- /dev/null +++ b/src/main/java/com/awakenedredstone/neoskies/datagen/NeoSkiesBlockTagProvider.java @@ -0,0 +1,76 @@ +package com.awakenedredstone.neoskies.datagen; + +import com.awakenedredstone.neoskies.logic.tags.NeoSkiesBlockTags; +import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; +import net.fabricmc.fabric.api.datagen.v1.provider.FabricTagProvider; +import net.fabricmc.fabric.api.tag.convention.v1.ConventionalBlockTags; +import net.minecraft.block.Blocks; +import net.minecraft.registry.RegistryWrapper; +import net.minecraft.registry.tag.BlockTags; + +import java.util.concurrent.CompletableFuture; + +public class NeoSkiesBlockTagProvider extends FabricTagProvider.BlockTagProvider { + public NeoSkiesBlockTagProvider(FabricDataOutput output, CompletableFuture registriesFuture) { + super(output, registriesFuture); + } + + @Override + protected void configure(RegistryWrapper.WrapperLookup arg) { + getOrCreateTagBuilder(NeoSkiesBlockTags.ANVIL) + .forceAddTag(BlockTags.ANVIL); + + getOrCreateTagBuilder(NeoSkiesBlockTags.BEACON) + .add(Blocks.BEACON); + + getOrCreateTagBuilder(NeoSkiesBlockTags.BREWING_STAND) + .add(Blocks.BREWING_STAND); + + getOrCreateTagBuilder(NeoSkiesBlockTags.COMPOSTER) + .add(Blocks.COMPOSTER); + + getOrCreateTagBuilder(NeoSkiesBlockTags.CONTAINERS) + .forceAddTag(BlockTags.CAMPFIRES) + .forceAddTag(ConventionalBlockTags.CHESTS) + .forceAddTag(ConventionalBlockTags.WOODEN_BARRELS) + .forceAddTag(ConventionalBlockTags.SHULKER_BOXES) + .add( + Blocks.DISPENSER, + Blocks.DROPPER, + Blocks.FURNACE, + Blocks.BLAST_FURNACE, + Blocks.SMOKER, + Blocks.HOPPER, + Blocks.CHISELED_BOOKSHELF, + Blocks.DECORATED_POT, + Blocks.JUKEBOX, + Blocks.SPAWNER + ); + + getOrCreateTagBuilder(NeoSkiesBlockTags.DOORS) + .forceAddTag(BlockTags.DOORS) + .forceAddTag(BlockTags.TRAPDOORS) + .forceAddTag(BlockTags.FENCE_GATES); + + getOrCreateTagBuilder(NeoSkiesBlockTags.LECTERN) + .add(Blocks.LECTERN); + + getOrCreateTagBuilder(NeoSkiesBlockTags.LODESTONE) + .add(Blocks.LODESTONE); + + getOrCreateTagBuilder(NeoSkiesBlockTags.REDSTONE) + .forceAddTag(BlockTags.BUTTONS) + .forceAddTag(BlockTags.PRESSURE_PLATES) + .add( + Blocks.REDSTONE_WIRE, + Blocks.REPEATER, + Blocks.COMPARATOR, + Blocks.NOTE_BLOCK, + Blocks.LEVER, + Blocks.DAYLIGHT_DETECTOR + ); + + getOrCreateTagBuilder(NeoSkiesBlockTags.RESPAWN_ANCHOR) + .add(Blocks.RESPAWN_ANCHOR); + } +} diff --git a/src/main/java/com/awakenedredstone/neoskies/datagen/NeoSkiesDatagen.java b/src/main/java/com/awakenedredstone/neoskies/datagen/NeoSkiesDatagen.java new file mode 100644 index 0000000..b59d195 --- /dev/null +++ b/src/main/java/com/awakenedredstone/neoskies/datagen/NeoSkiesDatagen.java @@ -0,0 +1,14 @@ +package com.awakenedredstone.neoskies.datagen; + +import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint; +import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator; + +public class NeoSkiesDatagen implements DataGeneratorEntrypoint { + @Override + public void onInitializeDataGenerator(FabricDataGenerator generator) { + FabricDataGenerator.Pack pack = generator.createPack(); + pack.addProvider(NeoSkiesItemTagProvider::new); + pack.addProvider(NeoSkiesBlockTagProvider::new); + pack.addProvider(NeoSkiesEntityTagProvider::new); + } +} diff --git a/src/main/java/com/awakenedredstone/neoskies/datagen/NeoSkiesEntityTagProvider.java b/src/main/java/com/awakenedredstone/neoskies/datagen/NeoSkiesEntityTagProvider.java new file mode 100644 index 0000000..9b07524 --- /dev/null +++ b/src/main/java/com/awakenedredstone/neoskies/datagen/NeoSkiesEntityTagProvider.java @@ -0,0 +1,24 @@ +package com.awakenedredstone.neoskies.datagen; + +import com.awakenedredstone.neoskies.logic.tags.NeoSkiesEntityTags; +import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; +import net.fabricmc.fabric.api.datagen.v1.provider.FabricTagProvider; +import net.minecraft.entity.EntityType; +import net.minecraft.registry.RegistryWrapper; + +import java.util.concurrent.CompletableFuture; + +public class NeoSkiesEntityTagProvider extends FabricTagProvider.EntityTypeTagProvider { + public NeoSkiesEntityTagProvider(FabricDataOutput output, CompletableFuture registriesFuture) { + super(output, registriesFuture); + } + + @Override + protected void configure(RegistryWrapper.WrapperLookup arg) { + getOrCreateTagBuilder(NeoSkiesEntityTags.ARMOR_STAND) + .add(EntityType.ARMOR_STAND); + + getOrCreateTagBuilder(NeoSkiesEntityTags.LEASH_KNOT) + .add(EntityType.LEASH_KNOT); + } +} diff --git a/src/main/java/com/awakenedredstone/neoskies/datagen/NeoSkiesItemTagProvider.java b/src/main/java/com/awakenedredstone/neoskies/datagen/NeoSkiesItemTagProvider.java new file mode 100644 index 0000000..e204a62 --- /dev/null +++ b/src/main/java/com/awakenedredstone/neoskies/datagen/NeoSkiesItemTagProvider.java @@ -0,0 +1,71 @@ +package com.awakenedredstone.neoskies.datagen; + +import com.awakenedredstone.neoskies.logic.tags.NeoSkiesItemTags; +import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; +import net.fabricmc.fabric.api.datagen.v1.provider.FabricTagProvider; +import net.minecraft.item.*; +import net.minecraft.registry.Registries; +import net.minecraft.registry.RegistryWrapper; +import net.minecraft.registry.tag.ItemTags; + +import java.util.concurrent.CompletableFuture; + +public class NeoSkiesItemTagProvider extends FabricTagProvider.ItemTagProvider { + public NeoSkiesItemTagProvider(FabricDataOutput output, CompletableFuture registriesFuture) { + super(output, registriesFuture); + } + + @Override + protected void configure(RegistryWrapper.WrapperLookup arg) { + FabricTagProvider.FabricTagBuilder blockInteraction = getOrCreateTagBuilder(NeoSkiesItemTags.BLOCK_INTERACTION) + .forceAddTag(ItemTags.AXES) + .forceAddTag(ItemTags.HOES) + .forceAddTag(ItemTags.SHOVELS) + .forceAddTag(ItemTags.MUSIC_DISCS) + .add( + Items.ARMOR_STAND, + Items.BONE_MEAL, + Items.BRUSH, + Items.COMPASS, + Items.DEBUG_STICK, + Items.END_CRYSTAL, + Items.ENDER_EYE, + Items.FILLED_MAP, + Items.FIRE_CHARGE, + Items.FIREWORK_ROCKET, + Items.FLINT_AND_STEEL, + Items.HONEYCOMB, + Items.LEAD, + Items.POWDER_SNOW_BUCKET, + Items.SHEARS + ); + + for (Item item : Registries.ITEM) { + if (item instanceof DecorationItem || + item instanceof MinecartItem || + item instanceof PlaceableOnWaterItem || + item instanceof SpawnEggItem || + item instanceof PotionItem + ) { + blockInteraction.add(item); + } + } + + FabricTagProvider.FabricTagBuilder generalInteraction = getOrCreateTagBuilder(NeoSkiesItemTags.BLOCK_INTERACTION) + .forceAddTag(ItemTags.BOATS) + .add( + Items.ENDER_EYE, + Items.GLASS_BOTTLE + ); + + for (Item item : Registries.ITEM) { + if (item instanceof BucketItem || + item instanceof SpawnEggItem + ) { + generalInteraction.add(item); + } + } + + + } +} diff --git a/src/main/java/skylands/duck/ExtendedChunk.java b/src/main/java/com/awakenedredstone/neoskies/duck/ExtendedChunk.java similarity index 77% rename from src/main/java/skylands/duck/ExtendedChunk.java rename to src/main/java/com/awakenedredstone/neoskies/duck/ExtendedChunk.java index cf67fef..cd62097 100644 --- a/src/main/java/skylands/duck/ExtendedChunk.java +++ b/src/main/java/com/awakenedredstone/neoskies/duck/ExtendedChunk.java @@ -1,4 +1,4 @@ -package skylands.duck; +package com.awakenedredstone.neoskies.duck; import net.minecraft.world.chunk.ChunkSection; diff --git a/src/main/java/com/awakenedredstone/neoskies/duck/ExtendedPlayerManager.java b/src/main/java/com/awakenedredstone/neoskies/duck/ExtendedPlayerManager.java new file mode 100644 index 0000000..79a6c05 --- /dev/null +++ b/src/main/java/com/awakenedredstone/neoskies/duck/ExtendedPlayerManager.java @@ -0,0 +1,7 @@ +package com.awakenedredstone.neoskies.duck; + +import net.minecraft.server.network.ServerPlayerEntity; + +public interface ExtendedPlayerManager { + ServerPlayerEntity resetPlayer(ServerPlayerEntity player); +} diff --git a/src/main/java/com/awakenedredstone/neoskies/duck/ExtendedServerPlayerEntity.java b/src/main/java/com/awakenedredstone/neoskies/duck/ExtendedServerPlayerEntity.java new file mode 100644 index 0000000..462c197 --- /dev/null +++ b/src/main/java/com/awakenedredstone/neoskies/duck/ExtendedServerPlayerEntity.java @@ -0,0 +1,7 @@ +package com.awakenedredstone.neoskies.duck; + +import net.minecraft.server.network.ServerPlayerEntity; + +public interface ExtendedServerPlayerEntity { + void neoskies$simpleCopyFrom(ServerPlayerEntity player); +} diff --git a/src/main/java/skylands/event/PlayerConnectEvent.java b/src/main/java/com/awakenedredstone/neoskies/event/PlayerConnectEvent.java similarity index 73% rename from src/main/java/skylands/event/PlayerConnectEvent.java rename to src/main/java/com/awakenedredstone/neoskies/event/PlayerConnectEvent.java index ca194fb..4ad0f0c 100644 --- a/src/main/java/skylands/event/PlayerConnectEvent.java +++ b/src/main/java/com/awakenedredstone/neoskies/event/PlayerConnectEvent.java @@ -1,22 +1,17 @@ -package skylands.event; +package com.awakenedredstone.neoskies.event; import net.minecraft.server.MinecraftServer; import net.minecraft.server.network.ServerPlayerEntity; -import nota.player.SongPlayer; -import skylands.api.SkylandsAPI; -import skylands.logic.Member; -import skylands.logic.Skylands; -import skylands.util.Texts; +//import nota.player.SongPlayer; +import com.awakenedredstone.neoskies.api.SkylandsAPI; +import com.awakenedredstone.neoskies.logic.Member; +import com.awakenedredstone.neoskies.logic.Skylands; +import com.awakenedredstone.neoskies.util.Texts; @SuppressWarnings("unused") public class PlayerConnectEvent { public static void onJoin(MinecraftServer server, ServerPlayerEntity player) { - SongPlayer sp = Skylands.getInstance().hub.songPlayer; - if (sp != null) { - sp.addPlayer(player); - } - Skylands.getInstance().islands.getByPlayer(player).ifPresent(island -> island.owner.name = player.getName().getString()); Skylands.getInstance().islands.stuck.forEach(island -> { @@ -34,7 +29,7 @@ public static void onJoin(MinecraftServer server, ServerPlayerEntity player) { SkylandsAPI.getIsland(player.getWorld()).ifPresent(island -> { if (!island.isMember(player) && island.isBanned(player)) { - player.sendMessage(Texts.prefixed("message.skylands.ban_player.ban", map -> map.put("owner", island.owner.name))); + player.sendMessage(Texts.prefixed("message.neoskies.ban_player.ban", map -> map.put("owner", island.owner.name))); Skylands.getInstance().hub.visit(player); } }); diff --git a/src/main/java/skylands/event/PlayerEvents.java b/src/main/java/com/awakenedredstone/neoskies/event/PlayerEvents.java similarity index 94% rename from src/main/java/skylands/event/PlayerEvents.java rename to src/main/java/com/awakenedredstone/neoskies/event/PlayerEvents.java index a8cc149..07ba60b 100644 --- a/src/main/java/skylands/event/PlayerEvents.java +++ b/src/main/java/com/awakenedredstone/neoskies/event/PlayerEvents.java @@ -1,10 +1,9 @@ -package skylands.event; +package com.awakenedredstone.neoskies.event; import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.api.event.EventFactory; import net.minecraft.server.network.ServerPlayerEntity; -@Deprecated //TODO: Move to Stimuli public interface PlayerEvents { Event TICK = EventFactory.createArrayBacked(PlayerTick.class, (listeners) -> player -> { for (PlayerTick event : listeners) { diff --git a/src/main/java/com/awakenedredstone/neoskies/event/ServerEventListener.java b/src/main/java/com/awakenedredstone/neoskies/event/ServerEventListener.java new file mode 100644 index 0000000..4b6b658 --- /dev/null +++ b/src/main/java/com/awakenedredstone/neoskies/event/ServerEventListener.java @@ -0,0 +1,85 @@ +package com.awakenedredstone.neoskies.event; + +import eu.pb4.common.economy.api.CommonEconomy; +import eu.pb4.placeholders.api.PlaceholderResult; +import eu.pb4.placeholders.api.Placeholders; +import net.minecraft.server.MinecraftServer; +import com.awakenedredstone.neoskies.SkylandsMain; +import com.awakenedredstone.neoskies.logic.Island; +import com.awakenedredstone.neoskies.logic.Skylands; +import com.awakenedredstone.neoskies.util.PreInitData; +import com.awakenedredstone.neoskies.util.Texts; + +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; +import java.util.Optional; + +public class ServerEventListener { + + public static void onTick(MinecraftServer server) { + Skylands.getInstance().onTick(server); + } + + public static void onStart(MinecraftServer server) { + Skylands.init(server); + PreInitData.close(); + CommonEconomy.register("neoskies", Skylands.getInstance().economy.PROVIDER); + registerPlaceholders(); + } + + public static void onStop(MinecraftServer server) { + Skylands.getInstance().close(); + } + + //TODO: Add placeholders + private static void registerPlaceholders() { + String missing = Texts.of("neoskies.island.placeholders.missing_island").getString(); + PlaceholderResult invalid = PlaceholderResult.invalid(missing); + + Placeholders.register(SkylandsMain.id("locked"), (context, argument) -> { + Optional island = Skylands.getInstance().islands.getByPlayer(context.player()); + return island.map(value -> PlaceholderResult.value(value.locked ? "Locked" : "Open")).orElse(invalid); + }); + + Placeholders.register(SkylandsMain.id("size"), (context, argument) -> { + Optional island = Skylands.getInstance().islands.getByPlayer(context.player()); + return island.map(value -> PlaceholderResult.value(String.valueOf(value.radius * 2 + 1))).orElse(invalid); + }); + + Placeholders.register(SkylandsMain.id("id"), (context, argument) -> { + Optional islandOptional = Skylands.getInstance().islands.getByPlayer(context.player()); + return islandOptional.map(island -> PlaceholderResult.value(island.getIslandId().toString())).orElse(invalid); + }); + + Placeholders.register(SkylandsMain.id("owner"), (context, argument) -> { + Optional islandOptional = Skylands.getInstance().islands.getByPlayer(context.player()); + return islandOptional.map(island -> PlaceholderResult.value(island.owner.name)).orElse(invalid); + }); + + Placeholders.register(SkylandsMain.id("scanning"), (context, argument) -> { + Optional islandOptional = Skylands.getInstance().islands.getByPlayer(context.player()); + return islandOptional.map(island -> PlaceholderResult.value(Texts.of(island.isScanning() ? "neoskies.island.scanning" : "neoskies.island.not_scanning"))).orElse(invalid); + }); + + Placeholders.register(SkylandsMain.id("raw/scanning"), (context, argument) -> { + Optional islandOptional = Skylands.getInstance().islands.getByPlayer(context.player()); + return islandOptional.map(island -> PlaceholderResult.value(String.valueOf(island.isScanning()))).orElse(invalid); + }); + + Placeholders.register(SkylandsMain.id("creation_date"), (context, argument) -> { + Optional islandOptional = Skylands.getInstance().islands.getByPlayer(context.player()); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy").withZone(ZoneId.systemDefault()); + return islandOptional.map(island -> PlaceholderResult.value(formatter.format(island.getCreated()))).orElse(invalid); + }); + + Placeholders.register(SkylandsMain.id("wallet"), (context, argument) -> { + Optional islandOptional = Skylands.getInstance().islands.getByPlayer(context.player()); + return islandOptional.map(island -> PlaceholderResult.value(island.getWallet().formattedBalance())).orElse(invalid); + }); + + Placeholders.register(SkylandsMain.id("points"), (context, argument) -> { + Optional islandOptional = Skylands.getInstance().islands.getByPlayer(context.player()); + return islandOptional.map(island -> PlaceholderResult.value(String.valueOf(island.getPoints()))).orElse(invalid); + }); + } +} diff --git a/src/main/java/skylands/font/FontManager.java b/src/main/java/com/awakenedredstone/neoskies/font/FontManager.java similarity index 88% rename from src/main/java/skylands/font/FontManager.java rename to src/main/java/com/awakenedredstone/neoskies/font/FontManager.java index 05e39a5..3ab5349 100644 --- a/src/main/java/skylands/font/FontManager.java +++ b/src/main/java/com/awakenedredstone/neoskies/font/FontManager.java @@ -1,4 +1,4 @@ -package skylands.font; +package com.awakenedredstone.neoskies.font; import com.google.gson.JsonElement; import com.mojang.serialization.JsonOps; @@ -8,16 +8,18 @@ import net.minecraft.resource.ResourceType; import net.minecraft.util.Identifier; import org.jetbrains.annotations.ApiStatus; -import skylands.SkylandsMain; -import skylands.util.PreInitData; +import com.awakenedredstone.neoskies.SkylandsMain; +import com.awakenedredstone.neoskies.util.PreInitData; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; +import java.nio.charset.StandardCharsets; import java.util.List; @ApiStatus.Internal @ApiStatus.Experimental +@Deprecated public class FontManager implements SimpleSynchronousResourceReloadListener { public static final FontManager INSTANCE = new FontManager(); @@ -38,7 +40,7 @@ public void reload(ResourceManager manager) { if (fontProviders == null) { if (PreInitData.open()) PreInitData.getInstance().setResourceManager(manager); for (Identifier id : manager.findResources("font", path -> path.getPath().endsWith(".glyphs.json")).keySet()) { - try (InputStream stream = manager.getResource(id).get().getInputStream(); Reader reader = new InputStreamReader(stream, "UTF-8");) { + try (InputStream stream = manager.getResource(id).get().getInputStream(); Reader reader = new InputStreamReader(stream, StandardCharsets.UTF_8)) { fontProviders = FontProvider.LIST_CODEC.parse(JsonOps.INSTANCE, SkylandsMain.GSON.fromJson(reader, JsonElement.class)).resultOrPartial(SkylandsMain.LOGGER::error).orElseThrow(); } catch (Exception e) { SkylandsMain.LOGGER.error("Error occurred while loading the fonts data for " + id.toString(), e); diff --git a/src/main/java/skylands/font/FontProvider.java b/src/main/java/com/awakenedredstone/neoskies/font/FontProvider.java similarity index 96% rename from src/main/java/skylands/font/FontProvider.java rename to src/main/java/com/awakenedredstone/neoskies/font/FontProvider.java index 7676317..9849505 100644 --- a/src/main/java/skylands/font/FontProvider.java +++ b/src/main/java/com/awakenedredstone/neoskies/font/FontProvider.java @@ -1,17 +1,18 @@ -package skylands.font; +package com.awakenedredstone.neoskies.font; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.util.Identifier; import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.Nullable; -import skylands.SkylandsMain; -import skylands.logic.Skylands; +import com.awakenedredstone.neoskies.SkylandsMain; +import com.awakenedredstone.neoskies.logic.Skylands; import java.io.IOException; import java.io.InputStream; import java.util.*; +@Deprecated public class FontProvider { public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( diff --git a/src/main/java/com/awakenedredstone/neoskies/gui/CommonGuiElements.java b/src/main/java/com/awakenedredstone/neoskies/gui/CommonGuiElements.java new file mode 100644 index 0000000..90f288c --- /dev/null +++ b/src/main/java/com/awakenedredstone/neoskies/gui/CommonGuiElements.java @@ -0,0 +1,41 @@ +package com.awakenedredstone.neoskies.gui; + +import eu.pb4.sgui.api.elements.GuiElement; +import eu.pb4.sgui.api.elements.GuiElementBuilder; +import net.minecraft.item.Items; +import net.minecraft.screen.ScreenTexts; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; + +public class CommonGuiElements { + private static final GuiElement PURPLE_PLATE = new GuiElementBuilder(Items.PURPLE_STAINED_GLASS_PANE).setName(Text.empty()).build(); + private static final GuiElement WHITE_PLATE = new GuiElementBuilder(Items.WHITE_STAINED_GLASS_PANE).setName(Text.empty()).build(); + public static GuiElementBuilder nextPage() { + return new GuiElementBuilder(Items.PLAYER_HEAD) + .setName(Text.translatable("spectatorMenu.next_page").formatted(Formatting.WHITE)) + .hideFlags() + .setSkullOwner("eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYzg2MTg1YjFkNTE5YWRlNTg1ZjE4NGMzNGYzZjNlMjBiYjY0MWRlYjg3OWU4MTM3OGU0ZWFmMjA5Mjg3In19fQ"); + } + + public static GuiElementBuilder previousPage() { + return new GuiElementBuilder(Items.PLAYER_HEAD) + .setName(Text.translatable("spectatorMenu.previous_page").formatted(Formatting.WHITE)) + .hideFlags() + .setSkullOwner("eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMzEwODI5OGZmMmIyNjk1MWQ2ODNlNWFkZTQ2YTQyZTkwYzJmN2M3ZGQ0MWJhYTkwOGJjNTg1MmY4YzMyZTU4MyJ9fX0"); + } + + public static GuiElementBuilder back(Runnable runnable) { + return new GuiElementBuilder(Items.STRUCTURE_VOID).setName(ScreenTexts.BACK).setCallback((a, b, c, gui) -> { + PagedGui.playClickSound(gui.getPlayer()); + runnable.run(); + }); + } + + public static GuiElement purple() { + return PURPLE_PLATE; + } + + public static GuiElement white() { + return WHITE_PLATE; + } +} diff --git a/src/main/java/skylands/gui/IslandSettingsGui.java b/src/main/java/com/awakenedredstone/neoskies/gui/IslandSettingsGui.java similarity index 78% rename from src/main/java/skylands/gui/IslandSettingsGui.java rename to src/main/java/com/awakenedredstone/neoskies/gui/IslandSettingsGui.java index 962055f..48642f7 100644 --- a/src/main/java/skylands/gui/IslandSettingsGui.java +++ b/src/main/java/com/awakenedredstone/neoskies/gui/IslandSettingsGui.java @@ -1,9 +1,9 @@ -package skylands.gui; +package com.awakenedredstone.neoskies.gui; -import com.awakenedredstone.cbserverconfig.polymer.CBGuiElement; -import com.awakenedredstone.cbserverconfig.polymer.CBGuiElementBuilder; -import com.awakenedredstone.cbserverconfig.polymer.CBSimpleGuiBuilder; -import com.awakenedredstone.cbserverconfig.util.Utils; +import com.awakenedredstone.neoskies.gui.polymer.CBGuiElement; +import com.awakenedredstone.neoskies.gui.polymer.CBGuiElementBuilder; +import com.awakenedredstone.neoskies.gui.polymer.CBSimpleGuiBuilder; +import com.awakenedredstone.neoskies.util.UIUtils; import eu.pb4.sgui.api.gui.GuiInterface; import eu.pb4.sgui.api.gui.SimpleGui; import eu.pb4.sgui.api.gui.SlotGuiInterface; @@ -16,10 +16,10 @@ import net.minecraft.util.Identifier; import net.minecraft.util.math.MathHelper; import org.jetbrains.annotations.Nullable; -import skylands.api.island.IslandSettings; -import skylands.api.island.SettingsManager; -import skylands.logic.Island; -import skylands.util.Texts; +import com.awakenedredstone.neoskies.api.island.IslandSettings; +import com.awakenedredstone.neoskies.api.island.SettingsManager; +import com.awakenedredstone.neoskies.logic.Island; +import com.awakenedredstone.neoskies.util.Texts; import java.util.List; import java.util.Map; @@ -34,9 +34,8 @@ public class IslandSettingsGui { private int page = 0; private final CBGuiElement filler = new CBGuiElementBuilder(Items.BLACK_STAINED_GLASS_PANE).setName(Text.empty()).build(); - //TODO: Update to use translations - private final CBGuiElement nextPage = new CBGuiElementBuilder(Items.LIME_STAINED_GLASS_PANE).setName(Texts.of("Next page")).setCallback((index, type, action, gui) -> offsetPage(1, gui)).build(); - private final CBGuiElement prevPage = new CBGuiElementBuilder(Items.RED_STAINED_GLASS_PANE).setName(Texts.of("Previous page")).setCallback((index, type, action, gui) -> offsetPage(-1, gui)).build(); + private final CBGuiElement nextPage = new CBGuiElementBuilder(Items.LIME_STAINED_GLASS_PANE).setName(Texts.of("neoskies.page.next")).setCallback((index, type, action, gui) -> offsetPage(1, gui)).build(); + private final CBGuiElement prevPage = new CBGuiElementBuilder(Items.RED_STAINED_GLASS_PANE).setName(Texts.of("neoskies.page.previous")).setCallback((index, type, action, gui) -> offsetPage(-1, gui)).build(); public IslandSettingsGui(Island island, @Nullable GuiInterface parent) { @@ -45,9 +44,9 @@ public IslandSettingsGui(Island island, @Nullable GuiInterface parent) { this.entries = island.getSettings().entrySet().stream().toList(); updateGui = gui -> { - Utils.fillGui(gui, filler); + UIUtils.fillGui(gui, filler); - gui.setTitle(Texts.of("gui.skylands.island_settings")); + gui.setTitle(Texts.of("gui.neoskies.island_settings")); int slot = 10; int offset = page * 24; @@ -61,7 +60,7 @@ public IslandSettingsGui(Island island, @Nullable GuiInterface parent) { if (page > 0) gui.setSlot(gui.getSize() - 9, prevPage); CBGuiElementBuilder close = new CBGuiElementBuilder(Items.BARRIER) - .setName(Texts.of("gui.skylands.close")) + .setName(Texts.of("gui.neoskies.close")) .setCallback((index, type, action, gui1) -> { gui.getPlayer().playSound(SoundEvents.UI_BUTTON_CLICK.value(), SoundCategory.MASTER, 0.3f, 1); if (parent != null) { @@ -85,7 +84,7 @@ public IslandSettingsGui(Island island, @Nullable GuiInterface parent) { public SimpleGui buildGui(ServerPlayerEntity player) { CBSimpleGuiBuilder builder = new CBSimpleGuiBuilder(ScreenHandlerType.GENERIC_9X6, false); - Utils.fillGui(builder, filler); + UIUtils.fillGui(builder, filler); builder.setOnOpen(updateGui::accept); builder.setOnClick(simpleUpdateGui::accept); diff --git a/src/main/java/com/awakenedredstone/neoskies/gui/PagedGui.java b/src/main/java/com/awakenedredstone/neoskies/gui/PagedGui.java new file mode 100644 index 0000000..c1eb568 --- /dev/null +++ b/src/main/java/com/awakenedredstone/neoskies/gui/PagedGui.java @@ -0,0 +1,231 @@ +package com.awakenedredstone.neoskies.gui; + +import eu.pb4.sgui.api.elements.GuiElement; +import eu.pb4.sgui.api.elements.GuiElementBuilder; +import eu.pb4.sgui.api.elements.GuiElementBuilderInterface; +import eu.pb4.sgui.api.elements.GuiElementInterface; +import eu.pb4.sgui.api.gui.SimpleGui; +import it.unimi.dsi.fastutil.objects.Object2IntMap; +import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.screen.ScreenHandlerType; +import net.minecraft.screen.slot.Slot; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.sound.SoundCategory; +import net.minecraft.sound.SoundEvent; +import net.minecraft.sound.SoundEvents; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; +import org.jetbrains.annotations.Nullable; + +import java.util.List; +import java.util.function.IntFunction; + +public abstract class PagedGui extends SimpleGui { + private static final Object2IntMap> TYPE_TO_SIZE = new Object2IntOpenHashMap<>(); + + protected int page = 0; + + public static SimpleGui of(ServerPlayerEntity player, List elements) { + return of(player, elements, null); + } + public static SimpleGui of(ServerPlayerEntity player, List elements, @Nullable IntFunction navbar) { + return new FromList(ScreenHandlerType.GENERIC_9X6, player, false, elements, navbar); + } + + public PagedGui(ScreenHandlerType type, ServerPlayerEntity player, boolean includePlayerInventorySlots) { + super(type, player, includePlayerInventorySlots); + } + + protected void setPage(int page) { + this.page = Math.min(this.getPageAmount() - 1, Math.max(0, page)); + this.updateDisplay(); + } + + protected void nextPage() { + setPage(this.page + 1); + } + + protected boolean canNextPage() { + return this.getPageAmount() > this.page + 1; + } + + protected void previousPage() { + setPage(this.page - 1); + } + + protected boolean canPreviousPage() { + return this.page - 1 >= 0; + } + + protected void updateDisplay() { + var pageSize = this.getSinglePageSize(); + var offset = this.page * pageSize; + + for (int i = 0; i < pageSize; i++) { + var element = this.getElement(offset + i); + + if (element == null) { + element = DisplayElement.empty(); + } + + if (element.element() != null) { + this.setSlot(i, element.element()); + } else if (element.slot() != null) { + this.setSlotRedirect(i, element.slot()); + } + } + + for (int i = 0; i < 9; i++) { + var navElement = this.getNavElement(i); + + if (navElement == null) { + navElement = DisplayElement.EMPTY; + } + + if (navElement.element != null) { + this.setSlot(i + pageSize, navElement.element); + } else if (navElement.slot != null) { + this.setSlotRedirect(i + pageSize, navElement.slot); + } + } + } + + protected int getPage() { + return this.page; + } + + public final int getSinglePageSize() { + return 9 * (TYPE_TO_SIZE.getInt(this.type) + (this.isIncludingPlayer() ? 4 : 0)); + } + + protected abstract int getPageAmount(); + + protected abstract DisplayElement getElement(int id); + + protected DisplayElement getNavElement(int id) { + return switch (id) { + case 2 -> DisplayElement.previousPage(this); + case 6 -> DisplayElement.nextPage(this); + default -> DisplayElement.filler(); + }; + } + + public record DisplayElement(@Nullable GuiElementInterface element, @Nullable Slot slot) { + private static final DisplayElement EMPTY = DisplayElement.of(new GuiElement(ItemStack.EMPTY, GuiElementInterface.EMPTY_CALLBACK)); + private static final DisplayElement FILLER = DisplayElement.of( + new GuiElementBuilder(Items.WHITE_STAINED_GLASS_PANE) + .setName(Text.empty()) + .hideFlags() + ); + + public static DisplayElement of(GuiElementInterface element) { + return new DisplayElement(element, null); + } + + public static DisplayElement of(GuiElementBuilderInterface element) { + return new DisplayElement(element.build(), null); + } + + public static DisplayElement of(Slot slot) { + return new DisplayElement(null, slot); + } + + public static DisplayElement nextPage(PagedGui gui) { + if (gui.canNextPage()) { + return DisplayElement.of( + CommonGuiElements.nextPage().setCallback((x, y, z) -> { + playClickSound(gui.player); + gui.nextPage(); + }) + ); + } else { + return DisplayElement.of( + new GuiElementBuilder(Items.PLAYER_HEAD) + .setName(Text.translatable("spectatorMenu.next_page").formatted(Formatting.DARK_GRAY)) + .hideFlags() + .setSkullOwner(SkinEncoder.encode("7e57720a4878c8bcab0e9c9c47d9e55128ccd77ba3445a54a91e3e1e1a27356e")) + ); + } + } + + public static DisplayElement previousPage(PagedGui gui) { + if (gui.canPreviousPage()) { + return DisplayElement.of( + CommonGuiElements.previousPage() + .setCallback((x, y, z) -> { + playClickSound(gui.player); + gui.previousPage(); + }) + ); + } else { + return DisplayElement.of( + new GuiElementBuilder(Items.PLAYER_HEAD) + .setName(Text.translatable("spectatorMenu.previous_page").formatted(Formatting.DARK_GRAY)) + .hideFlags() + .setSkullOwner(SkinEncoder.encode("50820f76e3e041c75f76d0f301232bdf48321b534fe6a859ccb873d2981a9623")) + ); + } + } + + public static DisplayElement filler() { + return FILLER; + } + + public static DisplayElement empty() { + return EMPTY; + } + } + + public static void playSound(ServerPlayerEntity player, SoundEvent sound) { + player.playSound(sound, SoundCategory.MASTER, 1, 1); + } + + public static void playClickSound(ServerPlayerEntity player) { + playSound(player, SoundEvents.UI_BUTTON_CLICK.value()); + } + + public static class FromList extends PagedGui { + + protected final List list; + @Nullable + private final IntFunction navbar; + + public FromList(ScreenHandlerType type, ServerPlayerEntity player, boolean includePlayerInventorySlots, List guiElementInterfaces, IntFunction navbar) { + super(type, player, includePlayerInventorySlots); + this.list = guiElementInterfaces; + this.navbar = navbar; + this.updateDisplay(); + } + + @Override + protected DisplayElement getNavElement(int id) { + var x = navbar != null ? navbar.apply(id) : null; + return x != null ? DisplayElement.of(x) : super.getNavElement(id); + } + + protected List getList() { + return list; + } + + @Override + protected int getPageAmount() { + return this.getList().size() / this.getSinglePageSize() + 1; + } + + @Override + protected DisplayElement getElement(int id) { + return this.getList().size() > id ? DisplayElement.of(this.getList().get(id)) : DisplayElement.empty(); + } + } + + static { + TYPE_TO_SIZE.defaultReturnValue(0); + TYPE_TO_SIZE.put(ScreenHandlerType.GENERIC_9X2, 1); + TYPE_TO_SIZE.put(ScreenHandlerType.GENERIC_9X3, 2); + TYPE_TO_SIZE.put(ScreenHandlerType.GENERIC_9X4, 3); + TYPE_TO_SIZE.put(ScreenHandlerType.GENERIC_9X5, 4); + TYPE_TO_SIZE.put(ScreenHandlerType.GENERIC_9X6, 5); + } +} diff --git a/src/main/java/com/awakenedredstone/neoskies/gui/SkinEncoder.java b/src/main/java/com/awakenedredstone/neoskies/gui/SkinEncoder.java new file mode 100644 index 0000000..8d8b830 --- /dev/null +++ b/src/main/java/com/awakenedredstone/neoskies/gui/SkinEncoder.java @@ -0,0 +1,29 @@ +package com.awakenedredstone.neoskies.gui; + +import java.nio.charset.StandardCharsets; +import java.util.Base64; + +public class SkinEncoder { + /** + * @param hash a hash part of the skin URL after http://textures.minecraft.net/texture/ + * @return Base64-encoded skin texture for player heads + */ + public static String encode(String hash) { + if (hash == null) return null; + if (hash.length() > 80) { + return hash; + } + + return encodeUrl("http://textures.minecraft.net/texture/" + hash); + } + + /** + * @return Base64-encoded skin texture for player heads + */ + public static String encodeUrl(String url) { + if (url == null) return null; + var value = """ + {"textures":{"SKIN":{"url":"%s"}}}""".formatted(url); + return new String(Base64.getEncoder().encode(value.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8); + } +} diff --git a/src/main/java/com/awakenedredstone/neoskies/gui/polymer/CBGuiElement.java b/src/main/java/com/awakenedredstone/neoskies/gui/polymer/CBGuiElement.java new file mode 100644 index 0000000..0ac3eb7 --- /dev/null +++ b/src/main/java/com/awakenedredstone/neoskies/gui/polymer/CBGuiElement.java @@ -0,0 +1,25 @@ +package com.awakenedredstone.neoskies.gui.polymer; + +import net.minecraft.item.ItemStack; + +public class CBGuiElement extends eu.pb4.sgui.api.elements.GuiElement { + public CBGuiElement(ItemStack item, ClickCallback callback) { + super(item, callback); + } + + public CBGuiElement(ItemStack item, ItemClickCallback callback) { + super(item, callback); + } + + public CBGuiElementBuilder getBuilder() { + return CBGuiElementBuilder.from(this); + } + + public CBGuiElementBuilder getBuilderSimple() { + return CBGuiElementBuilder.fromSimple(this); + } + + public CBGuiElement copy() { + return CBGuiElementBuilder.from(this).build(); + } +} diff --git a/src/main/java/com/awakenedredstone/neoskies/gui/polymer/CBGuiElementBuilder.java b/src/main/java/com/awakenedredstone/neoskies/gui/polymer/CBGuiElementBuilder.java new file mode 100644 index 0000000..ff91b05 --- /dev/null +++ b/src/main/java/com/awakenedredstone/neoskies/gui/polymer/CBGuiElementBuilder.java @@ -0,0 +1,341 @@ +package com.awakenedredstone.neoskies.gui.polymer; + +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.minecraft.MinecraftProfileTextures; +import eu.pb4.sgui.api.elements.GuiElementBuilder; +import eu.pb4.sgui.api.elements.GuiElementInterface; +import net.minecraft.enchantment.Enchantment; +import net.minecraft.enchantment.Enchantments; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.nbt.NbtElement; +import net.minecraft.nbt.NbtHelper; +import net.minecraft.nbt.NbtList; +import net.minecraft.registry.Registries; +import net.minecraft.server.MinecraftServer; +import net.minecraft.text.MutableText; +import net.minecraft.text.Text; +import net.minecraft.util.Identifier; +import net.minecraft.util.Util; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; +import java.util.UUID; + +public class CBGuiElementBuilder extends eu.pb4.sgui.api.elements.GuiElementBuilder { + + /** + * Constructs a GuiElementBuilder with the default options + */ + public CBGuiElementBuilder() {} + + /** + * Constructs a GuiElementBuilder with the specified Item. + * + * @param item the item to use + */ + public CBGuiElementBuilder(Item item) { + super(item); + } + + /** + * Constructs a GuiElementBuilder with the specified Item + * and number of items. + * + * @param item the item to use + * @param count the number of items + */ + public CBGuiElementBuilder(Item item, int count) { + super(item, count); + } + + /** + * Constructs a GuiElementBuilder based on the supplied stack. + * + * @param stack the stack to base the builder of + * @return the constructed builder + */ + @NotNull + public static CBGuiElementBuilder from(@NotNull ItemStack stack) { + CBGuiElementBuilder builder = new CBGuiElementBuilder(stack.getItem(), stack.getCount()); + NbtCompound tag = stack.getOrCreateNbt().copy(); + + if (stack.hasCustomName()) { + builder.setName((MutableText) stack.getName()); + tag.getCompound("display").remove("Name"); + } + + if (tag.contains("display") && tag.getCompound("display").contains("Lore")) { + builder.setLore(CBGuiElementBuilder.getLore(stack)); + tag.getCompound("display").remove("Lore"); + } + + if (stack.isDamaged()) { + builder.setDamage(stack.getDamage()); + tag.remove("Damage"); + } + + if (stack.hasEnchantments()) { + for (NbtElement enc : stack.getEnchantments()) { + Registries.ENCHANTMENT.getOrEmpty(Identifier.tryParse(((NbtCompound) enc).getString("id"))).ifPresent(enchantment -> builder.enchant(enchantment, ((NbtCompound) enc).getInt("lvl"))); + } + tag.remove("Enchantments"); + } + + if (stack.getOrCreateNbt().contains("HideFlags")) { + builder.hideFlags(stack.getOrCreateNbt().getByte("HideFlags")); + tag.remove("HideFlags"); + } + + builder.tag = tag; + + return builder; + } + + @NotNull + public static CBGuiElementBuilder from(@NotNull CBGuiElement element) { + CBGuiElementBuilder builder = from(element.getItemStack()); + builder.callback = element.getGuiCallback(); + + return builder; + } + + @NotNull + public static CBGuiElementBuilder fromSimple(@NotNull CBGuiElement element) { + return from(element.getItemStack()); + } + + /** + * Sets the type of Item of the element. + * + * @param item the item to use + * @return this element builder + */ + public CBGuiElementBuilder setItem(Item item) { + this.item = item; + return this; + } + + /** + * Sets the name of the element. + * + * @param name the name to use + * @return this element builder + */ + public CBGuiElementBuilder setName(@NotNull Text name) { + this.name = name.copy(); + return this; + } + + /** + * Sets the number of items in the element. + * + * @param count the number of items + * @return this element builder + */ + public CBGuiElementBuilder setCount(int count) { + this.count = count; + return this; + } + + /** + * Sets the lore lines of the element. + * + * @param lore a list of all the lore lines + * @return this element builder + */ + public CBGuiElementBuilder setLore(List lore) { + this.lore = lore; + return this; + } + + /** + * Adds a line of lore to the element. + * + * @param lore the line to add + * @return this element builder + */ + public CBGuiElementBuilder addLoreLine(Text lore) { + this.lore.add(lore); + return this; + } + + /** + * Set the damage of the element. This will only be + * visible if the item supports has durability. + * + * @param damage the amount of durability the item is missing + * @return this element builder + */ + public CBGuiElementBuilder setDamage(int damage) { + this.damage = damage; + return this; + } + + /** + * Hides all {@link ItemStack.TooltipSection}s from the element display + * + * @return this element builder + */ + public CBGuiElementBuilder hideFlags() { + this.hideFlags = 127; + return this; + } + + /** + * Hides a {@link ItemStack.TooltipSection} + * from the elements display. + * + * @param section the section to hide + * @return this element builder + */ + public CBGuiElementBuilder hideFlag(@NotNull ItemStack.TooltipSection section) { + this.hideFlags = (byte) (this.hideFlags | section.getFlag()); + return this; + } + + /** + * Set the {@link ItemStack.TooltipSection}s to + * hide from the elements display, by the flags. + * + * @param value the flags to hide + * @return this element builder + * @see CBGuiElementBuilder#hideFlag(ItemStack.TooltipSection) + */ + public CBGuiElementBuilder hideFlags(byte value) { + this.hideFlags = value; + return this; + } + + /** + * Give the element the specified enchantment. + * + * @param enchantment the enchantment to apply + * @param level the level of the specified enchantment + * @return this element builder + */ + public CBGuiElementBuilder enchant(Enchantment enchantment, int level) { + this.enchantments.put(enchantment, level); + return this; + } + + /** + * Sets the element to have an enchantment glint. + * + * @return this element builder + */ + public CBGuiElementBuilder glow() { + this.enchantments.put(Enchantments.LUCK_OF_THE_SEA, 1); + return hideFlag(ItemStack.TooltipSection.ENCHANTMENTS); + } + + /** + * Sets the custom model data of the element. + * + * @param value the value used for custom model data + * @return this element builder + */ + public CBGuiElementBuilder setCustomModelData(int value) { + this.getOrCreateNbt().putInt("CustomModelData", value); + return this; + } + + /** + * Sets the element to be unbreakable, also hides the durability bar. + * + * @return this element builder + */ + public CBGuiElementBuilder unbreakable() { + this.getOrCreateNbt().putBoolean("Unbreakable", true); + return hideFlag(ItemStack.TooltipSection.UNBREAKABLE); + } + + /** + * Sets the skull owner tag of a player head. + * If the server parameter is not supplied it may lag the client while it loads the texture, + * otherwise if the server is provided and the {@link GameProfile} contains a UUID then the + * textures will be loaded by the server. This can take some time the first load, + * however the skins are cached for later uses so its often less noticeable to let the + * server load the textures. + * + * @param profile the {@link GameProfile} of the owner + * @param server the server instance, used to get the textures + * @return this element builder + */ + public GuiElementBuilder setSkullOwner(GameProfile profile, @Nullable MinecraftServer server) { + if (profile.getId() != null && server != null) { + if (server.getSessionService().getTextures(profile) == MinecraftProfileTextures.EMPTY) { + var tmp = server.getSessionService().fetchProfile(profile.getId(), false); + if (tmp != null) { + profile = tmp.profile(); + } + } + + this.getOrCreateNbt().put("SkullOwner", NbtHelper.writeGameProfile(new NbtCompound(), profile)); + } else { + this.getOrCreateNbt().putString("SkullOwner", profile.getName()); + } + return this; + } + + /** + * Sets the skull owner tag of a player head. + * This method uses raw values required by client to display the skin + * Ideal for textures generated with 3rd party websites like mineskin.org + * + * @param value texture value used by client + * @return this element builder + */ + public CBGuiElementBuilder setSkullOwner(String value) { + return this.setSkullOwner(value, null, null); + } + + /** + * Sets the skull owner tag of a player head. + * This method uses raw values required by client to display the skin + * Ideal for textures generated with 3rd party websites like mineskin.org + * + * @param value texture value used by client + * @param signature optional signature, will be ignored when set to null + * @param uuid UUID of skin owner, if null default will be used + * @return this element builder + */ + public CBGuiElementBuilder setSkullOwner(String value, @Nullable String signature, @Nullable UUID uuid) { + NbtCompound skullOwner = new NbtCompound(); + NbtCompound properties = new NbtCompound(); + NbtCompound valueData = new NbtCompound(); + NbtList textures = new NbtList(); + + valueData.putString("Value", value); + if (signature != null) { + valueData.putString("Signature", signature); + } + + textures.add(valueData); + properties.put("textures", textures); + + skullOwner.put("Id", NbtHelper.fromUuid(uuid != null ? uuid : Util.NIL_UUID)); + skullOwner.put("Properties", properties); + this.getOrCreateNbt().put("SkullOwner", skullOwner); + + return this; + } + + @Override + public CBGuiElementBuilder setCallback(CBGuiElement.ClickCallback callback) { + this.callback = callback; + return this; + } + + @Override + public CBGuiElementBuilder setCallback(GuiElementInterface.ItemClickCallback callback) { + this.callback = callback; + return this; + } + + public CBGuiElement build() { + return new CBGuiElement(asStack(), this.callback); + } +} diff --git a/src/main/java/com/awakenedredstone/neoskies/gui/polymer/CBSimpleGuiBuilder.java b/src/main/java/com/awakenedredstone/neoskies/gui/polymer/CBSimpleGuiBuilder.java new file mode 100644 index 0000000..8508d69 --- /dev/null +++ b/src/main/java/com/awakenedredstone/neoskies/gui/polymer/CBSimpleGuiBuilder.java @@ -0,0 +1,269 @@ +package com.awakenedredstone.neoskies.gui.polymer; + +import eu.pb4.sgui.api.ClickType; +import eu.pb4.sgui.api.GuiHelpers; +import eu.pb4.sgui.api.SlotHolder; +import eu.pb4.sgui.api.elements.GuiElement; +import eu.pb4.sgui.api.elements.GuiElementBuilderInterface; +import eu.pb4.sgui.api.elements.GuiElementInterface; +import eu.pb4.sgui.api.gui.SimpleGui; +import net.minecraft.item.ItemStack; +import net.minecraft.screen.ScreenHandlerType; +import net.minecraft.screen.slot.Slot; +import net.minecraft.screen.slot.SlotActionType; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.text.Text; +import org.jetbrains.annotations.NotNull; + +import java.util.function.Consumer; + +public class CBSimpleGuiBuilder implements SlotHolder { + private final int size; + private final int width; + private final int height; + private final ScreenHandlerType type; + private final GuiElementInterface[] elements; + private final Slot[] slotRedirects; + private final boolean includePlayer; + private final int sizeCont; + private boolean lockPlayerInventory = false; + private boolean hasRedirects = false; + private Text title = null; + private Consumer onTick = gui -> {}; + private Consumer onClose = gui -> {}; + private Consumer onOpen = gui -> {}; + private Consumer onClick = gui -> {}; + + /** + * Constructs a new simple container gui for the supplied player. + * + * @param type the screen handler that the client should display + * @param manipulatePlayerSlots if true the players inventory + * will be treated as slots of this gui + */ + public CBSimpleGuiBuilder(ScreenHandlerType type, boolean manipulatePlayerSlots) { + this.height = GuiHelpers.getHeight(type); + this.width = GuiHelpers.getWidth(type); + + this.type = type; + + int tmp = manipulatePlayerSlots ? 36 : 0; + this.size = this.width * this.height + tmp; + this.sizeCont = this.width * this.height; + this.elements = new GuiElementInterface[this.size]; + this.slotRedirects = new Slot[this.size]; + + this.includePlayer = manipulatePlayerSlots; + } + + /** + * Creates {@link SimpleGui} instance based on this builder. + * + * @param player Player + * @return SimpleGui instance + */ + public SimpleGui build(ServerPlayerEntity player) { + SimpleGui gui = new SimpleGui(this.type, player, this.includePlayer) { + @Override + public void onTick() { + onTick.accept(this); + super.onTick(); + } + + @Override + public void onClose() { + onClose.accept(this); + super.onClose(); + } + + @Override + public void onOpen() { + onOpen.accept(this); + super.onOpen(); + } + + @Override + public boolean onClick(int index, ClickType type, SlotActionType action, GuiElementInterface element) { + onClick.accept(this); + return super.onClick(index, type, action, element); + } + }; + gui.setTitle(this.title); + gui.setLockPlayerInventory(true); + + int pos = 0; + + for (GuiElementInterface element : this.elements) { + if (element != null) { + gui.setSlot(pos, element); + } + pos++; + } + + pos = 0; + + for (Slot slot : this.slotRedirects) { + if (slot != null) { + gui.setSlotRedirect(pos, slot); + } + pos++; + } + + return gui; + } + + public Consumer getOnTick() { + return onTick; + } + + public void setOnTick(Consumer onTick) { + this.onTick = onTick; + } + + public Consumer getOnClose() { + return onClose; + } + + public void setOnClose(Consumer onClose) { + this.onClose = onClose; + } + + public Consumer getOnOpen() { + return onOpen; + } + + public void setOnOpen(Consumer onOpen) { + this.onOpen = onOpen; + } + + public Consumer getOnClick() { + return onClick; + } + + public void setOnClick(Consumer onClick) { + this.onClick = onClick; + } + + public int getHeight() { + return this.height; + } + + public int getWidth() { + return this.width; + } + + public void setSlot(int index, GuiElementInterface element) { + this.elements[index] = element; + } + + public void addSlot(GuiElementInterface element) { + this.setSlot(this.getFirstEmptySlot(), element); + } + + public void setSlot(int index, ItemStack itemStack) { + this.setSlot(index, new GuiElement(itemStack, GuiElementInterface.EMPTY_CALLBACK)); + } + + public void addSlot(ItemStack itemStack) { + this.setSlot(this.getFirstEmptySlot(), itemStack); + } + + public void setSlot(int index, @NotNull GuiElementBuilderInterface element) { + this.setSlot(index, element.build()); + } + + public void addSlot(@NotNull GuiElementBuilderInterface element) { + this.setSlot(this.getFirstEmptySlot(), element.build()); + } + + public void setSlot(int index, ItemStack itemStack, GuiElement.ClickCallback callback) { + this.setSlot(index, new GuiElement(itemStack, callback)); + } + + public void setSlot(int index, ItemStack itemStack, GuiElementInterface.ItemClickCallback callback) { + this.setSlot(index, new GuiElement(itemStack, callback)); + } + + public void addSlot(ItemStack itemStack, GuiElement.ClickCallback callback) { + this.setSlot(this.getFirstEmptySlot(), new GuiElement(itemStack, callback)); + } + + public void addSlot(ItemStack itemStack, GuiElementInterface.ItemClickCallback callback) { + this.setSlot(this.getFirstEmptySlot(), new GuiElement(itemStack, callback)); + } + + public void setSlotRedirect(int index, Slot slot) { + this.elements[index] = null; + this.slotRedirects[index] = slot; + this.hasRedirects = true; + } + + public void addSlotRedirect(Slot slot) { + this.setSlotRedirect(this.getFirstEmptySlot(), slot); + } + + public int getFirstEmptySlot() { + for (int i = 0; i < this.elements.length; i++) { + if (this.elements[i] == null && this.slotRedirects[i] == null) { + return i; + } + } + return -1; + } + + public void clearSlot(int index) { + this.elements[index] = null; + this.slotRedirects[index] = null; + } + + public boolean isIncludingPlayer() { + return this.includePlayer; + } + + public int getVirtualSize() { + return this.sizeCont; + } + + public GuiElementInterface getSlot(int index) { + if (index >= 0 && index < this.size) { + return this.elements[index]; + } + return null; + } + + public Slot getSlotRedirect(int index) { + if (index >= 0 && index < this.size) { + return this.slotRedirects[index]; + } + return null; + } + + public boolean isRedirectingSlots() { + return this.hasRedirects; + } + + public Text getTitle() { + return this.title; + } + + public void setTitle(Text title) { + this.title = title; + } + + public ScreenHandlerType getType() { + return this.type; + } + + @Override + public int getSize() { + return this.size; + } + + public boolean getLockPlayerInventory() { + return this.lockPlayerInventory || this.includePlayer; + } + + public void setLockPlayerInventory(boolean value) { + this.lockPlayerInventory = value; + } +} diff --git a/src/main/java/skylands/logic/Hub.java b/src/main/java/com/awakenedredstone/neoskies/logic/Hub.java similarity index 66% rename from src/main/java/skylands/logic/Hub.java rename to src/main/java/com/awakenedredstone/neoskies/logic/Hub.java index 2965837..8bff5a0 100644 --- a/src/main/java/skylands/logic/Hub.java +++ b/src/main/java/com/awakenedredstone/neoskies/logic/Hub.java @@ -1,37 +1,44 @@ -package skylands.logic; +package com.awakenedredstone.neoskies.logic; +import com.awakenedredstone.neoskies.api.events.IslandEvents; +import com.awakenedredstone.neoskies.util.Texts; import net.fabricmc.fabric.api.dimension.v1.FabricDimensions; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.nbt.NbtCompound; -import net.minecraft.server.MinecraftServer; -import net.minecraft.util.math.BlockPos; +import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.util.math.Vec3d; import net.minecraft.world.TeleportTarget; -import nota.player.PositionSongPlayer; -import skylands.SkylandsMain; -import skylands.api.events.IslandEvents; -import skylands.data.reloadable.SongsData; -import skylands.util.Texts; public class Hub { public Vec3d pos = new Vec3d(0, 80, 0); public boolean hasProtection = false; - public PositionSongPlayer songPlayer = null; + //public PositionSongPlayer songPlayer = null; public void visit(PlayerEntity player) { + visit(player, false); + } + + public void visit(PlayerEntity player, boolean silent) { var world = Skylands.getServer().getOverworld(); - player.sendMessage(Texts.prefixed("message.skylands.hub_visit")); - FabricDimensions.teleport(player, world, new TeleportTarget(Skylands.getInstance().hub.pos, new Vec3d(0, 0, 0), 0, 0)); + if (!silent) player.sendMessage(Texts.prefixed("message.neoskies.hub_visit")); + FabricDimensions.teleport(player, world, new TeleportTarget(this.pos, new Vec3d(0, 0, 0), 0, 0)); IslandEvents.ON_HUB_VISIT.invoker().invoke(player, world); } - public void initSongPlayer(MinecraftServer server) { + public void positionInto(ServerPlayerEntity player) { + player.setPosition(this.pos); + player.setVelocity(0, 0, 0); + player.setYaw(0); + player.setPitch(0); + } + + /*public void initSongPlayer(MinecraftServer server) { PositionSongPlayer sp = new PositionSongPlayer(SongsData.INSTANCE.playlist, server.getOverworld()); sp.setDistance(256); sp.setId(SkylandsMain.id("hub_song_player")); sp.setBlockPos(BlockPos.ofFloored(pos)); this.songPlayer = sp; - } + }*/ public void readFromNbt(NbtCompound nbt) { NbtCompound hubNbt = nbt.getCompound("hub"); diff --git a/src/main/java/skylands/logic/Invites.java b/src/main/java/com/awakenedredstone/neoskies/logic/Invites.java similarity index 83% rename from src/main/java/skylands/logic/Invites.java rename to src/main/java/com/awakenedredstone/neoskies/logic/Invites.java index 66db0aa..640738a 100644 --- a/src/main/java/skylands/logic/Invites.java +++ b/src/main/java/com/awakenedredstone/neoskies/logic/Invites.java @@ -1,15 +1,15 @@ -package skylands.logic; +package com.awakenedredstone.neoskies.logic; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.server.MinecraftServer; -import skylands.util.Texts; +import com.awakenedredstone.neoskies.util.Texts; import java.util.ArrayList; import java.util.Optional; import java.util.UUID; public class Invites { - public ArrayList invites = new ArrayList<>(); + public final ArrayList invites = new ArrayList<>(); public void tick(MinecraftServer server) { invites.forEach(Invite::tick); @@ -35,8 +35,8 @@ public boolean hasInvite(Island island, PlayerEntity player) { } public static class Invite { - public UUID uuid; - public Island island; + public final UUID uuid; + public final Island island; public boolean accepted = false; public int ticks = (60 * 20) * 5; @@ -57,7 +57,7 @@ public void accept(PlayerEntity player) { this.accepted = true; island.members.add(new Member(player)); } else { - player.sendMessage(Texts.prefixed("message.skylands.accept.no_island")); + player.sendMessage(Texts.prefixed("message.neoskies.accept.no_island")); } } } diff --git a/src/main/java/skylands/logic/Island.java b/src/main/java/com/awakenedredstone/neoskies/logic/Island.java similarity index 80% rename from src/main/java/skylands/logic/Island.java rename to src/main/java/com/awakenedredstone/neoskies/logic/Island.java index 9bf2886..d9a512d 100644 --- a/src/main/java/skylands/logic/Island.java +++ b/src/main/java/com/awakenedredstone/neoskies/logic/Island.java @@ -1,12 +1,9 @@ -package skylands.logic; +package com.awakenedredstone.neoskies.logic; import eu.pb4.common.economy.api.EconomyAccount; -import lombok.Getter; -import lombok.Setter; import net.minecraft.block.Block; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.nbt.NbtCompound; -import net.minecraft.registry.Registries; import net.minecraft.registry.RegistryKeys; import net.minecraft.server.MinecraftServer; import net.minecraft.server.world.ServerWorld; @@ -23,15 +20,16 @@ import net.minecraft.world.dimension.DimensionTypes; import net.minecraft.world.gen.chunk.FlatChunkGenerator; import net.minecraft.world.gen.chunk.FlatChunkGeneratorConfig; -import skylands.SkylandsMain; -import skylands.api.events.IslandEvents; -import skylands.api.island.IslandSettings; -import skylands.api.island.PermissionLevel; -import skylands.api.island.SettingsManager; -import skylands.logic.economy.SkylandsEconomyAccount; -import skylands.util.Constants; -import skylands.util.Players; -import skylands.util.Texts; +import org.jetbrains.annotations.Nullable; +import com.awakenedredstone.neoskies.SkylandsMain; +import com.awakenedredstone.neoskies.api.events.IslandEvents; +import com.awakenedredstone.neoskies.api.island.IslandSettings; +import com.awakenedredstone.neoskies.api.island.PermissionLevel; +import com.awakenedredstone.neoskies.api.island.SettingsManager; +import com.awakenedredstone.neoskies.logic.economy.SkylandsEconomyAccount; +import com.awakenedredstone.neoskies.util.Constants; +import com.awakenedredstone.neoskies.util.Players; +import com.awakenedredstone.neoskies.util.Texts; import xyz.nucleoid.fantasy.Fantasy; import xyz.nucleoid.fantasy.RuntimeWorldConfig; import xyz.nucleoid.fantasy.RuntimeWorldHandle; @@ -39,34 +37,34 @@ import java.time.Instant; import java.util.*; -//TODO: Advanced island settings //TODO: Island levels +//TODO: Advanced island settings public class Island { - private final MinecraftServer server = skylands.logic.Skylands.getServer(); - private final Fantasy fantasy = skylands.logic.Skylands.getInstance().fantasy; - private final Map settings = new HashMap<>(); + protected final Fantasy fantasy = Skylands.getInstance().fantasy; + protected final Map settings = new HashMap<>(); public final Member owner; - @Getter private UUID islandId = UUID.randomUUID(); - private RuntimeWorldConfig islandConfig = null; - private RuntimeWorldConfig netherConfig = null; - private RuntimeWorldConfig endConfig = null; - public ArrayList members = new ArrayList<>(); - public ArrayList bans = new ArrayList<>(); - public int radius = SkylandsMain.MAIN_CONFIG.defaultIslandRadius(); + private UUID islandId = UUID.randomUUID(); + protected RuntimeWorldConfig islandConfig = null; + protected RuntimeWorldConfig netherConfig = null; + protected RuntimeWorldConfig endConfig = null; + public final List members = new ArrayList<>(); + public final List bans = new ArrayList<>(); + public int radius = Skylands.getConfig().defaultIslandRadius; private EconomyAccount wallet; boolean freshCreated = false; public boolean locked = false; - public Vec3d spawnPos = SkylandsMain.MAIN_CONFIG.defaultIslandLocation(); - public Vec3d visitsPos = SkylandsMain.MAIN_CONFIG.defaultIslandLocation(); - public LinkedHashMap blocks = new LinkedHashMap<>(); + public Vec3d spawnPos = Skylands.getConfig().defaultIslandLocation; + public Vec3d visitsPos = Skylands.getConfig().defaultIslandLocation; + //TODO: not store hundreds of blocks in memory + protected Map blocks = new LinkedHashMap<>(); + private long points = 0; public boolean hasNether = false; public boolean hasEnd = false; - @Getter @Setter private boolean scanning = false; - public Instant created = Instant.now(); + private Instant created = Instant.now(); public Island(UUID uuid, String name) { this(new Member(uuid, name)); @@ -134,15 +132,17 @@ public static Island fromNbt(NbtCompound nbt) { } }); + island.points = nbt.getLong("points"); NbtCompound blocksNbt = nbt.getCompound("blocks"); blocksNbt.getKeys().forEach(key -> { - Block block = Registries.BLOCK.get(new Identifier(key)); int amount = blocksNbt.getInt(key); - island.blocks.put(block, amount); + island.blocks.put(new Identifier(key), amount); }); SettingsManager.update(island.settings); + //TODO: Load gamerules into island + return island; } @@ -201,15 +201,40 @@ public NbtCompound toNbt() { }); nbt.put("settings", settingsNbt); + nbt.putLong("points", this.points); NbtCompound blocksNbt = new NbtCompound(); - this.blocks.forEach((block, amount) -> { - blocksNbt.putInt(Registries.BLOCK.getId(block).toString(), amount); - }); + this.blocks.forEach((block, amount) -> blocksNbt.putInt(block.toString(), amount)); nbt.put("blocks", blocksNbt); + nbt.put("game_rules", getOverworld().getGameRules().toNbt()); + return nbt; } + public UUID getIslandId() { + return islandId; + } + + public Map getBlocks() { + return blocks; + } + + public long getPoints() { + return points; + } + + public boolean isScanning() { + return scanning; + } + + public Instant getCreated() { + return created; + } + + public void setScanning(boolean scanning) { + this.scanning = scanning; + } + public boolean isMember(PlayerEntity player) { if (this.owner.uuid.equals(player.getUuid())) { return true; @@ -246,7 +271,7 @@ public boolean isBanned(String player) { @SuppressWarnings("BooleanMethodIsAlwaysInverted") public boolean isWithinBorder(BlockPos pos) { - if (radius < 0) return true; + if (radius <= 0) return true; int minY = getOverworld().getBottomY(); return new Box(new BlockPos(0, 0, 0)).expand(radius).withMinY(minY - 1).withMaxY(getOverworld().getTopY() + 1).contains(new Vec3d(pos.getX(), pos.getY(), pos.getZ())); } @@ -263,7 +288,7 @@ public boolean isInteractionAllowed(Identifier identifier, PermissionLevel sourc return source.getLevel() >= getSettings(identifier).permissionLevel.getLevel(); } - public RuntimeWorldHandle getHandler() { + public RuntimeWorldHandle getOverworldHandler() { if (this.islandConfig == null) { this.islandConfig = createIslandConfig(); } @@ -271,7 +296,7 @@ public RuntimeWorldHandle getHandler() { } private RuntimeWorldConfig createIslandConfig() { - var biome = this.server.getRegistryManager().get(RegistryKeys.BIOME).getEntry(this.server.getRegistryManager().get(RegistryKeys.BIOME).getOrThrow(BiomeKeys.PLAINS)); + var biome = Skylands.getServer().getRegistryManager().get(RegistryKeys.BIOME).getEntry(Skylands.getServer().getRegistryManager().get(RegistryKeys.BIOME).getOrThrow(BiomeKeys.PLAINS)); FlatChunkGeneratorConfig flat = new FlatChunkGeneratorConfig(Optional.empty(), biome, List.of()); FlatChunkGenerator generator = new FlatChunkGenerator(flat); @@ -291,7 +316,7 @@ public RuntimeWorldHandle getNetherHandler() { } private RuntimeWorldConfig createNetherConfig() { - var biome = this.server.getRegistryManager().get(RegistryKeys.BIOME).getEntry(this.server.getRegistryManager().get(RegistryKeys.BIOME).getOrThrow(BiomeKeys.NETHER_WASTES)); + var biome = Skylands.getServer().getRegistryManager().get(RegistryKeys.BIOME).getEntry(Skylands.getServer().getRegistryManager().get(RegistryKeys.BIOME).getOrThrow(BiomeKeys.NETHER_WASTES)); FlatChunkGeneratorConfig flat = new FlatChunkGeneratorConfig(Optional.empty(), biome, List.of()); FlatChunkGenerator generator = new FlatChunkGenerator(flat); @@ -311,7 +336,7 @@ public RuntimeWorldHandle getEndHandler() { } private RuntimeWorldConfig createEndConfig() { - var biome = this.server.getRegistryManager().get(RegistryKeys.BIOME).getEntry(this.server.getRegistryManager().get(RegistryKeys.BIOME).getOrThrow(BiomeKeys.THE_END)); + var biome = Skylands.getServer().getRegistryManager().get(RegistryKeys.BIOME).getEntry(Skylands.getServer().getRegistryManager().get(RegistryKeys.BIOME).getOrThrow(BiomeKeys.THE_END)); FlatChunkGeneratorConfig flat = new FlatChunkGeneratorConfig(Optional.empty(), biome, List.of()); FlatChunkGenerator generator = new FlatChunkGenerator(flat); @@ -324,12 +349,11 @@ private RuntimeWorldConfig createEndConfig() { } public ServerWorld getOverworld() { - RuntimeWorldHandle handler = this.getHandler(); + RuntimeWorldHandle handler = this.getOverworldHandler(); handler.setTickWhenEmpty(false); return handler.asWorld(); } - //TODO: End island public ServerWorld getEnd() { RuntimeWorldHandle handler = this.getEndHandler(); handler.setTickWhenEmpty(false); @@ -346,6 +370,15 @@ public ServerWorld getNether() { return world; } + public void updateBlocks(@Nullable LinkedHashMap blocks) { + if (blocks != null) this.blocks = blocks; + this.points = 0; + this.blocks.forEach((block, integer) -> { + Integer points = Skylands.getConfig().blockPoints.getOrDefault(block, 1); + this.points += (long) integer * points; + }); + } + public void visit(PlayerEntity player, Vec3d pos) { ServerWorld world = this.getOverworld(); player.teleport(world, pos.getX(), pos.getY(), pos.getZ(), Set.of(), 0, 0); @@ -353,7 +386,7 @@ public void visit(PlayerEntity player, Vec3d pos) { if(!isMember(player)) { Players.get(this.owner.name).ifPresent(owner -> { if(!player.getUuid().equals(owner.getUuid())) { - owner.sendMessage(Texts.prefixed("message.skylands.island_visit.visit", map -> map.put("visitor", player.getName().getString()))); + owner.sendMessage(Texts.prefixed("message.neoskies.island_visit.visit", map -> map.put("visitor", player.getName().getString()))); } }); } @@ -376,7 +409,7 @@ public void visitAsVisitor(PlayerEntity player) { public void onFirstLoad(PlayerEntity player) { ServerWorld world = this.getOverworld(); - StructureTemplate structure = server.getStructureTemplateManager().getTemplateOrBlank(SkylandsMain.id("start_island")); + StructureTemplate structure = Skylands.getServer().getStructureTemplateManager().getTemplateOrBlank(SkylandsMain.id("start_island")); StructurePlacementData data = new StructurePlacementData().setMirror(BlockMirror.NONE).setIgnoreEntities(true); structure.place(world, new BlockPos(-7, 65, -7), new BlockPos(0, 0, 0), data, world.getRandom(), Block.NOTIFY_ALL); IslandEvents.ON_ISLAND_FIRST_LOAD.invoker().invoke(player, world, this); diff --git a/src/main/java/skylands/logic/IslandStuck.java b/src/main/java/com/awakenedredstone/neoskies/logic/IslandStuck.java similarity index 52% rename from src/main/java/skylands/logic/IslandStuck.java rename to src/main/java/com/awakenedredstone/neoskies/logic/IslandStuck.java index 3f68d41..52d494f 100644 --- a/src/main/java/skylands/logic/IslandStuck.java +++ b/src/main/java/com/awakenedredstone/neoskies/logic/IslandStuck.java @@ -1,14 +1,19 @@ -package skylands.logic; +package com.awakenedredstone.neoskies.logic; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.nbt.NbtCompound; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.PlayerManager; +import net.minecraft.server.network.ServerPlayerEntity; +import com.awakenedredstone.neoskies.duck.ExtendedPlayerManager; +import java.nio.file.Path; import java.util.ArrayList; import java.util.Optional; import java.util.UUID; public class IslandStuck { - public ArrayList stuck = new ArrayList<>(); + public final ArrayList stuck = new ArrayList<>(); public Island create(PlayerEntity player) { for (var island : this.stuck) { @@ -20,22 +25,57 @@ public Island create(PlayerEntity player) { return island; } - public void delete(PlayerEntity player) { - this.getByPlayer(player).ifPresent(island -> { - island.getNetherHandler().delete(); - island.getEndHandler().delete(); - island.getHandler().delete(); + public void delete(Island island) { + MinecraftServer server = Skylands.getServer(); + + island.getOverworldHandler().delete(); + island.getNetherHandler().delete(); + island.getEndHandler().delete(); + + PlayerManager playerManager = server.getPlayerManager(); + + island.members.forEach(member -> { + ServerPlayerEntity player = playerManager.getPlayer(member.uuid); + if (player != null) { + player.closeHandledScreen(); + } }); - stuck.removeIf(island -> island.owner.uuid.equals(player.getUuid())); + + if (Skylands.getConfig().resetPlayerWithIsland) { + Member owner = island.owner; + deletePlayer(owner); + + island.members.forEach(this::deletePlayer); + } + + island.getOverworld().getPlayers().forEach(player -> Skylands.syncWithTick(() -> Skylands.getInstance().hub.visit(player, true))); + island.getNether().getPlayers().forEach(player -> Skylands.syncWithTick(() -> Skylands.getInstance().hub.visit(player, true))); + island.getEnd().getPlayers().forEach(player -> Skylands.syncWithTick(() -> Skylands.getInstance().hub.visit(player, true))); + + stuck.remove(island); + } + + private void deletePlayer(Member member) { + MinecraftServer server = Skylands.getServer(); + PlayerManager playerManager = server.getPlayerManager(); + Path playerDataDir = server.saveHandler.playerDataDir.toPath(); + + playerDataDir.resolve(member.uuid.toString() + ".dat").toFile().delete(); + ServerPlayerEntity player = playerManager.getPlayer(member.uuid); + if (player != null) { + ServerPlayerEntity newPlayer = ((ExtendedPlayerManager) playerManager).resetPlayer(player); + player.networkHandler.player = newPlayer; + server.saveHandler.savePlayerData(newPlayer); + Skylands.getInstance().hub.visit(newPlayer, true); + } + } + + public void delete(PlayerEntity player) { + this.getByPlayer(player).ifPresent(this::delete); } public void delete(String playerName) { - this.getByPlayer(playerName).ifPresent(island -> { - island.getNetherHandler().delete(); - island.getEndHandler().delete(); - island.getHandler().delete(); - }); - stuck.removeIf(island -> island.owner.name.equals(playerName)); + this.getByPlayer(playerName).ifPresent(this::delete); } public Optional getByPlayer(PlayerEntity player) { @@ -81,6 +121,11 @@ public boolean hasIsland(UUID uuid) { return false; } + /* + TODO: + Store island data on the island world (cardinal) component, + only keeping required data on the main world (cardinal) component + */ public void readFromNbt(NbtCompound nbt) { NbtCompound islandStuckNbt = nbt.getCompound("islandStuck"); int size = islandStuckNbt.getInt("size"); @@ -93,6 +138,11 @@ public void readFromNbt(NbtCompound nbt) { } } + /* + TODO: + Store island data on the island world (cardinal) component, + only keeping required data on the main world (cardinal) component + */ public void writeToNbt(NbtCompound nbt) { NbtCompound islandStuckNbt = new NbtCompound(); islandStuckNbt.putInt("size", this.stuck.size()); diff --git a/src/main/java/skylands/logic/Member.java b/src/main/java/com/awakenedredstone/neoskies/logic/Member.java similarity index 90% rename from src/main/java/skylands/logic/Member.java rename to src/main/java/com/awakenedredstone/neoskies/logic/Member.java index c0bcade..03e45ba 100644 --- a/src/main/java/skylands/logic/Member.java +++ b/src/main/java/com/awakenedredstone/neoskies/logic/Member.java @@ -1,4 +1,4 @@ -package skylands.logic; +package com.awakenedredstone.neoskies.logic; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.nbt.NbtCompound; @@ -7,7 +7,7 @@ public class Member { public String name; - public UUID uuid; + public final UUID uuid; public Member(UUID uuid, String name) { this.uuid = uuid; diff --git a/src/main/java/skylands/logic/Skylands.java b/src/main/java/com/awakenedredstone/neoskies/logic/Skylands.java similarity index 59% rename from src/main/java/skylands/logic/Skylands.java rename to src/main/java/com/awakenedredstone/neoskies/logic/Skylands.java index 3287f62..d92ced5 100644 --- a/src/main/java/skylands/logic/Skylands.java +++ b/src/main/java/com/awakenedredstone/neoskies/logic/Skylands.java @@ -1,19 +1,21 @@ -package skylands.logic; +package com.awakenedredstone.neoskies.logic; -import lombok.Getter; +import com.awakenedredstone.neoskies.config.IslandRanking; +import com.awakenedredstone.neoskies.config.MainConfig; +import eu.pb4.common.protection.api.CommonProtection; import net.minecraft.nbt.NbtCompound; import net.minecraft.resource.ResourceManager; import net.minecraft.server.MinecraftServer; -import skylands.logic.economy.Economy; -import skylands.util.NbtMigrator; -import skylands.util.PreInitData; -import skylands.util.Scheduler; +import com.awakenedredstone.neoskies.SkylandsMain; +import com.awakenedredstone.neoskies.logic.economy.Economy; +import com.awakenedredstone.neoskies.logic.protection.SkylandsProtectionProvider; +import com.awakenedredstone.neoskies.util.NbtMigrator; +import com.awakenedredstone.neoskies.util.PreInitData; +import com.awakenedredstone.neoskies.util.Scheduler; import xyz.nucleoid.fantasy.Fantasy; public class Skylands { - @Getter private int format = 1; - @Getter private static Skylands instance; private final MinecraftServer server; public final Fantasy fantasy; @@ -22,6 +24,9 @@ public class Skylands { public final Invites invites; public final Economy economy; public final Scheduler scheduler; + private final SkylandsProtectionProvider protectionProvider; + private static final MainConfig CONFIG = new MainConfig(); + private static final IslandRanking RANKING_CONFIG = new IslandRanking(); public Skylands(MinecraftServer server) { this.scheduler = new Scheduler(); @@ -31,10 +36,20 @@ public Skylands(MinecraftServer server) { this.hub = new Hub(); this.invites = new Invites(); this.economy = new Economy(); + this. protectionProvider = new SkylandsProtectionProvider(); + CommonProtection.register(SkylandsMain.id("neoskies"), protectionProvider); + } + + public static Skylands getInstance() { + return instance; + } + + public int getFormat() { + return format; } public void readFromNbt(NbtCompound nbt) { - NbtCompound skylandsNbt = nbt.getCompound("skylands"); + NbtCompound skylandsNbt = nbt.getCompound("neoskies"); if (skylandsNbt.isEmpty()) return; NbtMigrator.update(skylandsNbt); @@ -51,7 +66,7 @@ public void writeToNbt(NbtCompound nbt) { this.islands.writeToNbt(skylandsNbt); this.hub.writeToNbt(skylandsNbt); - nbt.put("skylands", skylandsNbt); + nbt.put("neoskies", skylandsNbt); } //Lock the instance so noone can possibly change it @@ -68,6 +83,7 @@ public void onTick(MinecraftServer server) { public void close() { Skylands.instance = null; this.scheduler.close(); + CommonProtection.remove(SkylandsMain.id("neoskies")); } public static MinecraftServer getServer() { @@ -82,4 +98,15 @@ public static ResourceManager getResourceManager() { return instance == null ? PreInitData.getInstance().getResourceManager() : Skylands.getServer().getResourceManager(); } + public static MainConfig getConfig() { + return CONFIG; + } + + public static IslandRanking getRankingConfig() { + return RANKING_CONFIG; + } + + public static void syncWithTick(Runnable runnable) { + Skylands.getScheduler().schedule(0, runnable); + } } diff --git a/src/main/java/skylands/logic/SkylandsRegistries.java b/src/main/java/com/awakenedredstone/neoskies/logic/SkylandsRegistries.java similarity index 76% rename from src/main/java/skylands/logic/SkylandsRegistries.java rename to src/main/java/com/awakenedredstone/neoskies/logic/SkylandsRegistries.java index ea65ac1..be07daf 100644 --- a/src/main/java/skylands/logic/SkylandsRegistries.java +++ b/src/main/java/com/awakenedredstone/neoskies/logic/SkylandsRegistries.java @@ -1,12 +1,12 @@ -package skylands.logic; +package com.awakenedredstone.neoskies.logic; import net.fabricmc.fabric.api.event.registry.FabricRegistryBuilder; import net.minecraft.registry.RegistryKey; import net.minecraft.registry.SimpleRegistry; import net.minecraft.util.Identifier; -import skylands.SkylandsMain; -import skylands.api.island.PermissionLevel; -import skylands.logic.settings.IslandSettings; +import com.awakenedredstone.neoskies.SkylandsMain; +import com.awakenedredstone.neoskies.api.island.PermissionLevel; +import com.awakenedredstone.neoskies.logic.settings.IslandSettings; public class SkylandsRegistries { public static final SimpleRegistry ISLAND_SETTINGS = createRegistry(SkylandsMain.id("island_settings")); diff --git a/src/main/java/skylands/logic/economy/Economy.java b/src/main/java/com/awakenedredstone/neoskies/logic/economy/Economy.java similarity index 81% rename from src/main/java/skylands/logic/economy/Economy.java rename to src/main/java/com/awakenedredstone/neoskies/logic/economy/Economy.java index 40ff6b8..7a66c56 100644 --- a/src/main/java/skylands/logic/economy/Economy.java +++ b/src/main/java/com/awakenedredstone/neoskies/logic/economy/Economy.java @@ -1,9 +1,9 @@ -package skylands.logic.economy; +package com.awakenedredstone.neoskies.logic.economy; import eu.pb4.common.economy.api.CommonEconomy; import eu.pb4.common.economy.api.EconomyCurrency; import net.minecraft.util.Identifier; -import skylands.SkylandsMain; +import com.awakenedredstone.neoskies.SkylandsMain; public class Economy { public Economy() { diff --git a/src/main/java/skylands/logic/economy/SkylandsEconomyAccount.java b/src/main/java/com/awakenedredstone/neoskies/logic/economy/SkylandsEconomyAccount.java similarity index 88% rename from src/main/java/skylands/logic/economy/SkylandsEconomyAccount.java rename to src/main/java/com/awakenedredstone/neoskies/logic/economy/SkylandsEconomyAccount.java index bab4f73..fdbf8c5 100644 --- a/src/main/java/skylands/logic/economy/SkylandsEconomyAccount.java +++ b/src/main/java/com/awakenedredstone/neoskies/logic/economy/SkylandsEconomyAccount.java @@ -1,4 +1,4 @@ -package skylands.logic.economy; +package com.awakenedredstone.neoskies.logic.economy; import eu.pb4.common.economy.api.EconomyAccount; import eu.pb4.common.economy.api.EconomyCurrency; @@ -6,7 +6,7 @@ import eu.pb4.common.economy.api.EconomyTransaction; import net.minecraft.text.Text; import net.minecraft.util.Identifier; -import skylands.logic.Skylands; +import com.awakenedredstone.neoskies.logic.Skylands; import java.math.BigInteger; import java.util.UUID; @@ -28,7 +28,7 @@ public SkylandsEconomyAccount(UUID islandUuid, Identifier id, long balance) { @Override public Text name() { - return Text.translatable("skylands.economy.name"); + return Text.translatable("neoskies.economy.name"); } @Override @@ -73,10 +73,10 @@ public EconomyCurrency currency() { } private EconomyTransaction failure(long transactionAmount) { - return new EconomyTransaction.Simple(false, Text.translatable("skylands.economy.transaction.fail"), balance(), balance(), transactionAmount, this); + return new EconomyTransaction.Simple(false, Text.translatable("neoskies.economy.transaction.fail"), balance(), balance(), transactionAmount, this); } private EconomyTransaction success(long transactionAmount) { - return new EconomyTransaction.Simple(true, Text.translatable("skylands.economy.transaction.success"), balance() - transactionAmount, balance(), transactionAmount, this); + return new EconomyTransaction.Simple(true, Text.translatable("neoskies.economy.transaction.success"), balance() - transactionAmount, balance(), transactionAmount, this); } } diff --git a/src/main/java/skylands/logic/economy/SkylandsEconomyCurrency.java b/src/main/java/com/awakenedredstone/neoskies/logic/economy/SkylandsEconomyCurrency.java similarity index 80% rename from src/main/java/skylands/logic/economy/SkylandsEconomyCurrency.java rename to src/main/java/com/awakenedredstone/neoskies/logic/economy/SkylandsEconomyCurrency.java index 81abebf..be4ecb3 100644 --- a/src/main/java/skylands/logic/economy/SkylandsEconomyCurrency.java +++ b/src/main/java/com/awakenedredstone/neoskies/logic/economy/SkylandsEconomyCurrency.java @@ -1,10 +1,10 @@ -package skylands.logic.economy; +package com.awakenedredstone.neoskies.logic.economy; import eu.pb4.common.economy.api.EconomyCurrency; import eu.pb4.common.economy.api.EconomyProvider; import net.minecraft.text.Text; import net.minecraft.util.Identifier; -import skylands.logic.Skylands; +import com.awakenedredstone.neoskies.logic.Skylands; @SuppressWarnings("ClassCanBeRecord") public class SkylandsEconomyCurrency implements EconomyCurrency { @@ -16,7 +16,7 @@ public SkylandsEconomyCurrency(Identifier id) { @Override public Text name() { - return Text.translatable("skylands.economy.name"); + return Text.translatable("neoskies.economy.name"); } @Override @@ -31,7 +31,7 @@ public String formatValue(long value, boolean precise) { @Override public long parseValue(String value) throws NumberFormatException { - String parse = value.replace("$", ""); + String parse = value.replaceFirst("^\\$", ""); return Long.parseLong(parse); } diff --git a/src/main/java/skylands/logic/economy/SkylandsEconomyProvider.java b/src/main/java/com/awakenedredstone/neoskies/logic/economy/SkylandsEconomyProvider.java similarity index 86% rename from src/main/java/skylands/logic/economy/SkylandsEconomyProvider.java rename to src/main/java/com/awakenedredstone/neoskies/logic/economy/SkylandsEconomyProvider.java index 4473d9b..319efcd 100644 --- a/src/main/java/skylands/logic/economy/SkylandsEconomyProvider.java +++ b/src/main/java/com/awakenedredstone/neoskies/logic/economy/SkylandsEconomyProvider.java @@ -1,26 +1,28 @@ -package skylands.logic.economy; +package com.awakenedredstone.neoskies.logic.economy; import com.mojang.authlib.GameProfile; import eu.pb4.common.economy.api.EconomyAccount; import eu.pb4.common.economy.api.EconomyCurrency; import eu.pb4.common.economy.api.EconomyProvider; -import lombok.Getter; import net.minecraft.server.MinecraftServer; import net.minecraft.text.Text; import org.jetbrains.annotations.Nullable; -import skylands.api.SkylandsAPI; -import skylands.logic.Island; -import skylands.logic.Skylands; +import com.awakenedredstone.neoskies.api.SkylandsAPI; +import com.awakenedredstone.neoskies.logic.Island; +import com.awakenedredstone.neoskies.logic.Skylands; import java.util.*; public class SkylandsEconomyProvider implements EconomyProvider { - @Getter private final Map accounts = new HashMap<>(); @Override public Text name() { - return Text.translatable("skylands.economy.name"); + return Text.translatable("neoskies.economy.name"); + } + + public Map getAccounts() { + return accounts; } @Override diff --git a/src/main/java/com/awakenedredstone/neoskies/logic/protection/SkylandsProtectionProvider.java b/src/main/java/com/awakenedredstone/neoskies/logic/protection/SkylandsProtectionProvider.java new file mode 100644 index 0000000..bc9c24d --- /dev/null +++ b/src/main/java/com/awakenedredstone/neoskies/logic/protection/SkylandsProtectionProvider.java @@ -0,0 +1,78 @@ +package com.awakenedredstone.neoskies.logic.protection; + +import com.awakenedredstone.neoskies.logic.registry.NeoSkiesIslandSettings; +import com.awakenedredstone.neoskies.logic.settings.IslandSettings; +import com.mojang.authlib.GameProfile; +import eu.pb4.common.protection.api.ProtectionProvider; +import net.minecraft.block.*; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.mob.Monster; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.registry.tag.TagKey; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Box; +import net.minecraft.world.World; +import com.awakenedredstone.neoskies.api.SkylandsAPI; +import com.awakenedredstone.neoskies.util.WorldProtection; + +import java.util.Map; + +public class SkylandsProtectionProvider implements ProtectionProvider { + @Override + public boolean isProtected(World world, BlockPos pos) { + return SkylandsAPI.isProtectedArea(world); + } + + @Override + public boolean isAreaProtected(World world, Box area) { + return SkylandsAPI.isProtectedArea(world); + } + + @Override + public boolean canBreakBlock(World world, BlockPos pos, GameProfile profile, PlayerEntity player) { + if (player == null) return true; + return WorldProtection.canModify(world, pos, player, NeoSkiesIslandSettings.BREAK_BLOCKS); + } + + @Override + public boolean canPlaceBlock(World world, BlockPos pos, GameProfile profile, PlayerEntity player) { + if (player == null) return true; + return WorldProtection.canModify(world, pos, player, NeoSkiesIslandSettings.PLACE_BLOCKS); + } + + @Override + public boolean canInteractBlock(World world, BlockPos pos, GameProfile profile, PlayerEntity player) { + if (player == null) return true; + BlockState state = world.getBlockState(pos); + IslandSettings settings = NeoSkiesIslandSettings.INTERACT_OTHER_BLOCKS; + + for (Map.Entry, IslandSettings> entry : NeoSkiesIslandSettings.getRuleBlockTags().entrySet()) { + if (state.isIn(entry.getKey())) { + settings = entry.getValue(); + break; + } + } + + return WorldProtection.canModify(world, pos, player, settings); + } + + @Override + public boolean canInteractEntity(World world, Entity entity, GameProfile profile, PlayerEntity player) { + if (player == null) return true; + + for (Map.Entry>, IslandSettings> entry : NeoSkiesIslandSettings.getRuleEntityTags().entrySet()) { + if (entity.getType().isIn(entry.getKey())) { + return WorldProtection.canModify(world, player, entry.getValue()); + } + } + + return WorldProtection.canModify(world, player); + } + + @Override + public boolean canDamageEntity(World world, Entity entity, GameProfile profile, PlayerEntity player) { + if (player == null) return true; + return WorldProtection.canModify(world, player, entity instanceof Monster ? NeoSkiesIslandSettings.HURT_HOSTILE : NeoSkiesIslandSettings.HURT_PASSIVE); + } +} diff --git a/src/main/java/com/awakenedredstone/neoskies/logic/registry/NeoSkiesIslandSettings.java b/src/main/java/com/awakenedredstone/neoskies/logic/registry/NeoSkiesIslandSettings.java new file mode 100644 index 0000000..8cf1e18 --- /dev/null +++ b/src/main/java/com/awakenedredstone/neoskies/logic/registry/NeoSkiesIslandSettings.java @@ -0,0 +1,100 @@ +package com.awakenedredstone.neoskies.logic.registry; + +import com.awakenedredstone.neoskies.SkylandsMain; +import com.awakenedredstone.neoskies.logic.tags.NeoSkiesBlockTags; +import com.awakenedredstone.neoskies.logic.settings.DefaultNeoSkiesIslandSettings; +import com.awakenedredstone.neoskies.logic.tags.NeoSkiesEntityTags; +import net.minecraft.block.Block; +import net.minecraft.entity.EntityType; +import net.minecraft.item.Items; +import net.minecraft.registry.Registry; +import com.awakenedredstone.neoskies.logic.SkylandsRegistries; +import com.awakenedredstone.neoskies.logic.settings.IslandSettings; +import net.minecraft.registry.tag.TagKey; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.HashMap; +import java.util.Map; + +public class NeoSkiesIslandSettings { + protected static final Map, IslandSettings> RULE_BLOCK_TAG = new HashMap<>(); + protected static final Map>, IslandSettings> RULE_ENTITY_TAG = new HashMap<>(); + + public static final IslandSettings PLACE_BLOCKS = new DefaultNeoSkiesIslandSettings("place_blocks", Items.STONE); + public static final IslandSettings BREAK_BLOCKS = new DefaultNeoSkiesIslandSettings("break_blocks", Items.WOODEN_PICKAXE); + + public static final IslandSettings USE_ANVIL = new DefaultNeoSkiesIslandSettings("use_anvil", Items.ANVIL); + public static final IslandSettings USE_BEACON = new DefaultNeoSkiesIslandSettings("use_beacon", Items.BEACON); + public static final IslandSettings USE_BREWING_STAND = new DefaultNeoSkiesIslandSettings("use_brewing_stand", Items.BREWING_STAND); + public static final IslandSettings USE_COMPOSTER = new DefaultNeoSkiesIslandSettings("use_composter", Items.COMPOSTER); + public static final IslandSettings USE_CONTAINERS = new DefaultNeoSkiesIslandSettings("use_containers", Items.CHEST); + public static final IslandSettings USE_DOORS = new DefaultNeoSkiesIslandSettings("use_doors", Items.OAK_DOOR); + public static final IslandSettings USE_LECTERN = new DefaultNeoSkiesIslandSettings("use_lectern", Items.LECTERN); + public static final IslandSettings USE_LODESTONE = new DefaultNeoSkiesIslandSettings("use_lodestone", Items.LODESTONE); + public static final IslandSettings USE_REDSTONE = new DefaultNeoSkiesIslandSettings("use_redstone", Items.REDSTONE); + public static final IslandSettings USE_RESPAWN_ANCHOR = new DefaultNeoSkiesIslandSettings("use_respawn_anchor", Items.RESPAWN_ANCHOR); + public static final IslandSettings INTERACT_DRIPLEAF = new DefaultNeoSkiesIslandSettings("interact_dripleaf", Items.BIG_DRIPLEAF); + public static final IslandSettings INTERACT_SCULK = new DefaultNeoSkiesIslandSettings("interact_sculk", Items.SCULK); + public static final IslandSettings INTERACT_OTHER_BLOCKS = new DefaultNeoSkiesIslandSettings("interact_other_blocks", Items.BELL, true); + + public static final IslandSettings USE_ARMOR_STAND = new DefaultNeoSkiesIslandSettings("use_armor_stand", Items.ARMOR_STAND); + public static final IslandSettings LEASH_ENTITY = new DefaultNeoSkiesIslandSettings("leash_entity", Items.LEAD); + public static final IslandSettings SHEAR_ENTITY = new DefaultNeoSkiesIslandSettings("shear_entity", Items.SHEARS); + public static final IslandSettings HURT_HOSTILE = new DefaultNeoSkiesIslandSettings("hurt_hostile", Items.DIAMOND_SWORD); + public static final IslandSettings HURT_PASSIVE = new DefaultNeoSkiesIslandSettings("hurt_passive", Items.WOODEN_SWORD); + + static { + addBlockTag(NeoSkiesBlockTags.ANVIL, USE_ANVIL); + addBlockTag(NeoSkiesBlockTags.BEACON, USE_BEACON); + addBlockTag(NeoSkiesBlockTags.BREWING_STAND, USE_BREWING_STAND); + addBlockTag(NeoSkiesBlockTags.COMPOSTER, USE_COMPOSTER); + addBlockTag(NeoSkiesBlockTags.CONTAINERS, USE_CONTAINERS); + addBlockTag(NeoSkiesBlockTags.DOORS, USE_DOORS); + addBlockTag(NeoSkiesBlockTags.LECTERN, USE_LECTERN); + addBlockTag(NeoSkiesBlockTags.LODESTONE, USE_LODESTONE); + addBlockTag(NeoSkiesBlockTags.REDSTONE, USE_REDSTONE); + addBlockTag(NeoSkiesBlockTags.RESPAWN_ANCHOR, USE_RESPAWN_ANCHOR); + + addEntityTag(NeoSkiesEntityTags.ARMOR_STAND, USE_ARMOR_STAND); + addEntityTag(NeoSkiesEntityTags.LEASH_KNOT, LEASH_ENTITY); + } + + public static void addBlockTag(TagKey tagKey, IslandSettings settings) { + RULE_BLOCK_TAG.put(tagKey, settings); + } + + public static void addEntityTag(TagKey> tagKey, IslandSettings settings) { + RULE_ENTITY_TAG.put(tagKey, settings); + } + + public static Map, IslandSettings> getRuleBlockTags() { + return RULE_BLOCK_TAG; + } + + public static Map>, IslandSettings> getRuleEntityTags() { + return RULE_ENTITY_TAG; + } + + public static void init() { + Class clazz = NeoSkiesIslandSettings.class; + IslandSettings settings; + for (Field field : clazz.getDeclaredFields()) { + try { + int modifiers = field.getModifiers(); + if (!Modifier.isStatic(modifiers) || !Modifier.isFinal(modifiers) || !Modifier.isPublic(modifiers)) continue; + boolean access = field.canAccess(null); + if (!access) field.setAccessible(true); + + if (field.getType() == IslandSettings.class) { + settings = (IslandSettings) field.get(null); + Registry.register(SkylandsRegistries.ISLAND_SETTINGS, settings.getIdentifier(), settings); + } + + if (!access) field.setAccessible(false); + } catch (IllegalAccessException e) { + SkylandsMain.LOGGER.error("Failed to register island settings", e); + } + } + } +} diff --git a/src/main/java/com/awakenedredstone/neoskies/logic/tags/NeoSkiesBlockTags.java b/src/main/java/com/awakenedredstone/neoskies/logic/tags/NeoSkiesBlockTags.java new file mode 100644 index 0000000..78cfa8e --- /dev/null +++ b/src/main/java/com/awakenedredstone/neoskies/logic/tags/NeoSkiesBlockTags.java @@ -0,0 +1,21 @@ +package com.awakenedredstone.neoskies.logic.tags; + +import com.awakenedredstone.neoskies.SkylandsMain; +import net.minecraft.block.Block; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.registry.tag.TagKey; + +public class NeoSkiesBlockTags { + public static final TagKey ANVIL = TagKey.of(RegistryKeys.BLOCK, SkylandsMain.id("islands/anvil")); + public static final TagKey BEACON = TagKey.of(RegistryKeys.BLOCK, SkylandsMain.id("islands/beacon")); + public static final TagKey BREWING_STAND = TagKey.of(RegistryKeys.BLOCK, SkylandsMain.id("islands/brewing_stand")); + public static final TagKey COMPOSTER = TagKey.of(RegistryKeys.BLOCK, SkylandsMain.id("islands/composter")); + public static final TagKey CONTAINERS = TagKey.of(RegistryKeys.BLOCK, SkylandsMain.id("islands/containers")); + public static final TagKey DOORS = TagKey.of(RegistryKeys.BLOCK, SkylandsMain.id("islands/doors")); + public static final TagKey LECTERN = TagKey.of(RegistryKeys.BLOCK, SkylandsMain.id("islands/lectern")); + public static final TagKey LODESTONE = TagKey.of(RegistryKeys.BLOCK, SkylandsMain.id("islands/lodestone")); + public static final TagKey REDSTONE = TagKey.of(RegistryKeys.BLOCK, SkylandsMain.id("islands/redstone")); + public static final TagKey RESPAWN_ANCHOR = TagKey.of(RegistryKeys.BLOCK, SkylandsMain.id("islands/respawn_anchor")); + //public static final TagKey DRIPLEAF = TagKey.of(RegistryKeys.BLOCK, SkylandsMain.id("islands/dripleaf")); + //public static final TagKey SCULK = TagKey.of(RegistryKeys.BLOCK, SkylandsMain.id("islands/sculk")); +} diff --git a/src/main/java/com/awakenedredstone/neoskies/logic/tags/NeoSkiesEntityTags.java b/src/main/java/com/awakenedredstone/neoskies/logic/tags/NeoSkiesEntityTags.java new file mode 100644 index 0000000..b14d600 --- /dev/null +++ b/src/main/java/com/awakenedredstone/neoskies/logic/tags/NeoSkiesEntityTags.java @@ -0,0 +1,13 @@ +package com.awakenedredstone.neoskies.logic.tags; + +import com.awakenedredstone.neoskies.SkylandsMain; +import net.minecraft.block.Block; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityType; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.registry.tag.TagKey; + +public class NeoSkiesEntityTags { + public static final TagKey> ARMOR_STAND = TagKey.of(RegistryKeys.ENTITY_TYPE, SkylandsMain.id("islands/armor_stand")); + public static final TagKey> LEASH_KNOT = TagKey.of(RegistryKeys.ENTITY_TYPE, SkylandsMain.id("islands/leash_knot")); +} diff --git a/src/main/java/com/awakenedredstone/neoskies/logic/tags/NeoSkiesItemTags.java b/src/main/java/com/awakenedredstone/neoskies/logic/tags/NeoSkiesItemTags.java new file mode 100644 index 0000000..f83610d --- /dev/null +++ b/src/main/java/com/awakenedredstone/neoskies/logic/tags/NeoSkiesItemTags.java @@ -0,0 +1,11 @@ +package com.awakenedredstone.neoskies.logic.tags; + +import com.awakenedredstone.neoskies.SkylandsMain; +import net.minecraft.item.Item; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.registry.tag.TagKey; + +public class NeoSkiesItemTags { + public static final TagKey BLOCK_INTERACTION = TagKey.of(RegistryKeys.ITEM, SkylandsMain.id("islands/block_interaction")); + public static final TagKey GENERAL_INTERACTION = TagKey.of(RegistryKeys.ITEM, SkylandsMain.id("islands/general_interaction")); +} diff --git a/src/main/java/skylands/logic/util/ChunkScanQueue.java b/src/main/java/com/awakenedredstone/neoskies/logic/util/ChunkScanQueue.java similarity index 97% rename from src/main/java/skylands/logic/util/ChunkScanQueue.java rename to src/main/java/com/awakenedredstone/neoskies/logic/util/ChunkScanQueue.java index f87f47b..588d31a 100644 --- a/src/main/java/skylands/logic/util/ChunkScanQueue.java +++ b/src/main/java/com/awakenedredstone/neoskies/logic/util/ChunkScanQueue.java @@ -1,4 +1,4 @@ -package skylands.logic.util; +package com.awakenedredstone.neoskies.logic.util; import net.minecraft.world.chunk.Chunk; diff --git a/src/main/java/skylands/mixin/block/EndPortalBlockMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/block/EndPortalBlockMixin.java similarity index 83% rename from src/main/java/skylands/mixin/block/EndPortalBlockMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/block/EndPortalBlockMixin.java index 8906c6e..71d3714 100644 --- a/src/main/java/skylands/mixin/block/EndPortalBlockMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/block/EndPortalBlockMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.block; +package com.awakenedredstone.neoskies.mixin.block; +import com.awakenedredstone.neoskies.logic.Skylands; import net.minecraft.block.BlockState; import net.minecraft.block.EndPortalBlock; import net.minecraft.entity.Entity; @@ -11,9 +12,9 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; -import skylands.SkylandsMain; -import skylands.api.SkylandsAPI; -import skylands.logic.Island; +import com.awakenedredstone.neoskies.SkylandsMain; +import com.awakenedredstone.neoskies.api.SkylandsAPI; +import com.awakenedredstone.neoskies.logic.Island; import java.util.Optional; @@ -23,7 +24,7 @@ public class EndPortalBlockMixin { @Inject(method = "onEntityCollision", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;moveToWorld(Lnet/minecraft/server/world/ServerWorld;)Lnet/minecraft/entity/Entity;"), locals = LocalCapture.CAPTURE_FAILHARD, cancellable = true) public void resourceKey(BlockState state, World world, BlockPos pos, Entity entity, CallbackInfo ci) { if (SkylandsAPI.isIsland(world)) { - if (!SkylandsMain.MAIN_CONFIG.enableEndIsland()) { + if (!Skylands.getConfig().enableEndIsland) { ci.cancel(); return; } diff --git a/src/main/java/skylands/mixin/block/FireBlockMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/block/FireBlockMixin.java similarity index 88% rename from src/main/java/skylands/mixin/block/FireBlockMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/block/FireBlockMixin.java index b5bf866..269e579 100644 --- a/src/main/java/skylands/mixin/block/FireBlockMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/block/FireBlockMixin.java @@ -1,4 +1,4 @@ -package skylands.mixin.block; +package com.awakenedredstone.neoskies.mixin.block; import net.minecraft.block.AbstractFireBlock; import net.minecraft.world.World; @@ -6,7 +6,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.Constants; +import com.awakenedredstone.neoskies.util.Constants; @Mixin(AbstractFireBlock.class) public class FireBlockMixin { diff --git a/src/main/java/skylands/mixin/block/accessor/WorldBorderAccessor.java b/src/main/java/com/awakenedredstone/neoskies/mixin/block/accessor/WorldBorderAccessor.java similarity index 83% rename from src/main/java/skylands/mixin/block/accessor/WorldBorderAccessor.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/block/accessor/WorldBorderAccessor.java index 7c28573..233d1a9 100644 --- a/src/main/java/skylands/mixin/block/accessor/WorldBorderAccessor.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/block/accessor/WorldBorderAccessor.java @@ -1,4 +1,4 @@ -package skylands.mixin.block.accessor; +package com.awakenedredstone.neoskies.mixin.block.accessor; import net.minecraft.world.border.WorldBorder; import org.spongepowered.asm.mixin.Mixin; diff --git a/src/main/java/skylands/mixin/block/entity/EndGatewayBlockEntityMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/block/entity/EndGatewayBlockEntityMixin.java similarity index 86% rename from src/main/java/skylands/mixin/block/entity/EndGatewayBlockEntityMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/block/entity/EndGatewayBlockEntityMixin.java index 15fbc08..03e5c75 100644 --- a/src/main/java/skylands/mixin/block/entity/EndGatewayBlockEntityMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/block/entity/EndGatewayBlockEntityMixin.java @@ -1,4 +1,4 @@ -package skylands.mixin.block.entity; +package com.awakenedredstone.neoskies.mixin.block.entity; import net.minecraft.block.entity.EndGatewayBlockEntity; import net.minecraft.registry.RegistryKey; @@ -6,7 +6,7 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; -import skylands.util.Worlds; +import com.awakenedredstone.neoskies.util.Worlds; @Mixin(EndGatewayBlockEntity.class) public class EndGatewayBlockEntityMixin { diff --git a/src/main/java/com/awakenedredstone/neoskies/mixin/compat/JanksonAcessor.java b/src/main/java/com/awakenedredstone/neoskies/mixin/compat/JanksonAcessor.java new file mode 100644 index 0000000..2de144d --- /dev/null +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/compat/JanksonAcessor.java @@ -0,0 +1,17 @@ +package com.awakenedredstone.neoskies.mixin.compat; + +import blue.endless.jankson.Jankson; +import blue.endless.jankson.api.Marshaller; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(value = Jankson.class, remap = false) +public interface JanksonAcessor { + @Invoker("") static Jankson createJankson(Jankson.Builder builder) { + throw new IllegalStateException("Mixin failed to apply"); + } + + @Accessor void setMarshaller(Marshaller marshaller); + @Accessor void setAllowBareRootObject(boolean allowBareRootObject); +} diff --git a/src/main/java/com/awakenedredstone/neoskies/mixin/compat/POJODeserializerAccessor.java b/src/main/java/com/awakenedredstone/neoskies/mixin/compat/POJODeserializerAccessor.java new file mode 100644 index 0000000..c546b54 --- /dev/null +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/compat/POJODeserializerAccessor.java @@ -0,0 +1,14 @@ +package com.awakenedredstone.neoskies.mixin.compat; + +import blue.endless.jankson.impl.POJODeserializer; +import blue.endless.jankson.impl.serializer.DeserializerFunctionPool; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(value = POJODeserializer.class, remap = false) +public interface POJODeserializerAccessor { + @Invoker + static DeserializerFunctionPool callDeserializersFor(Class targetClass) { + throw new IllegalStateException("Mixin failed to apply!"); + } +} diff --git a/src/main/java/skylands/mixin/entity/EntityMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/entity/EntityMixin.java similarity index 94% rename from src/main/java/skylands/mixin/entity/EntityMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/entity/EntityMixin.java index 1e8a47b..d022a13 100644 --- a/src/main/java/skylands/mixin/entity/EntityMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/entity/EntityMixin.java @@ -1,4 +1,4 @@ -package skylands.mixin.entity; +package com.awakenedredstone.neoskies.mixin.entity; import net.minecraft.entity.Entity; import net.minecraft.registry.RegistryKey; @@ -16,18 +16,17 @@ import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; -import skylands.api.SkylandsAPI; -import skylands.logic.Island; -import skylands.util.Worlds; +import com.awakenedredstone.neoskies.api.SkylandsAPI; +import com.awakenedredstone.neoskies.logic.Island; +import com.awakenedredstone.neoskies.util.Worlds; import java.util.Optional; -//TODO: Fix crash when other entities try to go trough the portal @Mixin(Entity.class) public abstract class EntityMixin { @Shadow - public World world; + private World world; @Shadow public abstract Vec3d getVelocity(); diff --git a/src/main/java/com/awakenedredstone/neoskies/mixin/entity/PlayerManagerMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/entity/PlayerManagerMixin.java new file mode 100644 index 0000000..ff6f472 --- /dev/null +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/entity/PlayerManagerMixin.java @@ -0,0 +1,175 @@ +package com.awakenedredstone.neoskies.mixin.entity; + +import com.llamalad7.mixinextras.sugar.Local; +import net.minecraft.advancement.AdvancementProgress; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityStatuses; +import net.minecraft.network.ClientConnection; +import net.minecraft.network.packet.s2c.play.*; +import net.minecraft.registry.RegistryKey; +import net.minecraft.screen.ScreenTexts; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.PlayerManager; +import net.minecraft.server.network.ConnectedClientData; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.World; +import net.minecraft.world.WorldProperties; +import org.slf4j.Logger; +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.Redirect; +import com.awakenedredstone.neoskies.api.SkylandsAPI; +import com.awakenedredstone.neoskies.duck.ExtendedPlayerManager; +import com.awakenedredstone.neoskies.duck.ExtendedServerPlayerEntity; +import com.awakenedredstone.neoskies.logic.Island; +import com.awakenedredstone.neoskies.logic.Skylands; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; + +@Mixin(PlayerManager.class) +public abstract class PlayerManagerMixin implements ExtendedPlayerManager { + @Shadow + @Final + private MinecraftServer server; + + @Shadow + @Final + private List players; + + @Shadow + public abstract void sendWorldInfo(ServerPlayerEntity player, ServerWorld world); + + @Shadow + public abstract void sendCommandTree(ServerPlayerEntity player); + + @Shadow + @Final + private Map playerMap; + + @Shadow + @Final + private static Logger LOGGER; + + @Inject(method = "onPlayerConnect", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;getWorld(Lnet/minecraft/registry/RegistryKey;)Lnet/minecraft/server/world/ServerWorld;", shift = At.Shift.BEFORE)) + private void loadIsland(ClientConnection connection, ServerPlayerEntity player, ConnectedClientData clientData, CallbackInfo ci, @Local RegistryKey registryKey) { + if (SkylandsAPI.isIsland(registryKey)) { + Optional islandOptional = SkylandsAPI.getIsland(registryKey); + if (islandOptional.isPresent()) { + Island island = islandOptional.get(); + + //Load the proper island dimension + if (SkylandsAPI.isOverworld(registryKey)) { + LOGGER.info("Loading overworld for " + registryKey.getValue()); + island.getOverworld(); + } else if (SkylandsAPI.isNether(registryKey)) { + LOGGER.info("Loading nether for " + registryKey.getValue()); + island.getNether(); + } else if (SkylandsAPI.isEnd(registryKey)) { + LOGGER.info("Loading end for " + registryKey.getValue()); + island.getEnd(); + } + } else { + LOGGER.warn("Unknown island {}, defaulting to hub", registryKey.getValue()); + Skylands.getInstance().hub.positionInto(player); + } + } + } + + @Redirect(method = "respawnPlayer", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/network/ServerPlayerEntity;getSpawnPointPosition()Lnet/minecraft/util/math/BlockPos;")) + private BlockPos skylands$respawnOnIsland(ServerPlayerEntity player) { + if (SkylandsAPI.isIsland(player.getWorld())) { + Optional islandOptional = SkylandsAPI.getIsland(player.getWorld()); + if (islandOptional.isPresent()) { + Island island = islandOptional.get(); + if (island.isMember(player)) { + return BlockPos.ofFloored(island.spawnPos); + } else { + return BlockPos.ofFloored(island.visitsPos); + } + } + } + return BlockPos.ofFloored(Skylands.getInstance().hub.pos); + } + + @Redirect(method = "respawnPlayer", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/network/ServerPlayerEntity;getSpawnPointDimension()Lnet/minecraft/registry/RegistryKey;")) + private RegistryKey skylands$fixRespawnDimension(ServerPlayerEntity player) { + return player.getWorld().getRegistryKey(); + } + + @Redirect(method = "respawnPlayer", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/PlayerEntity;findRespawnPosition(Lnet/minecraft/server/world/ServerWorld;Lnet/minecraft/util/math/BlockPos;FZZ)Ljava/util/Optional;")) + private Optional skylands$respawnOnIsland(ServerWorld world, BlockPos pos, float angle, boolean forced, boolean alive) { + return Optional.of(pos.toCenterPos()); + } + + @Override + //TODO: Update to newer version + public ServerPlayerEntity resetPlayer(ServerPlayerEntity player) { + player.networkHandler.sendPacket(new DeathMessageS2CPacket(player.getId(), ScreenTexts.EMPTY)); + player.getInventory().clear(); + player.wakeUp(); + player.refreshPosition(); + player.dropShoulderEntities(); + player.forgiveMobAnger(); + player.extinguish(); + player.setFrozenTicks(0); + player.setOnFire(false); + player.getDamageTracker().update(); + player.server.getAdvancementLoader().getAdvancements().forEach((advancement) -> { + AdvancementProgress advancementProgress = player.getAdvancementTracker().getProgress(advancement); + if (!advancementProgress.isAnyObtained()) return; + for (String string : advancementProgress.getObtainedCriteria()) { + player.getAdvancementTracker().revokeCriterion(advancement, string); + } + }); + player.getWorld().sendEntityStatus(player, EntityStatuses.PLAY_DEATH_SOUND_OR_ADD_PROJECTILE_HIT_PARTICLES); + + this.players.remove(player); + player.getServerWorld().removePlayer(player, Entity.RemovalReason.DISCARDED); + BlockPos blockPos = BlockPos.ofFloored(Skylands.getInstance().hub.pos); + float f = player.getSpawnAngle(); + boolean bl = player.isSpawnForced(); + ServerWorld serverWorld = this.server.getOverworld(); + ServerPlayerEntity serverPlayerEntity = new ServerPlayerEntity(this.server, serverWorld, player.getGameProfile(), player.getClientOptions()); + serverPlayerEntity.networkHandler = player.networkHandler; + ((ExtendedServerPlayerEntity) serverPlayerEntity).neoskies$simpleCopyFrom(player); + serverPlayerEntity.setId(player.getId()); + serverPlayerEntity.setMainArm(player.getMainArm()); + for (String string : player.getCommandTags()) { + serverPlayerEntity.addCommandTag(string); + } + + Vec3d vec3d = blockPos.toCenterPos(); + + serverPlayerEntity.refreshPositionAndAngles(vec3d.x, vec3d.y, vec3d.z, f, 0.0f); + serverPlayerEntity.setSpawnPoint(serverWorld.getRegistryKey(), blockPos, f, bl, false); + + while (!serverWorld.isSpaceEmpty(serverPlayerEntity) && serverPlayerEntity.getY() < (double) serverWorld.getTopY()) { + serverPlayerEntity.setPosition(serverPlayerEntity.getX(), serverPlayerEntity.getY() + 1.0, serverPlayerEntity.getZ()); + } + + WorldProperties worldProperties = serverPlayerEntity.getWorld().getLevelProperties(); + serverPlayerEntity.networkHandler.sendPacket(new PlayerRespawnS2CPacket(serverPlayerEntity.createCommonPlayerSpawnInfo(serverWorld), (byte) 0)); + serverPlayerEntity.networkHandler.requestTeleport(serverPlayerEntity.getX(), serverPlayerEntity.getY(), serverPlayerEntity.getZ(), serverPlayerEntity.getYaw(), serverPlayerEntity.getPitch()); + serverPlayerEntity.networkHandler.sendPacket(new PlayerSpawnPositionS2CPacket(serverWorld.getSpawnPos(), serverWorld.getSpawnAngle())); + serverPlayerEntity.networkHandler.sendPacket(new DifficultyS2CPacket(worldProperties.getDifficulty(), worldProperties.isDifficultyLocked())); + serverPlayerEntity.networkHandler.sendPacket(new ExperienceBarUpdateS2CPacket(serverPlayerEntity.experienceProgress, serverPlayerEntity.totalExperience, serverPlayerEntity.experienceLevel)); + this.sendWorldInfo(serverPlayerEntity, serverWorld); + this.sendCommandTree(serverPlayerEntity); + serverWorld.onPlayerRespawned(serverPlayerEntity); + this.players.add(serverPlayerEntity); + this.playerMap.put(serverPlayerEntity.getUuid(), serverPlayerEntity); + serverPlayerEntity.onSpawn(); + serverPlayerEntity.setHealth(serverPlayerEntity.getHealth()); + return serverPlayerEntity; + } +} diff --git a/src/main/java/skylands/mixin/entity/ServerPlayerEntityMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/entity/ServerPlayerEntityMixin.java similarity index 56% rename from src/main/java/skylands/mixin/entity/ServerPlayerEntityMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/entity/ServerPlayerEntityMixin.java index b6f3af9..a0dffaf 100644 --- a/src/main/java/skylands/mixin/entity/ServerPlayerEntityMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/entity/ServerPlayerEntityMixin.java @@ -1,28 +1,50 @@ -package skylands.mixin.entity; +package com.awakenedredstone.neoskies.mixin.entity; +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import com.mojang.authlib.GameProfile; import net.minecraft.entity.damage.DamageSource; import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.network.encryption.PublicPlayerSession; import net.minecraft.registry.RegistryKey; import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.server.network.ServerPlayerInteractionManager; import net.minecraft.server.world.ServerWorld; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; +import org.jetbrains.annotations.Nullable; +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.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import skylands.api.SkylandsAPI; -import skylands.event.PlayerEvents; -import skylands.util.Worlds; +import com.awakenedredstone.neoskies.api.SkylandsAPI; +import com.awakenedredstone.neoskies.duck.ExtendedServerPlayerEntity; +import com.awakenedredstone.neoskies.event.PlayerEvents; +import com.awakenedredstone.neoskies.util.Worlds; -import java.util.Optional; - -//TODO: Update chunks around the player -//TODO: Fix it not redirecting when the player joins @Mixin(ServerPlayerEntity.class) -public abstract class ServerPlayerEntityMixin extends PlayerEntity { +public abstract class ServerPlayerEntityMixin extends PlayerEntity implements ExtendedServerPlayerEntity { + + @Shadow + private boolean filterText; + + @Shadow + private @Nullable PublicPlayerSession session; + + @Shadow + @Final + public ServerPlayerInteractionManager interactionManager; + + @Shadow + private int syncedExperience; + + @Shadow + private float syncedHealth; + + @Shadow + private int syncedFoodLevel; public ServerPlayerEntityMixin(World world, BlockPos pos, float yaw, GameProfile gameProfile) { super(world, pos, yaw, gameProfile); @@ -30,17 +52,18 @@ public ServerPlayerEntityMixin(World world, BlockPos pos, float yaw, GameProfile @Inject(method = "createEndSpawnPlatform", at = @At("HEAD"), cancellable = true) public void blockEndPlatform(CallbackInfo ci) { - if (SkylandsAPI.isIsland(world)) { + if (SkylandsAPI.isIsland(getWorld())) { ci.cancel(); } } - @Redirect(method = "getPortalRect", at = @At(value = "INVOKE", target = "Ljava/util/Optional;isPresent()Z", ordinal = 1)) - public boolean skipErrorMessage(Optional instance) { - if (SkylandsAPI.isIsland(world)) { - return true; + @ModifyExpressionValue(method = "getPortalRect", at = @At(value = "INVOKE", target = "Ljava/util/Optional;isEmpty()Z")) + public boolean skipErrorMessage(boolean original) { + if (SkylandsAPI.isIsland(getWorld())) { + return false; } - return instance.isPresent(); + + return original; } @Redirect(method = "moveToWorld", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/world/ServerWorld;getRegistryKey()Lnet/minecraft/registry/RegistryKey;", ordinal = 1)) @@ -62,6 +85,10 @@ public RegistryKey getTeleportTarget_redirectRegistryKey(ServerWorld inst public RegistryKey worldChanged_redirectRegistryKey(ServerWorld instance) { return Worlds.redirect(instance.getRegistryKey()); } + @Redirect(method = "createCommonPlayerSpawnInfo", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/world/ServerWorld;getRegistryKey()Lnet/minecraft/registry/RegistryKey;")) + public RegistryKey createCommonPlayerSpawnInfo_redirectRegistryKey(ServerWorld instance) { + return Worlds.redirect(instance.getRegistryKey()); + } @Inject(method = "tick", at = @At(value = "HEAD")) public void tick(CallbackInfo ci) { @@ -73,4 +100,14 @@ private void onDeath(DamageSource source, CallbackInfo ci) { PlayerEvents.POST_DEATH.invoker().onPlayerPostDeath((ServerPlayerEntity) (Object) this); } + @Override + public void neoskies$simpleCopyFrom(ServerPlayerEntity oldPlayer) { + this.filterText = oldPlayer.shouldFilterText(); + this.session = oldPlayer.getSession(); + this.interactionManager.setGameMode(oldPlayer.interactionManager.getGameMode(), oldPlayer.interactionManager.getPreviousGameMode()); + this.sendAbilitiesUpdate(); + this.syncedExperience = -1; + this.syncedHealth = -1.0f; + this.syncedFoodLevel = -1; + } } diff --git a/src/main/java/skylands/mixin/item/ArmorStandItemMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/item/ArmorStandItemMixin.java similarity index 78% rename from src/main/java/skylands/mixin/item/ArmorStandItemMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/item/ArmorStandItemMixin.java index 8014c68..c5c84d9 100644 --- a/src/main/java/skylands/mixin/item/ArmorStandItemMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/item/ArmorStandItemMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.item; +package com.awakenedredstone.neoskies.mixin.item; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ArmorStandItem; import net.minecraft.item.ItemUsageContext; @@ -10,9 +11,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(ArmorStandItem.class) public class ArmorStandItemMixin { @@ -21,9 +20,9 @@ void useOnBlock(ItemUsageContext context, CallbackInfoReturnable c World world = context.getWorld(); PlayerEntity player = context.getPlayer(); BlockPos blockPos = context.getBlockPos().offset(context.getSide()); - if (!world.isClient && player != null) { + if (!world.isClient() && player != null) { if (!WorldProtection.canModify(world, blockPos, player)) { - protectionWarning(player, "item_use"); + ServerUtils.protectionWarning(player, "item_use"); cir.setReturnValue(ActionResult.FAIL); } } diff --git a/src/main/java/skylands/mixin/item/BlockItemMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/item/BlockItemMixin.java similarity index 77% rename from src/main/java/skylands/mixin/item/BlockItemMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/item/BlockItemMixin.java index 1ce3673..882459f 100644 --- a/src/main/java/skylands/mixin/item/BlockItemMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/item/BlockItemMixin.java @@ -1,23 +1,24 @@ -package skylands.mixin.item; +package com.awakenedredstone.neoskies.mixin.item; + +/*import net.minecraft.entity.player.PlayerEntity;*/ -import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.BlockItem; import net.minecraft.item.Item; -import net.minecraft.item.ItemUsageContext; +/*import net.minecraft.item.ItemUsageContext; import net.minecraft.network.packet.s2c.play.ScreenHandlerSlotUpdateS2CPacket; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.util.ActionResult; import net.minecraft.util.Hand; import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; +import net.minecraft.world.World;*/ import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; +/*import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import skylands.logic.registry.SkylandsIslandSettings; import skylands.util.WorldProtection; -import static skylands.util.ServerUtils.protectionWarning; +import static skylands.util.ServerUtils.ServerUtils.protectionWarning;*/ @Mixin(BlockItem.class) public class BlockItemMixin extends Item { @@ -25,19 +26,19 @@ public BlockItemMixin(Settings settings) { super(settings); } - @Inject(method = "useOnBlock", at = @At("HEAD"), cancellable = true) + /*@Inject(method = "useOnBlock", at = @At("HEAD"), cancellable = true) void useOnBlock(ItemUsageContext context, CallbackInfoReturnable cir) { World world = context.getWorld(); PlayerEntity player = context.getPlayer(); if (player instanceof ServerPlayerEntity serverPlayer) { BlockPos blockPos = context.getBlockPos().offset(context.getSide()); if (!WorldProtection.canModify(world, blockPos, player, SkylandsIslandSettings.PLACE)) { - protectionWarning(player, "block_place"); + ServerUtils.protectionWarning(player, "block_place"); int slot = context.getHand() == Hand.MAIN_HAND ? player.getInventory().selectedSlot : 40; var stack = context.getStack(); serverPlayer.networkHandler.sendPacket(new ScreenHandlerSlotUpdateS2CPacket(ScreenHandlerSlotUpdateS2CPacket.UPDATE_PLAYER_INVENTORY_SYNC_ID, 0, slot, stack)); cir.setReturnValue(ActionResult.FAIL); } } - } + }*/ } diff --git a/src/main/java/skylands/mixin/item/BoatItemMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/item/BoatItemMixin.java similarity index 91% rename from src/main/java/skylands/mixin/item/BoatItemMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/item/BoatItemMixin.java index a8dc859..1b2fd99 100644 --- a/src/main/java/skylands/mixin/item/BoatItemMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/item/BoatItemMixin.java @@ -1,4 +1,4 @@ -package skylands.mixin.item; +package com.awakenedredstone.neoskies.mixin.item; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.BoatItem; @@ -13,7 +13,7 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; -import skylands.util.WorldProtection; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(BoatItem.class) public class BoatItemMixin { @@ -21,7 +21,7 @@ public class BoatItemMixin { @Inject(method = "use", at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/item/BoatItem;raycast(Lnet/minecraft/world/World;Lnet/minecraft/entity/player/PlayerEntity;Lnet/minecraft/world/RaycastContext$FluidHandling;)Lnet/minecraft/util/hit/BlockHitResult;", shift = At.Shift.AFTER), cancellable = true, locals = LocalCapture.CAPTURE_FAILSOFT) void useOnBlock(World world, PlayerEntity user, Hand hand, CallbackInfoReturnable> cir, ItemStack itemStack, HitResult hitResult) { if (hitResult.getType() == HitResult.Type.MISS) return; - if (!world.isClient) { + if (!world.isClient()) { BlockPos blockPos = BlockPos.ofFloored(hitResult.getPos()); if (!WorldProtection.isWithinIsland(world, blockPos)) { cir.setReturnValue(TypedActionResult.fail(itemStack)); diff --git a/src/main/java/skylands/mixin/item/ItemMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/item/ItemStackMixin.java similarity index 61% rename from src/main/java/skylands/mixin/item/ItemMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/item/ItemStackMixin.java index e80d7fe..840f9fb 100644 --- a/src/main/java/skylands/mixin/item/ItemMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/item/ItemStackMixin.java @@ -1,29 +1,36 @@ -package skylands.mixin.item; +package com.awakenedredstone.neoskies.mixin.item; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.BlockItem; -import net.minecraft.item.Item; -import net.minecraft.item.ItemUsageContext; +import net.minecraft.item.*; import net.minecraft.util.ActionResult; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; 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; -import skylands.util.WorldProtection; -@Mixin(Item.class) -public class ItemMixin { +import com.awakenedredstone.neoskies.util.WorldProtection; + +@Mixin(ItemStack.class) +public abstract class ItemStackMixin { + + @Shadow + public abstract ActionResult useOnBlock(ItemUsageContext context); + + @Shadow + public abstract Item getItem(); @Inject(method = "useOnBlock", at = @At("HEAD"), cancellable = true) private void useOnBlock(ItemUsageContext context, CallbackInfoReturnable cir) { - if ((Object) this instanceof BlockItem) return; + if (getItem() instanceof BlockItem) return; + World world = context.getWorld(); PlayerEntity player = context.getPlayer(); - if (!world.isClient && player != null) { + if (!world.isClient() && player != null) { BlockPos blockPos = context.getBlockPos().offset(context.getSide()); if (!WorldProtection.canModify(world, blockPos, player)) { - //protectionWarning(player, "item_use"); + //ServerUtils.protectionWarning(player, "item_use"); cir.setReturnValue(ActionResult.FAIL); } } diff --git a/src/main/java/skylands/mixin/item/MinecartItemMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/item/MinecartItemMixin.java similarity index 78% rename from src/main/java/skylands/mixin/item/MinecartItemMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/item/MinecartItemMixin.java index a637ca9..575311c 100644 --- a/src/main/java/skylands/mixin/item/MinecartItemMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/item/MinecartItemMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.item; +package com.awakenedredstone.neoskies.mixin.item; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemUsageContext; import net.minecraft.item.MinecartItem; @@ -10,9 +11,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(MinecartItem.class) public class MinecartItemMixin { @@ -20,10 +19,10 @@ public class MinecartItemMixin { void useOnBlock(ItemUsageContext context, CallbackInfoReturnable cir) { World world = context.getWorld(); PlayerEntity player = context.getPlayer(); - if (!world.isClient && player != null) { + if (!world.isClient() && player != null) { BlockPos blockPos = context.getBlockPos().offset(context.getSide()); if (!WorldProtection.canModify(world, blockPos, player)) { - protectionWarning(player, "item_use"); + ServerUtils.protectionWarning(player, "item_use"); cir.setReturnValue(ActionResult.FAIL); } } diff --git a/src/main/java/skylands/mixin/world/ChunkMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/ChunkMixin.java similarity index 87% rename from src/main/java/skylands/mixin/world/ChunkMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/ChunkMixin.java index 1f1ed26..a4b4e80 100644 --- a/src/main/java/skylands/mixin/world/ChunkMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/ChunkMixin.java @@ -1,10 +1,10 @@ -package skylands.mixin.world; +package com.awakenedredstone.neoskies.mixin.world; import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.ChunkSection; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; -import skylands.duck.ExtendedChunk; +import com.awakenedredstone.neoskies.duck.ExtendedChunk; import java.util.HashSet; import java.util.Set; diff --git a/src/main/java/skylands/mixin/world/PlayerEntityMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/PlayerEntityMixin.java similarity index 66% rename from src/main/java/skylands/mixin/world/PlayerEntityMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/PlayerEntityMixin.java index 3ab3290..d08e5c2 100644 --- a/src/main/java/skylands/mixin/world/PlayerEntityMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/PlayerEntityMixin.java @@ -1,4 +1,4 @@ -package skylands.mixin.world; +package com.awakenedredstone.neoskies.mixin.world; import net.minecraft.entity.EntityType; import net.minecraft.entity.LivingEntity; @@ -10,43 +10,52 @@ import net.minecraft.world.World; import net.minecraft.world.border.WorldBorder; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import skylands.api.SkylandsAPI; -import skylands.logic.Island; -import skylands.mixin.block.accessor.WorldBorderAccessor; -import skylands.util.Worlds; +import com.awakenedredstone.neoskies.api.SkylandsAPI; +import com.awakenedredstone.neoskies.logic.Island; +import com.awakenedredstone.neoskies.mixin.block.accessor.WorldBorderAccessor; +import com.awakenedredstone.neoskies.util.Worlds; -/* TODO: ======= OPTIMIZE THIS ======= */ -/* TODO: ======= OPTIMIZE THIS ======= */ -/* TODO: ======= OPTIMIZE THIS ======= */ @Mixin(PlayerEntity.class) public abstract class PlayerEntityMixin extends LivingEntity { - private double lastSize = -1; - private Vec3d lastPos = Vec3d.ZERO; + @Unique private double lastSize = -1; + @Unique private Vec3d lastPos = Vec3d.ZERO; protected PlayerEntityMixin(EntityType entityType, World world) { super(entityType, world); } - /* TODO: ======= OPTIMIZE THIS ======= */ - /* TODO: ======= OPTIMIZE THIS ======= */ - /* TODO: ======= OPTIMIZE THIS ======= */ + /* TODO: ======= OPTIMISE THIS ======= */ // TODO: Add other visual ways to show the limit - @Inject(method = "increaseTravelMotionStats", at = @At("HEAD")) - private void increaseTravelMotionStats(double dx, double dy, double dz, CallbackInfo ci) { - if (((PlayerEntity) (Object) this) instanceof ServerPlayerEntity serverPlayer && SkylandsAPI.isIsland(world) && !lastPos.equals(getPos())) { + @Inject(method = "travel", at = @At("HEAD")) + private void increaseTravelMotionStats(Vec3d movementInput, CallbackInfo ci) { + if (((PlayerEntity) (Object) this) instanceof ServerPlayerEntity serverPlayer && SkylandsAPI.isIsland(getWorld()) && !lastPos.equals(getPos())) { + WorldBorder defaultWorldBorder = getWorld().getWorldBorder(); + Island island = SkylandsAPI.getIsland(getWorld()).get(); + if (island.radius <= 0) { + if (lastSize != -1) { + WorldBorder border = new WorldBorder(); + border.setCenter(0, 0); + WorldBorderAccessor borderAccessor = (WorldBorderAccessor) border; + borderAccessor.setArea(border.new StaticArea(defaultWorldBorder.getSize())); + serverPlayer.networkHandler.sendPacket(new WorldBorderInterpolateSizeS2CPacket(border)); + lastSize = -1; + } + return; + } + lastPos = getPos(); double x = Math.abs(getX()); double z = Math.abs(getZ()); int range = 64; - Island island = SkylandsAPI.getIsland(world).get(); + if (x > island.radius + range + 8 || z > island.radius + range + 8) { Worlds.returnToIslandSpawn(serverPlayer, false); return; } - WorldBorder defaultWorldBorder = world.getWorldBorder(); double oldSize = lastSize == -1 ? defaultWorldBorder.getSize() : lastSize; WorldBorder border = new WorldBorder(); border.setCenter(0, 0); @@ -54,11 +63,12 @@ private void increaseTravelMotionStats(double dx, double dy, double dz, Callback int finalRadius = island.radius + range; lastSize = Math.max(finalRadius, Math.abs(calculateBorderSize(island.radius, range))) * 2; if (x > finalRadius || z > finalRadius) lastSize = finalRadius * 2; - borderAccessor.setArea(border.new MovingArea(oldSize, lastSize, serverPlayer.pingMilliseconds + 100)); + borderAccessor.setArea(border.new MovingArea(oldSize, lastSize, /*serverPlayer.pingMilliseconds +*/ 100)); serverPlayer.networkHandler.sendPacket(new WorldBorderInterpolateSizeS2CPacket(border)); } } + @Unique private double calculateBorderSize(int islandRadius, int range) { int scale = islandRadius + range - 2; double in = islandRadius + range + 128; @@ -75,6 +85,7 @@ private double calculateBorderSize(int islandRadius, int range) { } else return in; } + @Unique @SuppressWarnings("SameParameterValue") private static double scaleDown(double start, double end, double delta) { double t = (delta - start) / (end - start); diff --git a/src/main/java/skylands/mixin/world/PortalForcerMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/PortalForcerMixin.java similarity index 88% rename from src/main/java/skylands/mixin/world/PortalForcerMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/PortalForcerMixin.java index 739d5d3..948e4ff 100644 --- a/src/main/java/skylands/mixin/world/PortalForcerMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/PortalForcerMixin.java @@ -1,4 +1,4 @@ -package skylands.mixin.world; +package com.awakenedredstone.neoskies.mixin.world; import net.minecraft.server.world.ServerWorld; import net.minecraft.util.math.BlockPos; @@ -11,8 +11,8 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.api.SkylandsAPI; -import skylands.logic.Island; +import com.awakenedredstone.neoskies.api.SkylandsAPI; +import com.awakenedredstone.neoskies.logic.Island; import java.util.Optional; diff --git a/src/main/java/skylands/mixin/world/ServerWorldMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/ServerWorldMixin.java similarity index 81% rename from src/main/java/skylands/mixin/world/ServerWorldMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/ServerWorldMixin.java index 9d654ba..5efe72f 100644 --- a/src/main/java/skylands/mixin/world/ServerWorldMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/ServerWorldMixin.java @@ -1,5 +1,7 @@ -package skylands.mixin.world; +package com.awakenedredstone.neoskies.mixin.world; +import com.awakenedredstone.neoskies.config.MainConfig; +import com.awakenedredstone.neoskies.logic.Skylands; import com.google.common.collect.ImmutableList; import net.minecraft.entity.Entity; import net.minecraft.entity.ItemEntity; @@ -11,6 +13,7 @@ import net.minecraft.server.WorldGenerationProgressListener; import net.minecraft.server.world.ServerWorld; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.random.RandomSequencesState; import net.minecraft.util.profiler.Profiler; import net.minecraft.village.ZombieSiegeManager; import net.minecraft.world.MutableWorldProperties; @@ -24,7 +27,7 @@ import net.minecraft.world.spawner.CatSpawner; import net.minecraft.world.spawner.PatrolSpawner; import net.minecraft.world.spawner.PhantomSpawner; -import net.minecraft.world.spawner.Spawner; +import net.minecraft.world.spawner.SpecialSpawner; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mutable; @@ -33,9 +36,9 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.SkylandsMain; -import skylands.api.SkylandsAPI; -import skylands.util.WorldProtection; +import com.awakenedredstone.neoskies.SkylandsMain; +import com.awakenedredstone.neoskies.api.SkylandsAPI; +import com.awakenedredstone.neoskies.util.WorldProtection; import java.util.List; import java.util.concurrent.Executor; @@ -44,7 +47,7 @@ @Mixin(ServerWorld.class) public abstract class ServerWorldMixin extends World implements StructureWorldAccess { - @Mutable @Shadow @Final private List spawners; + @Mutable @Shadow @Final private List spawners; protected ServerWorldMixin(MutableWorldProperties properties, RegistryKey registryRef, DynamicRegistryManager registryManager, RegistryEntry dimensionEntry, Supplier profiler, boolean isClient, boolean debugWorld, long biomeAccess, int maxChainedNeighborUpdates) { super(properties, registryRef, registryManager, dimensionEntry, profiler, isClient, debugWorld, biomeAccess, maxChainedNeighborUpdates); @@ -52,11 +55,11 @@ protected ServerWorldMixin(MutableWorldProperties properties, RegistryKey @Inject(method = "spawnEntity", at = @At("HEAD"), cancellable = true) private void spawnEntity(Entity entity, CallbackInfoReturnable cir) { - if (!SkylandsMain.MAIN_CONFIG.disableEntitiesOutsideIslands()) return; + if (!Skylands.getConfig().disableEntitiesOutsideIslands) return; if (entity instanceof ItemEntity || entity instanceof ProjectileEntity) return; World world = entity.getWorld(); BlockPos blockPos = entity.getBlockPos(); - if (!world.isClient) { + if (!world.isClient()) { if (!WorldProtection.isWithinIsland(world, blockPos)) { cir.setReturnValue(false); } @@ -64,7 +67,7 @@ private void spawnEntity(Entity entity, CallbackInfoReturnable cir) { } @Inject(method = "", at = @At("TAIL")) - private void skylands$fixSpawning(MinecraftServer server, Executor workerExecutor, LevelStorage.Session session, ServerWorldProperties properties, RegistryKey worldKey, DimensionOptions dimensionOptions, WorldGenerationProgressListener worldGenerationProgressListener, boolean debugWorld, long seed, List spawners, boolean shouldTickTime, CallbackInfo ci) { + private void skylands$fixSpawning(MinecraftServer server, Executor workerExecutor, LevelStorage.Session session, ServerWorldProperties properties, RegistryKey worldKey, DimensionOptions dimensionOptions, WorldGenerationProgressListener worldGenerationProgressListener, boolean debugWorld, long seed, List spawners, boolean shouldTickTime, RandomSequencesState randomSequencesState, CallbackInfo ci) { if (SkylandsAPI.isIsland(worldKey)) { this.spawners = ImmutableList.of(new PhantomSpawner(), new PatrolSpawner(), new CatSpawner(), new ZombieSiegeManager(), new WanderingTraderManager(properties)); } diff --git a/src/main/java/skylands/mixin/world/protection/AbstractBlockStateMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/AbstractBlockStateMixin.java similarity index 90% rename from src/main/java/skylands/mixin/world/protection/AbstractBlockStateMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/AbstractBlockStateMixin.java index 34feda0..198c18a 100644 --- a/src/main/java/skylands/mixin/world/protection/AbstractBlockStateMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/AbstractBlockStateMixin.java @@ -1,4 +1,4 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; import net.minecraft.block.AbstractBlock; import net.minecraft.server.world.ServerWorld; @@ -8,7 +8,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import skylands.api.SkylandsAPI; +import com.awakenedredstone.neoskies.api.SkylandsAPI; @Mixin(AbstractBlock.AbstractBlockState.class) public class AbstractBlockStateMixin { diff --git a/src/main/java/skylands/mixin/world/protection/AbstractCandleBlockMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/AbstractCandleBlockMixin.java similarity index 79% rename from src/main/java/skylands/mixin/world/protection/AbstractCandleBlockMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/AbstractCandleBlockMixin.java index 929d266..0bf32f8 100644 --- a/src/main/java/skylands/mixin/world/protection/AbstractCandleBlockMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/AbstractCandleBlockMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.block.AbstractCandleBlock; import net.minecraft.block.BlockState; import net.minecraft.entity.player.PlayerEntity; @@ -11,19 +12,17 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(AbstractCandleBlock.class) public class AbstractCandleBlockMixin { @Inject(method = "onProjectileHit", at = @At("HEAD"), cancellable = true) private void onProjectileHit(World world, BlockState state, BlockHitResult hit, ProjectileEntity projectile, CallbackInfo ci) { - if (!world.isClient) { + if (!world.isClient()) { BlockPos pos = hit.getBlockPos(); if ((projectile.getOwner() instanceof PlayerEntity player && !WorldProtection.canModify(world, pos, player))) { - if (projectile.isOnFire()) protectionWarning(player, "ignite"); + if (projectile.isOnFire()) ServerUtils.protectionWarning(player, "ignite"); ci.cancel(); } else if (!WorldProtection.isWithinIsland(world, pos)) { ci.cancel(); diff --git a/src/main/java/skylands/mixin/world/protection/AnvilBlockMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/AnvilBlockMixin.java similarity index 78% rename from src/main/java/skylands/mixin/world/protection/AnvilBlockMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/AnvilBlockMixin.java index bc52e82..1d62a5f 100644 --- a/src/main/java/skylands/mixin/world/protection/AnvilBlockMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/AnvilBlockMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.block.AnvilBlock; import net.minecraft.block.BlockState; import net.minecraft.entity.player.PlayerEntity; @@ -12,18 +13,16 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(AnvilBlock.class) public class AnvilBlockMixin { @Inject(method = "onUse", at = @At("HEAD"), cancellable = true) void onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable cir) { - if (!world.isClient) { + if (!world.isClient()) { if (!WorldProtection.canModify(world, pos, player)) { - protectionWarning(player, "anvil"); + ServerUtils.protectionWarning(player, "anvil"); cir.setReturnValue(ActionResult.FAIL); } } diff --git a/src/main/java/skylands/mixin/world/protection/ArmorStandMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/ArmorStandMixin.java similarity index 66% rename from src/main/java/skylands/mixin/world/protection/ArmorStandMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/ArmorStandMixin.java index f742748..ada4fc0 100644 --- a/src/main/java/skylands/mixin/world/protection/ArmorStandMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/ArmorStandMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.entity.EntityType; import net.minecraft.entity.EquipmentSlot; import net.minecraft.entity.LivingEntity; @@ -16,9 +17,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(ArmorStandEntity.class) public abstract class ArmorStandMixin extends LivingEntity { @@ -29,9 +28,9 @@ protected ArmorStandMixin(EntityType entityType, World w @Inject(method = "damage", at = @At("HEAD"), cancellable = true) void damage(DamageSource source, float amount, CallbackInfoReturnable cir) { - if (!world.isClient && source.getAttacker() instanceof PlayerEntity attacker) { - if (!WorldProtection.canModify(world, this.getBlockPos(), attacker)) { - protectionWarning(attacker, "entity_hurt"); + if (!getWorld().isClient() && source.getAttacker() instanceof PlayerEntity attacker) { + if (!WorldProtection.canModify(getWorld(), this.getBlockPos(), attacker)) { + ServerUtils.protectionWarning(attacker, "entity_hurt"); cir.setReturnValue(false); } } @@ -39,9 +38,9 @@ void damage(DamageSource source, float amount, CallbackInfoReturnable c @Inject(method = "interactAt", at = @At("HEAD"), cancellable = true) void interactAt(PlayerEntity player, Vec3d hitPos, Hand hand, CallbackInfoReturnable cir) { - if (!player.world.isClient) { - if (!WorldProtection.canModify(player.world, BlockPos.ofFloored(hitPos), player)) { - protectionWarning(player, "armor_stand_use"); + if (!player.getWorld().isClient()) { + if (!WorldProtection.canModify(player.getWorld(), BlockPos.ofFloored(hitPos), player)) { + ServerUtils.protectionWarning(player, "armor_stand_use"); cir.setReturnValue(ActionResult.FAIL); } } @@ -49,9 +48,9 @@ void interactAt(PlayerEntity player, Vec3d hitPos, Hand hand, CallbackInfoReturn @Inject(method = "equip", at = @At("HEAD"), cancellable = true) void equip(PlayerEntity player, EquipmentSlot slot, ItemStack stack, Hand hand, CallbackInfoReturnable cir) { - if (!player.world.isClient) { - if (!WorldProtection.canModify(player.world, this.getBlockPos(), player)) { - protectionWarning(player, "armor_stand_use"); + if (!player.getWorld().isClient()) { + if (!WorldProtection.canModify(player.getWorld(), this.getBlockPos(), player)) { + ServerUtils.protectionWarning(player, "armor_stand_use"); cir.setReturnValue(false); } } diff --git a/src/main/java/skylands/mixin/world/protection/AxeItemMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/AxeItemMixin.java similarity index 75% rename from src/main/java/skylands/mixin/world/protection/AxeItemMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/AxeItemMixin.java index 13d5b36..b8a213b 100644 --- a/src/main/java/skylands/mixin/world/protection/AxeItemMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/AxeItemMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.AxeItem; import net.minecraft.item.ItemUsageContext; @@ -9,9 +10,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(AxeItem.class) public class AxeItemMixin { @@ -20,9 +19,9 @@ public class AxeItemMixin { void useOnBlock(ItemUsageContext context, CallbackInfoReturnable cir) { World world = context.getWorld(); PlayerEntity player = context.getPlayer(); - if (!world.isClient && player != null) { + if (!world.isClient() && player != null) { if (!WorldProtection.canModify(world, context.getBlockPos(), player)) { - protectionWarning(player, "axe_use"); + ServerUtils.protectionWarning(player, "axe_use"); cir.setReturnValue(ActionResult.FAIL); } } diff --git a/src/main/java/skylands/mixin/world/protection/BeaconBlockMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/BeaconBlockMixin.java similarity index 78% rename from src/main/java/skylands/mixin/world/protection/BeaconBlockMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/BeaconBlockMixin.java index 56576ec..d218936 100644 --- a/src/main/java/skylands/mixin/world/protection/BeaconBlockMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/BeaconBlockMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.block.BeaconBlock; import net.minecraft.block.BlockState; import net.minecraft.entity.player.PlayerEntity; @@ -12,18 +13,16 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(BeaconBlock.class) public class BeaconBlockMixin { @Inject(method = "onUse", at = @At("HEAD"), cancellable = true) void onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable cir) { - if (!world.isClient) { + if (!world.isClient()) { if (!WorldProtection.canModify(world, pos, player)) { - protectionWarning(player, "interact"); + ServerUtils.protectionWarning(player, "interact"); cir.setReturnValue(ActionResult.FAIL); } } diff --git a/src/main/java/skylands/mixin/world/protection/BigDripLeafMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/BigDripLeafMixin.java similarity index 82% rename from src/main/java/skylands/mixin/world/protection/BigDripLeafMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/BigDripLeafMixin.java index 1c11cc5..1168814 100644 --- a/src/main/java/skylands/mixin/world/protection/BigDripLeafMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/BigDripLeafMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.block.BigDripleafBlock; import net.minecraft.block.BlockState; import net.minecraft.entity.Entity; @@ -12,16 +13,14 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(BigDripleafBlock.class) public class BigDripLeafMixin { @Inject(method = "onProjectileHit", at = @At("HEAD"), cancellable = true) void onProjectileHit(World world, BlockState state, BlockHitResult hit, ProjectileEntity projectile, CallbackInfo ci) { - if (!world.isClient) { + if (!world.isClient()) { if (!WorldProtection.isWithinIsland(world, hit.getBlockPos())) { ci.cancel(); } @@ -30,9 +29,9 @@ void onProjectileHit(World world, BlockState state, BlockHitResult hit, Projecti @Inject(method = "onEntityCollision", at = @At("HEAD"), cancellable = true) void onEntityCollision(BlockState state, World world, BlockPos pos, Entity entity, CallbackInfo ci) { - if (!world.isClient) { + if (!world.isClient()) { if ((entity instanceof PlayerEntity player && !WorldProtection.canModify(world, pos, player))) { - protectionWarning(player, "dripleaf"); + ServerUtils.protectionWarning(player, "dripleaf"); ci.cancel(); } else if (!WorldProtection.isWithinIsland(world, pos)) { ci.cancel(); diff --git a/src/main/java/skylands/mixin/world/protection/BoatMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/BoatMixin.java similarity index 63% rename from src/main/java/skylands/mixin/world/protection/BoatMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/BoatMixin.java index 404314b..2572f30 100644 --- a/src/main/java/skylands/mixin/world/protection/BoatMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/BoatMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; import net.minecraft.entity.damage.DamageSource; @@ -12,9 +13,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(BoatEntity.class) public abstract class BoatMixin extends Entity { @@ -23,20 +22,20 @@ public BoatMixin(EntityType type, World world) { super(type, world); } - @Inject(method = "damage", at = @At("HEAD"), cancellable = true) + /*@Inject(method = "damage", at = @At("HEAD"), cancellable = true) void preventDamage(DamageSource source, float amount, CallbackInfoReturnable cir) { - if (!world.isClient && source.getAttacker() instanceof PlayerEntity attacker) { - if (!WorldProtection.canModify(world, getBlockPos(), attacker)) { - protectionWarning(attacker, "entity_hurt"); + if (!getWorld().isClient() && source.getAttacker() instanceof PlayerEntity attacker) { + if (!WorldProtection.canModify(getWorld(), getBlockPos(), attacker)) { + ServerUtils.protectionWarning(attacker, "entity_hurt"); cir.setReturnValue(false); } } - } + }*/ @Inject(method = "interact", at = @At("HEAD"), cancellable = true) void preventInteraction(PlayerEntity player, Hand hand, CallbackInfoReturnable cir) { - if (!WorldProtection.canModify(world, getBlockPos(), player)) { - protectionWarning(player, "interact"); + if (!WorldProtection.canModify(getWorld(), getBlockPos(), player)) { + ServerUtils.protectionWarning(player, "interact"); cir.setReturnValue(ActionResult.PASS); } } diff --git a/src/main/java/skylands/mixin/world/protection/BoneMealItemMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/BoneMealItemMixin.java similarity index 75% rename from src/main/java/skylands/mixin/world/protection/BoneMealItemMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/BoneMealItemMixin.java index d02112a..539af62 100644 --- a/src/main/java/skylands/mixin/world/protection/BoneMealItemMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/BoneMealItemMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.BoneMealItem; import net.minecraft.item.ItemUsageContext; @@ -9,9 +10,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(BoneMealItem.class) public class BoneMealItemMixin { @@ -20,9 +19,9 @@ public class BoneMealItemMixin { void useOnBlock(ItemUsageContext context, CallbackInfoReturnable cir) { World world = context.getWorld(); PlayerEntity player = context.getPlayer(); - if (!world.isClient && player != null) { + if (!world.isClient() && player != null) { if (!WorldProtection.canModify(world, context.getBlockPos(), player)) { - protectionWarning(player, "bone_meal_use"); + ServerUtils.protectionWarning(player, "bone_meal_use"); cir.setReturnValue(ActionResult.FAIL); } } diff --git a/src/main/java/skylands/mixin/world/protection/BrewingStandBlockMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/BrewingStandBlockMixin.java similarity index 78% rename from src/main/java/skylands/mixin/world/protection/BrewingStandBlockMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/BrewingStandBlockMixin.java index fef2f56..93466b2 100644 --- a/src/main/java/skylands/mixin/world/protection/BrewingStandBlockMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/BrewingStandBlockMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.block.BlockState; import net.minecraft.block.BrewingStandBlock; import net.minecraft.entity.player.PlayerEntity; @@ -12,18 +13,16 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(BrewingStandBlock.class) public class BrewingStandBlockMixin { @Inject(method = "onUse", at = @At("HEAD"), cancellable = true) void onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable cir) { - if (!world.isClient) { + if (!world.isClient()) { if (!WorldProtection.canModify(world, pos, player)) { - protectionWarning(player, "brewing_stand"); + ServerUtils.protectionWarning(player, "brewing_stand"); cir.setReturnValue(ActionResult.FAIL); } } diff --git a/src/main/java/skylands/mixin/world/protection/BucketItemMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/BucketItemMixin.java similarity index 85% rename from src/main/java/skylands/mixin/world/protection/BucketItemMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/BucketItemMixin.java index f20d9fb..2dde3ba 100644 --- a/src/main/java/skylands/mixin/world/protection/BucketItemMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/BucketItemMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.BucketItem; import net.minecraft.item.ItemStack; @@ -14,9 +15,7 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(BucketItem.class) public class BucketItemMixin { @@ -24,11 +23,11 @@ public class BucketItemMixin { @SuppressWarnings("InvalidInjectorMethodSignature") @Inject(method = "use", at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/item/BucketItem;raycast(Lnet/minecraft/world/World;Lnet/minecraft/entity/player/PlayerEntity;Lnet/minecraft/world/RaycastContext$FluidHandling;)Lnet/minecraft/util/hit/BlockHitResult;", shift = At.Shift.AFTER), cancellable = true, locals = LocalCapture.CAPTURE_FAILSOFT) void use(World world, PlayerEntity user, Hand hand, CallbackInfoReturnable> cir, ItemStack itemStack, BlockHitResult blockHitResult) { - if (!world.isClient) { + if (!world.isClient()) { if (blockHitResult.getType() == HitResult.Type.MISS) return; BlockPos blockPos = BlockPos.ofFloored(blockHitResult.getPos()); if (!WorldProtection.canModify(world, blockPos, user)) { - protectionWarning(user, "bucket_use"); + ServerUtils.protectionWarning(user, "bucket_use"); cir.setReturnValue(TypedActionResult.fail(user.getStackInHand(hand))); } } diff --git a/src/main/java/skylands/mixin/world/protection/ButtonMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/ButtonMixin.java similarity index 76% rename from src/main/java/skylands/mixin/world/protection/ButtonMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/ButtonMixin.java index f83c7fa..ad0b452 100644 --- a/src/main/java/skylands/mixin/world/protection/ButtonMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/ButtonMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.block.BlockState; import net.minecraft.block.ButtonBlock; import net.minecraft.block.WallMountedBlock; @@ -13,12 +14,10 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(ButtonBlock.class) -public class ButtonMixin extends WallMountedBlock { +public abstract class ButtonMixin extends WallMountedBlock { public ButtonMixin(Settings settings) { super(settings); @@ -26,9 +25,9 @@ public ButtonMixin(Settings settings) { @Inject(method = "onUse", at = @At("HEAD"), cancellable = true) void onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable cir) { - if (!world.isClient) { + if (!world.isClient()) { if (!WorldProtection.canModify(world, pos, player)) { - protectionWarning(player, "redstone"); + ServerUtils.protectionWarning(player, "redstone"); cir.setReturnValue(ActionResult.FAIL); } } diff --git a/src/main/java/skylands/mixin/world/protection/CampfireBlockMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/CampfireBlockMixin.java similarity index 81% rename from src/main/java/skylands/mixin/world/protection/CampfireBlockMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/CampfireBlockMixin.java index 4c4b108..df1225f 100644 --- a/src/main/java/skylands/mixin/world/protection/CampfireBlockMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/CampfireBlockMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.block.BlockState; import net.minecraft.block.CampfireBlock; import net.minecraft.entity.player.PlayerEntity; @@ -17,9 +18,7 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(CampfireBlock.class) public class CampfireBlockMixin { @@ -30,9 +29,9 @@ public class CampfireBlockMixin { @Inject(method = "onUse", at = @At("HEAD"), cancellable = true) void onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable cir) { - if (!world.isClient) { + if (!world.isClient()) { if (!WorldProtection.canModify(world, pos, player)) { - if (state.get(LIT)) protectionWarning(player, "interact"); + if (state.get(LIT)) ServerUtils.protectionWarning(player, "interact"); cir.setReturnValue(ActionResult.FAIL); } } @@ -40,10 +39,10 @@ void onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Han @Inject(method = "onProjectileHit", at = @At("HEAD"), cancellable = true) private void onProjectileHit(World world, BlockState state, BlockHitResult hit, ProjectileEntity projectile, CallbackInfo ci) { - if (!world.isClient) { + if (!world.isClient()) { BlockPos pos = hit.getBlockPos(); if ((projectile.getOwner() instanceof PlayerEntity player && !WorldProtection.canModify(world, pos, player))) { - if (projectile.isOnFire()) protectionWarning(player, "ignite"); + if (projectile.isOnFire()) ServerUtils.protectionWarning(player, "ignite"); ci.cancel(); } else if (!WorldProtection.isWithinIsland(world, pos)) { ci.cancel(); diff --git a/src/main/java/skylands/mixin/world/protection/CandleBlockMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/CandleBlockMixin.java similarity index 79% rename from src/main/java/skylands/mixin/world/protection/CandleBlockMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/CandleBlockMixin.java index 3db77e2..7ad1788 100644 --- a/src/main/java/skylands/mixin/world/protection/CandleBlockMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/CandleBlockMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.block.BlockState; import net.minecraft.block.CandleBlock; import net.minecraft.entity.player.PlayerEntity; @@ -15,9 +16,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(CandleBlock.class) public class CandleBlockMixin { @@ -28,9 +27,9 @@ public class CandleBlockMixin { @Inject(method = "onUse", at = @At("HEAD"), cancellable = true) void onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable cir) { - if (!world.isClient) { + if (!world.isClient()) { if (!WorldProtection.canModify(world, pos, player)) { - if (state.get(LIT)) protectionWarning(player, "extinguish"); + if (state.get(LIT)) ServerUtils.protectionWarning(player, "extinguish"); cir.setReturnValue(ActionResult.FAIL); } } diff --git a/src/main/java/skylands/mixin/world/protection/CandleCakeBlockMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/CandleCakeBlockMixin.java similarity index 80% rename from src/main/java/skylands/mixin/world/protection/CandleCakeBlockMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/CandleCakeBlockMixin.java index ad4376f..f3812c6 100644 --- a/src/main/java/skylands/mixin/world/protection/CandleCakeBlockMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/CandleCakeBlockMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.block.BlockState; import net.minecraft.block.CandleCakeBlock; import net.minecraft.entity.player.PlayerEntity; @@ -15,9 +16,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(CandleCakeBlock.class) public class CandleCakeBlockMixin { @@ -28,9 +27,9 @@ public class CandleCakeBlockMixin { @Inject(method = "onUse", at = @At("HEAD"), cancellable = true) void onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable cir) { - if (!world.isClient) { + if (!world.isClient()) { if (!WorldProtection.canModify(world, pos, player)) { - if (state.get(LIT)) protectionWarning(player, "extinguish"); + if (state.get(LIT)) ServerUtils.protectionWarning(player, "extinguish"); cir.setReturnValue(ActionResult.FAIL); } } diff --git a/src/main/java/skylands/mixin/world/protection/CauldronBlockMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/CauldronBlockMixin.java similarity index 78% rename from src/main/java/skylands/mixin/world/protection/CauldronBlockMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/CauldronBlockMixin.java index 36af2dd..ede1575 100644 --- a/src/main/java/skylands/mixin/world/protection/CauldronBlockMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/CauldronBlockMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.block.AbstractCauldronBlock; import net.minecraft.block.BlockState; import net.minecraft.entity.player.PlayerEntity; @@ -12,18 +13,16 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(AbstractCauldronBlock.class) public class CauldronBlockMixin { @Inject(method = "onUse", at = @At("HEAD"), cancellable = true) void onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable cir) { - if (!world.isClient) { + if (!world.isClient()) { if (!WorldProtection.canModify(world, pos, player)) { - protectionWarning(player, "cauldron"); + ServerUtils.protectionWarning(player, "cauldron"); cir.setReturnValue(ActionResult.FAIL); } } diff --git a/src/main/java/skylands/mixin/world/protection/ChestBlockMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/ChestBlockMixin.java similarity index 77% rename from src/main/java/skylands/mixin/world/protection/ChestBlockMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/ChestBlockMixin.java index 71b9633..eaf7fa8 100644 --- a/src/main/java/skylands/mixin/world/protection/ChestBlockMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/ChestBlockMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.block.BlockState; import net.minecraft.block.ChestBlock; import net.minecraft.entity.player.PlayerEntity; @@ -12,18 +13,16 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(ChestBlock.class) public class ChestBlockMixin { @Inject(method = "onUse", at = @At("HEAD"), cancellable = true) void onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable cir) { - if (!world.isClient) { + if (!world.isClient()) { if (!WorldProtection.canModify(world, pos, player)) { - protectionWarning(player, "chest_open"); + ServerUtils.protectionWarning(player, "chest_open"); cir.setReturnValue(ActionResult.FAIL); } } diff --git a/src/main/java/skylands/mixin/world/protection/ChestBoatMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/ChestBoatMixin.java similarity index 73% rename from src/main/java/skylands/mixin/world/protection/ChestBoatMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/ChestBoatMixin.java index 66b4fd2..81df5e0 100644 --- a/src/main/java/skylands/mixin/world/protection/ChestBoatMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/ChestBoatMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.entity.EntityType; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.vehicle.BoatEntity; @@ -11,9 +12,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(ChestBoatEntity.class) public class ChestBoatMixin extends BoatEntity { @@ -24,9 +23,9 @@ public ChestBoatMixin(EntityType entityType, World world) @Inject(method = "interact", at = @At("HEAD"), cancellable = true) void interact(PlayerEntity player, Hand hand, CallbackInfoReturnable cir) { - if (!player.world.isClient) { - if (!WorldProtection.canModify(player.world, player)) { - protectionWarning(player, "boat_open"); + if (!player.getWorld().isClient()) { + if (!WorldProtection.canModify(player.getWorld(), player)) { + ServerUtils.protectionWarning(player, "boat_open"); cir.setReturnValue(ActionResult.FAIL); } } diff --git a/src/main/java/skylands/mixin/world/protection/ComparatorMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/ComparatorMixin.java similarity index 80% rename from src/main/java/skylands/mixin/world/protection/ComparatorMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/ComparatorMixin.java index ce60aea..b313f9e 100644 --- a/src/main/java/skylands/mixin/world/protection/ComparatorMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/ComparatorMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.block.AbstractRedstoneGateBlock; import net.minecraft.block.BlockState; import net.minecraft.block.ComparatorBlock; @@ -13,9 +14,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(ComparatorBlock.class) public abstract class ComparatorMixin extends AbstractRedstoneGateBlock { @@ -26,9 +25,9 @@ protected ComparatorMixin(Settings settings) { @Inject(method = "onUse", at = @At("HEAD"), cancellable = true) void onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable cir) { - if (!world.isClient) { + if (!world.isClient()) { if (!WorldProtection.canModify(world, pos, player)) { - protectionWarning(player, "redstone"); + ServerUtils.protectionWarning(player, "redstone"); cir.setReturnValue(ActionResult.FAIL); } } diff --git a/src/main/java/skylands/mixin/world/protection/CompassItemMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/CompassItemMixin.java similarity index 76% rename from src/main/java/skylands/mixin/world/protection/CompassItemMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/CompassItemMixin.java index 0438d94..e145465 100644 --- a/src/main/java/skylands/mixin/world/protection/CompassItemMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/CompassItemMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.block.Blocks; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.CompassItem; @@ -12,9 +13,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(CompassItem.class) public class CompassItemMixin { @@ -24,9 +23,11 @@ void useOnBlock(ItemUsageContext context, CallbackInfoReturnable c World world = context.getWorld(); PlayerEntity player = context.getPlayer(); BlockPos blockPos = context.getBlockPos(); - if (!world.isClient && player instanceof ServerPlayerEntity serverPlayer) { + if (!world.isClient() && player instanceof ServerPlayerEntity serverPlayer) { if (!WorldProtection.canModify(world, blockPos, serverPlayer)) { - if (world.getBlockState(blockPos).isOf(Blocks.LODESTONE)) protectionWarning(player, "lodestone"); + if (world.getBlockState(blockPos).isOf(Blocks.LODESTONE)) { + ServerUtils.protectionWarning(player, "lodestone"); + } cir.setReturnValue(ActionResult.FAIL); } } diff --git a/src/main/java/skylands/mixin/world/protection/ComposterBlockMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/ComposterBlockMixin.java similarity index 78% rename from src/main/java/skylands/mixin/world/protection/ComposterBlockMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/ComposterBlockMixin.java index 4c347ed..0890fdd 100644 --- a/src/main/java/skylands/mixin/world/protection/ComposterBlockMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/ComposterBlockMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.block.BlockState; import net.minecraft.block.ComposterBlock; import net.minecraft.entity.player.PlayerEntity; @@ -12,18 +13,16 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(ComposterBlock.class) public class ComposterBlockMixin { @Inject(method = "onUse", at = @At("HEAD"), cancellable = true) void onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable cir) { - if (!world.isClient) { + if (!world.isClient()) { if (!WorldProtection.canModify(world, pos, player)) { - protectionWarning(player, "composter"); + ServerUtils.protectionWarning(player, "composter"); cir.setReturnValue(ActionResult.FAIL); } } diff --git a/src/main/java/skylands/mixin/world/protection/DaylightDetectorBlockMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/DaylightDetectorBlockMixin.java similarity index 78% rename from src/main/java/skylands/mixin/world/protection/DaylightDetectorBlockMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/DaylightDetectorBlockMixin.java index a73413d..cf0caeb 100644 --- a/src/main/java/skylands/mixin/world/protection/DaylightDetectorBlockMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/DaylightDetectorBlockMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.block.BlockState; import net.minecraft.block.DaylightDetectorBlock; import net.minecraft.entity.player.PlayerEntity; @@ -12,18 +13,16 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(DaylightDetectorBlock.class) public class DaylightDetectorBlockMixin { @Inject(method = "onUse", at = @At("HEAD"), cancellable = true) private void onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable cir) { - if (!world.isClient) { + if (!world.isClient()) { if (!WorldProtection.canModify(world, pos, player)) { - protectionWarning(player, "redstone"); + ServerUtils.protectionWarning(player, "redstone"); cir.setReturnValue(ActionResult.FAIL); } } diff --git a/src/main/java/skylands/mixin/world/protection/DecorationEntityMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/DecorationEntityMixin.java similarity index 71% rename from src/main/java/skylands/mixin/world/protection/DecorationEntityMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/DecorationEntityMixin.java index 6057a3f..ebf08df 100644 --- a/src/main/java/skylands/mixin/world/protection/DecorationEntityMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/DecorationEntityMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; import net.minecraft.entity.damage.DamageSource; @@ -12,9 +13,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(AbstractDecorationEntity.class) public abstract class DecorationEntityMixin extends Entity { @@ -28,9 +27,9 @@ public DecorationEntityMixin(EntityType type, World world) { @Inject(method = "damage", at = @At("HEAD"), cancellable = true) void damage(DamageSource source, float amount, CallbackInfoReturnable cir) { - if (!world.isClient && source.getAttacker() instanceof PlayerEntity attacker) { - if (!WorldProtection.canModify(world, this.getBlockPos(), attacker)) { - protectionWarning(attacker, "entity_hurt"); + if (!getWorld().isClient() && source.getAttacker() instanceof PlayerEntity attacker) { + if (!WorldProtection.canModify(getWorld(), this.getBlockPos(), attacker)) { + ServerUtils.protectionWarning(attacker, "entity_hurt"); cir.setReturnValue(false); } } diff --git a/src/main/java/skylands/mixin/world/protection/DecorationItemMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/DecorationItemMixin.java similarity index 78% rename from src/main/java/skylands/mixin/world/protection/DecorationItemMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/DecorationItemMixin.java index 591b100..ca1f0d3 100644 --- a/src/main/java/skylands/mixin/world/protection/DecorationItemMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/DecorationItemMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.DecorationItem; import net.minecraft.item.Item; @@ -10,9 +11,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(DecorationItem.class) public class DecorationItemMixin extends Item { @@ -25,9 +24,9 @@ public DecorationItemMixin(Settings settings) { void useOnBlock(ItemUsageContext context, CallbackInfoReturnable cir) { World world = context.getWorld(); PlayerEntity player = context.getPlayer(); - if (!world.isClient && player != null) { + if (!world.isClient() && player != null) { if (!WorldProtection.canModify(world, context.getBlockPos().offset(context.getSide()), player)) { - protectionWarning(player, "item_place"); + ServerUtils.protectionWarning(player, "item_place"); cir.setReturnValue(ActionResult.FAIL); } } diff --git a/src/main/java/skylands/mixin/world/protection/DispenserBlockMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/DispenserBlockMixin.java similarity index 79% rename from src/main/java/skylands/mixin/world/protection/DispenserBlockMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/DispenserBlockMixin.java index c16f9d1..115b00e 100644 --- a/src/main/java/skylands/mixin/world/protection/DispenserBlockMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/DispenserBlockMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.block.BlockState; import net.minecraft.block.DispenserBlock; import net.minecraft.entity.player.PlayerEntity; @@ -17,9 +18,7 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(DispenserBlock.class) public class DispenserBlockMixin { @@ -29,8 +28,8 @@ public class DispenserBlockMixin { public static DirectionProperty FACING; @Inject(method = "dispense", at = @At("HEAD"), cancellable = true) - private void dispense(ServerWorld world, BlockPos pos, CallbackInfo ci) { - if (!world.isClient) { + private void dispense(ServerWorld world, BlockState state, BlockPos pos, CallbackInfo ci) { + if (!world.isClient()) { if (!WorldProtection.isWithinIsland(world, pos) || !WorldProtection.isWithinIsland(world, pos.offset((world.getBlockState(pos).get(FACING))))) { ci.cancel(); } @@ -39,9 +38,9 @@ private void dispense(ServerWorld world, BlockPos pos, CallbackInfo ci) { @Inject(method = "onUse", at = @At("HEAD"), cancellable = true) private void onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable cir) { - if (!world.isClient) { + if (!world.isClient()) { if (!WorldProtection.canModify(world, pos, player)) { - protectionWarning(player, "dispenser_open"); + ServerUtils.protectionWarning(player, "dispenser_open"); cir.setReturnValue(ActionResult.FAIL); } } diff --git a/src/main/java/skylands/mixin/world/protection/DoorBlockMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/DoorBlockMixin.java similarity index 77% rename from src/main/java/skylands/mixin/world/protection/DoorBlockMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/DoorBlockMixin.java index 970b997..05a582d 100644 --- a/src/main/java/skylands/mixin/world/protection/DoorBlockMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/DoorBlockMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.block.BlockState; import net.minecraft.block.DoorBlock; import net.minecraft.entity.player.PlayerEntity; @@ -12,18 +13,16 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(DoorBlock.class) public class DoorBlockMixin { @Inject(method = "onUse", at = @At("HEAD"), cancellable = true) void onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable cir) { - if (!world.isClient) { + if (!world.isClient()) { if (!WorldProtection.canModify(world, pos, player)) { - protectionWarning(player, "door_open"); + ServerUtils.protectionWarning(player, "door_open"); cir.setReturnValue(ActionResult.FAIL); } } diff --git a/src/main/java/skylands/mixin/world/protection/DropperBlockMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/DropperBlockMixin.java similarity index 71% rename from src/main/java/skylands/mixin/world/protection/DropperBlockMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/DropperBlockMixin.java index 4f2e43f..9849356 100644 --- a/src/main/java/skylands/mixin/world/protection/DropperBlockMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/DropperBlockMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import net.minecraft.block.BlockState; import net.minecraft.block.DropperBlock; import net.minecraft.server.world.ServerWorld; import net.minecraft.util.math.BlockPos; @@ -7,14 +8,14 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import skylands.util.WorldProtection; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(DropperBlock.class) public class DropperBlockMixin extends DispenserBlockMixin { @Inject(method = "dispense", at = @At("HEAD"), cancellable = true) - private void dispense(ServerWorld world, BlockPos pos, CallbackInfo ci) { - if (!world.isClient) { + private void dispense(ServerWorld world, BlockState state, BlockPos pos, CallbackInfo ci) { + if (!world.isClient()) { if (!WorldProtection.isWithinIsland(world, pos) || !WorldProtection.isWithinIsland(world, pos.offset((world.getBlockState(pos).get(FACING))))) { ci.cancel(); } diff --git a/src/main/java/skylands/mixin/world/protection/EnderEyeItemMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/EnderEyeItemMixin.java similarity index 75% rename from src/main/java/skylands/mixin/world/protection/EnderEyeItemMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/EnderEyeItemMixin.java index 00d589f..cd9c703 100644 --- a/src/main/java/skylands/mixin/world/protection/EnderEyeItemMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/EnderEyeItemMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.EnderEyeItem; import net.minecraft.item.ItemUsageContext; @@ -9,9 +10,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(EnderEyeItem.class) public class EnderEyeItemMixin { @@ -20,9 +19,9 @@ public class EnderEyeItemMixin { void useOnBlock(ItemUsageContext context, CallbackInfoReturnable cir) { World world = context.getWorld(); PlayerEntity player = context.getPlayer(); - if (!world.isClient && player != null) { + if (!world.isClient() && player != null) { if (!WorldProtection.canModify(world, context.getBlockPos(), player)) { - protectionWarning(player, "interact"); + ServerUtils.protectionWarning(player, "interact"); cir.setReturnValue(ActionResult.FAIL); } } diff --git a/src/main/java/skylands/mixin/world/protection/FarmlandBlockMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/FarmlandBlockMixin.java similarity index 72% rename from src/main/java/skylands/mixin/world/protection/FarmlandBlockMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/FarmlandBlockMixin.java index 8bc7a1f..6548e51 100644 --- a/src/main/java/skylands/mixin/world/protection/FarmlandBlockMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/FarmlandBlockMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.block.BlockState; import net.minecraft.block.FarmlandBlock; import net.minecraft.entity.Entity; @@ -10,18 +11,16 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(FarmlandBlock.class) public class FarmlandBlockMixin { @Inject(method = "onLandedUpon", at = @At("HEAD"), cancellable = true) void onLandedUpon(World world, BlockState state, BlockPos pos, Entity entity, float fallDistance, CallbackInfo ci) { - if (!world.isClient && entity instanceof PlayerEntity player) { + if (!world.isClient() && entity instanceof PlayerEntity player) { if (!WorldProtection.canModify(world, pos, player)) { - protectionWarning(player, "farmland_spoil"); + ServerUtils.protectionWarning(player, "farmland_spoil"); ci.cancel(); } } diff --git a/src/main/java/skylands/mixin/world/protection/FenceBlockMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/FenceBlockMixin.java similarity index 78% rename from src/main/java/skylands/mixin/world/protection/FenceBlockMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/FenceBlockMixin.java index aafafde..4998540 100644 --- a/src/main/java/skylands/mixin/world/protection/FenceBlockMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/FenceBlockMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.block.BlockState; import net.minecraft.block.FenceBlock; import net.minecraft.entity.player.PlayerEntity; @@ -12,18 +13,16 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(FenceBlock.class) public class FenceBlockMixin { @Inject(method = "onUse", at = @At("HEAD"), cancellable = true) void onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable cir) { - if (!world.isClient) { + if (!world.isClient()) { if (!WorldProtection.canModify(world, pos, player)) { - protectionWarning(player, "fence"); + ServerUtils.protectionWarning(player, "fence"); cir.setReturnValue(ActionResult.FAIL); } } diff --git a/src/main/java/skylands/mixin/world/protection/FenceGateBlockMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/FenceGateBlockMixin.java similarity index 77% rename from src/main/java/skylands/mixin/world/protection/FenceGateBlockMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/FenceGateBlockMixin.java index 4369b02..3131287 100644 --- a/src/main/java/skylands/mixin/world/protection/FenceGateBlockMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/FenceGateBlockMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.block.BlockState; import net.minecraft.block.FenceGateBlock; import net.minecraft.entity.player.PlayerEntity; @@ -12,18 +13,16 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(FenceGateBlock.class) public class FenceGateBlockMixin { @Inject(method = "onUse", at = @At("HEAD"), cancellable = true) void onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable cir) { - if (!world.isClient) { + if (!world.isClient()) { if (!WorldProtection.canModify(world, pos, player)) { - protectionWarning(player, "fence_gate_open"); + ServerUtils.protectionWarning(player, "fence_gate_open"); cir.setReturnValue(ActionResult.FAIL); } } diff --git a/src/main/java/skylands/mixin/world/protection/FilledMapItemMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/FilledMapItemMixin.java similarity index 75% rename from src/main/java/skylands/mixin/world/protection/FilledMapItemMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/FilledMapItemMixin.java index a7535b4..aa60f07 100644 --- a/src/main/java/skylands/mixin/world/protection/FilledMapItemMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/FilledMapItemMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.FilledMapItem; import net.minecraft.item.ItemUsageContext; @@ -9,9 +10,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(FilledMapItem.class) public class FilledMapItemMixin { @@ -20,9 +19,9 @@ public class FilledMapItemMixin { void useOnBlock(ItemUsageContext context, CallbackInfoReturnable cir) { World world = context.getWorld(); PlayerEntity player = context.getPlayer(); - if (!world.isClient && player != null) { + if (!world.isClient() && player != null) { if (!WorldProtection.canModify(world, context.getBlockPos(), player)) { - protectionWarning(player, "interact"); + ServerUtils.protectionWarning(player, "interact"); cir.setReturnValue(ActionResult.FAIL); } } diff --git a/src/main/java/skylands/mixin/world/protection/FireChargeItemMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/FireChargeItemMixin.java similarity index 77% rename from src/main/java/skylands/mixin/world/protection/FireChargeItemMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/FireChargeItemMixin.java index 0460f9e..d98d272 100644 --- a/src/main/java/skylands/mixin/world/protection/FireChargeItemMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/FireChargeItemMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.FireChargeItem; import net.minecraft.item.ItemUsageContext; @@ -10,9 +11,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(FireChargeItem.class) public class FireChargeItemMixin { @@ -22,9 +21,9 @@ void useOnBlock(ItemUsageContext context, CallbackInfoReturnable c World world = context.getWorld(); PlayerEntity player = context.getPlayer(); BlockPos blockPos = context.getBlockPos(); - if (!world.isClient && player != null) { + if (!world.isClient() && player != null) { if (!WorldProtection.canModify(world, blockPos.offset(context.getSide()), player)) { - protectionWarning(player, "flint_and_steel_use"); + ServerUtils.protectionWarning(player, "flint_and_steel_use"); cir.setReturnValue(ActionResult.FAIL); } } diff --git a/src/main/java/skylands/mixin/world/protection/FlintAndSteelMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/FlintAndSteelMixin.java similarity index 78% rename from src/main/java/skylands/mixin/world/protection/FlintAndSteelMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/FlintAndSteelMixin.java index 74d2071..301a924 100644 --- a/src/main/java/skylands/mixin/world/protection/FlintAndSteelMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/FlintAndSteelMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.block.TntBlock; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.FlintAndSteelItem; @@ -11,9 +12,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(FlintAndSteelItem.class) public class FlintAndSteelMixin { @@ -23,10 +22,10 @@ void useOnBlock(ItemUsageContext context, CallbackInfoReturnable c World world = context.getWorld(); PlayerEntity player = context.getPlayer(); BlockPos blockPos = context.getBlockPos(); - if (!world.isClient && player != null) { + if (!world.isClient() && player != null) { if (!WorldProtection.canModify(world, blockPos.offset(context.getSide()), player)) { if (!(world.getBlockState(blockPos).getBlock() instanceof TntBlock)) - protectionWarning(player, "flint_and_steel_use"); + ServerUtils.protectionWarning(player, "flint_and_steel_use"); cir.setReturnValue(ActionResult.FAIL); } } diff --git a/src/main/java/skylands/mixin/world/protection/FlowerPotBlockMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/FlowerPotBlockMixin.java similarity index 77% rename from src/main/java/skylands/mixin/world/protection/FlowerPotBlockMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/FlowerPotBlockMixin.java index 7bf8111..d491e8e 100644 --- a/src/main/java/skylands/mixin/world/protection/FlowerPotBlockMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/FlowerPotBlockMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.block.BlockState; import net.minecraft.block.FlowerPotBlock; import net.minecraft.entity.player.PlayerEntity; @@ -12,18 +13,16 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(FlowerPotBlock.class) public class FlowerPotBlockMixin { @Inject(method = "onUse", at = @At("HEAD"), cancellable = true) void onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable cir) { - if (!world.isClient) { + if (!world.isClient()) { if (!WorldProtection.canModify(world, pos, player)) { - protectionWarning(player, "flower_pot_use"); + ServerUtils.protectionWarning(player, "flower_pot_use"); cir.setReturnValue(ActionResult.FAIL); } } diff --git a/src/main/java/skylands/mixin/world/protection/FurnaceBlockMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/FurnaceBlockMixin.java similarity index 78% rename from src/main/java/skylands/mixin/world/protection/FurnaceBlockMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/FurnaceBlockMixin.java index 03bd69b..9bcd3cf 100644 --- a/src/main/java/skylands/mixin/world/protection/FurnaceBlockMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/FurnaceBlockMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.block.AbstractFurnaceBlock; import net.minecraft.block.BlockState; import net.minecraft.entity.player.PlayerEntity; @@ -12,18 +13,16 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(AbstractFurnaceBlock.class) public class FurnaceBlockMixin { @Inject(method = "onUse", at = @At("HEAD"), cancellable = true) void onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable cir) { - if (!world.isClient) { + if (!world.isClient()) { if (!WorldProtection.canModify(world, pos, player)) { - protectionWarning(player, "furnace_open"); + ServerUtils.protectionWarning(player, "furnace_open"); cir.setReturnValue(ActionResult.FAIL); } } diff --git a/src/main/java/skylands/mixin/world/protection/HoeItemMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/HoeItemMixin.java similarity index 75% rename from src/main/java/skylands/mixin/world/protection/HoeItemMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/HoeItemMixin.java index 821a537..2e8f271 100644 --- a/src/main/java/skylands/mixin/world/protection/HoeItemMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/HoeItemMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.HoeItem; import net.minecraft.item.ItemUsageContext; @@ -9,9 +10,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(HoeItem.class) public class HoeItemMixin { @@ -20,9 +19,9 @@ public class HoeItemMixin { void useOnBlock(ItemUsageContext context, CallbackInfoReturnable cir) { World world = context.getWorld(); PlayerEntity player = context.getPlayer(); - if (!world.isClient && player != null) { + if (!world.isClient() && player != null) { if (!WorldProtection.canModify(world, context.getBlockPos(), player)) { - protectionWarning(player, "hoe_use"); + ServerUtils.protectionWarning(player, "hoe_use"); cir.setReturnValue(ActionResult.FAIL); } } diff --git a/src/main/java/skylands/mixin/world/protection/HoneycombItemMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/HoneycombItemMixin.java similarity index 77% rename from src/main/java/skylands/mixin/world/protection/HoneycombItemMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/HoneycombItemMixin.java index b19e2ea..e030c05 100644 --- a/src/main/java/skylands/mixin/world/protection/HoneycombItemMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/HoneycombItemMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.HoneycombItem; import net.minecraft.item.ItemUsageContext; @@ -10,9 +11,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(HoneycombItem.class) public class HoneycombItemMixin { @@ -21,10 +20,10 @@ public class HoneycombItemMixin { void useOnBlock(ItemUsageContext context, CallbackInfoReturnable cir) { World world = context.getWorld(); PlayerEntity player = context.getPlayer(); - if (!world.isClient && player != null) { + if (!world.isClient() && player != null) { BlockPos blockPos = context.getBlockPos(); if (!WorldProtection.canModify(world, blockPos, player)) { - protectionWarning(player, "item_use"); + ServerUtils.protectionWarning(player, "item_use"); cir.setReturnValue(ActionResult.FAIL); } } diff --git a/src/main/java/skylands/mixin/world/protection/HopperBlockEntityMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/HopperBlockEntityMixin.java similarity index 91% rename from src/main/java/skylands/mixin/world/protection/HopperBlockEntityMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/HopperBlockEntityMixin.java index e4a94f7..ec44a08 100644 --- a/src/main/java/skylands/mixin/world/protection/HopperBlockEntityMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/HopperBlockEntityMixin.java @@ -1,4 +1,4 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; import net.minecraft.block.BlockState; import net.minecraft.block.HopperBlock; @@ -12,7 +12,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import skylands.util.WorldProtection; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(HopperBlockEntity.class) public abstract class HopperBlockEntityMixin extends LootableContainerBlockEntity { diff --git a/src/main/java/skylands/mixin/world/protection/HopperBlockMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/HopperBlockMixin.java similarity index 85% rename from src/main/java/skylands/mixin/world/protection/HopperBlockMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/HopperBlockMixin.java index b257e07..6b06515 100644 --- a/src/main/java/skylands/mixin/world/protection/HopperBlockMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/HopperBlockMixin.java @@ -1,6 +1,8 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import com.llamalad7.mixinextras.injector.ModifyReturnValue; +import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.BlockWithEntity; import net.minecraft.block.HopperBlock; @@ -20,9 +22,7 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(HopperBlock.class) public abstract class HopperBlockMixin extends BlockWithEntity { @@ -35,9 +35,9 @@ protected HopperBlockMixin(Settings settings) { @Inject(method = "onUse", at = @At("HEAD"), cancellable = true) public void blockOpening(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable cir) { - if (!world.isClient) { + if (!world.isClient()) { if (!WorldProtection.canModify(world, pos, player)) { - protectionWarning(player, "hopper_open"); + ServerUtils.protectionWarning(player, "hopper_open"); cir.setReturnValue(ActionResult.FAIL); } } @@ -49,10 +49,10 @@ private BlockState lockHopper(BlockState original, ItemPlacementContext ctx) { } @Inject(method = "updateEnabled", at = @At("HEAD"), cancellable = true) - void lockHopper(World world, BlockPos pos, BlockState state, int flags, CallbackInfo ci) { - if (!world.isClient) { + void lockHopper(World world, BlockPos pos, BlockState state, CallbackInfo ci) { + if (!world.isClient()) { if (!WorldProtection.isWithinIsland(world, pos)) { - world.setBlockState(pos, state.with(ENABLED, false), flags); + world.setBlockState(pos, state.with(ENABLED, false), 0); ci.cancel(); } } diff --git a/src/main/java/skylands/mixin/world/protection/HopperMinecartEntityMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/HopperMinecartEntityMixin.java similarity index 81% rename from src/main/java/skylands/mixin/world/protection/HopperMinecartEntityMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/HopperMinecartEntityMixin.java index 3fc3209..6a249ac 100644 --- a/src/main/java/skylands/mixin/world/protection/HopperMinecartEntityMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/HopperMinecartEntityMixin.java @@ -1,4 +1,4 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; import net.minecraft.entity.EntityType; import net.minecraft.entity.vehicle.HopperMinecartEntity; @@ -8,7 +8,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(HopperMinecartEntity.class) public abstract class HopperMinecartEntityMixin extends StorageMinecartEntity { @@ -19,7 +19,7 @@ protected HopperMinecartEntityMixin(EntityType entityType, World world) { @Inject(method = "isEnabled", at = @At("TAIL"), cancellable = true) private void lockMinecartHopper(CallbackInfoReturnable cir) { - if (!WorldProtection.isWithinIsland(world, getBlockPos())) { + if (!WorldProtection.isWithinIsland(getWorld(), getBlockPos())) { cir.setReturnValue(false); } } diff --git a/src/main/java/skylands/mixin/world/protection/ItemFrameEntityMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/ItemFrameEntityMixin.java similarity index 68% rename from src/main/java/skylands/mixin/world/protection/ItemFrameEntityMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/ItemFrameEntityMixin.java index 2b7cb34..2e046cf 100644 --- a/src/main/java/skylands/mixin/world/protection/ItemFrameEntityMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/ItemFrameEntityMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.entity.EntityType; import net.minecraft.entity.damage.DamageSource; import net.minecraft.entity.decoration.AbstractDecorationEntity; @@ -12,9 +13,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(ItemFrameEntity.class) public abstract class ItemFrameEntityMixin extends AbstractDecorationEntity { @@ -25,9 +24,9 @@ protected ItemFrameEntityMixin(EntityType en @Inject(method = "damage", at = @At("HEAD"), cancellable = true) void damage(DamageSource source, float amount, CallbackInfoReturnable cir) { - if (!world.isClient && source.getAttacker() instanceof PlayerEntity attacker) { - if (!WorldProtection.canModify(world, attacker)) { - protectionWarning(attacker, "entity_hurt"); + if (!getWorld().isClient() && source.getAttacker() instanceof PlayerEntity attacker) { + if (!WorldProtection.canModify(getWorld(), attacker)) { + ServerUtils.protectionWarning(attacker, "entity_hurt"); cir.setReturnValue(false); } } @@ -35,9 +34,9 @@ void damage(DamageSource source, float amount, CallbackInfoReturnable c @Inject(method = "interact", at = @At("HEAD"), cancellable = true) void interact(PlayerEntity player, Hand hand, CallbackInfoReturnable cir) { - if (!player.world.isClient) { - if (!WorldProtection.canModify(world, this.getBlockPos(), player)) { - protectionWarning(player, "item_frame_use"); + if (!player.getWorld().isClient()) { + if (!WorldProtection.canModify(getWorld(), this.getBlockPos(), player)) { + ServerUtils.protectionWarning(player, "item_frame_use"); cir.setReturnValue(ActionResult.FAIL); } } diff --git a/src/main/java/skylands/mixin/world/protection/LeadItemMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/LeadItemMixin.java similarity index 76% rename from src/main/java/skylands/mixin/world/protection/LeadItemMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/LeadItemMixin.java index 27409dd..8e6e1a8 100644 --- a/src/main/java/skylands/mixin/world/protection/LeadItemMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/LeadItemMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemUsageContext; import net.minecraft.item.LeadItem; @@ -9,9 +10,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(LeadItem.class) public class LeadItemMixin { @@ -20,9 +19,9 @@ public class LeadItemMixin { void useOnBlock(ItemUsageContext context, CallbackInfoReturnable cir) { World world = context.getWorld(); PlayerEntity player = context.getPlayer(); - if (!world.isClient && player != null) { + if (!world.isClient() && player != null) { if (!WorldProtection.canModify(world, context.getBlockPos(), player)) { - protectionWarning(player, "fence"); + ServerUtils.protectionWarning(player, "fence"); player.getInventory().updateItems(); cir.setReturnValue(ActionResult.FAIL); } diff --git a/src/main/java/skylands/mixin/world/protection/LeashKnotEntityMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/LeashKnotEntityMixin.java similarity index 72% rename from src/main/java/skylands/mixin/world/protection/LeashKnotEntityMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/LeashKnotEntityMixin.java index 3a2aeed..73aa2db 100644 --- a/src/main/java/skylands/mixin/world/protection/LeashKnotEntityMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/LeashKnotEntityMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.entity.EntityType; import net.minecraft.entity.decoration.LeashKnotEntity; import net.minecraft.entity.player.PlayerEntity; @@ -10,9 +11,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(LeashKnotEntity.class) public abstract class LeashKnotEntityMixin extends DecorationEntityMixin { @@ -23,9 +22,9 @@ public LeashKnotEntityMixin(EntityType type, World world) { @Inject(method = "interact", at = @At("HEAD"), cancellable = true) void interact(PlayerEntity player, Hand hand, CallbackInfoReturnable cir) { - if (!world.isClient && player != null) { - if (!WorldProtection.canModify(world, attachmentPos, player)) { - protectionWarning(player, "leash"); + if (!getWorld().isClient() && player != null) { + if (!WorldProtection.canModify(getWorld(), attachmentPos, player)) { + ServerUtils.protectionWarning(player, "leash"); player.getInventory().updateItems(); cir.setReturnValue(ActionResult.FAIL); } diff --git a/src/main/java/skylands/mixin/world/protection/LecternBlockMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/LecternBlockMixin.java similarity index 81% rename from src/main/java/skylands/mixin/world/protection/LecternBlockMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/LecternBlockMixin.java index 8495bf3..ebae5b0 100644 --- a/src/main/java/skylands/mixin/world/protection/LecternBlockMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/LecternBlockMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.block.BlockState; import net.minecraft.block.LecternBlock; import net.minecraft.entity.player.PlayerEntity; @@ -15,9 +16,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(LecternBlock.class) public class LecternBlockMixin { @@ -28,9 +27,9 @@ public class LecternBlockMixin { @Inject(method = "onUse", at = @At("HEAD"), cancellable = true) void onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable cir) { - if (!world.isClient) { + if (!world.isClient()) { if (!WorldProtection.canModify(world, pos, player) && !state.get(HAS_BOOK)) { - protectionWarning(player, "lectern"); + ServerUtils.protectionWarning(player, "lectern"); cir.setReturnValue(ActionResult.FAIL); } } diff --git a/src/main/java/skylands/mixin/world/protection/LeverMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/LeverMixin.java similarity index 76% rename from src/main/java/skylands/mixin/world/protection/LeverMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/LeverMixin.java index c113aa6..7d59848 100644 --- a/src/main/java/skylands/mixin/world/protection/LeverMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/LeverMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.block.BlockState; import net.minecraft.block.LeverBlock; import net.minecraft.block.WallMountedBlock; @@ -13,12 +14,10 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(LeverBlock.class) -public class LeverMixin extends WallMountedBlock { +public abstract class LeverMixin extends WallMountedBlock { public LeverMixin(Settings settings) { super(settings); @@ -26,9 +25,9 @@ public LeverMixin(Settings settings) { @Inject(method = "onUse", at = @At("HEAD"), cancellable = true) void onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable cir) { - if (!world.isClient) { + if (!world.isClient()) { if (!WorldProtection.canModify(world, pos, player)) { - protectionWarning(player, "redstone"); + ServerUtils.protectionWarning(player, "redstone"); cir.setReturnValue(ActionResult.FAIL); } } diff --git a/src/main/java/skylands/mixin/world/protection/LivingEntityMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/LivingEntityMixin.java similarity index 63% rename from src/main/java/skylands/mixin/world/protection/LivingEntityMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/LivingEntityMixin.java index 1bf1f07..cf28f20 100644 --- a/src/main/java/skylands/mixin/world/protection/LivingEntityMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/LivingEntityMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; import net.minecraft.entity.LivingEntity; @@ -10,10 +11,8 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.api.SkylandsAPI; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.api.SkylandsAPI; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(LivingEntity.class) public abstract class LivingEntityMixin extends Entity { @@ -24,18 +23,18 @@ public LivingEntityMixin(EntityType type, World world) { @Inject(method = "damage", at = @At("HEAD"), cancellable = true) void damage(DamageSource source, float amount, CallbackInfoReturnable cir) { - if (!world.isClient) { + if (!getWorld().isClient()) { if ((LivingEntity) (Object) this instanceof PlayerEntity player) { - if (!WorldProtection.canModify(world, this.getBlockPos(), player) && !source.equals(world.getDamageSources().outOfWorld()) && !SkylandsAPI.isHub(world)) { + if (!WorldProtection.canModify(getWorld(), this.getBlockPos(), player) && !source.equals(getWorld().getDamageSources().outOfWorld()) && !SkylandsAPI.isHub(getWorld())) { cir.setReturnValue(false); } } if (source.getAttacker() instanceof PlayerEntity attacker) { System.out.println(attacker.getDisplayName()); System.out.println(this.getBlockPos()); - System.out.println(WorldProtection.canModify(world, this.getBlockPos(), attacker)); - if (!WorldProtection.canModify(world, this.getBlockPos(), attacker)) { - protectionWarning(attacker, "entity_hurt"); + System.out.println(WorldProtection.canModify(getWorld(), this.getBlockPos(), attacker)); + if (!WorldProtection.canModify(getWorld(), this.getBlockPos(), attacker)) { + ServerUtils.protectionWarning(attacker, "entity_hurt"); cir.setReturnValue(false); } } diff --git a/src/main/java/skylands/mixin/world/protection/MinecartMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/MinecartMixin.java similarity index 62% rename from src/main/java/skylands/mixin/world/protection/MinecartMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/MinecartMixin.java index a9bce05..c850e4a 100644 --- a/src/main/java/skylands/mixin/world/protection/MinecartMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/MinecartMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; import net.minecraft.entity.damage.DamageSource; @@ -10,9 +11,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(AbstractMinecartEntity.class) public abstract class MinecartMixin extends Entity { @@ -21,13 +20,13 @@ public MinecartMixin(EntityType type, World world) { super(type, world); } - @Inject(method = "damage", at = @At("HEAD"), cancellable = true) + /*@Inject(method = "damage", at = @At("HEAD"), cancellable = true) void damage(DamageSource source, float amount, CallbackInfoReturnable cir) { - if (!world.isClient && source.getAttacker() instanceof PlayerEntity attacker) { - if (!WorldProtection.canModify(world, getBlockPos(), attacker)) { - protectionWarning(attacker, "entity_hurt"); + if (!getWorld().isClient() && source.getAttacker() instanceof PlayerEntity attacker) { + if (!WorldProtection.canModify(getWorld(), getBlockPos(), attacker)) { + ServerUtils.protectionWarning(attacker, "entity_hurt"); cir.setReturnValue(false); } } - } + }*/ } diff --git a/src/main/java/skylands/mixin/world/protection/NoteBlockMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/NoteBlockMixin.java similarity index 77% rename from src/main/java/skylands/mixin/world/protection/NoteBlockMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/NoteBlockMixin.java index 7efcd4b..6a5a955 100644 --- a/src/main/java/skylands/mixin/world/protection/NoteBlockMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/NoteBlockMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.block.BlockState; import net.minecraft.block.NoteBlock; import net.minecraft.entity.player.PlayerEntity; @@ -12,18 +13,16 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(NoteBlock.class) public class NoteBlockMixin { @Inject(method = "onUse", at = @At("HEAD"), cancellable = true) void onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable cir) { - if (!world.isClient) { + if (!world.isClient()) { if (!WorldProtection.canModify(world, pos, player)) { - protectionWarning(player, "noteblock"); + ServerUtils.protectionWarning(player, "noteblock"); cir.setReturnValue(ActionResult.FAIL); } } diff --git a/src/main/java/skylands/mixin/world/protection/PistonBlockMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/PistonBlockMixin.java similarity index 92% rename from src/main/java/skylands/mixin/world/protection/PistonBlockMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/PistonBlockMixin.java index ab519cc..53692d0 100644 --- a/src/main/java/skylands/mixin/world/protection/PistonBlockMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/PistonBlockMixin.java @@ -1,4 +1,4 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; import net.minecraft.block.AirBlock; import net.minecraft.block.BlockState; @@ -10,7 +10,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(PistonBlock.class) public class PistonBlockMixin { diff --git a/src/main/java/skylands/mixin/world/protection/PlayerEntityMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/PlayerEntityMixin.java similarity index 78% rename from src/main/java/skylands/mixin/world/protection/PlayerEntityMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/PlayerEntityMixin.java index 538f1f0..5b4f198 100644 --- a/src/main/java/skylands/mixin/world/protection/PlayerEntityMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/PlayerEntityMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; import net.minecraft.util.math.BlockPos; @@ -9,9 +10,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(PlayerEntity.class) public class PlayerEntityMixin { @@ -20,10 +19,10 @@ public class PlayerEntityMixin { private void canPlaceOn(BlockPos pos, Direction facing, ItemStack stack, CallbackInfoReturnable cir) { PlayerEntity player = (PlayerEntity) (Object) this; World world = player.getWorld(); - if (!world.isClient) { + if (!world.isClient()) { BlockPos blockPos = pos.offset(facing); if (!WorldProtection.canModify(world, blockPos, player)) { - protectionWarning(player, "place_on"); + ServerUtils.protectionWarning(player, "place_on"); cir.setReturnValue(false); } } @@ -33,9 +32,9 @@ private void canPlaceOn(BlockPos pos, Direction facing, ItemStack stack, Callbac private void canModifyBlocks(CallbackInfoReturnable cir) { PlayerEntity player = (PlayerEntity) (Object) this; World world = player.getWorld(); - if (!world.isClient) { + if (!world.isClient()) { if (!WorldProtection.canModify(world, player)) { - protectionWarning(player, "modify"); + ServerUtils.protectionWarning(player, "modify"); cir.setReturnValue(false); } } diff --git a/src/main/java/skylands/mixin/world/protection/PotionEntityMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/PotionEntityMixin.java similarity index 73% rename from src/main/java/skylands/mixin/world/protection/PotionEntityMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/PotionEntityMixin.java index 92dbfff..10e049a 100644 --- a/src/main/java/skylands/mixin/world/protection/PotionEntityMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/PotionEntityMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.block.AbstractCandleBlock; import net.minecraft.block.BlockState; import net.minecraft.block.CampfireBlock; @@ -14,9 +15,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(PotionEntity.class) public abstract class PotionEntityMixin extends ThrownItemEntity { @@ -27,14 +26,14 @@ public PotionEntityMixin(EntityType entityType, Worl @Inject(method = "extinguishFire", at = @At("HEAD"), cancellable = true) void interact(BlockPos pos, CallbackInfo ci) { - if (!world.isClient) { - if ((getOwner() instanceof PlayerEntity player && !WorldProtection.canModify(world, pos, player))) { - BlockState blockState = this.world.getBlockState(pos); + if (!getWorld().isClient()) { + if ((getOwner() instanceof PlayerEntity player && !WorldProtection.canModify(getWorld(), pos, player))) { + BlockState blockState = this.getWorld().getBlockState(pos); if (blockState.isIn(BlockTags.FIRE) || AbstractCandleBlock.isLitCandle(blockState) || CampfireBlock.isLitCampfire(blockState)) { - protectionWarning(player, "extinguish"); + ServerUtils.protectionWarning(player, "extinguish"); } ci.cancel(); - } else if (!WorldProtection.isWithinIsland(world, pos)) { + } else if (!WorldProtection.isWithinIsland(getWorld(), pos)) { ci.cancel(); } } diff --git a/src/main/java/skylands/mixin/world/protection/PressurePlateBlockMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/PressurePlateBlockMixin.java similarity index 78% rename from src/main/java/skylands/mixin/world/protection/PressurePlateBlockMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/PressurePlateBlockMixin.java index 1bc5faf..3bd5c48 100644 --- a/src/main/java/skylands/mixin/world/protection/PressurePlateBlockMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/PressurePlateBlockMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.block.AbstractPressurePlateBlock; import net.minecraft.block.BlockState; import net.minecraft.entity.Entity; @@ -10,18 +11,16 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(AbstractPressurePlateBlock.class) public class PressurePlateBlockMixin { @Inject(method = "updatePlateState", at = @At("HEAD"), cancellable = true) private void updatePlateState(Entity entity, World world, BlockPos pos, BlockState state, int output, CallbackInfo ci) { - if (!world.isClient) { + if (!world.isClient()) { if ((entity instanceof PlayerEntity player && !WorldProtection.canModify(world, pos, player))) { - protectionWarning(player, "redstone"); + ServerUtils.protectionWarning(player, "redstone"); ci.cancel(); } else if (!WorldProtection.isWithinIsland(world, pos)) { ci.cancel(); diff --git a/src/main/java/skylands/mixin/world/protection/PumpkinBlockMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/PumpkinBlockMixin.java similarity index 77% rename from src/main/java/skylands/mixin/world/protection/PumpkinBlockMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/PumpkinBlockMixin.java index d2d499b..d24afea 100644 --- a/src/main/java/skylands/mixin/world/protection/PumpkinBlockMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/PumpkinBlockMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.block.BlockState; import net.minecraft.block.PumpkinBlock; import net.minecraft.entity.player.PlayerEntity; @@ -13,18 +14,18 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(PumpkinBlock.class) public class PumpkinBlockMixin { @Inject(method = "onUse", at = @At("HEAD"), cancellable = true) void onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable cir) { - if (!world.isClient) { + if (!world.isClient()) { if (!WorldProtection.canModify(world, pos, player)) { - if (player.getMainHandStack().getItem() instanceof ShearsItem) protectionWarning(player, "shears_use"); + if (player.getMainHandStack().getItem() instanceof ShearsItem) { + ServerUtils.protectionWarning(player, "shears_use"); + } cir.setReturnValue(ActionResult.FAIL); } } diff --git a/src/main/java/skylands/mixin/world/protection/RedstoneWireMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/RedstoneWireMixin.java similarity index 88% rename from src/main/java/skylands/mixin/world/protection/RedstoneWireMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/RedstoneWireMixin.java index b2e42a4..5455098 100644 --- a/src/main/java/skylands/mixin/world/protection/RedstoneWireMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/RedstoneWireMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.RedstoneWireBlock; @@ -18,9 +19,7 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(RedstoneWireBlock.class) public class RedstoneWireMixin extends Block { @@ -31,9 +30,9 @@ public RedstoneWireMixin(Settings settings) { @Inject(method = "onUse", at = @At("HEAD"), cancellable = true) void preventInteraction(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable cir) { - if (!world.isClient) { + if (!world.isClient()) { if (!WorldProtection.canModify(world, pos, player)) { - protectionWarning(player, "redstone"); + ServerUtils.protectionWarning(player, "redstone"); cir.setReturnValue(ActionResult.FAIL); } } @@ -41,7 +40,7 @@ void preventInteraction(BlockState state, World world, BlockPos pos, PlayerEntit @Inject(method = "update", at = @At("HEAD"), cancellable = true) void preventActivation(World world, BlockPos pos, BlockState state, CallbackInfo ci) { - if (!world.isClient) { + if (!world.isClient()) { if (!WorldProtection.isWithinIsland(world, pos)) { ci.cancel(); } @@ -59,7 +58,7 @@ void preventChange(BlockState state, Direction direction, BlockState neighborSta @Inject(method = "getRenderConnectionType(Lnet/minecraft/world/BlockView;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/math/Direction;Z)Lnet/minecraft/block/enums/WireConnection;", at = @At("HEAD"), cancellable = true) private void preventConnection(BlockView world, BlockPos pos, Direction direction, boolean bl, CallbackInfoReturnable cir) { - if (!((World) world).isClient) { + if (!((World) world).isClient()) { if (!WorldProtection.isWithinIsland((World) world, pos.offset(direction))) { cir.setReturnValue(WireConnection.NONE); } diff --git a/src/main/java/skylands/mixin/world/protection/RepeaterMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/RepeaterMixin.java similarity index 80% rename from src/main/java/skylands/mixin/world/protection/RepeaterMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/RepeaterMixin.java index 70eb872..4eafa4f 100644 --- a/src/main/java/skylands/mixin/world/protection/RepeaterMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/RepeaterMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.block.AbstractRedstoneGateBlock; import net.minecraft.block.BlockState; import net.minecraft.block.RepeaterBlock; @@ -13,9 +14,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(RepeaterBlock.class) public abstract class RepeaterMixin extends AbstractRedstoneGateBlock { @@ -26,9 +25,9 @@ protected RepeaterMixin(Settings settings) { @Inject(method = "onUse", at = @At("HEAD"), cancellable = true) void onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable cir) { - if (!world.isClient) { + if (!world.isClient()) { if (!WorldProtection.canModify(world, pos, player)) { - protectionWarning(player, "redstone"); + ServerUtils.protectionWarning(player, "redstone"); cir.setReturnValue(ActionResult.FAIL); } } diff --git a/src/main/java/skylands/mixin/world/protection/RespawnAnchorBlockMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/RespawnAnchorBlockMixin.java similarity index 75% rename from src/main/java/skylands/mixin/world/protection/RespawnAnchorBlockMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/RespawnAnchorBlockMixin.java index c487b5e..eb68184 100644 --- a/src/main/java/skylands/mixin/world/protection/RespawnAnchorBlockMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/RespawnAnchorBlockMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.block.BlockState; import net.minecraft.block.RespawnAnchorBlock; import net.minecraft.entity.player.PlayerEntity; @@ -12,18 +13,17 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(RespawnAnchorBlock.class) public class RespawnAnchorBlockMixin { + //TODO: There was a todo here, idk why @Inject(method = "onUse", at = @At("HEAD"), cancellable = true) void onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable cir) { - if (!world.isClient) { + if (!world.isClient()) { if (!WorldProtection.canModify(world, pos, player)) { - protectionWarning(player, "interact"); + ServerUtils.protectionWarning(player, "interact"); cir.setReturnValue(ActionResult.FAIL); } } diff --git a/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/SculkCatalystBlockEntityMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/SculkCatalystBlockEntityMixin.java new file mode 100644 index 0000000..bdde03c --- /dev/null +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/SculkCatalystBlockEntityMixin.java @@ -0,0 +1,40 @@ +package com.awakenedredstone.neoskies.mixin.world.protection; + +import com.awakenedredstone.neoskies.logic.registry.NeoSkiesIslandSettings; +import net.minecraft.block.BlockState; +import net.minecraft.block.entity.SculkCatalystBlockEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import net.minecraft.util.math.random.Random; +import net.minecraft.world.event.GameEvent; +import net.minecraft.world.event.PositionSource; +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.CallbackInfoReturnable; +import com.awakenedredstone.neoskies.util.WorldProtection; + +import java.util.Optional; + +@Mixin(SculkCatalystBlockEntity.Listener.class) +public abstract class SculkCatalystBlockEntityMixin { + + @Shadow + public abstract PositionSource getPositionSource(); + + @Inject(method = "listen", at = @At("HEAD"), cancellable = true) + private void listen(ServerWorld world, GameEvent event, GameEvent.Emitter emitter, Vec3d emitterPos, CallbackInfoReturnable cir) { + Optional optional = getPositionSource().getPos(world); + if (optional.isEmpty()) return; + if (!(emitter.sourceEntity() instanceof PlayerEntity player)) return; + if (!world.isClient()) { + if (!WorldProtection.canModify(world, BlockPos.ofFloored(optional.get()), player, NeoSkiesIslandSettings.INTERACT_SCULK)) { + cir.setReturnValue(false); + } + } + } +} diff --git a/src/main/java/skylands/mixin/world/protection/SculkSensorBlockEntityMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/SculkSensorBlockEntityMixin.java similarity index 58% rename from src/main/java/skylands/mixin/world/protection/SculkSensorBlockEntityMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/SculkSensorBlockEntityMixin.java index 5903d0b..298dada 100644 --- a/src/main/java/skylands/mixin/world/protection/SculkSensorBlockEntityMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/SculkSensorBlockEntityMixin.java @@ -1,25 +1,25 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.logic.registry.NeoSkiesIslandSettings; import net.minecraft.block.entity.SculkSensorBlockEntity; import net.minecraft.entity.Entity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.server.world.ServerWorld; import net.minecraft.util.math.BlockPos; import net.minecraft.world.event.GameEvent; -import net.minecraft.world.event.listener.GameEventListener; 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 skylands.util.WorldProtection; +import com.awakenedredstone.neoskies.util.WorldProtection; -@Mixin(SculkSensorBlockEntity.class) +@Mixin(SculkSensorBlockEntity.VibrationCallback.class) public class SculkSensorBlockEntityMixin { @Inject(method = "accept", at = @At("HEAD"), cancellable = true) - private void accept(ServerWorld world, GameEventListener listener, BlockPos pos, GameEvent event, Entity entity, Entity sourceEntity, float distance, CallbackInfo ci) { - if (!world.isClient) { - if ((entity instanceof PlayerEntity player && !WorldProtection.canModify(world, pos, player)) || !WorldProtection.isWithinIsland(world, pos)) { + private void accept(ServerWorld world, BlockPos pos, GameEvent event, Entity sourceEntity, Entity entity, float distance, CallbackInfo ci) { + if (!world.isClient()) { + if ((entity instanceof PlayerEntity player && !WorldProtection.canModify(world, pos, player, NeoSkiesIslandSettings.INTERACT_SCULK))) { ci.cancel(); } } diff --git a/src/main/java/skylands/mixin/world/protection/SculkSensorBlockMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/SculkSensorBlockMixin.java similarity index 60% rename from src/main/java/skylands/mixin/world/protection/SculkSensorBlockMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/SculkSensorBlockMixin.java index 6a167eb..779b8a6 100644 --- a/src/main/java/skylands/mixin/world/protection/SculkSensorBlockMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/SculkSensorBlockMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.logic.registry.NeoSkiesIslandSettings; import net.minecraft.block.BlockState; import net.minecraft.block.SculkSensorBlock; import net.minecraft.entity.Entity; @@ -10,15 +11,15 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import skylands.util.WorldProtection; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(SculkSensorBlock.class) public class SculkSensorBlockMixin { @Inject(method = "setActive", at = @At("HEAD"), cancellable = true) - private static void setActive(Entity entity, World world, BlockPos pos, BlockState state, int power, CallbackInfo ci) { - if (!world.isClient) { - if ((entity instanceof PlayerEntity player && !WorldProtection.canModify(world, pos, player)) || !WorldProtection.isWithinIsland(world, pos)) { + private void setActive(Entity sourceEntity, World world, BlockPos pos, BlockState state, int power, int frequency, CallbackInfo ci) { + if (!world.isClient()) { + if ((sourceEntity instanceof PlayerEntity player && !WorldProtection.canModify(world, pos, player, NeoSkiesIslandSettings.INTERACT_SCULK))) { ci.cancel(); } } @@ -26,8 +27,8 @@ private static void setActive(Entity entity, World world, BlockPos pos, BlockSta @Inject(method = "onSteppedOn", at = @At("HEAD"), cancellable = true) private void onSteppedOn(World world, BlockPos pos, BlockState state, Entity entity, CallbackInfo ci) { - if (!world.isClient) { - if ((entity instanceof PlayerEntity player && !WorldProtection.canModify(world, pos, player)) || !WorldProtection.isWithinIsland(world, pos)) { + if (!world.isClient()) { + if ((entity instanceof PlayerEntity player && !WorldProtection.canModify(world, pos, player, NeoSkiesIslandSettings.INTERACT_SCULK))) { ci.cancel(); } } diff --git a/src/main/java/skylands/mixin/world/protection/SculkShriekerBlockEntityMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/SculkShriekerBlockEntityMixin.java similarity index 58% rename from src/main/java/skylands/mixin/world/protection/SculkShriekerBlockEntityMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/SculkShriekerBlockEntityMixin.java index a0c82d9..e607bd1 100644 --- a/src/main/java/skylands/mixin/world/protection/SculkShriekerBlockEntityMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/SculkShriekerBlockEntityMixin.java @@ -1,25 +1,25 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.logic.registry.NeoSkiesIslandSettings; import net.minecraft.block.entity.SculkShriekerBlockEntity; import net.minecraft.entity.Entity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.server.world.ServerWorld; import net.minecraft.util.math.BlockPos; import net.minecraft.world.event.GameEvent; -import net.minecraft.world.event.listener.GameEventListener; 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 skylands.util.WorldProtection; +import com.awakenedredstone.neoskies.util.WorldProtection; -@Mixin(SculkShriekerBlockEntity.class) +@Mixin(SculkShriekerBlockEntity.VibrationCallback.class) public class SculkShriekerBlockEntityMixin { @Inject(method = "accept", at = @At("HEAD"), cancellable = true) - private void accept(ServerWorld world, GameEventListener listener, BlockPos pos, GameEvent event, Entity entity, Entity sourceEntity, float distance, CallbackInfo ci) { - if (!world.isClient) { - if ((entity instanceof PlayerEntity player && !WorldProtection.canModify(world, pos, player)) || !WorldProtection.isWithinIsland(world, pos)) { + private void accept(ServerWorld world, BlockPos pos, GameEvent event, Entity sourceEntity, Entity entity, float distance, CallbackInfo ci) { + if (!world.isClient()) { + if ((entity instanceof PlayerEntity player && !WorldProtection.canModify(world, pos, player, NeoSkiesIslandSettings.INTERACT_SCULK))) { ci.cancel(); } } diff --git a/src/main/java/skylands/mixin/world/protection/SculkShriekerBlockMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/SculkShriekerBlockMixin.java similarity index 72% rename from src/main/java/skylands/mixin/world/protection/SculkShriekerBlockMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/SculkShriekerBlockMixin.java index 015a325..5d069a1 100644 --- a/src/main/java/skylands/mixin/world/protection/SculkShriekerBlockMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/SculkShriekerBlockMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.logic.registry.NeoSkiesIslandSettings; import net.minecraft.block.BlockState; import net.minecraft.block.SculkShriekerBlock; import net.minecraft.entity.Entity; @@ -10,15 +11,15 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import skylands.util.WorldProtection; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(SculkShriekerBlock.class) public class SculkShriekerBlockMixin { @Inject(method = "onSteppedOn", at = @At("HEAD"), cancellable = true) private void onSteppedOn(World world, BlockPos pos, BlockState state, Entity entity, CallbackInfo ci) { - if (!world.isClient) { - if ((entity instanceof PlayerEntity player && !WorldProtection.canModify(world, pos, player)) || !WorldProtection.isWithinIsland(world, pos)) { + if (!world.isClient()) { + if ((entity instanceof PlayerEntity player && !WorldProtection.canModify(world, pos, player, NeoSkiesIslandSettings.INTERACT_SCULK))) { ci.cancel(); } } diff --git a/src/main/java/skylands/mixin/world/protection/SculkSpreadCursorMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/SculkSpreadCursorMixin.java similarity index 88% rename from src/main/java/skylands/mixin/world/protection/SculkSpreadCursorMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/SculkSpreadCursorMixin.java index e0de2e1..3e3c28a 100644 --- a/src/main/java/skylands/mixin/world/protection/SculkSpreadCursorMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/SculkSpreadCursorMixin.java @@ -1,4 +1,4 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; import net.minecraft.block.entity.SculkSpreadManager; import net.minecraft.server.world.ServerWorld; @@ -9,7 +9,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import skylands.util.WorldProtection; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(SculkSpreadManager.Cursor.class) public class SculkSpreadCursorMixin { diff --git a/src/main/java/skylands/mixin/world/protection/ShearsItemMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/ShearsItemMixin.java similarity index 75% rename from src/main/java/skylands/mixin/world/protection/ShearsItemMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/ShearsItemMixin.java index 5531b9e..ccfd057 100644 --- a/src/main/java/skylands/mixin/world/protection/ShearsItemMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/ShearsItemMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemUsageContext; import net.minecraft.item.ShearsItem; @@ -9,9 +10,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(ShearsItem.class) public class ShearsItemMixin { @@ -20,9 +19,9 @@ public class ShearsItemMixin { void useOnBlock(ItemUsageContext context, CallbackInfoReturnable cir) { World world = context.getWorld(); PlayerEntity player = context.getPlayer(); - if (!world.isClient && player != null) { + if (!world.isClient() && player != null) { if (!WorldProtection.canModify(world, context.getBlockPos(), player)) { - protectionWarning(player, "shears_use"); + ServerUtils.protectionWarning(player, "shears_use"); cir.setReturnValue(ActionResult.FAIL); } } diff --git a/src/main/java/skylands/mixin/world/protection/ShovelItemMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/ShovelItemMixin.java similarity index 75% rename from src/main/java/skylands/mixin/world/protection/ShovelItemMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/ShovelItemMixin.java index 2834abf..3d624d5 100644 --- a/src/main/java/skylands/mixin/world/protection/ShovelItemMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/ShovelItemMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemUsageContext; import net.minecraft.item.ShovelItem; @@ -9,9 +10,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(ShovelItem.class) public class ShovelItemMixin { @@ -20,9 +19,9 @@ public class ShovelItemMixin { void useOnBlock(ItemUsageContext context, CallbackInfoReturnable cir) { World world = context.getWorld(); PlayerEntity player = context.getPlayer(); - if (!world.isClient && player != null) { + if (!world.isClient() && player != null) { if (!WorldProtection.canModify(world, context.getBlockPos(), player)) { - protectionWarning(player, "shovel_use"); + ServerUtils.protectionWarning(player, "shovel_use"); cir.setReturnValue(ActionResult.FAIL); } } diff --git a/src/main/java/skylands/mixin/world/protection/ShulkerBoxBlockMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/ShulkerBoxBlockMixin.java similarity index 77% rename from src/main/java/skylands/mixin/world/protection/ShulkerBoxBlockMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/ShulkerBoxBlockMixin.java index 650bfb4..fc872af 100644 --- a/src/main/java/skylands/mixin/world/protection/ShulkerBoxBlockMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/ShulkerBoxBlockMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.block.BlockState; import net.minecraft.block.ShulkerBoxBlock; import net.minecraft.entity.player.PlayerEntity; @@ -12,18 +13,16 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(ShulkerBoxBlock.class) public class ShulkerBoxBlockMixin { @Inject(method = "onUse", at = @At("HEAD"), cancellable = true) void onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable cir) { - if (!world.isClient) { + if (!world.isClient()) { if (!WorldProtection.canModify(world, pos, player)) { - protectionWarning(player, "shulker_box_open"); + ServerUtils.protectionWarning(player, "shulker_box_open"); cir.setReturnValue(ActionResult.FAIL); } } diff --git a/src/main/java/skylands/mixin/world/protection/StorageMinecartMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/StorageMinecartMixin.java similarity index 66% rename from src/main/java/skylands/mixin/world/protection/StorageMinecartMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/StorageMinecartMixin.java index 8e21b93..53f7d59 100644 --- a/src/main/java/skylands/mixin/world/protection/StorageMinecartMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/StorageMinecartMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.vehicle.StorageMinecartEntity; import net.minecraft.util.ActionResult; @@ -8,18 +9,16 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(StorageMinecartEntity.class) public class StorageMinecartMixin { @Inject(method = "interact", at = @At("HEAD"), cancellable = true) void interact(PlayerEntity player, Hand hand, CallbackInfoReturnable cir) { - if (!player.world.isClient) { - if (!WorldProtection.canModify(player.world, player)) { - protectionWarning(player, "minecart_open"); + if (!player.getWorld().isClient()) { + if (!WorldProtection.canModify(player.getWorld(), player)) { + ServerUtils.protectionWarning(player, "minecart_open"); cir.setReturnValue(ActionResult.FAIL); } } diff --git a/src/main/java/skylands/mixin/world/protection/SweetBerryBushBlockMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/SweetBerryBushBlockMixin.java similarity index 78% rename from src/main/java/skylands/mixin/world/protection/SweetBerryBushBlockMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/SweetBerryBushBlockMixin.java index 0dbcb87..3075619 100644 --- a/src/main/java/skylands/mixin/world/protection/SweetBerryBushBlockMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/SweetBerryBushBlockMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.block.BlockState; import net.minecraft.block.SweetBerryBushBlock; import net.minecraft.entity.player.PlayerEntity; @@ -12,18 +13,16 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(SweetBerryBushBlock.class) public class SweetBerryBushBlockMixin { @Inject(method = "onUse", at = @At("HEAD"), cancellable = true) void onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable cir) { - if (!world.isClient) { + if (!world.isClient()) { if (!WorldProtection.canModify(world, pos, player)) { - protectionWarning(player, "interact"); + ServerUtils.protectionWarning(player, "interact"); cir.setReturnValue(ActionResult.FAIL); } } diff --git a/src/main/java/skylands/mixin/world/protection/TargetBlockMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/TargetBlockMixin.java similarity index 80% rename from src/main/java/skylands/mixin/world/protection/TargetBlockMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/TargetBlockMixin.java index 5f631ad..d0b6809 100644 --- a/src/main/java/skylands/mixin/world/protection/TargetBlockMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/TargetBlockMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.block.BlockState; import net.minecraft.block.TargetBlock; import net.minecraft.entity.player.PlayerEntity; @@ -11,19 +12,17 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(TargetBlock.class) public class TargetBlockMixin { @Inject(method = "onProjectileHit", at = @At("HEAD"), cancellable = true) private void useOnBlock(World world, BlockState state, BlockHitResult hit, ProjectileEntity projectile, CallbackInfo ci) { - if (!world.isClient) { + if (!world.isClient()) { if (projectile.getOwner() instanceof PlayerEntity player) { if (!WorldProtection.canModify(world, hit.getBlockPos(), player)) { - protectionWarning(player, "target"); + ServerUtils.protectionWarning(player, "target"); ci.cancel(); } } diff --git a/src/main/java/skylands/mixin/world/protection/TntBlockMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/TntBlockMixin.java similarity index 83% rename from src/main/java/skylands/mixin/world/protection/TntBlockMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/TntBlockMixin.java index ad8ecf7..566bc7b 100644 --- a/src/main/java/skylands/mixin/world/protection/TntBlockMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/TntBlockMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.TntBlock; @@ -19,16 +20,14 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(TntBlock.class) public class TntBlockMixin { @Inject(method = "primeTnt(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/entity/LivingEntity;)V", at = @At("HEAD"), cancellable = true) private static void primeTnt(World world, BlockPos pos, LivingEntity igniter, CallbackInfo ci) { - if (!world.isClient) { + if (!world.isClient()) { if (!WorldProtection.isWithinIsland(world, pos)) { ci.cancel(); } @@ -37,7 +36,7 @@ private static void primeTnt(World world, BlockPos pos, LivingEntity igniter, Ca @Inject(method = "onProjectileHit", at = @At("HEAD"), cancellable = true) private void onProjectileHit(World world, BlockState state, BlockHitResult hit, ProjectileEntity projectile, CallbackInfo ci) { - if (!world.isClient) { + if (!world.isClient()) { if (!WorldProtection.isWithinIsland(world, hit.getBlockPos())) { ci.cancel(); } @@ -46,7 +45,7 @@ private void onProjectileHit(World world, BlockState state, BlockHitResult hit, @Inject(method = "neighborUpdate", at = @At("HEAD"), cancellable = true) private void neighborUpdate(BlockState state, World world, BlockPos pos, Block sourceBlock, BlockPos sourcePos, boolean notify, CallbackInfo ci) { - if (!world.isClient) { + if (!world.isClient()) { if (!WorldProtection.isWithinIsland(world, pos)) { ci.cancel(); } @@ -55,7 +54,7 @@ private void neighborUpdate(BlockState state, World world, BlockPos pos, Block s @Inject(method = "onBlockAdded", at = @At("HEAD"), cancellable = true) private void onBlockAdded(BlockState state, World world, BlockPos pos, BlockState oldState, boolean notify, CallbackInfo ci) { - if (!world.isClient) { + if (!world.isClient()) { if (!WorldProtection.isWithinIsland(world, pos)) { ci.cancel(); } @@ -64,7 +63,7 @@ private void onBlockAdded(BlockState state, World world, BlockPos pos, BlockStat @Inject(method = "onDestroyedByExplosion", at = @At("HEAD"), cancellable = true) private void onDestroyedByExplosion(World world, BlockPos pos, Explosion explosion, CallbackInfo ci) { - if (!world.isClient) { + if (!world.isClient()) { if (!WorldProtection.isWithinIsland(world, pos)) { ci.cancel(); } @@ -72,21 +71,21 @@ private void onDestroyedByExplosion(World world, BlockPos pos, Explosion explosi } @Inject(method = "onBreak", at = @At("HEAD"), cancellable = true) - private void onBreak(World world, BlockPos pos, BlockState state, PlayerEntity player, CallbackInfo ci) { - if (!world.isClient) { + private void onBreak(World world, BlockPos pos, BlockState state, PlayerEntity player, CallbackInfoReturnable cir) { + if (!world.isClient()) { if (!WorldProtection.canModify(world, pos, player)) { - protectionWarning(player, "tnt_break"); - ci.cancel(); + ServerUtils.protectionWarning(player, "tnt_break"); + cir.setReturnValue(state); } } } @Inject(method = "onUse", at = @At("HEAD"), cancellable = true) private void onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable cir) { - if (!world.isClient) { + if (!world.isClient()) { if (!WorldProtection.canModify(world, pos, player)) { ItemStack itemStack = player.getStackInHand(hand); - if (!itemStack.isOf(Items.FLINT_AND_STEEL) && !itemStack.isOf(Items.FIRE_CHARGE)) protectionWarning(player, "tnt_ignite"); + if (!itemStack.isOf(Items.FLINT_AND_STEEL) && !itemStack.isOf(Items.FIRE_CHARGE)) ServerUtils.protectionWarning(player, "tnt_ignite"); cir.setReturnValue(ActionResult.FAIL); } } diff --git a/src/main/java/skylands/mixin/world/protection/TrapdoorBlockMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/TrapdoorBlockMixin.java similarity index 77% rename from src/main/java/skylands/mixin/world/protection/TrapdoorBlockMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/TrapdoorBlockMixin.java index 6211fdd..19bbf05 100644 --- a/src/main/java/skylands/mixin/world/protection/TrapdoorBlockMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/TrapdoorBlockMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.block.BlockState; import net.minecraft.block.TrapdoorBlock; import net.minecraft.entity.player.PlayerEntity; @@ -12,18 +13,16 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(TrapdoorBlock.class) public class TrapdoorBlockMixin { @Inject(method = "onUse", at = @At("HEAD"), cancellable = true) void onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable cir) { - if (!world.isClient) { + if (!world.isClient()) { if (!WorldProtection.canModify(world, pos, player)) { - protectionWarning(player, "trapdoor_open"); + ServerUtils.protectionWarning(player, "trapdoor_open"); cir.setReturnValue(ActionResult.FAIL); } } diff --git a/src/main/java/skylands/mixin/world/protection/VibrationListenerMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/VibrationListenerMixin.java similarity index 59% rename from src/main/java/skylands/mixin/world/protection/VibrationListenerMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/VibrationListenerMixin.java index 90336e1..63a9252 100644 --- a/src/main/java/skylands/mixin/world/protection/VibrationListenerMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/VibrationListenerMixin.java @@ -1,36 +1,35 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.logic.registry.NeoSkiesIslandSettings; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.server.world.ServerWorld; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; import net.minecraft.world.event.GameEvent; import net.minecraft.world.event.PositionSource; -import net.minecraft.world.event.listener.VibrationListener; -import org.spongepowered.asm.mixin.Final; +import net.minecraft.world.event.Vibrations; 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; -import skylands.util.WorldProtection; +import com.awakenedredstone.neoskies.util.WorldProtection; import java.util.Optional; -@Mixin(VibrationListener.class) -public class VibrationListenerMixin { +@Mixin(Vibrations.VibrationListener.class) +public abstract class VibrationListenerMixin { @Shadow - @Final - protected PositionSource positionSource; + public abstract PositionSource getPositionSource(); - @Inject(method = "listen", at = @At("HEAD"), cancellable = true) + @Inject(method = "listen*", at = @At("HEAD"), cancellable = true) private void accept(ServerWorld world, GameEvent event, GameEvent.Emitter emitter, Vec3d emitterPos, CallbackInfoReturnable cir) { - if (!world.isClient) { - Optional optional = positionSource.getPos(world); + if (!world.isClient()) { + Optional optional = getPositionSource().getPos(world); if (optional.isEmpty()) return; BlockPos pos = BlockPos.ofFloored(optional.get()); - if ((emitter.sourceEntity() instanceof PlayerEntity player && !WorldProtection.canModify(world, pos, player)) || !WorldProtection.isWithinIsland(world, pos)) { + if ((emitter.sourceEntity() instanceof PlayerEntity player && !WorldProtection.canModify(world, pos, player, NeoSkiesIslandSettings.INTERACT_SCULK))) { cir.setReturnValue(false); } } diff --git a/src/main/java/skylands/mixin/world/protection/VillagerEntityMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/VillagerEntityMixin.java similarity index 66% rename from src/main/java/skylands/mixin/world/protection/VillagerEntityMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/VillagerEntityMixin.java index 2835a9e..e107cb4 100644 --- a/src/main/java/skylands/mixin/world/protection/VillagerEntityMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/VillagerEntityMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.entity.passive.VillagerEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.util.ActionResult; @@ -8,18 +9,16 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(VillagerEntity.class) public class VillagerEntityMixin { @Inject(method = "interactMob", at = @At("HEAD"), cancellable = true) void interact(PlayerEntity player, Hand hand, CallbackInfoReturnable cir) { - if (!player.world.isClient) { - if (!WorldProtection.canModify(player.world, player)) { - protectionWarning(player, "villager_use"); + if (!player.getWorld().isClient()) { + if (!WorldProtection.canModify(player.getWorld(), player)) { + ServerUtils.protectionWarning(player, "villager_use"); cir.setReturnValue(ActionResult.FAIL); } } diff --git a/src/main/java/skylands/mixin/world/protection/WorldMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/WorldMixin.java similarity index 72% rename from src/main/java/skylands/mixin/world/protection/WorldMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/WorldMixin.java index 55c9198..3997677 100644 --- a/src/main/java/skylands/mixin/world/protection/WorldMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/WorldMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.logic.Skylands; import net.minecraft.block.BlockState; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; @@ -7,15 +8,15 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.SkylandsMain; -import skylands.util.WorldProtection; +import com.awakenedredstone.neoskies.SkylandsMain; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(World.class) public class WorldMixin { @Inject(method = "setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;II)Z", at = @At("HEAD"), cancellable = true) private void setBlockState(BlockPos pos, BlockState state, int flags, int maxUpdateDepth, CallbackInfoReturnable cir) { - if (!SkylandsMain.MAIN_CONFIG.disableBlocksOutsideIslands()) return; + if (!Skylands.getConfig().disableBlocksOutsideIslands) return; if (!WorldProtection.isWithinIsland((World) (Object) this, pos)) cir.setReturnValue(false); } } diff --git a/src/main/java/skylands/mixin/world/protection/WritableBookItemMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/WritableBookItemMixin.java similarity index 77% rename from src/main/java/skylands/mixin/world/protection/WritableBookItemMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/WritableBookItemMixin.java index 0a07ab5..71acdcd 100644 --- a/src/main/java/skylands/mixin/world/protection/WritableBookItemMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/WritableBookItemMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemUsageContext; import net.minecraft.item.WritableBookItem; @@ -9,9 +10,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(WritableBookItem.class) public class WritableBookItemMixin { @@ -20,9 +19,9 @@ public class WritableBookItemMixin { void useOnBlock(ItemUsageContext context, CallbackInfoReturnable cir) { World world = context.getWorld(); PlayerEntity player = context.getPlayer(); - if (!world.isClient && player != null) { + if (!world.isClient() && player != null) { if (!WorldProtection.canModify(world, context.getBlockPos(), player)) { - protectionWarning(player, "lectern"); + ServerUtils.protectionWarning(player, "lectern"); player.getInventory().updateItems(); cir.setReturnValue(ActionResult.FAIL); } diff --git a/src/main/java/skylands/mixin/world/protection/WrittenBookItemMixin.java b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/WrittenBookItemMixin.java similarity index 77% rename from src/main/java/skylands/mixin/world/protection/WrittenBookItemMixin.java rename to src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/WrittenBookItemMixin.java index 7c2c055..f45de03 100644 --- a/src/main/java/skylands/mixin/world/protection/WrittenBookItemMixin.java +++ b/src/main/java/com/awakenedredstone/neoskies/mixin/world/protection/WrittenBookItemMixin.java @@ -1,5 +1,6 @@ -package skylands.mixin.world.protection; +package com.awakenedredstone.neoskies.mixin.world.protection; +import com.awakenedredstone.neoskies.util.ServerUtils; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemUsageContext; import net.minecraft.item.WrittenBookItem; @@ -9,9 +10,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; +import com.awakenedredstone.neoskies.util.WorldProtection; @Mixin(WrittenBookItem.class) public class WrittenBookItemMixin { @@ -20,9 +19,9 @@ public class WrittenBookItemMixin { void useOnBlock(ItemUsageContext context, CallbackInfoReturnable cir) { World world = context.getWorld(); PlayerEntity player = context.getPlayer(); - if (!world.isClient && player != null) { + if (!world.isClient() && player != null) { if (!WorldProtection.canModify(world, context.getBlockPos(), player)) { - protectionWarning(player, "lectern"); + ServerUtils.protectionWarning(player, "lectern"); player.getInventory().updateItems(); cir.setReturnValue(ActionResult.FAIL); } diff --git a/src/main/java/com/awakenedredstone/neoskies/util/AutoRegister.java b/src/main/java/com/awakenedredstone/neoskies/util/AutoRegister.java new file mode 100644 index 0000000..8162f15 --- /dev/null +++ b/src/main/java/com/awakenedredstone/neoskies/util/AutoRegister.java @@ -0,0 +1,6 @@ +package com.awakenedredstone.neoskies.util; + +import net.minecraft.registry.Registry; + +public abstract class AutoRegister { +} diff --git a/src/main/java/skylands/util/Constants.java b/src/main/java/com/awakenedredstone/neoskies/util/Constants.java similarity index 72% rename from src/main/java/skylands/util/Constants.java rename to src/main/java/com/awakenedredstone/neoskies/util/Constants.java index 91d47b5..941ec40 100644 --- a/src/main/java/skylands/util/Constants.java +++ b/src/main/java/com/awakenedredstone/neoskies/util/Constants.java @@ -1,6 +1,6 @@ -package skylands.util; +package com.awakenedredstone.neoskies.util; -import skylands.SkylandsMain; +import com.awakenedredstone.neoskies.SkylandsMain; public class Constants { public static final String NAMESPACE = SkylandsMain.MOD_ID; diff --git a/src/main/java/skylands/util/DynamicPlaceholders.java b/src/main/java/com/awakenedredstone/neoskies/util/DynamicPlaceholders.java similarity index 91% rename from src/main/java/skylands/util/DynamicPlaceholders.java rename to src/main/java/com/awakenedredstone/neoskies/util/DynamicPlaceholders.java index 124c109..c9d8c72 100644 --- a/src/main/java/skylands/util/DynamicPlaceholders.java +++ b/src/main/java/com/awakenedredstone/neoskies/util/DynamicPlaceholders.java @@ -1,11 +1,11 @@ -package skylands.util; +package com.awakenedredstone.neoskies.util; import eu.pb4.placeholders.api.PlaceholderContext; import eu.pb4.placeholders.api.PlaceholderHandler; import eu.pb4.placeholders.api.PlaceholderResult; import eu.pb4.placeholders.api.Placeholders; import net.minecraft.text.Text; -import skylands.logic.Skylands; +import com.awakenedredstone.neoskies.logic.Skylands; import java.util.Map; diff --git a/src/main/java/skylands/util/FontUtils.java b/src/main/java/com/awakenedredstone/neoskies/util/FontUtils.java similarity index 94% rename from src/main/java/skylands/util/FontUtils.java rename to src/main/java/com/awakenedredstone/neoskies/util/FontUtils.java index 02b0aa7..af6b408 100644 --- a/src/main/java/skylands/util/FontUtils.java +++ b/src/main/java/com/awakenedredstone/neoskies/util/FontUtils.java @@ -1,7 +1,7 @@ -package skylands.util; +package com.awakenedredstone.neoskies.util; -import skylands.font.FontManager; -import skylands.font.FontProvider; +import com.awakenedredstone.neoskies.font.FontManager; +import com.awakenedredstone.neoskies.font.FontProvider; public class FontUtils { public static int getStringWidth(String string) { diff --git a/src/main/java/skylands/util/IslandUtils.java b/src/main/java/com/awakenedredstone/neoskies/util/IslandUtils.java similarity index 70% rename from src/main/java/skylands/util/IslandUtils.java rename to src/main/java/com/awakenedredstone/neoskies/util/IslandUtils.java index 74434b0..c2608b8 100644 --- a/src/main/java/skylands/util/IslandUtils.java +++ b/src/main/java/com/awakenedredstone/neoskies/util/IslandUtils.java @@ -1,7 +1,7 @@ -package skylands.util; +package com.awakenedredstone.neoskies.util; import net.minecraft.entity.player.PlayerEntity; -import skylands.logic.Island; +import com.awakenedredstone.neoskies.logic.Island; public class IslandUtils { diff --git a/src/main/java/com/awakenedredstone/neoskies/util/MapBuilder.java b/src/main/java/com/awakenedredstone/neoskies/util/MapBuilder.java new file mode 100644 index 0000000..ad9addc --- /dev/null +++ b/src/main/java/com/awakenedredstone/neoskies/util/MapBuilder.java @@ -0,0 +1,36 @@ +package com.awakenedredstone.neoskies.util; + +import com.google.common.collect.ImmutableMap; + +import java.util.HashMap; +import java.util.Map; + +public class MapBuilder { + private final Map map = new HashMap<>(); + + public MapBuilder put(K key, V value) { + map.put(key, value); + return this; + } + + public Map build() { + return map; + } + + public ImmutableMap immutable() { + return ImmutableMap.copyOf(map); + } + + public static class StringMap extends MapBuilder { + @Override + public StringMap put(String key, String value) { + super.put(key, value); + return this; + } + + public StringMap putAny(String key, Object value) { + super.put(key, String.valueOf(value)); + return this; + } + } +} diff --git a/src/main/java/skylands/util/NbtMigrator.java b/src/main/java/com/awakenedredstone/neoskies/util/NbtMigrator.java similarity index 79% rename from src/main/java/skylands/util/NbtMigrator.java rename to src/main/java/com/awakenedredstone/neoskies/util/NbtMigrator.java index f40650b..a96eb1d 100644 --- a/src/main/java/skylands/util/NbtMigrator.java +++ b/src/main/java/com/awakenedredstone/neoskies/util/NbtMigrator.java @@ -1,4 +1,4 @@ -package skylands.util; +package com.awakenedredstone.neoskies.util; import net.minecraft.nbt.NbtCompound; diff --git a/src/main/java/skylands/util/Players.java b/src/main/java/com/awakenedredstone/neoskies/util/Players.java similarity index 72% rename from src/main/java/skylands/util/Players.java rename to src/main/java/com/awakenedredstone/neoskies/util/Players.java index 21963d0..cf2c157 100644 --- a/src/main/java/skylands/util/Players.java +++ b/src/main/java/com/awakenedredstone/neoskies/util/Players.java @@ -1,13 +1,13 @@ -package skylands.util; +package com.awakenedredstone.neoskies.util; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.server.MinecraftServer; -import skylands.logic.Skylands; +import com.awakenedredstone.neoskies.logic.Skylands; import java.util.Optional; public class Players { - static MinecraftServer server = Skylands.getServer(); + static final MinecraftServer server = Skylands.getServer(); public static Optional get(String name) { for (var player : server.getPlayerManager().getPlayerList()) { diff --git a/src/main/java/skylands/util/PreInitData.java b/src/main/java/com/awakenedredstone/neoskies/util/PreInitData.java similarity index 63% rename from src/main/java/skylands/util/PreInitData.java rename to src/main/java/com/awakenedredstone/neoskies/util/PreInitData.java index 3d83179..b9ad944 100644 --- a/src/main/java/skylands/util/PreInitData.java +++ b/src/main/java/com/awakenedredstone/neoskies/util/PreInitData.java @@ -1,15 +1,20 @@ -package skylands.util; +package com.awakenedredstone.neoskies.util; -import lombok.Getter; -import lombok.Setter; import net.minecraft.resource.ResourceManager; public class PreInitData { private static boolean open = true; private static PreInitData instance = new PreInitData(); - @Getter @Setter private ResourceManager resourceManager; + public ResourceManager getResourceManager() { + return resourceManager; + } + + public void setResourceManager(ResourceManager resourceManager) { + this.resourceManager = resourceManager; + } + public static PreInitData getInstance() { return instance; } diff --git a/src/main/java/skylands/util/Scheduler.java b/src/main/java/com/awakenedredstone/neoskies/util/Scheduler.java similarity index 95% rename from src/main/java/skylands/util/Scheduler.java rename to src/main/java/com/awakenedredstone/neoskies/util/Scheduler.java index 2f5d1bc..cbd6786 100644 --- a/src/main/java/skylands/util/Scheduler.java +++ b/src/main/java/com/awakenedredstone/neoskies/util/Scheduler.java @@ -1,8 +1,8 @@ -package skylands.util; +package com.awakenedredstone.neoskies.util; import net.minecraft.server.MinecraftServer; import net.minecraft.util.Identifier; -import skylands.logic.Skylands; +import com.awakenedredstone.neoskies.logic.Skylands; import java.util.Comparator; import java.util.PriorityQueue; diff --git a/src/main/java/skylands/util/ServerUtils.java b/src/main/java/com/awakenedredstone/neoskies/util/ServerUtils.java similarity index 68% rename from src/main/java/skylands/util/ServerUtils.java rename to src/main/java/com/awakenedredstone/neoskies/util/ServerUtils.java index fdf2198..9e47ccc 100644 --- a/src/main/java/skylands/util/ServerUtils.java +++ b/src/main/java/com/awakenedredstone/neoskies/util/ServerUtils.java @@ -1,8 +1,10 @@ -package skylands.util; +package com.awakenedredstone.neoskies.util; +import com.awakenedredstone.neoskies.config.MainConfig; +import com.awakenedredstone.neoskies.logic.Skylands; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.text.Text; -import skylands.SkylandsMain; +import com.awakenedredstone.neoskies.SkylandsMain; import java.util.Map; import java.util.function.Consumer; @@ -10,7 +12,7 @@ public class ServerUtils { public static void protectionWarning(PlayerEntity player, String key) { - if (SkylandsMain.MAIN_CONFIG.showProtectionMessages()) actionbarPrefixed(player, "message.skylands.world_protection." + key); + if (Skylands.getConfig().showProtectionMessages) actionbarPrefixed(player, "island_protection." + key); } public static void actionbarPrefixed(PlayerEntity player, String message, Consumer> builder) { diff --git a/src/main/java/skylands/util/Texts.java b/src/main/java/com/awakenedredstone/neoskies/util/Texts.java similarity index 93% rename from src/main/java/skylands/util/Texts.java rename to src/main/java/com/awakenedredstone/neoskies/util/Texts.java index 0706df5..95c638e 100644 --- a/src/main/java/skylands/util/Texts.java +++ b/src/main/java/com/awakenedredstone/neoskies/util/Texts.java @@ -1,9 +1,10 @@ -package skylands.util; +package com.awakenedredstone.neoskies.util; +import com.awakenedredstone.neoskies.logic.Skylands; import eu.pb4.placeholders.api.TextParserUtils; import net.minecraft.text.Text; import net.minecraft.text.TranslatableTextContent; -import skylands.SkylandsMain; +import com.awakenedredstone.neoskies.SkylandsMain; import xyz.nucleoid.server.translations.api.Localization; import xyz.nucleoid.server.translations.api.language.ServerLanguage; @@ -14,13 +15,12 @@ public class Texts { private static final Map EMPTY_STRING_MAP = Collections.emptyMap(); - @Deprecated private static final Map EMPTY_TEXT_MAP = Collections.emptyMap(); - public static String PREFIX = "message.skylands.prefix"; + public static final String PREFIX = "message.neoskies.prefix"; public static String getTextString(Text text) { if (text.getContent() instanceof TranslatableTextContent tanslatable) { - return Localization.text(text, ServerLanguage.getLanguage(SkylandsMain.MAIN_CONFIG.language())).getString(); + return Localization.text(text, ServerLanguage.getLanguage(Skylands.getConfig().language)).getString(); } else return text.getString(); } diff --git a/src/main/java/com/awakenedredstone/neoskies/util/UIUtils.java b/src/main/java/com/awakenedredstone/neoskies/util/UIUtils.java new file mode 100644 index 0000000..d8a7ed9 --- /dev/null +++ b/src/main/java/com/awakenedredstone/neoskies/util/UIUtils.java @@ -0,0 +1,30 @@ +package com.awakenedredstone.neoskies.util; + +import eu.pb4.sgui.api.SlotHolder; +import eu.pb4.sgui.api.elements.GuiElementInterface; +import net.minecraft.util.Identifier; +import net.minecraft.util.crash.CrashException; +import net.minecraft.util.crash.CrashReport; +import org.jetbrains.annotations.NotNull; + +public class UIUtils { + public static @NotNull CrashException createCrashException(Throwable throwable, String message) { + return new CrashException(CrashReport.create(throwable, message)); + } + + public static void fillGui(@NotNull SlotHolder gui, GuiElementInterface item) { + for (int i = 0; i < gui.getSize(); i++) { + gui.setSlot(i, item); + } + } + + public static void quickFillGui(@NotNull SlotHolder gui, GuiElementInterface item) { + for (int i = 0; i < gui.getSize(); i++) { + if (gui.getSlot(i) == null || gui.getSlot(i).getItemStack().isEmpty()) gui.setSlot(i, item); + } + } + + public static @NotNull Identifier addToPath(@NotNull Identifier identifier, String toAdd) { + return new Identifier(identifier + "/" + toAdd); + } +} diff --git a/src/main/java/skylands/util/UnitConvertions.java b/src/main/java/com/awakenedredstone/neoskies/util/UnitConvertions.java similarity index 89% rename from src/main/java/skylands/util/UnitConvertions.java rename to src/main/java/com/awakenedredstone/neoskies/util/UnitConvertions.java index dfa24c6..84eabd6 100644 --- a/src/main/java/skylands/util/UnitConvertions.java +++ b/src/main/java/com/awakenedredstone/neoskies/util/UnitConvertions.java @@ -1,4 +1,4 @@ -package skylands.util; +package com.awakenedredstone.neoskies.util; public class UnitConvertions { diff --git a/src/main/java/skylands/util/WorldProtection.java b/src/main/java/com/awakenedredstone/neoskies/util/WorldProtection.java similarity index 51% rename from src/main/java/skylands/util/WorldProtection.java rename to src/main/java/com/awakenedredstone/neoskies/util/WorldProtection.java index 0b89435..4134049 100644 --- a/src/main/java/skylands/util/WorldProtection.java +++ b/src/main/java/com/awakenedredstone/neoskies/util/WorldProtection.java @@ -1,24 +1,25 @@ -package skylands.util; +package com.awakenedredstone.neoskies.util; import me.lucko.fabric.api.permissions.v0.Permissions; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import skylands.SkylandsMain; -import skylands.api.SkylandsAPI; -import skylands.api.island.PermissionLevel; -import skylands.logic.Island; -import skylands.logic.Skylands; -import skylands.logic.registry.SkylandsPermissionLevels; -import skylands.logic.settings.IslandSettings; +import com.awakenedredstone.neoskies.SkylandsMain; +import com.awakenedredstone.neoskies.api.SkylandsAPI; +import com.awakenedredstone.neoskies.api.island.PermissionLevel; +import com.awakenedredstone.neoskies.logic.Island; +import com.awakenedredstone.neoskies.logic.Skylands; +import com.awakenedredstone.neoskies.logic.registry.SkylandsPermissionLevels; +import com.awakenedredstone.neoskies.logic.settings.IslandSettings; import java.util.Optional; public class WorldProtection { + @SuppressWarnings("BooleanMethodIsAlwaysInverted") public static boolean canModify(World world, PlayerEntity player) { if (SkylandsMain.PROTECTION_BYPASS.contains(player)) { - if (Permissions.check(player, "skylands.admin.protection.bypass", 4)) return true; + if (Permissions.check(player, "neoskies.admin.protection.bypass", 4)) return true; else SkylandsMain.PROTECTION_BYPASS.remove(player); } Optional island = SkylandsAPI.getIsland(world); @@ -33,15 +34,23 @@ public static boolean canModify(World world, PlayerEntity player) { return true; } + @Deprecated + @SuppressWarnings("BooleanMethodIsAlwaysInverted") public static boolean canModify(World world, BlockPos pos, PlayerEntity player) { if (SkylandsMain.PROTECTION_BYPASS.contains(player)) { - if (Permissions.check(player, "skylands.admin.protection.bypass", 4)) return true; - else SkylandsMain.PROTECTION_BYPASS.remove(player); + if (Permissions.check(player, "neoskies.admin.protection.bypass", 4)) { + return true; + } else { + SkylandsMain.PROTECTION_BYPASS.remove(player); + } } Optional island = SkylandsAPI.getIsland(world); if (island.isPresent()) { - if (!island.get().isWithinBorder(pos)) return false; - else if (island.get().isMember(player)) return true; + if (!island.get().isWithinBorder(pos)) { + return false; + } else if (island.get().isMember(player)) { + return true; + } } if (world.getRegistryKey().equals(World.OVERWORLD)) { @@ -53,13 +62,41 @@ public static boolean canModify(World world, BlockPos pos, PlayerEntity player) public static boolean canModify(World world, BlockPos pos, PlayerEntity player, T setting) { if (SkylandsMain.PROTECTION_BYPASS.contains(player)) { - if (Permissions.check(player, "skylands.admin.protection.bypass", 4)) return true; - else SkylandsMain.PROTECTION_BYPASS.remove(player); + if (Permissions.check(player, "neoskies.admin.protection.bypass", 4)) { + return true; + } else { + SkylandsMain.PROTECTION_BYPASS.remove(player); + } + } + + Optional island = SkylandsAPI.getIsland(world); + if (island.isPresent()) { + if (!island.get().isWithinBorder(pos)) { + return false; + } + if (island.get().isInteractionAllowed(setting.getIdentifier(), getPlayerPermissionLevel(world, player))) { + return true; + } + } + + if (world.getRegistryKey().equals(World.OVERWORLD) && Skylands.getInstance().hub.hasProtection) { + return false; + } + + return false; + } + + public static boolean canModify(World world, PlayerEntity player, T setting) { + if (SkylandsMain.PROTECTION_BYPASS.contains(player)) { + if (Permissions.check(player, "neoskies.admin.protection.bypass", 4)) { + return true; + } else { + SkylandsMain.PROTECTION_BYPASS.remove(player); + } } Optional island = SkylandsAPI.getIsland(world); if (island.isPresent()) { - if (!island.get().isWithinBorder(pos)) return false; if (island.get().isInteractionAllowed(setting.getIdentifier(), getPlayerPermissionLevel(world, player))) { return true; } @@ -75,8 +112,12 @@ public static boolean canModify(World world, BlockPos public static PermissionLevel getPlayerPermissionLevel(World world, PlayerEntity player) { Optional island = SkylandsAPI.getIsland(world); if (island.isPresent() && island.get().isMember(player)) { - if (island.get().owner.uuid == player.getUuid()) return SkylandsPermissionLevels.OWNER; - else return SkylandsPermissionLevels.MEMBER; + if (island.get().owner.uuid == player.getUuid()) { + return SkylandsPermissionLevels.OWNER; + } + else { + return SkylandsPermissionLevels.MEMBER; + } } return SkylandsPermissionLevels.VISITOR; @@ -85,7 +126,9 @@ public static PermissionLevel getPlayerPermissionLevel(World world, PlayerEntity public static boolean isWithinIsland(World world, BlockPos pos) { Optional island = SkylandsAPI.getIsland(world); - if (SkylandsAPI.isHub(world)) return true; + if (SkylandsAPI.isHub(world)) { + return true; + } if (island.isPresent() && (!island.get().isWithinBorder(pos))) { return false; diff --git a/src/main/java/skylands/util/Worlds.java b/src/main/java/com/awakenedredstone/neoskies/util/Worlds.java similarity index 77% rename from src/main/java/skylands/util/Worlds.java rename to src/main/java/com/awakenedredstone/neoskies/util/Worlds.java index 6ddea30..8ab08d2 100644 --- a/src/main/java/skylands/util/Worlds.java +++ b/src/main/java/com/awakenedredstone/neoskies/util/Worlds.java @@ -1,4 +1,4 @@ -package skylands.util; +package com.awakenedredstone.neoskies.util; import net.fabricmc.fabric.api.dimension.v1.FabricDimensions; import net.minecraft.registry.RegistryKey; @@ -6,11 +6,11 @@ import net.minecraft.util.math.Vec3d; import net.minecraft.world.TeleportTarget; import net.minecraft.world.World; -import skylands.SkylandsMain; -import skylands.api.SkylandsAPI; -import skylands.logic.Hub; -import skylands.logic.Island; -import skylands.logic.Skylands; +import com.awakenedredstone.neoskies.SkylandsMain; +import com.awakenedredstone.neoskies.api.SkylandsAPI; +import com.awakenedredstone.neoskies.logic.Hub; +import com.awakenedredstone.neoskies.logic.Island; +import com.awakenedredstone.neoskies.logic.Skylands; import java.util.Optional; @@ -22,8 +22,8 @@ public static void returnToIslandSpawn(ServerPlayerEntity player, boolean fallDa player.stopRiding(); - if (SkylandsAPI.isIsland(player.world)) { - Optional islandOptional = SkylandsAPI.getIsland(player.world); + if (SkylandsAPI.isIsland(player.getWorld())) { + Optional islandOptional = SkylandsAPI.getIsland(player.getWorld()); if (islandOptional.isPresent()) { Island island = islandOptional.get(); if (island.isMember(player)) { @@ -36,8 +36,8 @@ public static void returnToIslandSpawn(ServerPlayerEntity player, boolean fallDa } } else { Hub hub = Skylands.getInstance().hub; - if (!SkylandsMain.MAIN_CONFIG.safeVoidFallDamage()) player.fallDistance = 0; - FabricDimensions.teleport(player, player.getWorld(), new TeleportTarget(hub.pos, new Vec3d(0, 0, 0), 0, 0)); + if (!Skylands.getConfig().safeVoidFallDamage) player.fallDistance = 0; + hub.visit(player, true); } } diff --git a/src/main/java/skylands/config/MainConfig.java b/src/main/java/skylands/config/MainConfig.java deleted file mode 100644 index 7cf27f0..0000000 --- a/src/main/java/skylands/config/MainConfig.java +++ /dev/null @@ -1,30 +0,0 @@ -package skylands.config; - -import io.wispforest.owo.config.annotation.Config; -import net.minecraft.util.math.Vec3d; - -import java.util.ArrayList; -import java.util.List; - -@SuppressWarnings("unused") -@Config(name = "skylands", wrapperName = "MainConfigs") -public class MainConfig { - public String language = "en_us"; - public String command = "sl"; - public List commandAliases = new ArrayList<>(); - public String adminCommand = "force-sl"; - public List adminCommandAliases = new ArrayList<>(); - public boolean allowVisitCurrentIsland = false; - public int defaultIslandRadius = -1; - //public int deletionCooldown = -1; - //public int islandLimit = -1; - //public boolean resetPlayerWithIsland = false; - public Vec3d defaultIslandLocation = new Vec3d(0.5d, 75d, 0.5d); - public boolean disableBlocksOutsideIslands = false; - public boolean disableEntitiesOutsideIslands = false; - public boolean enableEndIsland = false; - public boolean safeVoid = false; - public boolean safeVoidFallDamage = true; - public byte safeVoidBlocksBelow = 16; - public boolean showProtectionMessages = true; -} diff --git a/src/main/java/skylands/data/reloadable/SongsData.java b/src/main/java/skylands/data/reloadable/SongsData.java deleted file mode 100644 index 2f2837c..0000000 --- a/src/main/java/skylands/data/reloadable/SongsData.java +++ /dev/null @@ -1,45 +0,0 @@ -package skylands.data.reloadable; - -import net.fabricmc.fabric.api.resource.ResourceManagerHelper; -import net.fabricmc.fabric.api.resource.SimpleSynchronousResourceReloadListener; -import net.minecraft.resource.ResourceManager; -import net.minecraft.resource.ResourceType; -import net.minecraft.util.Identifier; -import nota.model.Playlist; -import nota.utils.NBSDecoder; -import skylands.SkylandsMain; - -import java.io.InputStream; - -public class SongsData implements SimpleSynchronousResourceReloadListener { - public static final SongsData INSTANCE = new SongsData(); - - public Playlist playlist = null; - - public static void init() { - ResourceManagerHelper.get(ResourceType.SERVER_DATA).registerReloadListener(SongsData.INSTANCE); - } - - @Override - public Identifier getFabricId() { - return SkylandsMain.id("songs"); - } - - @Override - public void reload(ResourceManager manager) { - if (playlist == null) { - for (Identifier id : manager.findResources("songs", path -> path.getPath().endsWith(".nbs")).keySet()) { - try (InputStream stream = manager.getResource(id).get().getInputStream()) { - if (playlist == null) { - playlist = new Playlist(NBSDecoder.parse(stream)); - } else { - playlist.add(NBSDecoder.parse(stream)); - } - } catch (Exception e) { - SkylandsMain.LOGGER.error("Error occurred while loading resource nbs " + id.toString(), e); - } - } - } - - } -} diff --git a/src/main/java/skylands/event/BlockBreakEvent.java b/src/main/java/skylands/event/BlockBreakEvent.java deleted file mode 100644 index f56289b..0000000 --- a/src/main/java/skylands/event/BlockBreakEvent.java +++ /dev/null @@ -1,29 +0,0 @@ -package skylands.event; - -import net.minecraft.block.BlockState; -import net.minecraft.block.CropBlock; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; -import skylands.logic.registry.SkylandsIslandSettings; -import skylands.util.Texts; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; - -@SuppressWarnings("unused") -public class BlockBreakEvent { - - public static boolean onBreak(World world, PlayerEntity player, BlockPos pos, BlockState state) { - if (!WorldProtection.canModify(world, pos, player, SkylandsIslandSettings.BREAK)) { - protectionWarning(player, "block_break"); - return false; - } - - if (state.getBlock() instanceof CropBlock crop && crop.isMature(state)) { - player.sendMessage(Texts.prefixed("message.skylands.right_click_harvest.tip"), true); - } - - return true; - } -} diff --git a/src/main/java/skylands/event/ServerEventListener.java b/src/main/java/skylands/event/ServerEventListener.java deleted file mode 100644 index ab95a4e..0000000 --- a/src/main/java/skylands/event/ServerEventListener.java +++ /dev/null @@ -1,43 +0,0 @@ -package skylands.event; - -import eu.pb4.common.economy.api.CommonEconomy; -import eu.pb4.placeholders.api.PlaceholderResult; -import eu.pb4.placeholders.api.Placeholders; -import net.minecraft.server.MinecraftServer; -import skylands.SkylandsMain; -import skylands.logic.Island; -import skylands.logic.Skylands; -import skylands.util.PreInitData; - -import java.util.Optional; - -public class ServerEventListener { - - public static void onTick(MinecraftServer server) { - Skylands.getInstance().onTick(server); - } - - public static void onStart(MinecraftServer server) { - Skylands.init(server); - PreInitData.close(); - CommonEconomy.register("skylands", Skylands.getInstance().economy.PROVIDER); - registerPlaceholders(); - } - - public static void onStop(MinecraftServer server) { - Skylands.getInstance().close(); - } - - //TODO: Add placeholders - private static void registerPlaceholders() { - Placeholders.register(SkylandsMain.id("locked"), (context, argument) -> { - Optional island = Skylands.getInstance().islands.getByPlayer(context.player()); - return island.map(value -> PlaceholderResult.value(value.locked ? "Locked" : "Open")).orElseGet(() -> PlaceholderResult.invalid("Missing island!")); - }); - - Placeholders.register(SkylandsMain.id("size"), (context, argument) -> { - Optional island = Skylands.getInstance().islands.getByPlayer(context.player()); - return island.map(value -> PlaceholderResult.value(String.valueOf(value.radius * 2 + 1))).orElseGet(() -> PlaceholderResult.invalid("Missing island!")); - }); - } -} diff --git a/src/main/java/skylands/event/UseBlockEvent.java b/src/main/java/skylands/event/UseBlockEvent.java deleted file mode 100644 index 22c49cf..0000000 --- a/src/main/java/skylands/event/UseBlockEvent.java +++ /dev/null @@ -1,52 +0,0 @@ -package skylands.event; - -import net.minecraft.block.Block; -import net.minecraft.block.BlockState; -import net.minecraft.block.CropBlock; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.util.ActionResult; -import net.minecraft.util.Hand; -import net.minecraft.util.hit.BlockHitResult; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; -import skylands.util.Texts; -import skylands.util.WorldProtection; - -public class UseBlockEvent { - - public static ActionResult onBlockUse(PlayerEntity player, World world, Hand hand, BlockHitResult hitResult) { - BlockPos pos = hitResult.getBlockPos(); - BlockState state = world.getBlockState(pos); - ItemStack toolStack = player.getStackInHand(hand); - - if (state.getBlock() instanceof CropBlock crop && crop.isMature(state)) { - if (WorldProtection.canModify(world, pos, player)) { - Item replant = state.getBlock().getPickStack(world, pos, state).getItem(); - final boolean[] removedReplant = {false}; - - Block.getDroppedStacks(state, (ServerWorld) world, pos, null, player, toolStack).forEach(stack -> { - if (!removedReplant[0] && stack.getItem() == replant) { - stack.setCount(stack.getCount() - 1); - removedReplant[0] = true; - } - - Block.dropStack(world, pos, stack); - }); - - state.onStacksDropped((ServerWorld) world, pos, toolStack, true); - world.setBlockState(pos, crop.withAge(0)); - - return ActionResult.SUCCESS; - } else { - player.sendMessage(Texts.prefixed("message.skylands.world_protection.harvest"), true); - return ActionResult.PASS; - } - - } - - return ActionResult.PASS; - } -} diff --git a/src/main/java/skylands/event/UseEntityEvent.java b/src/main/java/skylands/event/UseEntityEvent.java deleted file mode 100644 index b2b3a60..0000000 --- a/src/main/java/skylands/event/UseEntityEvent.java +++ /dev/null @@ -1,22 +0,0 @@ -package skylands.event; - -import net.minecraft.entity.Entity; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.util.ActionResult; -import net.minecraft.util.Hand; -import net.minecraft.world.World; - -@SuppressWarnings("unused") -public class UseEntityEvent { - - public static ActionResult onUse(PlayerEntity player, World world, Hand hand, Entity entity) { -// if(world.getRegistryKey().getValue().getNamespace().equals(Mod.MOD_ID)) { -// var island = Skylands.getInstance().islandStuck.get(UUID.fromString(world.getRegistryKey().getValue().getPath())); -// if(island.isPresent() && !island.get().isMember(player)) { -// player.sendMessage(Text.of("Skylands > You can't interact with entities out here!"), true); -// return ActionResult.FAIL; -// } -// } - return ActionResult.PASS; - } -} diff --git a/src/main/java/skylands/event/UseItemEvent.java b/src/main/java/skylands/event/UseItemEvent.java deleted file mode 100644 index 388711d..0000000 --- a/src/main/java/skylands/event/UseItemEvent.java +++ /dev/null @@ -1,16 +0,0 @@ -package skylands.event; - -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.util.Hand; -import net.minecraft.util.TypedActionResult; -import net.minecraft.world.World; - -@SuppressWarnings("unused") -public class UseItemEvent { - - public static TypedActionResult onUse(PlayerEntity player, World world, Hand hand) { - ItemStack stack = player.getStackInHand(hand); - return TypedActionResult.pass(stack); - } -} diff --git a/src/main/java/skylands/logic/registry/SkylandsIslandSettings.java b/src/main/java/skylands/logic/registry/SkylandsIslandSettings.java deleted file mode 100644 index 98360d6..0000000 --- a/src/main/java/skylands/logic/registry/SkylandsIslandSettings.java +++ /dev/null @@ -1,34 +0,0 @@ -package skylands.logic.registry; - -import io.wispforest.owo.registration.reflect.AutoRegistryContainer; -import net.minecraft.item.Items; -import net.minecraft.registry.Registry; -import skylands.logic.SkylandsRegistries; -import skylands.logic.settings.DefaultSkylandsIslandSettings; -import skylands.logic.settings.IslandSettings; - -public class SkylandsIslandSettings implements AutoRegistryContainer { - public static final IslandSettings PLACE = new DefaultSkylandsIslandSettings("place", Items.STONE); - public static final IslandSettings BREAK = new DefaultSkylandsIslandSettings("break", Items.WOODEN_PICKAXE); - public static final IslandSettings REDSTONE = new DefaultSkylandsIslandSettings("redstone", Items.REDSTONE); - public static final IslandSettings BEACON = new DefaultSkylandsIslandSettings("beacon", Items.BEACON); - public static final IslandSettings COMPOSTER = new DefaultSkylandsIslandSettings("composter", Items.COMPOSTER); - public static final IslandSettings LODESTONE = new DefaultSkylandsIslandSettings("lodestone", Items.LODESTONE); - public static final IslandSettings ANVIL = new DefaultSkylandsIslandSettings("anvil", Items.ANVIL); - public static final IslandSettings BREWING_STAND = new DefaultSkylandsIslandSettings("brewing_stand", Items.BREWING_STAND); - public static final IslandSettings CONTAINERS = new DefaultSkylandsIslandSettings("containers", Items.CHEST); - public static final IslandSettings RESPAWN_ANCHOR = new DefaultSkylandsIslandSettings("respawn_anchor", Items.RESPAWN_ANCHOR); - public static final IslandSettings HURT_HOSTILE = new DefaultSkylandsIslandSettings("hurt_hostile", Items.DIAMOND_SWORD); - public static final IslandSettings HURT_PASSIVE = new DefaultSkylandsIslandSettings("hurt_passive", Items.WOODEN_SWORD); - public static final IslandSettings DRIPLEAF = new DefaultSkylandsIslandSettings("dripleaf", Items.BIG_DRIPLEAF); - - @Override - public Registry getRegistry() { - return SkylandsRegistries.ISLAND_SETTINGS; - } - - @Override - public Class getTargetFieldType() { - return IslandSettings.class; - } -} diff --git a/src/main/java/skylands/mixin/entity/PlayerManagerMixin.java b/src/main/java/skylands/mixin/entity/PlayerManagerMixin.java deleted file mode 100644 index 30f6145..0000000 --- a/src/main/java/skylands/mixin/entity/PlayerManagerMixin.java +++ /dev/null @@ -1,46 +0,0 @@ -package skylands.mixin.entity; - -import net.minecraft.registry.RegistryKey; -import net.minecraft.server.PlayerManager; -import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Vec3d; -import net.minecraft.world.World; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; -import skylands.api.SkylandsAPI; -import skylands.logic.Island; -import skylands.logic.Skylands; - -import java.util.Optional; - -@Mixin(PlayerManager.class) -public abstract class PlayerManagerMixin { - @Redirect(method = "respawnPlayer", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/network/ServerPlayerEntity;getSpawnPointPosition()Lnet/minecraft/util/math/BlockPos;")) - private BlockPos skylands$respawnOnIsland(ServerPlayerEntity player) { - if (SkylandsAPI.isIsland(player.world)) { - Optional islandOptional = SkylandsAPI.getIsland(player.world); - if (islandOptional.isPresent()) { - Island island = islandOptional.get(); - if (island.isMember(player)) { - return BlockPos.ofFloored(island.spawnPos); - } else { - return BlockPos.ofFloored(island.visitsPos); - } - } - } - return BlockPos.ofFloored(Skylands.getInstance().hub.pos); - } - - @Redirect(method = "respawnPlayer", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/network/ServerPlayerEntity;getSpawnPointDimension()Lnet/minecraft/registry/RegistryKey;")) - private RegistryKey skylands$fixRespawnDimension(ServerPlayerEntity player) { - return player.world.getRegistryKey(); - } - - @Redirect(method = "respawnPlayer", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/PlayerEntity;findRespawnPosition(Lnet/minecraft/server/world/ServerWorld;Lnet/minecraft/util/math/BlockPos;FZZ)Ljava/util/Optional;")) - private Optional skylands$respawnOnIsland(ServerWorld world, BlockPos pos, float angle, boolean forced, boolean alive) { - return Optional.of(pos.toCenterPos()); - } -} diff --git a/src/main/java/skylands/mixin/world/protection/BarrelBlockMixin.java b/src/main/java/skylands/mixin/world/protection/BarrelBlockMixin.java deleted file mode 100644 index 7ba2377..0000000 --- a/src/main/java/skylands/mixin/world/protection/BarrelBlockMixin.java +++ /dev/null @@ -1,31 +0,0 @@ -package skylands.mixin.world.protection; - -import net.minecraft.block.BarrelBlock; -import net.minecraft.block.BlockState; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.util.ActionResult; -import net.minecraft.util.Hand; -import net.minecraft.util.hit.BlockHitResult; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; -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; -import skylands.util.WorldProtection; - -import static skylands.util.ServerUtils.protectionWarning; - -@Mixin(BarrelBlock.class) -public class BarrelBlockMixin { - - @Inject(method = "onUse", at = @At("HEAD"), cancellable = true) - void onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable cir) { - if (!world.isClient) { - if (!WorldProtection.canModify(world, pos, player)) { - protectionWarning(player, "barrel_open"); - cir.setReturnValue(ActionResult.FAIL); - } - } - } -} diff --git a/src/main/java/skylands/mixin/world/protection/SculkCatalystBlockEntityMixin.java b/src/main/java/skylands/mixin/world/protection/SculkCatalystBlockEntityMixin.java deleted file mode 100644 index 947a934..0000000 --- a/src/main/java/skylands/mixin/world/protection/SculkCatalystBlockEntityMixin.java +++ /dev/null @@ -1,32 +0,0 @@ -package skylands.mixin.world.protection; - -import net.minecraft.block.BlockState; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.block.entity.BlockEntityType; -import net.minecraft.block.entity.SculkCatalystBlockEntity; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Vec3d; -import net.minecraft.world.event.GameEvent; -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; -import skylands.util.WorldProtection; - -@Mixin(SculkCatalystBlockEntity.class) -public abstract class SculkCatalystBlockEntityMixin extends BlockEntity { - - public SculkCatalystBlockEntityMixin(BlockEntityType type, BlockPos pos, BlockState state) { - super(type, pos, state); - } - - @Inject(method = "listen", at = @At("HEAD"), cancellable = true) - private void listen(ServerWorld world, GameEvent event, GameEvent.Emitter emitter, Vec3d emitterPos, CallbackInfoReturnable cir) { - if (!world.isClient) { - if (!WorldProtection.isWithinIsland(world, pos)) { - cir.setReturnValue(false); - } - } - } -} diff --git a/src/main/java/skylands/mixin/world/protection/SculkCatalystBlockMixin.java b/src/main/java/skylands/mixin/world/protection/SculkCatalystBlockMixin.java deleted file mode 100644 index 62f767d..0000000 --- a/src/main/java/skylands/mixin/world/protection/SculkCatalystBlockMixin.java +++ /dev/null @@ -1,25 +0,0 @@ -package skylands.mixin.world.protection; - -import net.minecraft.block.BlockState; -import net.minecraft.block.SculkCatalystBlock; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.random.Random; -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 skylands.util.WorldProtection; - -@Mixin(SculkCatalystBlock.class) -public class SculkCatalystBlockMixin { - - @Inject(method = "bloom", at = @At("HEAD"), cancellable = true) - private static void bloom(ServerWorld world, BlockPos pos, BlockState state, Random random, CallbackInfo ci) { - if (!world.isClient) { - if (!WorldProtection.isWithinIsland(world, pos)) { - ci.cancel(); - } - } - } -} diff --git a/src/main/resources/assets/skylands/icon.png b/src/main/resources/assets/neoskies/icon.png similarity index 100% rename from src/main/resources/assets/skylands/icon.png rename to src/main/resources/assets/neoskies/icon.png diff --git a/src/main/resources/data/skylands/font/default.glyphs.json b/src/main/resources/data/neoskies/font/default.glyphs.json similarity index 100% rename from src/main/resources/data/skylands/font/default.glyphs.json rename to src/main/resources/data/neoskies/font/default.glyphs.json diff --git a/src/main/resources/data/skylands/font/default.json b/src/main/resources/data/neoskies/font/default.json similarity index 99% rename from src/main/resources/data/skylands/font/default.json rename to src/main/resources/data/neoskies/font/default.json index 3507227..5058bff 100644 --- a/src/main/resources/data/skylands/font/default.json +++ b/src/main/resources/data/neoskies/font/default.json @@ -189,7 +189,7 @@ }, { "type": "legacy_unicode", - "sizes": "skylands:font/glyph_sizes.bin", + "sizes": "neoskies:font/glyph_sizes.bin", "template": "minecraft:font/unicode_page_%s.png" } ] diff --git a/src/main/resources/data/skylands/font/glyph_sizes.bin b/src/main/resources/data/neoskies/font/glyph_sizes.bin similarity index 100% rename from src/main/resources/data/skylands/font/glyph_sizes.bin rename to src/main/resources/data/neoskies/font/glyph_sizes.bin diff --git a/src/main/resources/data/skylands/songs/heads-will-roll.nbs b/src/main/resources/data/neoskies/songs/heads-will-roll.nbs similarity index 100% rename from src/main/resources/data/skylands/songs/heads-will-roll.nbs rename to src/main/resources/data/neoskies/songs/heads-will-roll.nbs diff --git a/src/main/resources/data/skylands/songs/home.nbs b/src/main/resources/data/neoskies/songs/home.nbs similarity index 100% rename from src/main/resources/data/skylands/songs/home.nbs rename to src/main/resources/data/neoskies/songs/home.nbs diff --git a/src/main/resources/data/skylands/songs/merry_go_round_of_life.nbs b/src/main/resources/data/neoskies/songs/merry_go_round_of_life.nbs similarity index 100% rename from src/main/resources/data/skylands/songs/merry_go_round_of_life.nbs rename to src/main/resources/data/neoskies/songs/merry_go_round_of_life.nbs diff --git a/src/main/resources/data/skylands/songs/our_great_mikado.nbs b/src/main/resources/data/neoskies/songs/our_great_mikado.nbs similarity index 100% rename from src/main/resources/data/skylands/songs/our_great_mikado.nbs rename to src/main/resources/data/neoskies/songs/our_great_mikado.nbs diff --git a/src/main/resources/data/skylands/structures/end_island.nbt b/src/main/resources/data/neoskies/structures/end_island.nbt similarity index 100% rename from src/main/resources/data/skylands/structures/end_island.nbt rename to src/main/resources/data/neoskies/structures/end_island.nbt diff --git a/src/main/resources/data/skylands/structures/nether_island.nbt b/src/main/resources/data/neoskies/structures/nether_island.nbt similarity index 100% rename from src/main/resources/data/skylands/structures/nether_island.nbt rename to src/main/resources/data/neoskies/structures/nether_island.nbt diff --git a/src/main/resources/data/skylands/structures/start_island.nbt b/src/main/resources/data/neoskies/structures/start_island.nbt similarity index 100% rename from src/main/resources/data/skylands/structures/start_island.nbt rename to src/main/resources/data/neoskies/structures/start_island.nbt diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 5b44b32..2078a50 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -1,46 +1,40 @@ { "schemaVersion": 1, - "id": "skylands-custom", + "id": "neoskies", "version": "${version}", - "name": "Skylands (custom)", - "description": "Simple Skyblock Islands generator and manager.\nModified version of Skylands", + "name": "NeoSkies", + "description": "", "authors": [ - "PinkGoosik", "Awakened Redstone" ], - "contributors": [ - "KujouMolean" - ], - "contact": { - "homepage": "https://modrinth.com/mod/skylands", - "sources": "https://github.com/tyap-lyap/skylands", - "issues": "https://github.com/tyap-lyap/skylands/issues" - }, "license": "LGPL-3.0", - "icon": "assets/skylands/icon.png", - "accessWidener": "skylands.accesswidener", + "icon": "assets/neoskies/icon.png", + "accessWidener": "neoskies.accesswidener", "environment": "*", "entrypoints": { "main": [ - "skylands.SkylandsMain" + "com.awakenedredstone.neoskies.SkylandsMain" + ], + "fabric-datagen": [ + "com.awakenedredstone.neoskies.datagen.NeoSkiesDatagen" ], "cardinal-components": [ - "skylands.data.SkylandComponents" + "com.awakenedredstone.neoskies.data.SkylandComponents" ] }, "mixins": [ - "skylands.mixins.json" + "neoskies.mixins.json" ], "custom": { "cardinal-components": [ - "skylands:world_data", - "skylands:player_data" + "neoskies:world_data", + "neoskies:player_data" ] }, "depends": { "fabricloader": "*", "fabric-api": ">=0.76.0", - "minecraft": "1.19.4", + "minecraft": "1.20.4", "java": ">=17" }, "breaks": { diff --git a/src/main/resources/skylands.accesswidener b/src/main/resources/neoskies.accesswidener similarity index 50% rename from src/main/resources/skylands.accesswidener rename to src/main/resources/neoskies.accesswidener index 9a44d95..04184b9 100644 --- a/src/main/resources/skylands.accesswidener +++ b/src/main/resources/neoskies.accesswidener @@ -4,12 +4,20 @@ accessWidener v1 named accessible class net/minecraft/world/border/WorldBorder$Area accessible class net/minecraft/world/border/WorldBorder$MovingArea accessible class net/minecraft/world/border/WorldBorder$StaticArea +accessible class net/minecraft/block/entity/SculkSensorBlockEntity$VibrationCallback +accessible class net/minecraft/block/entity/SculkShriekerBlockEntity$VibrationCallback # Methods accessible method net/minecraft/server/network/ServerPlayerEntity getPermissionLevel ()I accessible method net/minecraft/world/border/WorldBorder$MovingArea (Lnet/minecraft/world/border/WorldBorder;DDJ)V accessible method net/minecraft/text/TranslatableTextContent updateTranslations ()V +accessible method net/minecraft/server/network/ServerPlayerInteractionManager setGameMode (Lnet/minecraft/world/GameMode;Lnet/minecraft/world/GameMode;)V +accessible method net/minecraft/entity/Entity refreshPosition ()V +accessible method net/minecraft/entity/player/PlayerEntity dropShoulderEntities ()V +accessible method net/minecraft/server/network/ServerPlayerEntity forgiveMobAnger ()V # Fields accessible field net/minecraft/text/TranslatableTextContent translations Ljava/util/List; accessible field net/minecraft/server/world/ThreadedAnvilChunkStorage chunkHolders Lit/unimi/dsi/fastutil/longs/Long2ObjectLinkedOpenHashMap; +accessible field net/minecraft/world/WorldSaveHandler playerDataDir Ljava/io/File; +accessible field net/minecraft/server/MinecraftServer saveHandler Lnet/minecraft/world/WorldSaveHandler;