From b75b4e1df1969485fa2c681985907f8334549412 Mon Sep 17 00:00:00 2001 From: iceBear67 Date: Thu, 27 Mar 2025 23:24:49 +0800 Subject: [PATCH] refactor(ALL): bump minecraft version to 1.21.5 trimmed unused feature: /gamerule CustomEntity API, Custom Item API We'll use Polymer for replacement in the future. Tests needed. --- build.gradle | 3 +- gradle.properties | 26 +++---- .../io/ib67/sfcraft/SFCraftInitializer.java | 7 -- .../java/io/ib67/sfcraft/SFEntityType.java | 52 -------------- src/main/java/io/ib67/sfcraft/SFItems.java | 33 --------- .../io/ib67/sfcraft/item/AeroBackpack.java | 26 ------- .../java/io/ib67/sfcraft/item/SFItem.java | 8 --- .../io/ib67/sfcraft/item/TickableItem.java | 10 --- .../mixin/common/bridge/EntityBridge.java | 2 +- .../server/AbstractFurnaceBlockMixin.java | 9 ++- .../mixin/server/ServerChunkManagerMixin.java | 12 ++++ .../mixin/server/ServerWorldMixin.java | 8 +++ .../hack/EntitySpawnS2CPacketMixin.java | 17 ----- .../server/hack/HoverEntityContentMixin.java | 18 ----- .../server/hack/RegistryHandlerMixin.java | 21 ------ .../sfcraft/mixin/server/item/ItemMixin.java | 23 ------ .../mixin/server/item/ItemStackMixin.java | 71 ------------------- .../mixin/server/item/PlayerEntityMixin.java | 42 ----------- .../server/subserver/PlayerManagerMixin.java | 5 +- .../subserver/ServerPlayerEntityMixin.java | 16 ++--- .../mixin/server/subserver/WorldMixin.java | 35 --------- .../ib67/sfcraft/module/CustomItemModule.java | 65 ----------------- .../module/ElytraSpeedMeterModule.java | 14 +--- .../io/ib67/sfcraft/module/RoomModule.java | 27 ++----- .../io/ib67/sfcraft/module/WelcomeModule.java | 3 +- .../module/chat/decorator/ChatPingModule.java | 4 +- .../chat/decorator/ChatSendLocModule.java | 4 +- .../sfcraft/module/command/BackModule.java | 2 +- .../module/randomevt/LongNightModule.java | 54 -------------- .../randomevt/longnight/LongNightEvent.java | 3 +- .../module/room/CreativeRoomModule.java | 1 - .../supervisor/web/SchematicUploader.java | 7 +- .../room/data/RoomWorldDataLoader.java | 55 -------------- .../java/io/ib67/sfcraft/util/Helper.java | 3 +- .../io/ib67/sfcraft/util/TypedNbtList.java | 6 +- .../util/litematic/LitematicConverter.java | 54 +++++++++----- .../util/litematic/LitematicConverterV3.java | 23 +++--- src/main/resources/sfcraft.accesswidener | 3 +- src/main/resources/sfcraft.mixins.json | 10 +-- 39 files changed, 124 insertions(+), 658 deletions(-) delete mode 100644 src/main/java/io/ib67/sfcraft/SFEntityType.java delete mode 100644 src/main/java/io/ib67/sfcraft/SFItems.java delete mode 100644 src/main/java/io/ib67/sfcraft/item/AeroBackpack.java delete mode 100644 src/main/java/io/ib67/sfcraft/item/SFItem.java delete mode 100644 src/main/java/io/ib67/sfcraft/item/TickableItem.java create mode 100644 src/main/java/io/ib67/sfcraft/mixin/server/ServerChunkManagerMixin.java delete mode 100644 src/main/java/io/ib67/sfcraft/mixin/server/hack/EntitySpawnS2CPacketMixin.java delete mode 100644 src/main/java/io/ib67/sfcraft/mixin/server/hack/HoverEntityContentMixin.java delete mode 100644 src/main/java/io/ib67/sfcraft/mixin/server/hack/RegistryHandlerMixin.java delete mode 100644 src/main/java/io/ib67/sfcraft/mixin/server/item/ItemMixin.java delete mode 100644 src/main/java/io/ib67/sfcraft/mixin/server/item/ItemStackMixin.java delete mode 100644 src/main/java/io/ib67/sfcraft/mixin/server/item/PlayerEntityMixin.java delete mode 100644 src/main/java/io/ib67/sfcraft/mixin/server/subserver/WorldMixin.java delete mode 100644 src/main/java/io/ib67/sfcraft/module/CustomItemModule.java delete mode 100644 src/main/java/io/ib67/sfcraft/module/randomevt/LongNightModule.java delete mode 100644 src/main/java/io/ib67/sfcraft/room/data/RoomWorldDataLoader.java diff --git a/build.gradle b/build.gradle index ba96044..4bf8086 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ plugins { id 'maven-publish' id("io.freefair.lombok") version "8.6" id("com.github.johnrengelman.shadow") version "8.1.1" - id 'fabric-loom' version '1.7.3' + id 'fabric-loom' version '1.10.1' } version = project.mod_version @@ -18,7 +18,6 @@ repositories { // Loom adds the essential maven repositories to download Minecraft and libraries from automatically. // See https://docs.gradle.org/current/userguide/declaring_repositories.html // for more information about repositories. - maven { url 'https://maven.wispforest.io/releases/' } } dependencies { diff --git a/gradle.properties b/gradle.properties index 01b70ab..7681710 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,19 +1,11 @@ # Done to increase the memory available to gradle. -org.gradle.jvmargs=-Xmx1G - -# Fabric Properties - # check these on https://modmuss50.me/fabric.html - minecraft_version=1.21 - yarn_mappings=1.21+build.7 - loader_version=0.15.11 - +org.gradle.jvmargs=-Xmx4G +minecraft_version=1.21.5 +yarn_mappings=1.21.5+build.1 +loader_version=0.16.10 +# Fabric API +fabric_version=0.119.5+1.21.5 # Mod Properties - mod_version = 1.0.0 - maven_group = io.ib67 - archives_base_name = sfcraft - -# Dependencies - # check this on https://modmuss50.me/fabric.html - fabric_version=0.100.4+1.21 - owo_version=0.12.10+1.21 - +mod_version=1.0.0 +maven_group=io.ib67 +archives_base_name=sfcraft \ No newline at end of file diff --git a/src/main/java/io/ib67/sfcraft/SFCraftInitializer.java b/src/main/java/io/ib67/sfcraft/SFCraftInitializer.java index 5e698e6..f95ba58 100644 --- a/src/main/java/io/ib67/sfcraft/SFCraftInitializer.java +++ b/src/main/java/io/ib67/sfcraft/SFCraftInitializer.java @@ -8,7 +8,6 @@ import io.ib67.sfcraft.module.chat.ChatPrefixModule; import io.ib67.sfcraft.module.chat.decorator.ChatPingModule; import io.ib67.sfcraft.module.chat.decorator.ChatSendLocModule; import io.ib67.sfcraft.module.compat.ModCompatModule; -import io.ib67.sfcraft.module.randomevt.LongNightModule; import io.ib67.sfcraft.module.room.CreativeRoomModule; import io.ib67.sfcraft.module.supervisor.WebModule; import io.ib67.sfcraft.module.supervisor.web.SchematicUploader; @@ -25,9 +24,6 @@ import io.ib67.sfcraft.module.command.ManagementModule; import io.ib67.sfcraft.registry.room.SimpleRoomRegistry; import io.ib67.sfcraft.room.RoomTeleporter; import lombok.extern.log4j.Log4j2; -import net.fabricmc.fabric.api.event.registry.FabricRegistryBuilder; -import net.minecraft.registry.Registries; -import net.minecraft.registry.Registry; import net.minecraft.server.MinecraftServer; @Log4j2 @@ -61,12 +57,10 @@ public class SFCraftInitializer extends GuiceModInitializer { registerFeature(FartFertilizerModule.class); registerFeature(ChatPingModule.class); registerFeature(ChatSendLocModule.class); - registerFeature(LongNightModule.class); registerFeature(ModCompatModule.class); registerFeature(RoomModule.class); registerFeature(CreativeRoomModule.class); registerFeature(ChatPrefixModule.class); - registerFeature(CustomItemModule.class); registerWebModules(); } @@ -91,7 +85,6 @@ public class SFCraftInitializer extends GuiceModInitializer { @Override protected Injector onInit() { - SFEntityType.registerEntities(); return SFCraft.injector = Guice.createInjector( new SFCraft(), this diff --git a/src/main/java/io/ib67/sfcraft/SFEntityType.java b/src/main/java/io/ib67/sfcraft/SFEntityType.java deleted file mode 100644 index c5cc97d..0000000 --- a/src/main/java/io/ib67/sfcraft/SFEntityType.java +++ /dev/null @@ -1,52 +0,0 @@ -package io.ib67.sfcraft; - -import io.ib67.sfcraft.entity.SFGuiderEntity; -import lombok.experimental.UtilityClass; -import lombok.extern.log4j.Log4j2; -import net.fabricmc.fabric.api.object.builder.v1.entity.FabricDefaultAttributeRegistry; -import net.fabricmc.fabric.api.object.builder.v1.entity.FabricEntityTypeBuilder; -import net.minecraft.entity.EntityType; -import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.SpawnGroup; -import net.minecraft.entity.attribute.DefaultAttributeContainer; -import net.minecraft.registry.Registries; -import net.minecraft.registry.Registry; -import net.minecraft.util.Identifier; - -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -@Log4j2 -public class SFEntityType { - public static final EntityType GUIDER = Registry.register( - Registries.ENTITY_TYPE, - Identifier.of(SFCraft.MOD_ID , "guider"), - EntityType.Builder.create(SFGuiderEntity::new, SpawnGroup.CREATURE) - .dimensions(0.35F, 0.6F) - .eyeHeight(0.36F) - .vehicleAttachment(0.04F) - .maxTrackingRange(8) - .trackingTickInterval(2).build() - ); - private static SFEntityType registry; - private final Map, EntityType> mappedEntityTypes = new ConcurrentHashMap<>(); - - private void init() { - register(GUIDER, EntityType.ALLAY, SFGuiderEntity.createAllayAttributes().build()); - } - - private void register(EntityType custom, EntityType origin, DefaultAttributeContainer attr) { - FabricDefaultAttributeRegistry.register(custom, attr); - mappedEntityTypes.put(custom, origin); - } - - static void registerEntities() { - registry = new SFEntityType(); - registry.init(); - } - - public static EntityType mapToVanilla(EntityType type) { - return (EntityType) registry.mappedEntityTypes.getOrDefault(type, type); - } -} diff --git a/src/main/java/io/ib67/sfcraft/SFItems.java b/src/main/java/io/ib67/sfcraft/SFItems.java deleted file mode 100644 index 54bb259..0000000 --- a/src/main/java/io/ib67/sfcraft/SFItems.java +++ /dev/null @@ -1,33 +0,0 @@ -package io.ib67.sfcraft; - -import io.ib67.sfcraft.item.AeroBackpack; -import io.ib67.sfcraft.mixin.common.bridge.ItemBridge; -import net.fabricmc.fabric.api.event.registry.FabricRegistryBuilder; -import net.fabricmc.fabric.api.event.registry.RegistryAttribute; -import net.minecraft.item.ArmorItem; -import net.minecraft.item.Item; -import net.minecraft.registry.Registry; -import net.minecraft.registry.RegistryKey; -import net.minecraft.util.Identifier; - -import static io.ib67.sfcraft.SFRegistries.ITEMS; - -public class SFItems { - public static final Item AERO_BACKPACK = register( - new AeroBackpack(new Item.Settings().maxDamage(ArmorItem.Type.CHESTPLATE.getMaxDamage(15))), "aero_backpack"); - public static final String SF_ITEM_TYPE_KEY = "sf_type"; - - public static void init() { - } - - private static Item register(Item item, String id) { - Identifier itemID = Identifier.of(SFCraft.MOD_ID, id); - Item registeredItem = Registry.register(ITEMS, itemID, item); - ((ItemBridge) registeredItem).setRegistryEntry(ITEMS.getEntry(itemID).get()); - return registeredItem; - } - - public static Item getById(Identifier item) { - return ITEMS.get(item); - } -} diff --git a/src/main/java/io/ib67/sfcraft/item/AeroBackpack.java b/src/main/java/io/ib67/sfcraft/item/AeroBackpack.java deleted file mode 100644 index 20b4785..0000000 --- a/src/main/java/io/ib67/sfcraft/item/AeroBackpack.java +++ /dev/null @@ -1,26 +0,0 @@ -package io.ib67.sfcraft.item; - -import net.minecraft.entity.EquipmentSlot; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.*; -import net.minecraft.registry.entry.RegistryEntry; -import net.minecraft.text.Text; - -public class AeroBackpack extends ArmorItem implements TickableItem, SFItem { - private static final Text STATUS_MESSAGE = Text.of("You're wearing aero backpack!"); - - public AeroBackpack(Settings settings) { - super(ArmorMaterials.IRON, Type.CHESTPLATE, settings); - } - - @Override - public void onUpdate(PlayerEntity player, ItemStack stack, EquipmentSlot slot) { - if (slot != EquipmentSlot.CHEST) return; - player.sendMessage(STATUS_MESSAGE, true); - } - - @Override - public Item getMappedItem() { - return Items.IRON_CHESTPLATE; - } -} diff --git a/src/main/java/io/ib67/sfcraft/item/SFItem.java b/src/main/java/io/ib67/sfcraft/item/SFItem.java deleted file mode 100644 index dcf7249..0000000 --- a/src/main/java/io/ib67/sfcraft/item/SFItem.java +++ /dev/null @@ -1,8 +0,0 @@ -package io.ib67.sfcraft.item; - -import net.minecraft.item.Item; -import net.minecraft.registry.entry.RegistryEntry; - -public interface SFItem { - Item getMappedItem(); -} diff --git a/src/main/java/io/ib67/sfcraft/item/TickableItem.java b/src/main/java/io/ib67/sfcraft/item/TickableItem.java deleted file mode 100644 index 94f694c..0000000 --- a/src/main/java/io/ib67/sfcraft/item/TickableItem.java +++ /dev/null @@ -1,10 +0,0 @@ -package io.ib67.sfcraft.item; - -import net.minecraft.entity.EquipmentSlot; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.server.network.ServerPlayerEntity; - -public interface TickableItem { - void onUpdate(PlayerEntity player, ItemStack stack, EquipmentSlot slot); -} diff --git a/src/main/java/io/ib67/sfcraft/mixin/common/bridge/EntityBridge.java b/src/main/java/io/ib67/sfcraft/mixin/common/bridge/EntityBridge.java index 5f96708..4752015 100644 --- a/src/main/java/io/ib67/sfcraft/mixin/common/bridge/EntityBridge.java +++ b/src/main/java/io/ib67/sfcraft/mixin/common/bridge/EntityBridge.java @@ -7,7 +7,7 @@ import org.spongepowered.asm.mixin.gen.Invoker; @Mixin(Entity.class) public interface EntityBridge { - @Accessor("FALL_FLYING_FLAG_INDEX") + @Accessor("GLIDING_FLAG_INDEX") static int sfcraft$getFlyingFlagIndex() { throw new AssertionError(); } diff --git a/src/main/java/io/ib67/sfcraft/mixin/server/AbstractFurnaceBlockMixin.java b/src/main/java/io/ib67/sfcraft/mixin/server/AbstractFurnaceBlockMixin.java index de9ceb1..e8be87e 100644 --- a/src/main/java/io/ib67/sfcraft/mixin/server/AbstractFurnaceBlockMixin.java +++ b/src/main/java/io/ib67/sfcraft/mixin/server/AbstractFurnaceBlockMixin.java @@ -8,6 +8,7 @@ import net.minecraft.block.entity.AbstractFurnaceBlockEntity; import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.BlockEntityTicker; import net.minecraft.block.entity.BlockEntityType; +import net.minecraft.server.world.ServerWorld; import net.minecraft.util.math.BlockPos; import net.minecraft.world.GameRules; import net.minecraft.world.World; @@ -26,15 +27,17 @@ public abstract class AbstractFurnaceBlockMixin extends BlockWithEntity { * @author icybear * @reason to replace their ticker */ + @Nullable @Overwrite - public static @Nullable BlockEntityTicker validateTicker( + public static BlockEntityTicker validateTicker( World world, BlockEntityType givenType, BlockEntityType expectedType ) { - return world.isClient ? null : BlockWithEntity.validateTicker(givenType, expectedType, AbstractFurnaceBlockMixin::tickMultiple); + return world instanceof ServerWorld sw ? BlockWithEntity.validateTicker(givenType, expectedType, AbstractFurnaceBlockMixin::tickMultiple) : null; } @Unique - private static void tickMultiple(World world, BlockPos pos, BlockState state, AbstractFurnaceBlockEntity blockEntity) { + private static void tickMultiple(World _world, BlockPos pos, BlockState state, E blockEntity) { + var world = (ServerWorld) _world; AbstractFurnaceBlockEntity.tick(world, pos, state, blockEntity); int i = world.getGameRules().getInt(GameRules.PLAYERS_SLEEPING_PERCENTAGE); if (((ServerWorldBridge) world).getSleepManager().canSkipNight(i)) { diff --git a/src/main/java/io/ib67/sfcraft/mixin/server/ServerChunkManagerMixin.java b/src/main/java/io/ib67/sfcraft/mixin/server/ServerChunkManagerMixin.java new file mode 100644 index 0000000..0cc1785 --- /dev/null +++ b/src/main/java/io/ib67/sfcraft/mixin/server/ServerChunkManagerMixin.java @@ -0,0 +1,12 @@ +package io.ib67.sfcraft.mixin.server; + +import net.minecraft.server.world.ChunkLevelManager; +import net.minecraft.server.world.ServerChunkManager; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(ServerChunkManager.class) +public interface ServerChunkManagerMixin { + @Accessor("levelManager") + ChunkLevelManager getLevelManager(); +} diff --git a/src/main/java/io/ib67/sfcraft/mixin/server/ServerWorldMixin.java b/src/main/java/io/ib67/sfcraft/mixin/server/ServerWorldMixin.java index c014fc4..f917900 100644 --- a/src/main/java/io/ib67/sfcraft/mixin/server/ServerWorldMixin.java +++ b/src/main/java/io/ib67/sfcraft/mixin/server/ServerWorldMixin.java @@ -1,11 +1,19 @@ package io.ib67.sfcraft.mixin.server; +import io.ib67.sfcraft.SFCraft; import io.ib67.sfcraft.mixin.common.bridge.ServerWorldBridge; +import io.ib67.sfcraft.module.RoomModule; import io.ib67.sfcraft.util.MixinHelper; +import net.minecraft.registry.RegistryKey; import net.minecraft.server.world.ServerWorld; import net.minecraft.world.GameRules; +import net.minecraft.world.World; +import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.*; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(ServerWorld.class) public abstract class ServerWorldMixin { diff --git a/src/main/java/io/ib67/sfcraft/mixin/server/hack/EntitySpawnS2CPacketMixin.java b/src/main/java/io/ib67/sfcraft/mixin/server/hack/EntitySpawnS2CPacketMixin.java deleted file mode 100644 index 4ea274b..0000000 --- a/src/main/java/io/ib67/sfcraft/mixin/server/hack/EntitySpawnS2CPacketMixin.java +++ /dev/null @@ -1,17 +0,0 @@ -package io.ib67.sfcraft.mixin.server.hack; - -import io.ib67.sfcraft.SFCraftInitializer; -import io.ib67.sfcraft.SFEntityType; -import net.minecraft.entity.EntityType; -import net.minecraft.network.packet.s2c.play.EntitySpawnS2CPacket; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.ModifyArg; - -@Mixin(EntitySpawnS2CPacket.class) -public class EntitySpawnS2CPacketMixin { - @ModifyArg(method = "write", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/codec/PacketCodec;encode(Ljava/lang/Object;Ljava/lang/Object;)V"), index = 1) - public Object mapModType(Object type) { - return SFEntityType.mapToVanilla((EntityType) type); - } -} diff --git a/src/main/java/io/ib67/sfcraft/mixin/server/hack/HoverEntityContentMixin.java b/src/main/java/io/ib67/sfcraft/mixin/server/hack/HoverEntityContentMixin.java deleted file mode 100644 index 2546341..0000000 --- a/src/main/java/io/ib67/sfcraft/mixin/server/hack/HoverEntityContentMixin.java +++ /dev/null @@ -1,18 +0,0 @@ -package io.ib67.sfcraft.mixin.server.hack; - -import io.ib67.sfcraft.SFCraftInitializer; -import io.ib67.sfcraft.SFEntityType; -import net.minecraft.entity.EntityType; -import net.minecraft.text.HoverEvent; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(HoverEvent.EntityContent.class) -public class HoverEntityContentMixin { - @Inject(method = "method_54198", at = @At("HEAD"), cancellable = true) - private static void sf$mapToVanilla(HoverEvent.EntityContent content, CallbackInfoReturnable cir) { - cir.setReturnValue(SFEntityType.mapToVanilla(content.entityType)); - } -} diff --git a/src/main/java/io/ib67/sfcraft/mixin/server/hack/RegistryHandlerMixin.java b/src/main/java/io/ib67/sfcraft/mixin/server/hack/RegistryHandlerMixin.java deleted file mode 100644 index 5b4f2d6..0000000 --- a/src/main/java/io/ib67/sfcraft/mixin/server/hack/RegistryHandlerMixin.java +++ /dev/null @@ -1,21 +0,0 @@ -package io.ib67.sfcraft.mixin.server.hack; - -import it.unimi.dsi.fastutil.objects.Object2IntMap; -import net.fabricmc.fabric.impl.registry.sync.packet.DirectRegistryPacketHandler; -import net.minecraft.util.Identifier; -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 java.util.Map; -import java.util.function.Consumer; -import java.util.stream.Collectors; - -@Mixin(DirectRegistryPacketHandler.class) -public abstract class RegistryHandlerMixin { - @Inject(method = "sendPacket", at = @At("HEAD"), remap = false) - public void sf$removeRegistry(Consumer sender, Map> registryMap, CallbackInfo ci) { - registryMap.clear(); - } -} diff --git a/src/main/java/io/ib67/sfcraft/mixin/server/item/ItemMixin.java b/src/main/java/io/ib67/sfcraft/mixin/server/item/ItemMixin.java deleted file mode 100644 index 5b004e1..0000000 --- a/src/main/java/io/ib67/sfcraft/mixin/server/item/ItemMixin.java +++ /dev/null @@ -1,23 +0,0 @@ -package io.ib67.sfcraft.mixin.server.item; - -import io.ib67.sfcraft.item.SFItem; -import net.minecraft.item.Item; -import net.minecraft.registry.DefaultedRegistry; -import net.minecraft.registry.entry.RegistryEntry; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - -@Mixin(Item.class) -public abstract class ItemMixin { - @Redirect( - method ="", - at= @At(value = "INVOKE", target = "Lnet/minecraft/registry/DefaultedRegistry;createEntry(Ljava/lang/Object;)Lnet/minecraft/registry/entry/RegistryEntry$Reference;") - ) - public RegistryEntry.Reference sf$redirectCreateEntry(DefaultedRegistry instance, Object o){ - if(this instanceof SFItem) { - return null; - } - return instance.createEntry(o); - } -} diff --git a/src/main/java/io/ib67/sfcraft/mixin/server/item/ItemStackMixin.java b/src/main/java/io/ib67/sfcraft/mixin/server/item/ItemStackMixin.java deleted file mode 100644 index 49ae5d5..0000000 --- a/src/main/java/io/ib67/sfcraft/mixin/server/item/ItemStackMixin.java +++ /dev/null @@ -1,71 +0,0 @@ -package io.ib67.sfcraft.mixin.server.item; - -import io.ib67.sfcraft.SFCraft; -import io.ib67.sfcraft.SFItems; -import io.ib67.sfcraft.SFRegistries; -import net.minecraft.component.ComponentHolder; -import net.minecraft.component.ComponentMapImpl; -import net.minecraft.component.DataComponentTypes; -import net.minecraft.item.Item; -import net.minecraft.item.ItemConvertible; -import net.minecraft.item.ItemStack; -import net.minecraft.item.Items; -import net.minecraft.util.Identifier; -import org.jetbrains.annotations.Nullable; -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.Unique; -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 org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(ItemStack.class) -public abstract class ItemStackMixin implements ComponentHolder { - @Shadow - @Final - @Deprecated - @Nullable - private Item item; - - @Shadow @Final private static Logger LOGGER; - @Unique - private Item sfItem; - - @Shadow public abstract boolean isEmpty(); - - @Inject(method = "(Lnet/minecraft/item/ItemConvertible;ILnet/minecraft/component/ComponentMapImpl;)V", at = @At("TAIL")) - private void initSFItem(ItemConvertible item, int count, ComponentMapImpl components, CallbackInfo ci) { - var _id = get(DataComponentTypes.CUSTOM_DATA); - if (_id != null && _id.contains(SFItems.SF_ITEM_TYPE_KEY)) { - var id = _id.copyNbt().getString(SFItems.SF_ITEM_TYPE_KEY); - try { - sfItem = SFRegistries.ITEMS.get(Identifier.of(SFCraft.MOD_ID, id)); - }catch(Exception e){ - e.printStackTrace(); - } - if(sfItem == null){ - LOGGER.warn("A invalid sfItem is being created: {}", id); - new IllegalStateException("Just stacktrace").printStackTrace(); - } - } - } - - @Inject(method = "getItem", at = @At("HEAD"), cancellable = true) - private void beforeGetItem(CallbackInfoReturnable cir) { - if (sfItem != null) cir.setReturnValue(sfItem); - } - - @Redirect(method = "getRegistryEntry", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;getItem()Lnet/minecraft/item/Item;")) - private Item sf$getMappedEntry(ItemStack instance) { - return isEmpty() ? Items.AIR : this.item; - } - - @Redirect(method = "copy", at= @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;getItem()Lnet/minecraft/item/Item;")) - private Item sf$getCopySubject(ItemStack instance){ - return isEmpty() ? Items.AIR : this.item; - } -} diff --git a/src/main/java/io/ib67/sfcraft/mixin/server/item/PlayerEntityMixin.java b/src/main/java/io/ib67/sfcraft/mixin/server/item/PlayerEntityMixin.java deleted file mode 100644 index 3a571dc..0000000 --- a/src/main/java/io/ib67/sfcraft/mixin/server/item/PlayerEntityMixin.java +++ /dev/null @@ -1,42 +0,0 @@ -package io.ib67.sfcraft.mixin.server.item; - -import io.ib67.sfcraft.item.TickableItem; -import net.minecraft.entity.EquipmentSlot; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.ItemStack; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -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; - -@Mixin(PlayerEntity.class) -public abstract class PlayerEntityMixin { - @Shadow - public abstract ItemStack getEquippedStack(EquipmentSlot slot); - - @Inject(method = "updateTurtleHelmet", at = @At("TAIL")) - public void sf$tickMyItems(CallbackInfo ci) { - checkAndUpdate(EquipmentSlot.OFFHAND); - checkAndUpdate(EquipmentSlot.MAINHAND); - checkAndUpdate(EquipmentSlot.HEAD); - checkAndUpdate(EquipmentSlot.CHEST); - checkAndUpdate(EquipmentSlot.LEGS); - checkAndUpdate(EquipmentSlot.FEET); - checkAndUpdate(EquipmentSlot.BODY); - } - - @Unique - private void checkAndUpdate(EquipmentSlot equipmentSlot) { - var item = getEquippedStack(equipmentSlot); - if (item.getItem() instanceof TickableItem tickableItem) { - tickableItem.onUpdate($this(), item, equipmentSlot); - } - } - - @Unique - private PlayerEntity $this() { - return (PlayerEntity) (Object) this; - } -} diff --git a/src/main/java/io/ib67/sfcraft/mixin/server/subserver/PlayerManagerMixin.java b/src/main/java/io/ib67/sfcraft/mixin/server/subserver/PlayerManagerMixin.java index 606ac6a..6a1b2f2 100644 --- a/src/main/java/io/ib67/sfcraft/mixin/server/subserver/PlayerManagerMixin.java +++ b/src/main/java/io/ib67/sfcraft/mixin/server/subserver/PlayerManagerMixin.java @@ -2,6 +2,7 @@ package io.ib67.sfcraft.mixin.server.subserver; import com.mojang.authlib.GameProfile; import io.ib67.sfcraft.SFCraft; +import io.ib67.sfcraft.mixin.server.ServerChunkManagerMixin; import io.ib67.sfcraft.module.RoomModule; import io.ib67.sfcraft.registry.RoomRegistry; import io.ib67.sfcraft.util.Helper; @@ -70,8 +71,8 @@ public abstract class PlayerManagerMixin { private void teleportToRoom(ServerPlayerEntity player, GlobalPos spawn) { var world = player.getServer().getWorld(spawn.dimension()); var pos = spawn.pos(); - world.getChunkManager().chunkLoadingManager.getTicketManager().handleChunkEnter(player.getWatchedSection(), player); - player.teleport(world, pos.getX(), pos.getY(), pos.getZ(), Set.of(), 0, 0); + ((ServerChunkManagerMixin)world.getChunkManager()).getLevelManager().handleChunkEnter(player.getWatchedSection(), player); + player.teleport(world, pos.getX(), pos.getY(), pos.getZ(), Set.of(), 0, 0, true); } @Inject(method = "remove", at = @At("HEAD")) diff --git a/src/main/java/io/ib67/sfcraft/mixin/server/subserver/ServerPlayerEntityMixin.java b/src/main/java/io/ib67/sfcraft/mixin/server/subserver/ServerPlayerEntityMixin.java index 9424f52..6d34649 100644 --- a/src/main/java/io/ib67/sfcraft/mixin/server/subserver/ServerPlayerEntityMixin.java +++ b/src/main/java/io/ib67/sfcraft/mixin/server/subserver/ServerPlayerEntityMixin.java @@ -15,8 +15,10 @@ import java.util.Set; @Mixin(ServerPlayerEntity.class) public abstract class ServerPlayerEntityMixin { - @Inject(at = @At("HEAD"), method = "teleport(Lnet/minecraft/server/world/ServerWorld;DDDLjava/util/Set;FF)Z", cancellable = true) - public void sf$interceptTeleport(ServerWorld world, double destX, double destY, double destZ, Set flags, float yaw, float pitch, CallbackInfoReturnable cir) { + //todo test this + //todo fix playground operate players in main world + @Inject(at=@At("HEAD"), method = "teleport(Lnet/minecraft/server/world/ServerWorld;DDDLjava/util/Set;FFZ)Z") + public void sf$interceptTeleport(ServerWorld world, double destX, double destY, double destZ, Set flags, float yaw, float pitch, boolean resetCamera, CallbackInfoReturnable cir) { var room = roomRegistry().getRoomBy($this().getUuid()); if (room != null) { if (world.getRegistryKey() != room.getSpawnPosition().dimension()) { @@ -25,16 +27,6 @@ public abstract class ServerPlayerEntityMixin { } } - @Inject(at = @At("HEAD"), method = "teleport(Lnet/minecraft/server/world/ServerWorld;DDDFF)V", cancellable = true) - public void sf$interceptTeleport(ServerWorld targetWorld, double x, double y, double z, float yaw, float pitch, CallbackInfo ci) { - var room = roomRegistry().getRoomBy($this().getUuid()); - if (room != null) { - if (targetWorld.getRegistryKey() != room.getSpawnPosition().dimension()) { - ci.cancel(); - } - } - } - private RoomRegistry roomRegistry() { return SFCraft.getInjector().getInstance(RoomRegistry.class); } diff --git a/src/main/java/io/ib67/sfcraft/mixin/server/subserver/WorldMixin.java b/src/main/java/io/ib67/sfcraft/mixin/server/subserver/WorldMixin.java deleted file mode 100644 index f4659c6..0000000 --- a/src/main/java/io/ib67/sfcraft/mixin/server/subserver/WorldMixin.java +++ /dev/null @@ -1,35 +0,0 @@ -package io.ib67.sfcraft.mixin.server.subserver; - -import io.ib67.sfcraft.SFCraft; -import io.ib67.sfcraft.module.RoomModule; -import net.minecraft.registry.RegistryKey; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.world.GameRules; -import net.minecraft.world.World; -import org.spongepowered.asm.mixin.*; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(World.class) -public abstract class WorldMixin { - @Shadow - public abstract boolean isClient(); - - @Shadow - @Final - private RegistryKey registryKey; - - @Unique - private GameRules sfcraft$customGameRule; - - @Inject(method = "getGameRules", at = @At("HEAD"), cancellable = true) - private void beforeGetGameRules(CallbackInfoReturnable cir) { - if (!isClient() && registryKey.getValue().getNamespace().equals(SFCraft.MOD_ID)) { - if (sfcraft$customGameRule == null) { - sfcraft$customGameRule = SFCraft.getInjector().getInstance(RoomModule.class).readGameRuleForRoom((ServerWorld) (Object) this); - } - cir.setReturnValue(sfcraft$customGameRule); - } - } -} diff --git a/src/main/java/io/ib67/sfcraft/module/CustomItemModule.java b/src/main/java/io/ib67/sfcraft/module/CustomItemModule.java deleted file mode 100644 index 242810b..0000000 --- a/src/main/java/io/ib67/sfcraft/module/CustomItemModule.java +++ /dev/null @@ -1,65 +0,0 @@ -package io.ib67.sfcraft.module; - -import com.mojang.brigadier.CommandDispatcher; -import com.mojang.brigadier.context.CommandContext; -import com.mojang.brigadier.exceptions.CommandSyntaxException; -import io.ib67.sfcraft.SFItems; -import io.ib67.sfcraft.ServerModule; -import io.ib67.sfcraft.item.SFItem; -import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; -import net.minecraft.command.CommandRegistryAccess; -import net.minecraft.command.argument.IdentifierArgumentType; -import net.minecraft.component.DataComponentTypes; -import net.minecraft.component.type.NbtComponent; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.server.command.CommandManager; -import net.minecraft.server.command.ServerCommandSource; -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; - -public class CustomItemModule extends ServerModule { - @Override - public void onInitialize() { - SFItems.init(); - CommandRegistrationCallback.EVENT - .register(this::registerCommand); - } - - private void registerCommand(CommandDispatcher dispatcher, CommandRegistryAccess registryAccess, CommandManager.RegistrationEnvironment environment) { - dispatcher.register( - CommandManager.literal("sfgive") - .then( - CommandManager.argument("item", IdentifierArgumentType.identifier()) - .executes(this::performGive) - ) - ); - } - - private static ItemStack getItemByName(Identifier id) throws CommandSyntaxException { - var item = SFItems.getById(id); - if(item == null) return null; - var stack = new ItemStack(((SFItem) item).getMappedItem()); - var cmp = new NbtCompound(); - cmp.putString(SFItems.SF_ITEM_TYPE_KEY, item.getRegistryEntry().getKey().map(it -> it.getValue().getPath()).orElseThrow()); - stack.set(DataComponentTypes.CUSTOM_DATA, NbtComponent.of(cmp)); - return stack.copy(); - } - - - private int performGive(CommandContext context) throws CommandSyntaxException { - var item = IdentifierArgumentType.getIdentifier(context, "item"); - if (!context.getSource().isExecutedByPlayer()) { - context.getSource().sendMessage(Text.of("Can't be executed by non-players")); - return 0; - } - var player = context.getSource().getPlayer(); - var itemStack = getItemByName(item); - if (itemStack != null) { - player.giveItemStack(itemStack); - }else{ - player.sendMessage(Text.of("Item with id "+item.toString()+" not exists.")); - } - return 1; - } -} diff --git a/src/main/java/io/ib67/sfcraft/module/ElytraSpeedMeterModule.java b/src/main/java/io/ib67/sfcraft/module/ElytraSpeedMeterModule.java index 928b3bd..e4268f8 100644 --- a/src/main/java/io/ib67/sfcraft/module/ElytraSpeedMeterModule.java +++ b/src/main/java/io/ib67/sfcraft/module/ElytraSpeedMeterModule.java @@ -2,16 +2,10 @@ package io.ib67.sfcraft.module; import io.ib67.sfcraft.ServerModule; import io.ib67.sfcraft.callback.SFCallbacks; -import io.ib67.sfcraft.util.ColorHelper; import it.unimi.dsi.fastutil.objects.*; import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents; +import net.minecraft.entity.EquipmentSlot; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.entity.player.PlayerInventory; -import net.minecraft.item.ElytraItem; -import net.minecraft.network.packet.Packet; -import net.minecraft.network.packet.s2c.play.SubtitleS2CPacket; -import net.minecraft.network.packet.s2c.play.TitleFadeS2CPacket; -import net.minecraft.network.packet.s2c.play.TitleS2CPacket; import net.minecraft.server.MinecraftServer; import net.minecraft.server.network.ServerPlayNetworkHandler; import net.minecraft.server.network.ServerPlayerEntity; @@ -19,10 +13,6 @@ import net.minecraft.text.MutableText; import net.minecraft.text.Text; import net.minecraft.util.Colors; import net.minecraft.util.math.BlockPos; -import org.spongepowered.asm.mixin.Unique; - -import java.awt.*; -import java.text.DecimalFormat; public class ElytraSpeedMeterModule extends ServerModule { private static final int BAR_LEN = 20; @@ -89,7 +79,7 @@ public class ElytraSpeedMeterModule extends ServerModule { } private Text generateDurabilityMeter(long f, PlayerEntity player) { - var stack = player.getInventory().getArmorStack(PlayerInventory.ARMOR_SLOTS[2]); + var stack = player.getEquippedStack(EquipmentSlot.CHEST); if (stack.isDamageable() && stack.isDamaged()) { var remaining = stack.getMaxDamage() - stack.getDamage(); var percent = (int) Math.ceil(((double) remaining / stack.getMaxDamage()) * 100); diff --git a/src/main/java/io/ib67/sfcraft/module/RoomModule.java b/src/main/java/io/ib67/sfcraft/module/RoomModule.java index 575c4b2..8b81ced 100644 --- a/src/main/java/io/ib67/sfcraft/module/RoomModule.java +++ b/src/main/java/io/ib67/sfcraft/module/RoomModule.java @@ -2,48 +2,32 @@ package io.ib67.sfcraft.module; import com.google.inject.Inject; import com.mojang.authlib.GameProfile; +import com.mojang.brigadier.Command; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.context.CommandContext; import io.ib67.sfcraft.ServerModule; import io.ib67.sfcraft.config.SFConfig; import io.ib67.sfcraft.inject.MinecraftServerSupplier; -import io.ib67.sfcraft.room.RequestedRoom; import io.ib67.sfcraft.registry.RoomRegistry; -import io.ib67.sfcraft.room.data.RoomWorldDataLoader; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; -import lombok.SneakyThrows; import lombok.extern.log4j.Log4j2; import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; import net.minecraft.command.CommandRegistryAccess; import net.minecraft.network.PacketCallbacks; -import net.minecraft.network.codec.PacketCodecs; import net.minecraft.network.packet.s2c.common.ServerTransferS2CPacket; import net.minecraft.network.packet.s2c.common.StoreCookieS2CPacket; import net.minecraft.registry.RegistryKey; import net.minecraft.server.command.CommandManager; import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.world.ChunkTicketType; -import net.minecraft.server.world.ServerWorld; import net.minecraft.text.Text; import net.minecraft.util.Identifier; import net.minecraft.util.Pair; -import net.minecraft.util.Unit; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.ChunkPos; -import net.minecraft.world.GameRules; import net.minecraft.world.World; -import org.apache.commons.lang3.RandomStringUtils; -import javax.crypto.Cipher; -import javax.crypto.SecretKey; -import javax.crypto.SecretKeyFactory; -import javax.crypto.spec.PBEKeySpec; -import javax.crypto.spec.SecretKeySpec; import java.nio.charset.StandardCharsets; -import java.security.Key; -import java.security.spec.KeySpec; import java.util.*; import java.util.concurrent.ConcurrentHashMap; @@ -76,7 +60,7 @@ public class RoomModule extends ServerModule { log.warn("Cannot find world {}", registryKeyBlockPosPair.getLeft()); continue; } - world.getChunkManager().addTicket(ChunkTicketType.START, new ChunkPos(registryKeyBlockPosPair.getRight()), 64, Unit.INSTANCE); + world.getChunkManager().addTicket(ChunkTicketType.START, new ChunkPos(registryKeyBlockPosPair.getRight()), 64); } } @@ -90,6 +74,9 @@ public class RoomModule extends ServerModule { private int onCleanReconnect(CommandContext serverCommandSourceCommandContext) { var player = serverCommandSourceCommandContext.getSource().getPlayer(); + if (player == null) { + return 0; + } if (!isVirtual(player.getUuid())) { player.sendMessage(Text.literal("你不在任何 \"房间\" 内。")); return 0; @@ -119,8 +106,4 @@ public class RoomModule extends ServerModule { public GameProfile devirtualize(UUID virtual) { return uuidMapper.get(virtual); } - - public GameRules readGameRuleForRoom(ServerWorld world){ - return RoomWorldDataLoader.get(world).getGameRules(); - } } diff --git a/src/main/java/io/ib67/sfcraft/module/WelcomeModule.java b/src/main/java/io/ib67/sfcraft/module/WelcomeModule.java index 471c0f9..8fe8f94 100644 --- a/src/main/java/io/ib67/sfcraft/module/WelcomeModule.java +++ b/src/main/java/io/ib67/sfcraft/module/WelcomeModule.java @@ -23,6 +23,7 @@ import net.minecraft.text.RawFilteredPair; import net.minecraft.text.Text; import java.net.InetSocketAddress; +import java.net.URI; import java.nio.file.Path; import java.time.Clock; import java.time.ZonedDateTime; @@ -51,7 +52,7 @@ public class WelcomeModule extends ServerModule { player.sendMessage(Text.of("§a您受本服务器成员邀请加入本服务器,以下是一些注意事项:")); player.sendMessage(Text.of(" - 服务器内已有的设施均为其他玩家的财产,(如可以)使用时请注意礼貌")); player.sendMessage(Text.literal(" - 服务器内有一些非原版特性,可以点击此条消息查看 [特性列表]") - .styled(s -> s.withClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://wiki.sfclub.cc/s/sfcraft-features")))); + .styled(s -> s.withClickEvent(new ClickEvent.OpenUrl(URI.create("https://wiki.sfclub.cc/s/sfcraft-features"))))); player.sendMessage(Text.of("§c - 邀请新成员即等同为其作担保")); player.sendMessage(Text.of("§7如果您想邀请朋友加入服务器, 可以向管理员提出申请§7 (需备注正/盗版/小号)")); player.sendMessage(Text.of("§7此外, 本服务器无密码登录,盗版账号安全责任自负")); diff --git a/src/main/java/io/ib67/sfcraft/module/chat/decorator/ChatPingModule.java b/src/main/java/io/ib67/sfcraft/module/chat/decorator/ChatPingModule.java index 3ac80a7..6a77285 100644 --- a/src/main/java/io/ib67/sfcraft/module/chat/decorator/ChatPingModule.java +++ b/src/main/java/io/ib67/sfcraft/module/chat/decorator/ChatPingModule.java @@ -21,7 +21,7 @@ import java.util.regex.MatchResult; import java.util.regex.Pattern; public class ChatPingModule extends ServerModule implements MessageDecorator { - private static final Pattern PING = Pattern.compile("(@[\\w]+)?"); + private static final Pattern PING = Pattern.compile("(@[\\w]+)?"); //todo remove the need of prefix @Inject MinecraftServerSupplier serverSupplier; @Inject @@ -51,7 +51,7 @@ public class ChatPingModule extends ServerModule implements MessageDecorator { var r = Text.literal(match.replaceAll(it -> this.matchPlayer(it, names, foundPlayers))); for (PlayerEntity foundPlayer : foundPlayers) { if (sender != null) { - foundPlayer.sendMessage(Text.literal(sender.getName().getLiteralString() + " 正在叫你。").withColor(Colors.LIGHT_GRAY)); + foundPlayer.sendMessage(Text.literal(sender.getName().getLiteralString() + " 正在叫你。").withColor(Colors.LIGHT_GRAY), true); } foundPlayer.playSoundToPlayer( SoundEvents.ENTITY_ITEM_PICKUP, diff --git a/src/main/java/io/ib67/sfcraft/module/chat/decorator/ChatSendLocModule.java b/src/main/java/io/ib67/sfcraft/module/chat/decorator/ChatSendLocModule.java index 902ed49..763c8dd 100644 --- a/src/main/java/io/ib67/sfcraft/module/chat/decorator/ChatSendLocModule.java +++ b/src/main/java/io/ib67/sfcraft/module/chat/decorator/ChatSendLocModule.java @@ -37,7 +37,7 @@ public class ChatSendLocModule extends ServerModule implements MessageDecorator private static Text generateLocText(ServerPlayerEntity sender) { if (sender == null) return Text.of(" (invalid position) "); - sender.addStatusEffect(new StatusEffectInstance(StatusEffects.GLOWING, 15*20)); + sender.addStatusEffect(new StatusEffectInstance(StatusEffects.GLOWING, 15 * 20)); var x = sender.getBlockPos().getX(); var y = sender.getBlockPos().getY(); var z = sender.getBlockPos().getZ(); @@ -46,7 +46,7 @@ public class ChatSendLocModule extends ServerModule implements MessageDecorator return Text .literal(" " + x + ", " + y + ", " + z + world + " ") .withColor(Helper.fromRgb(63, 254, 254)) - .styled(style -> style.withClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/gps " + key + " " + x + " " + y + " " + z))); + .styled(style -> style.withClickEvent(new ClickEvent.RunCommand("/gps " + key + " " + x + " " + y + " " + z))); } private static String translate(RegistryKey registryKey) { diff --git a/src/main/java/io/ib67/sfcraft/module/command/BackModule.java b/src/main/java/io/ib67/sfcraft/module/command/BackModule.java index 4710f67..4817446 100644 --- a/src/main/java/io/ib67/sfcraft/module/command/BackModule.java +++ b/src/main/java/io/ib67/sfcraft/module/command/BackModule.java @@ -55,7 +55,7 @@ public class BackModule extends ServerModule { public void onPlayerDeath(PlayerEntity player, DamageSource damageSource) { if (this.isEnabled() && Helper.canBack((ServerPlayerEntity) player)) { - player.sendMessage(Text.of("Tip: 死亡地点附近有玩家,可以使用 /back 传送到他们那里。(即使在对方也死亡的状态下)")); + player.sendMessage(Text.of("Tip: 死亡地点附近有玩家,可以使用 /back 传送到他们那里。(即使在对方也死亡的状态下)"), false); } } } diff --git a/src/main/java/io/ib67/sfcraft/module/randomevt/LongNightModule.java b/src/main/java/io/ib67/sfcraft/module/randomevt/LongNightModule.java deleted file mode 100644 index 20a09ef..0000000 --- a/src/main/java/io/ib67/sfcraft/module/randomevt/LongNightModule.java +++ /dev/null @@ -1,54 +0,0 @@ -package io.ib67.sfcraft.module.randomevt; - -import com.google.inject.Inject; -import com.mojang.datafixers.util.Either; -import io.ib67.sfcraft.ServerModule; -import io.ib67.sfcraft.callback.SFCallbacks; -import io.ib67.sfcraft.module.randomevt.longnight.DawnAfterLongNightEvent; -import io.ib67.sfcraft.module.randomevt.longnight.LongNightEvent; -import io.ib67.sfcraft.registry.RandomEventRegistry; -import net.fabricmc.fabric.api.event.player.UseItemCallback; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.item.Items; -import net.minecraft.text.Text; -import net.minecraft.util.*; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; - -public class LongNightModule extends ServerModule { - @Inject - RandomEventRegistry registry; - - @Override - public void onInitialize() { - registry.registerEvent(LongNightEvent::new, World.OVERWORLD - , world -> !LongNightEvent.isRunning() - && isEnabled() - && world.getTimeOfDay() % 24000 == 18000 - && world.getRandom().nextBetween(0, 100) < 5); // At midnight - registry.registerEvent(DawnAfterLongNightEvent::new, World.OVERWORLD - , world -> world.getTimeOfDay() % 22200 == 0); // At dawn - SFCallbacks.PLAYER_SLEEP.register(this::onPlayerSleep); - UseItemCallback.EVENT.register(this::onUseClock); - } - - private TypedActionResult onUseClock(PlayerEntity player, World world, Hand hand) { - if (player.isSpectator()) return TypedActionResult.pass(ItemStack.EMPTY); - if (player.getStackInHand(hand).isOf(Items.CLOCK)) { - if (LongNightEvent.isRunning()) - player.sendMessage(Text.literal("永夜还将持续约 " + LongNightEvent.getRemainingTicks() / 20 + " 秒。").withColor(Colors.LIGHT_GRAY)); - } - return TypedActionResult.pass(ItemStack.EMPTY); - } - - public Either onPlayerSleep(PlayerEntity player, BlockPos pos) { - if (!isEnabled()) return Either.right(Unit.INSTANCE); - if (LongNightEvent.isRunning()) { - player.sendMessage(Text.literal("你感到焦躁不安!").withColor(Colors.LIGHT_RED) - .append(Text.literal(" (永夜事件期间无法睡觉)").withColor(Colors.LIGHT_GRAY))); - return Either.left(PlayerEntity.SleepFailureReason.NOT_POSSIBLE_HERE); - } - return Either.right(Unit.INSTANCE); - } -} diff --git a/src/main/java/io/ib67/sfcraft/module/randomevt/longnight/LongNightEvent.java b/src/main/java/io/ib67/sfcraft/module/randomevt/longnight/LongNightEvent.java index 145ed82..769a82d 100644 --- a/src/main/java/io/ib67/sfcraft/module/randomevt/longnight/LongNightEvent.java +++ b/src/main/java/io/ib67/sfcraft/module/randomevt/longnight/LongNightEvent.java @@ -3,6 +3,7 @@ package io.ib67.sfcraft.module.randomevt.longnight; import io.ib67.sfcraft.module.randomevt.RandomEvent; import lombok.Getter; import lombok.RequiredArgsConstructor; +import net.minecraft.server.world.ServerWorld; import net.minecraft.text.Text; import net.minecraft.util.Colors; import net.minecraft.world.GameRules; @@ -14,7 +15,7 @@ public class LongNightEvent extends RandomEvent { static boolean isAtLongNight; @Getter private static int remainingTicks; - private final World world; + private final ServerWorld world; private boolean doDaylightCycle; private boolean doTraderSpawning; diff --git a/src/main/java/io/ib67/sfcraft/module/room/CreativeRoomModule.java b/src/main/java/io/ib67/sfcraft/module/room/CreativeRoomModule.java index 3e58441..6ce40f0 100644 --- a/src/main/java/io/ib67/sfcraft/module/room/CreativeRoomModule.java +++ b/src/main/java/io/ib67/sfcraft/module/room/CreativeRoomModule.java @@ -45,7 +45,6 @@ import java.util.Set; public class CreativeRoomModule extends ServerModule { private static final Set BYPASS_PERMISSIONS = Set.of( - "minecraft.command.gamerule", "carpet.command.player", "carpet.command.track", "minecraft.command.setblock", diff --git a/src/main/java/io/ib67/sfcraft/module/supervisor/web/SchematicUploader.java b/src/main/java/io/ib67/sfcraft/module/supervisor/web/SchematicUploader.java index 6b32c46..a4d72a0 100644 --- a/src/main/java/io/ib67/sfcraft/module/supervisor/web/SchematicUploader.java +++ b/src/main/java/io/ib67/sfcraft/module/supervisor/web/SchematicUploader.java @@ -30,6 +30,7 @@ import net.minecraft.text.Text; import org.jetbrains.annotations.NotNull; import java.awt.*; +import java.net.URI; import java.nio.file.Files; import java.nio.file.Path; import java.util.Base64; @@ -69,7 +70,7 @@ public class SchematicUploader extends WebHandler { } var url = generateSchematicUrl(source.isExecutedByPlayer() ? source.getPlayer().getName().getLiteralString() : "CONSOLE"); source.sendMessage(Text.literal("Click this URL to upload schematic files.").withColor(Color.GREEN.getRGB())); - source.sendMessage(Text.literal(url).styled(it -> it.withClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, url)))); + source.sendMessage(Text.literal(url).styled(it -> it.withClickEvent(new ClickEvent.OpenUrl(URI.create(url))))); return Command.SINGLE_SUCCESS; } @@ -173,8 +174,8 @@ public class SchematicUploader extends WebHandler { return; } player.sendMessage(Text.literal("Schematic " + fileName + " has been saved! Use //schem list to find it").withColor(Color.GREEN.getRGB())); - player.sendMessage(Text.literal("Or you can click this").styled(it->it.withUnderline(true).withClickEvent( - new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "//schem load " + fileName) + player.sendMessage(Text.literal("Or you can click this").styled(it -> it.withUnderline(true).withClickEvent( + new ClickEvent.SuggestCommand("//schem load " + fileName) ))); } } diff --git a/src/main/java/io/ib67/sfcraft/room/data/RoomWorldDataLoader.java b/src/main/java/io/ib67/sfcraft/room/data/RoomWorldDataLoader.java deleted file mode 100644 index a9c5850..0000000 --- a/src/main/java/io/ib67/sfcraft/room/data/RoomWorldDataLoader.java +++ /dev/null @@ -1,55 +0,0 @@ -package io.ib67.sfcraft.room.data; - -import com.mojang.serialization.Dynamic; -import lombok.Getter; -import net.minecraft.datafixer.DataFixTypes; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.nbt.NbtOps; -import net.minecraft.registry.RegistryWrapper; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.world.GameRules; -import net.minecraft.world.PersistentState; - -import java.util.Objects; - -@Getter -public class RoomWorldDataLoader extends PersistentState { - - private static final String NAME = "sfcraft_room_data"; - private static final Type TYPE = new Type<>(RoomWorldDataLoader::new, RoomWorldDataLoader::readNbt, DataFixTypes.LEVEL); - - private static final String TAG_GAME_RULES = "gameRules"; - - private final GameRules gameRules; - - public RoomWorldDataLoader() { - this(new GameRules()); - } - - public RoomWorldDataLoader(GameRules gameRules) { - this.gameRules = gameRules; - } - - public static RoomWorldDataLoader get(ServerWorld world) { - Objects.requireNonNull(world); - var state = world.getPersistentStateManager().getOrCreate(TYPE, NAME); - state.markDirty(); - return state; - } - - @Override - public NbtCompound writeNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup registry) { - nbt.put(TAG_GAME_RULES, gameRules.toNbt()); - return nbt; - } - - private static RoomWorldDataLoader readNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup registry) { - if (nbt.contains(TAG_GAME_RULES)) { - var c = nbt.getCompound(TAG_GAME_RULES); - var dynamic = new Dynamic<>(NbtOps.INSTANCE, c); - var rule = new GameRules(dynamic); - return new RoomWorldDataLoader(rule); - } - return new RoomWorldDataLoader(); - } -} diff --git a/src/main/java/io/ib67/sfcraft/util/Helper.java b/src/main/java/io/ib67/sfcraft/util/Helper.java index fbf4793..428bb2b 100644 --- a/src/main/java/io/ib67/sfcraft/util/Helper.java +++ b/src/main/java/io/ib67/sfcraft/util/Helper.java @@ -31,6 +31,7 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.util.Optional; +import java.util.Set; import java.util.UUID; import java.util.regex.Pattern; @@ -87,7 +88,7 @@ public class Helper { deltaZ = stand.getCollisionShape(world, pos).getMax(Direction.Axis.X); deltaZ = Double.isFinite(deltaZ) ? deltaZ / 2 : 0.5; } - player.teleport(world, x + deltaX, y + deltaY, z + deltaZ, yaw, pitch); + player.teleport(world, x + deltaX, y + deltaY, z + deltaZ, Set.of(), yaw, pitch, true); } return true; } diff --git a/src/main/java/io/ib67/sfcraft/util/TypedNbtList.java b/src/main/java/io/ib67/sfcraft/util/TypedNbtList.java index 2722224..183ccc6 100644 --- a/src/main/java/io/ib67/sfcraft/util/TypedNbtList.java +++ b/src/main/java/io/ib67/sfcraft/util/TypedNbtList.java @@ -8,13 +8,15 @@ import java.io.IOException; import java.util.List; public class TypedNbtList extends NbtList { + private final byte heldType; public TypedNbtList(List list, byte type) { - super(list, type); + super(list); + this.heldType = type; } @Override public void write(DataOutput output) throws IOException { - output.writeByte(this.getHeldType()); + output.writeByte(heldType); output.writeInt(this.size()); for (NbtElement nbtElement : this) { diff --git a/src/main/java/io/ib67/sfcraft/util/litematic/LitematicConverter.java b/src/main/java/io/ib67/sfcraft/util/litematic/LitematicConverter.java index 53c674f..2f3c3a6 100644 --- a/src/main/java/io/ib67/sfcraft/util/litematic/LitematicConverter.java +++ b/src/main/java/io/ib67/sfcraft/util/litematic/LitematicConverter.java @@ -10,6 +10,7 @@ import org.apache.commons.compress.utils.Lists; import java.io.InputStream; import java.util.ArrayList; +import java.util.List; import java.util.function.BiConsumer; import java.util.stream.Collectors; @@ -31,11 +32,14 @@ public class LitematicConverter implements AutoCloseable { BiConsumer schematicOutput ) { var root = NbtIo.readCompressed(input, sizeTracker); - var dataVersion = root.getInt("MinecraftDataVersion"); - var regionsNbt = root.getCompound("Regions"); + var dataVersion = root.getInt("MinecraftDataVersion") + .orElseThrow(() -> new IllegalStateException("MinecraftDataVersion not found")); + var regionsNbt = root.getCompound("Regions") + .orElseThrow(() -> new IllegalStateException("Regions not found")); var i = 0; for (String regionName : regionsNbt.getKeys()) { - var compound = regionsNbt.getCompound(regionName); + var compound = regionsNbt.getCompound(regionName) + .orElseThrow(() -> new IllegalStateException("Region " + regionName + " not found")); var j = i++; var schematic = convertRegionToSchematic(dataVersion, compound); schematicOutput.accept(regionName, schematic); @@ -56,11 +60,11 @@ public class LitematicConverter implements AutoCloseable { worldEditTag.putShort("Width", (short) Math.abs(size.x)); // block & tile entities - var paletteNbt = region.getList("BlockStatePalette", NbtElement.COMPOUND_TYPE); + var paletteNbt = region.getListOrEmpty("BlockStatePalette"); var wePalette = convertToWEPalette(paletteNbt); worldEditTag.putInt("PaletteMax", wePalette.getKeys().size()); worldEditTag.put("Palette", wePalette); - var tileEntities = region.getList("TileEntities", NbtElement.COMPOUND_TYPE); + var tileEntities = region.getListOrEmpty("TileEntities"); worldEditTag.put("BlockEntities", convertToWETileEntities(tileEntities)); worldEditTag.putInt("Version", 2); worldEditTag.putIntArray("Offset", new int[3]); @@ -72,9 +76,15 @@ public class LitematicConverter implements AutoCloseable { protected SizeTuple readSizeTuple(NbtCompound region) { var size = (NbtCompound) region.get("Size"); - var sizeX = size.getInt("x"); - var sizeY = size.getInt("y"); - var sizeZ = size.getInt("z"); + if (size == null) { + throw new IllegalStateException("Size not found"); + } + var sizeX = size.getInt("x") + .orElseThrow(() -> new IllegalStateException("Size X not found")); + var sizeY = size.getInt("y") + .orElseThrow(() -> new IllegalStateException("Size Y not found")); + var sizeZ = size.getInt("z") + .orElseThrow(() -> new IllegalStateException("Size Z not found")); return new SizeTuple(sizeX, sizeY, sizeZ); } @@ -85,11 +95,14 @@ public class LitematicConverter implements AutoCloseable { var weTE = new NbtCompound(); var tE = (NbtCompound) _tileEntity; weTE.putIntArray("Pos", new int[]{ - tE.getInt("x"), - tE.getInt("y"), + tE.getInt("x") + .orElseThrow(() -> new IllegalStateException("Pos X not found")), + tE.getInt("y") + .orElseThrow(() -> new IllegalStateException("Pos Y not found")), tE.getInt("z") + .orElseThrow(() -> new IllegalStateException("Pos Z not found")) }); - weTE.putString("Id", tE.getString("id")); + weTE.putString("Id", tE.getString("id").orElseThrow(() -> new IllegalStateException("Id not found"))); // other properties tE.remove("x"); tE.remove("y"); @@ -105,15 +118,15 @@ public class LitematicConverter implements AutoCloseable { var wePalette = new NbtCompound(); for (int i = 0; i < paletteNbt.size(); i++) { var entry = (NbtCompound) paletteNbt.get(i); - var name = new StringBuilder(entry.getString("Name")); - var properties = entry.getCompound("Properties"); + var name = new StringBuilder(entry.getString("Name").orElseThrow(() -> new IllegalStateException("Name not found"))); + var properties = entry.getCompound("Properties").orElseThrow(() -> new IllegalStateException("Properties not found")); if (!properties.isEmpty()) { name.append("["); var props = new ArrayList(); for (String key : properties.getKeys()) { props.add(key + "=" + properties.getString(key)); } - name.append(props.stream().collect(Collectors.joining(","))); + name.append(String.join(",", props)); name.append("]"); } wePalette.putInt(name.toString(), i); @@ -123,17 +136,20 @@ public class LitematicConverter implements AutoCloseable { protected NbtElement convertToWeMeta(SizeTuple size, NbtCompound region) { var pos = (NbtCompound) region.get("Position"); + if (pos == null){ + throw new IllegalStateException("Pos not found"); + } var nbt = new NbtCompound(); - nbt.putInt("WEOffsetX", pos.getInt("x") + (size.x < 0 ? size.x + 1 : 0)); - nbt.putInt("WEOffsetY", pos.getInt("y") + (size.y < 0 ? size.y + 1 : 0)); - nbt.putInt("WEOffsetZ", pos.getInt("z") + (size.z < 0 ? size.z + 1 : 0)); + nbt.putInt("WEOffsetX", pos.getInt("x").orElseThrow() + (size.x < 0 ? size.x + 1 : 0)); + nbt.putInt("WEOffsetY", pos.getInt("y").orElseThrow() + (size.y < 0 ? size.y + 1 : 0)); + nbt.putInt("WEOffsetZ", pos.getInt("z").orElseThrow() + (size.z < 0 ? size.z + 1 : 0)); return nbt; } protected byte[] convertToWEBlocks(SizeTuple size, NbtCompound region) { var blockCount = Math.abs(size.x * size.y * size.z); - var blockStates = region.getLongArray("BlockStates"); - int bitsPerBlock = region.getList("BlockStatePalette", NbtElement.COMPOUND_TYPE).size(); + var blockStates = region.getLongArray("BlockStates").orElse(new long[0]); + int bitsPerBlock = region.getListOrEmpty("BlockStatePalette").size(); bitsPerBlock = Math.max(2, Integer.SIZE - Integer.numberOfLeadingZeros(bitsPerBlock - 1)); int maxEntryValue = (1 << bitsPerBlock) - 1; var buffer = new PacketByteBuf(Unpooled.buffer()); diff --git a/src/main/java/io/ib67/sfcraft/util/litematic/LitematicConverterV3.java b/src/main/java/io/ib67/sfcraft/util/litematic/LitematicConverterV3.java index 3b9d7df..be4f9b0 100644 --- a/src/main/java/io/ib67/sfcraft/util/litematic/LitematicConverterV3.java +++ b/src/main/java/io/ib67/sfcraft/util/litematic/LitematicConverterV3.java @@ -35,9 +35,9 @@ public class LitematicConverterV3 extends LitematicConverter { schematicsTag.putShort("Width", (short) Math.abs(size.x())); // block & tile entities - var paletteNbt = region.getList("BlockStatePalette", NbtElement.COMPOUND_TYPE); + var paletteNbt = region.getListOrEmpty("BlockStatePalette"); var wePalette = convertToWEPalette(paletteNbt); - var tileEntities = region.getList("TileEntities", NbtElement.COMPOUND_TYPE); + var tileEntities = region.getListOrEmpty("TileEntities"); var blocksNbt = new NbtCompound(); blocksNbt.put("Palette", wePalette); @@ -63,7 +63,11 @@ public class LitematicConverterV3 extends LitematicConverter { var paletteIds = new Int2ObjectOpenHashMap<>(); var touchedIds = new IntOpenHashSet(); for (String key : wePalette.getKeys()) { - paletteIds.put(wePalette.getInt(key), key); + paletteIds.put( + wePalette.getInt(key) + .orElseThrow(() -> new IllegalStateException("Cannot find key " + key + " in palette from worldedit schematic")) + , key + ); } int counter = 0; try { @@ -79,8 +83,8 @@ public class LitematicConverterV3 extends LitematicConverter { } catch (Exception e) { log.error("Error validing schematic", e); } - paletteIds.keySet().intStream().filter(it->!touchedIds.contains(it)) - .forEach(it-> log.error("Unused palette id: {}, blockState: {}", it, paletteIds.get(it))); + paletteIds.keySet().intStream().filter(it -> !touchedIds.contains(it)) + .forEach(it -> log.error("Unused palette id: {}, blockState: {}", it, paletteIds.get(it))); } private static Vec3i decodePositionFromDataIndex(int width, int length, int index) { @@ -95,11 +99,14 @@ public class LitematicConverterV3 extends LitematicConverter { @Override protected NbtElement convertToWeMeta(SizeTuple size, NbtCompound region) { var pos = (NbtCompound) region.get("Position"); + if (pos == null) { + throw new IllegalStateException("Cannot find Position"); + } var worldEditNbt = new NbtCompound(); worldEditNbt.putIntArray("Origin", new int[]{ - pos.getInt("x") + (size.x() < 0 ? size.x() + 1 : 0), - pos.getInt("y") + (size.y() < 0 ? size.y() + 1 : 0), - pos.getInt("z") + (size.z() < 0 ? size.z() + 1 : 0) + pos.getInt("x").orElseThrow() + (size.x() < 0 ? size.x() + 1 : 0), + pos.getInt("y").orElseThrow() + (size.y() < 0 ? size.y() + 1 : 0), + pos.getInt("z").orElseThrow() + (size.z() < 0 ? size.z() + 1 : 0) }); var Metadata = new NbtCompound(); Metadata.put("WorldEdit", worldEditNbt); diff --git a/src/main/resources/sfcraft.accesswidener b/src/main/resources/sfcraft.accesswidener index dc5ba10..f2a4448 100644 --- a/src/main/resources/sfcraft.accesswidener +++ b/src/main/resources/sfcraft.accesswidener @@ -1,3 +1,4 @@ accessWidener v2 named mutable field net/minecraft/item/Item registryEntry Lnet/minecraft/registry/entry/RegistryEntry$Reference; -accessible method net/minecraft/nbt/NbtList (Ljava/util/List;B)V \ No newline at end of file +accessible method net/minecraft/nbt/NbtList (Ljava/util/List;)V +extendable class net/minecraft/nbt/NbtList \ No newline at end of file diff --git a/src/main/resources/sfcraft.mixins.json b/src/main/resources/sfcraft.mixins.json index 8817320..8ef23b3 100644 --- a/src/main/resources/sfcraft.mixins.json +++ b/src/main/resources/sfcraft.mixins.json @@ -7,7 +7,8 @@ "common.bridge.EntityBridge", "common.bridge.ItemBridge", "common.bridge.ServerPlayerBridge", - "common.bridge.ServerWorldBridge" + "common.bridge.ServerWorldBridge", + "server.ServerChunkManagerMixin" ], "client": [ ], @@ -26,12 +27,6 @@ "server.SleepManagerMixin", "server.fixes.EndermanEntityMixin", "server.fixes.ProjectileEntityMixin", - "server.hack.EntitySpawnS2CPacketMixin", - "server.hack.HoverEntityContentMixin", - "server.hack.RegistryHandlerMixin", - "server.item.ItemMixin", - "server.item.ItemStackMixin", - "server.item.PlayerEntityMixin", "server.optimize.LivingEntityMixin", "server.subserver.EntityMixin", "server.subserver.PlayerListS2CPacket$EntryMixin", @@ -39,7 +34,6 @@ "server.subserver.PlayerSaveHandlerMixin", "server.subserver.ServerLoginNetworkHandlerMixin", "server.subserver.ServerPlayerEntityMixin", - "server.subserver.WorldMixin", "server.subserver.command.GameRuleCommandMixin" ], "injectors": {