9
0
mirror of https://github.com/WiIIiam278/HuskSync.git synced 2025-12-19 14:59:21 +00:00

feat: Support fabric with 1.21

This commit is contained in:
동헌희
2024-07-07 20:15:22 +09:00
committed by Dong Heon Hee
parent 93f7294859
commit c16231b12b
6 changed files with 55 additions and 52 deletions

View File

@@ -26,7 +26,7 @@ import com.google.gson.annotations.SerializedName;
import lombok.*; import lombok.*;
import net.minecraft.advancement.AdvancementProgress; import net.minecraft.advancement.AdvancementProgress;
import net.minecraft.advancement.PlayerAdvancementTracker; import net.minecraft.advancement.PlayerAdvancementTracker;
import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.component.DataComponentTypes;
import net.minecraft.entity.attribute.EntityAttribute; import net.minecraft.entity.attribute.EntityAttribute;
import net.minecraft.entity.attribute.EntityAttributeInstance; import net.minecraft.entity.attribute.EntityAttributeInstance;
import net.minecraft.entity.attribute.EntityAttributeModifier; import net.minecraft.entity.attribute.EntityAttributeModifier;
@@ -34,15 +34,15 @@ import net.minecraft.entity.effect.StatusEffect;
import net.minecraft.entity.effect.StatusEffectInstance; import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.entity.player.HungerManager; import net.minecraft.entity.player.HungerManager;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.registry.Registries; import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry; import net.minecraft.registry.Registry;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.stat.StatType; import net.minecraft.stat.StatType;
import net.minecraft.stat.Stats; import net.minecraft.stat.Stats;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.TeleportTarget; import net.minecraft.world.TeleportTarget;
import net.william278.desertwell.util.ThrowingConsumer; import net.william278.desertwell.util.ThrowingConsumer;
import net.william278.husksync.FabricHuskSync; import net.william278.husksync.FabricHuskSync;
@@ -85,13 +85,10 @@ public abstract class FabricData implements Data {
stack.getItem().toString(), stack.getItem().toString(),
stack.getCount(), stack.getCount(),
stack.getName().getString(), stack.getName().getString(),
Optional.ofNullable(stack.getSubNbt(ItemStack.DISPLAY_KEY)) stack.getComponents().get(DataComponentTypes.LORE).lines().stream().map(Text::getString).toList(),
.flatMap(display -> Optional.ofNullable(display.get(ItemStack.LORE_KEY)) stack.getEnchantments().getEnchantments().stream()
.map(lore -> ((List<String>) lore).stream().toList())) //todo check this is ok .map(RegistryEntry::getIdAsString)
.orElse(null), .filter(Objects::nonNull)
stack.getEnchantments().stream()
.map(element -> EnchantmentHelper.getIdFromNbt((NbtCompound) element))
.filter(Objects::nonNull).map(Identifier::toString)
.toList() .toList()
) : null) ) : null)
.toArray(Stack[]::new); .toArray(Stack[]::new);
@@ -246,7 +243,7 @@ public abstract class FabricData implements Data {
.map(effect -> { .map(effect -> {
final StatusEffect type = matchEffectType(effect.type()); final StatusEffect type = matchEffectType(effect.type());
return type != null ? new StatusEffectInstance( return type != null ? new StatusEffectInstance(
type, RegistryEntry.of(type),
effect.duration(), effect.duration(),
effect.amplifier(), effect.amplifier(),
effect.isAmbient(), effect.isAmbient(),
@@ -278,7 +275,7 @@ public abstract class FabricData implements Data {
public List<Effect> getActiveEffects() { public List<Effect> getActiveEffects() {
return effects.stream() return effects.stream()
.map(potionEffect -> { .map(potionEffect -> {
final String key = getEffectId(potionEffect.getEffectType()); final String key = getEffectId(potionEffect.getEffectType().value());
return key != null ? new Effect( return key != null ? new Effect(
key, key,
potionEffect.getAmplifier(), potionEffect.getAmplifier(),
@@ -306,16 +303,16 @@ public abstract class FabricData implements Data {
public static FabricData.Advancements adapt(@NotNull ServerPlayerEntity player) { public static FabricData.Advancements adapt(@NotNull ServerPlayerEntity player) {
final MinecraftServer server = Objects.requireNonNull(player.getServer(), "Server is null"); final MinecraftServer server = Objects.requireNonNull(player.getServer(), "Server is null");
final List<Advancement> advancements = Lists.newArrayList(); final List<Advancement> advancements = Lists.newArrayList();
forEachAdvancement(server, advancement -> { forEachAdvancementEntry(server, advancementEntry -> {
final AdvancementProgress advancementProgress = player.getAdvancementTracker().getProgress(advancement); final AdvancementProgress advancementProgress = player.getAdvancementTracker().getProgress(advancementEntry);
final Map<String, Date> awardedCriteria = Maps.newHashMap(); final Map<String, Date> awardedCriteria = Maps.newHashMap();
advancementProgress.getObtainedCriteria().forEach((criteria) -> awardedCriteria.put(criteria, advancementProgress.getObtainedCriteria().forEach((criteria) -> awardedCriteria.put(criteria,
advancementProgress.getEarliestProgressObtainDate())); Date.from(advancementProgress.getEarliestProgressObtainDate())));
// Only save the advancement if criteria has been completed // Only save the advancement if criteria has been completed
if (!awardedCriteria.isEmpty()) { if (!awardedCriteria.isEmpty()) {
advancements.add(Advancement.adapt(advancement.getId().toString(), awardedCriteria)); advancements.add(Advancement.adapt(advancementEntry.id().asString(), awardedCriteria));
} }
}); });
return new FabricData.Advancements(advancements); return new FabricData.Advancements(advancements);
@@ -330,10 +327,10 @@ public abstract class FabricData implements Data {
public void apply(@NotNull FabricUser user, @NotNull FabricHuskSync plugin) throws IllegalStateException { public void apply(@NotNull FabricUser user, @NotNull FabricHuskSync plugin) throws IllegalStateException {
final ServerPlayerEntity player = user.getPlayer(); final ServerPlayerEntity player = user.getPlayer();
final MinecraftServer server = Objects.requireNonNull(player.getServer(), "Server is null"); final MinecraftServer server = Objects.requireNonNull(player.getServer(), "Server is null");
plugin.runAsync(() -> forEachAdvancement(server, advancement -> { plugin.runAsync(() -> forEachAdvancementEntry(server, advancementEntry -> {
final AdvancementProgress progress = player.getAdvancementTracker().getProgress(advancement); final AdvancementProgress progress = player.getAdvancementTracker().getProgress(advancementEntry);
final Optional<Advancement> record = completed.stream() final Optional<Advancement> record = completed.stream()
.filter(r -> r.getKey().equals(advancement.getId().toString())) .filter(r -> r.getKey().equals(advancementEntry.id().toString()))
.findFirst(); .findFirst();
if (record.isEmpty()) { if (record.isEmpty()) {
return; return;
@@ -342,7 +339,7 @@ public abstract class FabricData implements Data {
final Map<String, Date> criteria = record.get().getCompletedCriteria(); final Map<String, Date> criteria = record.get().getCompletedCriteria();
final List<String> awarded = Lists.newArrayList(progress.getObtainedCriteria()); final List<String> awarded = Lists.newArrayList(progress.getObtainedCriteria());
this.setAdvancement( this.setAdvancement(
plugin, advancement, player, user, plugin, advancementEntry, player, user,
criteria.keySet().stream().filter(key -> !awarded.contains(key)).toList(), criteria.keySet().stream().filter(key -> !awarded.contains(key)).toList(),
awarded.stream().filter(key -> !criteria.containsKey(key)).toList() awarded.stream().filter(key -> !criteria.containsKey(key)).toList()
); );
@@ -350,7 +347,7 @@ public abstract class FabricData implements Data {
} }
private void setAdvancement(@NotNull FabricHuskSync plugin, private void setAdvancement(@NotNull FabricHuskSync plugin,
@NotNull net.minecraft.advancement.Advancement advancement, @NotNull net.minecraft.advancement.AdvancementEntry advancementEntry,
@NotNull ServerPlayerEntity player, @NotNull ServerPlayerEntity player,
@NotNull FabricUser user, @NotNull FabricUser user,
@NotNull List<String> toAward, @NotNull List<String> toAward,
@@ -362,8 +359,8 @@ public abstract class FabricData implements Data {
// Award and revoke advancement criteria // Award and revoke advancement criteria
final PlayerAdvancementTracker progress = player.getAdvancementTracker(); final PlayerAdvancementTracker progress = player.getAdvancementTracker();
toAward.forEach(a -> progress.grantCriterion(advancement, a)); toAward.forEach(a -> progress.grantCriterion(advancementEntry, a));
toRevoke.forEach(r -> progress.revokeCriterion(advancement, r)); toRevoke.forEach(r -> progress.revokeCriterion(advancementEntry, r));
// Restore player exp level & progress // Restore player exp level & progress
if (!toAward.isEmpty() if (!toAward.isEmpty()
@@ -374,9 +371,9 @@ public abstract class FabricData implements Data {
}); });
} }
// Performs a consuming function for every advancement registered on the server // Performs a consuming function for every advancement entry registered on the server
private static void forEachAdvancement(@NotNull MinecraftServer server, private static void forEachAdvancementEntry(@NotNull MinecraftServer server,
@NotNull ThrowingConsumer<net.minecraft.advancement.Advancement> con) { @NotNull ThrowingConsumer<net.minecraft.advancement.AdvancementEntry> con) {
server.getAdvancementLoader().getAdvancements().forEach(con); server.getAdvancementLoader().getAdvancements().forEach(con);
} }
@@ -419,9 +416,9 @@ public abstract class FabricData implements Data {
player.getWorld(), "World is null" player.getWorld(), "World is null"
).getRegistryKey().getValue().toString(), ).getRegistryKey().getValue().toString(),
UUID.nameUUIDFromBytes( UUID.nameUUIDFromBytes(
player.getWorld().getDimensionKey().getValue().toString().getBytes() player.getWorld().getDimensionEntry().getIdAsString().getBytes()
), ),
player.getWorld().getDimensionKey().getValue().toString() player.getWorld().getDimensionEntry().getIdAsString()
) )
); );
} }
@@ -570,17 +567,17 @@ public abstract class FabricData implements Data {
public static FabricData.Attributes adapt(@NotNull ServerPlayerEntity player, @NotNull HuskSync plugin) { public static FabricData.Attributes adapt(@NotNull ServerPlayerEntity player, @NotNull HuskSync plugin) {
final List<Attribute> attributes = Lists.newArrayList(); final List<Attribute> attributes = Lists.newArrayList();
Registries.ATTRIBUTE.forEach(id -> { Registries.ATTRIBUTE.forEach(id -> {
final EntityAttributeInstance instance = player.getAttributeInstance(id); final EntityAttributeInstance instance = player.getAttributeInstance(RegistryEntry.of(id));
final Identifier key = Registries.ATTRIBUTE.getId(id); final Identifier key = Registries.ATTRIBUTE.getId(id);
if (instance == null || key == null) { if (instance == null || key == null) {
return; return;
} }
final Set<Modifier> modifiers = Sets.newHashSet(); final Set<Modifier> modifiers = Sets.newHashSet();
instance.getModifiers().forEach(modifier -> modifiers.add(new Modifier( instance.getModifiers().forEach(modifier -> modifiers.add(new Modifier(
modifier.getId(), UUID.nameUUIDFromBytes(modifier.id().toString().getBytes()),
modifier.getName(), modifier.id().examinableName(),
modifier.getValue(), modifier.value(),
modifier.getOperation().getId(), modifier.operation().getId(),
-1 -1
))); )));
attributes.add(new Attribute( attributes.add(new Attribute(
@@ -609,7 +606,7 @@ public abstract class FabricData implements Data {
@Override @Override
protected void apply(@NotNull FabricUser user, @NotNull FabricHuskSync plugin) { protected void apply(@NotNull FabricUser user, @NotNull FabricHuskSync plugin) {
Registries.ATTRIBUTE.forEach(id -> applyAttribute( Registries.ATTRIBUTE.forEach(id -> applyAttribute(
user.getPlayer().getAttributeInstance(id), user.getPlayer().getAttributeInstance(RegistryEntry.of(id)),
getAttribute(id).orElse(null) getAttribute(id).orElse(null)
)); ));
@@ -620,14 +617,13 @@ public abstract class FabricData implements Data {
if (instance == null) { if (instance == null) {
return; return;
} }
instance.setBaseValue(attribute == null ? instance.getAttribute().getDefaultValue() : attribute.baseValue()); instance.setBaseValue(attribute == null ? instance.getAttribute().value().getDefaultValue() : attribute.baseValue());
instance.getModifiers().forEach(instance::removeModifier); instance.getModifiers().forEach(instance::removeModifier);
if (attribute != null) { if (attribute != null) {
attribute.modifiers().forEach(modifier -> instance.addPersistentModifier(new EntityAttributeModifier( attribute.modifiers().forEach(modifier -> instance.addPersistentModifier(new EntityAttributeModifier(
modifier.uuid(), Identifier.of(modifier.uuid().toString()),
modifier.name(),
modifier.amount(), modifier.amount(),
EntityAttributeModifier.Operation.fromId(modifier.operationType()) EntityAttributeModifier.Operation.ID_TO_VALUE.apply(modifier.operationType())
))); )));
} }
} }

View File

@@ -27,6 +27,11 @@ import lombok.AllArgsConstructor;
import net.minecraft.datafixer.TypeReferences; import net.minecraft.datafixer.TypeReferences;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.*; import net.minecraft.nbt.*;
import net.minecraft.registry.DynamicRegistryManager;
import net.minecraft.registry.Registries;
import net.minecraft.world.World;
import net.minecraft.world.dimension.DimensionType;
import net.minecraft.world.dimension.DimensionTypes;
import net.william278.desertwell.util.Version; import net.william278.desertwell.util.Version;
import net.william278.husksync.FabricHuskSync; import net.william278.husksync.FabricHuskSync;
import net.william278.husksync.HuskSync; import net.william278.husksync.HuskSync;
@@ -94,7 +99,7 @@ public abstract class FabricSerializer {
public String serialize(@NotNull FabricData.Items.Inventory data) throws SerializationException { public String serialize(@NotNull FabricData.Items.Inventory data) throws SerializationException {
try { try {
final NbtCompound root = new NbtCompound(); final NbtCompound root = new NbtCompound();
root.put(ITEMS_TAG, serializeItemArray(data.getContents())); root.put(ITEMS_TAG, serializeItemArray(data.getContents(), (FabricHuskSync) getPlugin()));
root.putInt(HELD_ITEM_SLOT_TAG, data.getHeldItemSlot()); root.putInt(HELD_ITEM_SLOT_TAG, data.getHeldItemSlot());
return root.toString(); return root.toString();
} catch (Throwable e) { } catch (Throwable e) {
@@ -132,7 +137,7 @@ public abstract class FabricSerializer {
@Override @Override
public String serialize(@NotNull FabricData.Items.EnderChest data) throws SerializationException { public String serialize(@NotNull FabricData.Items.EnderChest data) throws SerializationException {
try { try {
return serializeItemArray(data.getContents()).toString(); return serializeItemArray(data.getContents(), (FabricHuskSync) getPlugin()).toString();
} catch (Throwable e) { } catch (Throwable e) {
throw new SerializationException("Failed to serialize ender chest item NBT to string", e); throw new SerializationException("Failed to serialize ender chest item NBT to string", e);
} }
@@ -161,9 +166,10 @@ public abstract class FabricSerializer {
final ItemStack[] contents = new ItemStack[tag.getInt("size")]; final ItemStack[] contents = new ItemStack[tag.getInt("size")];
final NbtList itemList = tag.getList("items", NbtElement.COMPOUND_TYPE); final NbtList itemList = tag.getList("items", NbtElement.COMPOUND_TYPE);
final DynamicRegistryManager registryManager = plugin.getMinecraftServer().getRegistryManager();
itemList.forEach(element -> { itemList.forEach(element -> {
final NbtCompound compound = (NbtCompound) element; final NbtCompound compound = (NbtCompound) element;
contents[compound.getInt("Slot")] = ItemStack.fromNbt(compound); contents[compound.getInt("Slot")] = ItemStack.fromNbt(registryManager, element).get();
}); });
plugin.debug(Arrays.toString(contents)); plugin.debug(Arrays.toString(contents));
return contents; return contents;
@@ -174,18 +180,18 @@ public abstract class FabricSerializer {
// Serialize items slot-by-slot // Serialize items slot-by-slot
@NotNull @NotNull
default NbtCompound serializeItemArray(@Nullable ItemStack @NotNull [] items) { default NbtCompound serializeItemArray(@Nullable ItemStack @NotNull [] items, @NotNull FabricHuskSync plugin) {
final NbtCompound container = new NbtCompound(); final NbtCompound container = new NbtCompound();
container.putInt("size", items.length); container.putInt("size", items.length);
final NbtList itemList = new NbtList(); final NbtList itemList = new NbtList();
final DynamicRegistryManager registryManager = plugin.getMinecraftServer().getRegistryManager();
for (int i = 0; i < items.length; i++) { for (int i = 0; i < items.length; i++) {
final ItemStack item = items[i]; final ItemStack item = items[i];
if (item == null || item.isEmpty()) { if (item == null || item.isEmpty()) {
continue; continue;
} }
NbtCompound entry = new NbtCompound(); NbtCompound entry = (NbtCompound) item.encode(registryManager);
entry.putInt("Slot", i); entry.putInt("Slot", i);
item.writeNbt(entry);
itemList.add(entry); itemList.add(entry);
} }
container.put(ITEMS_TAG, itemList); container.put(ITEMS_TAG, itemList);
@@ -205,7 +211,7 @@ public abstract class FabricSerializer {
} }
final NbtCompound compound = list.getCompound(i); final NbtCompound compound = list.getCompound(i);
final int slot = compound.getInt("Slot"); final int slot = compound.getInt("Slot");
itemStacks[slot] = ItemStack.fromNbt(upgradeItemData(list.getCompound(i), mcVersion, plugin)); itemStacks[slot] = ItemStack.fromNbt(DynamicRegistryManager.of(Registries.REGISTRIES), upgradeItemData(list.getCompound(i), mcVersion, plugin)).get();
} }
return itemStacks; return itemStacks;
} }

View File

@@ -104,7 +104,7 @@ public interface FabricUserDataHolder extends UserDataHolder {
@Override @Override
default Optional<Data.Items.EnderChest> getEnderChest() { default Optional<Data.Items.EnderChest> getEnderChest() {
return Optional.of(FabricData.Items.EnderChest.adapt( return Optional.of(FabricData.Items.EnderChest.adapt(
getPlayer().getEnderChestInventory().stacks getPlayer().getEnderChestInventory().getHeldStacks()
)); ));
} }

View File

@@ -20,9 +20,11 @@
package net.william278.husksync.mixins; package net.william278.husksync.mixins;
import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.enchantment.Enchantments;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory; import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.registry.tag.TagKey;
import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
import net.william278.husksync.event.PlayerDeathDropsCallback; import net.william278.husksync.event.PlayerDeathDropsCallback;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -54,7 +56,7 @@ public class PlayerEntityMixin {
final @Nullable ItemStack @NotNull [] toKeep = new ItemStack[inventory.size()]; final @Nullable ItemStack @NotNull [] toKeep = new ItemStack[inventory.size()];
for (int i = 0; i < inventory.size(); ++i) { for (int i = 0; i < inventory.size(); ++i) {
ItemStack itemStack = inventory.getStack(i); ItemStack itemStack = inventory.getStack(i);
if (!itemStack.isEmpty() && EnchantmentHelper.hasVanishingCurse(itemStack)) { if (!itemStack.isEmpty() && EnchantmentHelper.hasAnyEnchantmentsIn(itemStack, TagKey.of(Enchantments.VANISHING_CURSE.getRegistryRef(), Enchantments.VANISHING_CURSE.getValue()))) {
toKeep[i] = null; toKeep[i] = null;
continue; continue;
} }
@@ -69,7 +71,7 @@ public class PlayerEntityMixin {
final @Nullable ItemStack @NotNull [] toDrop = new ItemStack[inventory.size()]; final @Nullable ItemStack @NotNull [] toDrop = new ItemStack[inventory.size()];
for (int i = 0; i < inventory.size(); ++i) { for (int i = 0; i < inventory.size(); ++i) {
ItemStack itemStack = inventory.getStack(i); ItemStack itemStack = inventory.getStack(i);
if (!itemStack.isEmpty() && EnchantmentHelper.hasVanishingCurse(itemStack)) { if (!itemStack.isEmpty() && EnchantmentHelper.hasAnyEnchantmentsIn(itemStack, TagKey.of(Enchantments.VANISHING_CURSE.getRegistryRef(), Enchantments.VANISHING_CURSE.getValue()))) {
toDrop[i] = itemStack; toDrop[i] = itemStack;
continue; continue;
} }

View File

@@ -44,7 +44,6 @@ public abstract class ServerPlayNetworkHandlerMixin {
@Shadow @Shadow
public ServerPlayerEntity player; public ServerPlayerEntity player;
@Shadow
public abstract void sendPacket(Packet<?> packet); public abstract void sendPacket(Packet<?> packet);
@Inject(method = "onPlayerAction", at = @At("HEAD"), cancellable = true) @Inject(method = "onPlayerAction", at = @At("HEAD"), cancellable = true)
@@ -83,7 +82,7 @@ public abstract class ServerPlayNetworkHandlerMixin {
@Inject(method = "onCreativeInventoryAction", at = @At("HEAD"), cancellable = true) @Inject(method = "onCreativeInventoryAction", at = @At("HEAD"), cancellable = true)
public void onCreativeInventoryAction(CreativeInventoryActionC2SPacket packet, CallbackInfo ci) { public void onCreativeInventoryAction(CreativeInventoryActionC2SPacket packet, CallbackInfo ci) {
int slot = packet.getSlot(); int slot = packet.slot();
if (slot < 0) return; if (slot < 0) return;
ItemStack stack = this.player.getInventory().getStack(slot); ItemStack stack = this.player.getInventory().getStack(slot);

View File

@@ -18,6 +18,6 @@ fabric_minecraft_version=1.21
fabric_loader_version=0.15.11 fabric_loader_version=0.15.11
fabric_yarn_mappings=1.21+build.7 fabric_yarn_mappings=1.21+build.7
fabric_api_version=0.100.4+1.21 fabric_api_version=0.100.4+1.21
adventure_platform_fabric_version=5.9.0 adventure_platform_fabric_version=5.14.0
fabric_permissions_api_version=0.2-SNAPSHOT fabric_permissions_api_version=0.2-SNAPSHOT
sgui_version=1.2.2+1.20 sgui_version=1.6.0+1.21