diff --git a/build.gradle b/build.gradle index 29cfd34..68699eb 100644 --- a/build.gradle +++ b/build.gradle @@ -44,7 +44,7 @@ repositories { } dependencies { - paperweightDevelopmentBundle("io.papermc.paper:dev-bundle:1.20.6-R0.1-SNAPSHOT") + paperweightDevelopmentBundle("io.papermc.paper:dev-bundle:1.21-R0.1-SNAPSHOT") implementation "net.sf.jopt-simple:jopt-simple:5.0.4" implementation 'org.ow2.asm:asm:9.7' implementation 'org.ow2.asm:asm-commons:9.7' diff --git a/src/main/java/net/unknown/launchwrapper/Main.java b/src/main/java/net/unknown/launchwrapper/Main.java index 770d26a..9f171fc 100644 --- a/src/main/java/net/unknown/launchwrapper/Main.java +++ b/src/main/java/net/unknown/launchwrapper/Main.java @@ -49,13 +49,13 @@ public class Main { public static boolean FORCE_ALLOW_BUNDLE_FEATURES = System.getProperty("UnknownNetworkMagic") != null && System.getProperty("UnknownNetworkMagic").contains("bundle"); public static boolean FORCE_ALLOW_TRADE_REBALANCE_FEATURES = System.getProperty("UnknownNetworkMagic") != null && System.getProperty("UnknownNetworkMagic").contains("trade-rebalance"); - public static boolean FORCE_ALLOW_UPDATE_1_21 = System.getProperty("UnknownNetworkMagic") != null && System.getProperty("UnknownNetworkMagic").contains("update_1_21"); private static final String FILE_SEPARATOR = System.getProperty("file.separator"); + public static Path PAPERCLIP_JAR = System.getProperties().contains("unknown.bootstrap.paperclip_jar_path") ? Path.of(System.getProperty("unknown.bootstrap.paperclip_jar_path")) : Path.of("paper.jar"); public static Path SERVER_JAR = System.getProperties().contains("unknown.bootstrap.server_jar_path") ? Path.of(System.getProperty("unknown.bootstrap.server_jar_path")) : null; public static void main(String[] args) throws IOException, InterruptedException { - if (FORCE_ALLOW_BUNDLE_FEATURES || FORCE_ALLOW_TRADE_REBALANCE_FEATURES || FORCE_ALLOW_UPDATE_1_21) { - String activatedFeatureFlags = String.join(",", (FORCE_ALLOW_BUNDLE_FEATURES ? "bundle" : ""), (FORCE_ALLOW_TRADE_REBALANCE_FEATURES ? "trade_rebalance" : ""), (FORCE_ALLOW_UPDATE_1_21 ? "update_1_21" : "")); + if (FORCE_ALLOW_BUNDLE_FEATURES || FORCE_ALLOW_TRADE_REBALANCE_FEATURES) { + String activatedFeatureFlags = String.join(",", (FORCE_ALLOW_BUNDLE_FEATURES ? "bundle" : ""), (FORCE_ALLOW_TRADE_REBALANCE_FEATURES ? "trade_rebalance" : "")); System.out.println("\n" + "\n" + " Unknown Network Bootstrap\n" + @@ -66,7 +66,7 @@ public static void main(String[] args) throws IOException, InterruptedException Thread.sleep(TimeUnit.SECONDS.toMillis(3)); } - File paperJar = new File("./paper.jar"); + File paperJar = PAPERCLIP_JAR.toFile(); URL[] classpathUrls; if (paperJar.exists()) { diff --git a/src/main/java/net/unknown/launchwrapper/hopper/Filter.java b/src/main/java/net/unknown/launchwrapper/hopper/Filter.java index 9ccb2c3..4fbf4cd 100644 --- a/src/main/java/net/unknown/launchwrapper/hopper/Filter.java +++ b/src/main/java/net/unknown/launchwrapper/hopper/Filter.java @@ -57,7 +57,7 @@ static Filter fromTag(CompoundTag filterData, HolderLookup.Provider registryLook } if (filterData.contains("tag")) { - TagKey itemTag = TagKey.create(Registries.ITEM, new ResourceLocation(filterData.getString("tag"))); + TagKey itemTag = TagKey.create(Registries.ITEM, ResourceLocation.parse(filterData.getString("tag"))); DataComponentPatch componentPatch = filterData.contains("nbt") ? DataComponentPatch.CODEC.parse(registryLookup.createSerializationContext(NbtOps.INSTANCE), filterData.get("components")).getOrThrow() : null; return new TagFilter(itemTag, componentPatch); } diff --git a/src/main/java/net/unknown/launchwrapper/mixins/MixinChestBlockEntity.java b/src/main/java/net/unknown/launchwrapper/mixins/MixinChestBlockEntity.java index 041c704..5338f74 100644 --- a/src/main/java/net/unknown/launchwrapper/mixins/MixinChestBlockEntity.java +++ b/src/main/java/net/unknown/launchwrapper/mixins/MixinChestBlockEntity.java @@ -91,7 +91,7 @@ public void onLoad(CompoundTag nbt, HolderLookup.Provider registryLookup, Callba if (this.linkChestMode == LinkChestMode.CLIENT && link.contains("SourcePos", CompoundTag.TAG_COMPOUND)) { CompoundTag sourcePos = link.getCompound("SourcePos"); if (sourcePos.contains("Level") && sourcePos.contains("Pos", CompoundTag.TAG_INT_ARRAY)) { - ResourceKey levelKey = ResourceKey.create(Registries.DIMENSION, new ResourceLocation(sourcePos.getString("Level"))); + ResourceKey levelKey = ResourceKey.create(Registries.DIMENSION, ResourceLocation.parse(sourcePos.getString("Level"))); int[] pos = sourcePos.getIntArray("Pos"); if (pos.length == 3) { this.linkChestSource = new WrappedBlockPos(levelKey, new BlockPos(pos[0], pos[1], pos[2])); diff --git a/src/main/java/net/unknown/launchwrapper/mixins/MixinDamageEnchantment.java b/src/main/java/net/unknown/launchwrapper/mixins/MixinDamageEnchantment.java index 65c6934..9a688db 100644 --- a/src/main/java/net/unknown/launchwrapper/mixins/MixinDamageEnchantment.java +++ b/src/main/java/net/unknown/launchwrapper/mixins/MixinDamageEnchantment.java @@ -31,32 +31,59 @@ package net.unknown.launchwrapper.mixins; +import net.minecraft.advancements.critereon.DamageSourcePredicate; +import net.minecraft.advancements.critereon.TagPredicate; +import net.minecraft.core.HolderGetter; +import net.minecraft.core.registries.Registries; +import net.minecraft.data.worldgen.BootstrapContext; +import net.minecraft.resources.ResourceKey; +import net.minecraft.tags.DamageTypeTags; +import net.minecraft.tags.EnchantmentTags; +import net.minecraft.tags.ItemTags; import net.minecraft.world.entity.EquipmentSlot; -import net.minecraft.world.item.enchantment.DamageEnchantment; +import net.minecraft.world.entity.EquipmentSlotGroup; +import net.minecraft.world.item.Item; import net.minecraft.world.item.enchantment.Enchantment; +import net.minecraft.world.item.enchantment.EnchantmentEffectComponents; +import net.minecraft.world.item.enchantment.Enchantments; +import net.minecraft.world.item.enchantment.LevelBasedValue; +import net.minecraft.world.item.enchantment.effects.AddValue; +import net.minecraft.world.level.storage.loot.predicates.DamageSourceCondition; 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.ModifyArg; -@Mixin(DamageEnchantment.class) -public abstract class MixinDamageEnchantment extends Enchantment { - public MixinDamageEnchantment(EnchantmentDefinition properties) { - super(properties); - } +@Mixin(Enchantments.class) +public abstract class MixinDamageEnchantment { + @Shadow @Final public static ResourceKey SHARPNESS; - @ModifyArg(method = "", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/item/enchantment/Enchantment;(Lnet/minecraft/world/item/enchantment/Enchantment$EnchantmentDefinition;)V")) - private static EnchantmentDefinition onInit(EnchantmentDefinition properties) { - return new EnchantmentDefinition( - properties.supportedItems(), - properties.primaryItems(), - properties.weight(), - 10, // TODO 暫定対応 (ダメージ増加だけじゃなくアンデット特攻とかにも適用される) - properties.minCost(), - properties.maxCost(), - properties.anvilCost(), - properties.requiredFeatures(), - properties.slots()); + @ModifyArg(method = "bootstrap", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/item/enchantment/Enchantments;register(Lnet/minecraft/data/worldgen/BootstrapContext;Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/world/item/enchantment/Enchantment$Builder;)V", shift = At.Shift.BEFORE)) + private static Enchantment.Builder onBootstrap(BootstrapContext ctx, ResourceKey key, Enchantment.Builder builder) { + if (key == SHARPNESS) { + HolderGetter enchantLookup = ctx.lookup(Registries.ENCHANTMENT); + HolderGetter itemLookup = ctx.lookup(Registries.ITEM); + return Enchantment.enchantment( + Enchantment.definition( + itemLookup.getOrThrow(ItemTags.ARMOR_ENCHANTABLE), + 10, + 9, + Enchantment.dynamicCost(1, 11), + Enchantment.dynamicCost(12, 11), + 1, + EquipmentSlotGroup.ARMOR + ) + ) + .exclusiveWith(enchantLookup.getOrThrow(EnchantmentTags.ARMOR_EXCLUSIVE)) + .withEffect( + EnchantmentEffectComponents.DAMAGE_PROTECTION, + new AddValue(LevelBasedValue.perLevel(1.0F)), + DamageSourceCondition.hasDamageSource( + DamageSourcePredicate.Builder.damageType().tag(TagPredicate.isNot(DamageTypeTags.BYPASSES_INVULNERABILITY)) + )); + } else { + return builder; + } } } diff --git a/src/main/java/net/unknown/launchwrapper/mixins/MixinFeatureFlags.java b/src/main/java/net/unknown/launchwrapper/mixins/MixinFeatureFlags.java index 7821fa4..7b64524 100644 --- a/src/main/java/net/unknown/launchwrapper/mixins/MixinFeatureFlags.java +++ b/src/main/java/net/unknown/launchwrapper/mixins/MixinFeatureFlags.java @@ -49,7 +49,6 @@ private static FeatureFlagSet onClInit(FeatureFlag feature) { List additionalFlags = new ArrayList<>() {{ if (Main.FORCE_ALLOW_BUNDLE_FEATURES) add(FeatureFlags.BUNDLE); if (Main.FORCE_ALLOW_TRADE_REBALANCE_FEATURES) add(FeatureFlags.TRADE_REBALANCE); - if (Main.FORCE_ALLOW_UPDATE_1_21) add(FeatureFlags.UPDATE_1_21); }}; return !additionalFlags.isEmpty() ? FeatureFlagSet.of(feature, additionalFlags.toArray(FeatureFlag[]::new)) : FeatureFlagSet.of(feature); diff --git a/src/main/java/net/unknown/launchwrapper/mixins/MixinItem.java b/src/main/java/net/unknown/launchwrapper/mixins/MixinItem.java index 3ccc23f..95a2e78 100644 --- a/src/main/java/net/unknown/launchwrapper/mixins/MixinItem.java +++ b/src/main/java/net/unknown/launchwrapper/mixins/MixinItem.java @@ -32,20 +32,28 @@ package net.unknown.launchwrapper.mixins; import net.minecraft.core.component.DataComponentMap; +import net.minecraft.core.component.DataComponentPatch; import net.minecraft.core.component.DataComponentType; +import net.minecraft.core.component.DataComponents; +import net.minecraft.world.item.EggItem; import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; import net.unknown.launchwrapper.mixininterfaces.IMixinItem; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mutable; 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; @Mixin(Item.class) -public class MixinItem implements IMixinItem { +public abstract class MixinItem implements IMixinItem { @Mutable @Shadow @Final private DataComponentMap components; + @Shadow public abstract DataComponentMap components(); + @Override public void setComponent(DataComponentType type, T value) { this.components = this.getComponentBuilder().set(type, value).build(); @@ -55,4 +63,17 @@ public void setComponent(DataComponentType type, T value) { public DataComponentMap.Builder getComponentBuilder() { return DataComponentMap.builder().addAll(this.components); } + + @Inject(method = "verifyComponentsAfterLoad", at = @At("HEAD")) + private void onVerifyComponentsAfterLoad(ItemStack stack, CallbackInfo ci) { + // Previous MixinItems implementation is set Egg's default DataComponent minecraft:max_stack_size to 64, but this is server-side only, so we need to *FORCE* set it here to apply client to max_stack_size to 64. + // This operation will prevent you from setting the maximum stack size of eggs to 16. You can set it to 15 or 17, etc., but not 16. + if ((Object) this instanceof EggItem) { + if (stack.getComponents().has(DataComponents.MAX_STACK_SIZE) && stack.getComponents().get(DataComponents.MAX_STACK_SIZE).equals(this.components().get(DataComponents.MAX_STACK_SIZE))) { + stack.applyComponents(DataComponentPatch.builder() + .set(DataComponents.MAX_STACK_SIZE, 64) + .build()); + } + } + } } diff --git a/src/main/java/net/unknown/launchwrapper/mixins/MixinItems.java b/src/main/java/net/unknown/launchwrapper/mixins/MixinItems.java deleted file mode 100644 index f10a2df..0000000 --- a/src/main/java/net/unknown/launchwrapper/mixins/MixinItems.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2023 Unknown Network Developers and contributors. - * - * All rights reserved. - * - * NOTICE: This license is subject to change without prior notice. - * - * Redistribution and use in source and binary forms, *without modification*, - * are permitted provided that the following conditions are met: - * - * I. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * II. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * III. Neither the name of Unknown Network nor the names of its contributors may be used to - * endorse or promote products derived from this software without specific prior written permission. - * - * IV. This source code and binaries is provided by the copyright holders and contributors "AS-IS" and - * any express or implied warranties, including, but not limited to, the implied warranties of - * merchantability and fitness for a particular purpose are disclaimed. - * In not event shall the copyright owner or contributors be liable for - * any direct, indirect, incidental, special, exemplary, or consequential damages - * (including but not limited to procurement of substitute goods or services; - * loss of use data or profits; or business interruption) however caused and on any theory of liability, - * whether in contract, strict liability, or tort (including negligence or otherwise) - * arising in any way out of the use of this source code, event if advised of the possibility of such damage. - */ - -package net.unknown.launchwrapper.mixins; - -import net.minecraft.core.component.DataComponents; -import net.minecraft.resources.ResourceKey; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.Items; -import net.unknown.launchwrapper.mixininterfaces.IMixinItem; -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(Items.class) -public class MixinItems { - @Inject(method = "registerItem(Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/world/item/Item;)Lnet/minecraft/world/item/Item;", at = @At("HEAD")) - private static void onRegisterItem(ResourceKey key, Item item, CallbackInfoReturnable cir) { - if (key.location().equals(ResourceLocation.of("minecraft:egg", ':')) && item instanceof IMixinItem mixinItem) { - mixinItem.setComponent(DataComponents.MAX_STACK_SIZE, 64); // set max stack size to 64 - } - } -} diff --git a/src/main/java/net/unknown/launchwrapper/mixins/MixinServerLevel.java b/src/main/java/net/unknown/launchwrapper/mixins/MixinServerLevel.java index 11e50be..440fa73 100644 --- a/src/main/java/net/unknown/launchwrapper/mixins/MixinServerLevel.java +++ b/src/main/java/net/unknown/launchwrapper/mixins/MixinServerLevel.java @@ -32,7 +32,6 @@ package net.unknown.launchwrapper.mixins; import io.papermc.paper.configuration.WorldConfiguration; -import io.papermc.paper.util.math.ThreadUnsafeRandom; import net.minecraft.core.BlockPos; import net.minecraft.core.Holder; import net.minecraft.core.RegistryAccess; @@ -63,8 +62,6 @@ @Mixin(ServerLevel.class) public abstract class MixinServerLevel extends Level { - @Shadow @Final private ThreadUnsafeRandom randomTickRandom; - protected MixinServerLevel(WritableLevelData worlddatamutable, ResourceKey resourcekey, RegistryAccess iregistrycustom, Holder holder, Supplier supplier, boolean flag, boolean flag1, long i, int j, ChunkGenerator gen, BiomeProvider biomeProvider, World.Environment env, Function paperWorldConfigCreator, Executor executor) { super(worlddatamutable, resourcekey, iregistrycustom, holder, supplier, flag, flag1, i, j, gen, biomeProvider, env, paperWorldConfigCreator, executor); } @@ -77,7 +74,7 @@ public void onUpdateNeighborsAt(BlockPos blockPos, Block block, BlockPos origina if (blockState.getBlock() instanceof LeavesBlock || blockState.is(BlockTags.LEAVES)) { if (blockState.hasProperty(LeavesBlock.PERSISTENT) && !blockState.getValue(LeavesBlock.PERSISTENT)) { blockState.setValue(LeavesBlock.DISTANCE, LeavesBlock.DECAY_DISTANCE); - blockState.randomTick(level, blockPos, this.randomTickRandom); + blockState.randomTick(level, blockPos, this.random); } } } diff --git a/src/main/java/net/unknown/launchwrapper/util/WrappedBlockPos.java b/src/main/java/net/unknown/launchwrapper/util/WrappedBlockPos.java index 6c8b4c0..fe10ab3 100644 --- a/src/main/java/net/unknown/launchwrapper/util/WrappedBlockPos.java +++ b/src/main/java/net/unknown/launchwrapper/util/WrappedBlockPos.java @@ -35,7 +35,7 @@ import net.minecraft.resources.ResourceKey; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.TicketType; +import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler; import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; @@ -98,7 +98,7 @@ private BlockEntity getBlockEntity(boolean load, int maxRetry, int retryCount) { if (level != null) { if (!level.isLoaded(this.blockPos()) && load) { ChunkPos chunkPos = new ChunkPos(this.blockPos()); - level.getChunkSource().addRegionTicket(TicketType.CHUNK_LOAD, chunkPos, 0, 20 * 3L); + level.getChunkSource().addRegionTicket(ChunkTaskScheduler.CHUNK_LOAD, chunkPos, 0, 20 * 3L); ChunkAccess chunk = level.getChunkSource().getChunk(chunkPos.x, chunkPos.z, ChunkStatus.FULL, true); if (chunk != null) return chunk.getBlockEntity(this.blockPos()); } else if (level.isLoaded(this.blockPos())) { diff --git a/src/main/resources/unknownnetwork.mixins.json b/src/main/resources/unknownnetwork.mixins.json index 45153c6..7cbc9a9 100644 --- a/src/main/resources/unknownnetwork.mixins.json +++ b/src/main/resources/unknownnetwork.mixins.json @@ -20,7 +20,6 @@ "MixinHopperBlock", "MixinHopperBlockEntity", "MixinItem", - "MixinItems", "MixinJsonOps", "MixinMinecart", "MixinMinecraftServer",