feat: 完成跨版本化,修复fabric,forge同步错误逻辑

This commit is contained in:
叁玖领域 2026-03-14 18:13:25 +08:00
parent 099f29e76f
commit af3e313fde
33 changed files with 285 additions and 133 deletions

View File

@ -1,6 +1,5 @@
package top.r3944realms.lib39.core.sync; package top.r3944realms.lib39.core.sync;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
@ -15,8 +14,8 @@ import java.util.function.Function;
* The type Sync data 2 manager. * The type Sync data 2 manager.
*/ */
@SuppressWarnings({"unused", "DuplicatedCode"}) @SuppressWarnings({"unused", "DuplicatedCode"})
public class SyncData2Manager { public abstract class SyncData2Manager<V extends SyncData2Manager.TypedSyncEntry<?, ?>> {
protected final Map<ResourceLocation, TypedSyncEntry<?, ?>> typedEntries = Maps.newConcurrentMap(); protected abstract Map<ResourceLocation, V> getTypedEntries();
/** /**
* 数据提供者接口 - 用于通过键获取数据 * 数据提供者接口 - 用于通过键获取数据
@ -72,6 +71,7 @@ public class SyncData2Manager {
* @param manager the manager * @param manager the manager
* @param dataProvider the data provider * @param dataProvider the data provider
*/ */
@SuppressWarnings("unchecked")
public <K, T extends ISyncData<?>> void registerManagerWithProvider( public <K, T extends ISyncData<?>> void registerManagerWithProvider(
ResourceLocation key, ResourceLocation key,
ISyncManager<K, T> manager, ISyncManager<K, T> manager,
@ -81,7 +81,7 @@ public class SyncData2Manager {
Objects.requireNonNull(manager, "Sync manager cannot be null"); Objects.requireNonNull(manager, "Sync manager cannot be null");
Objects.requireNonNull(dataProvider, "Data provider cannot be null"); Objects.requireNonNull(dataProvider, "Data provider cannot be null");
typedEntries.put(key, new TypedSyncEntry<>(manager, dataProvider)); getTypedEntries().put(key, (V) new TypedSyncEntry<>(manager, dataProvider));
} }
/** /**
@ -93,6 +93,7 @@ public class SyncData2Manager {
* @param manager the manager * @param manager the manager
* @param getter the data getter function * @param getter the data getter function
*/ */
@SuppressWarnings("unchecked")
public <K, T extends ISyncData<?>> void registerManager( public <K, T extends ISyncData<?>> void registerManager(
ResourceLocation key, ResourceLocation key,
ISyncManager<K, T> manager, ISyncManager<K, T> manager,
@ -102,7 +103,7 @@ public class SyncData2Manager {
Objects.requireNonNull(manager, "Sync manager cannot be null"); Objects.requireNonNull(manager, "Sync manager cannot be null");
Objects.requireNonNull(getter, "Data getter function cannot be null"); Objects.requireNonNull(getter, "Data getter function cannot be null");
typedEntries.put(key, new TypedSyncEntry<>(manager, getter::apply)); getTypedEntries().put(key, (V) new TypedSyncEntry<>(manager, getter::apply));
} }
/** /**
@ -117,7 +118,7 @@ public class SyncData2Manager {
Objects.requireNonNull(manager, "Sync manager cannot be null"); Objects.requireNonNull(manager, "Sync manager cannot be null");
// 创建一个没有数据提供者的 TypedSyncEntry // 创建一个没有数据提供者的 TypedSyncEntry
typedEntries.put(key, new TypedSyncEntry<>( getTypedEntries().put(key, (V) new TypedSyncEntry<>(
(ISyncManager<?, ISyncData<?>>) manager, (ISyncManager<?, ISyncData<?>>) manager,
null null
)); ));
@ -133,7 +134,7 @@ public class SyncData2Manager {
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <K, T extends ISyncData<?>> Optional<ISyncManager<K, T>> getManager(ResourceLocation key) { public <K, T extends ISyncData<?>> Optional<ISyncManager<K, T>> getManager(ResourceLocation key) {
TypedSyncEntry<?,?> entry = typedEntries.get(key); TypedSyncEntry<?,?> entry = getTypedEntries().get(key);
return entry != null ? Optional.of((ISyncManager<K,T>) entry.manager) : Optional.empty(); return entry != null ? Optional.of((ISyncManager<K,T>) entry.manager) : Optional.empty();
} }
@ -146,7 +147,7 @@ public class SyncData2Manager {
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T extends ISyncData<?>> Optional<DataProvider<Entity, T>> getDataProvider(ResourceLocation key) { public <T extends ISyncData<?>> Optional<DataProvider<Entity, T>> getDataProvider(ResourceLocation key) {
TypedSyncEntry<?, ?> entry = typedEntries.get(key); TypedSyncEntry<?, ?> entry = getTypedEntries().get(key);
if (entry != null && entry.dataProvider != null) { if (entry != null && entry.dataProvider != null) {
return Optional.of((DataProvider<Entity, T>) entry.dataProvider); return Optional.of((DataProvider<Entity, T>) entry.dataProvider);
} }
@ -184,7 +185,7 @@ public class SyncData2Manager {
return; return;
} }
TypedSyncEntry<?, ?> entry = typedEntries.get(key); TypedSyncEntry<?, ?> entry = getTypedEntries().get(key);
if (entry != null) { if (entry != null) {
entry.allowedClasses.addAll(Arrays.asList(classes)); entry.allowedClasses.addAll(Arrays.asList(classes));
} }
@ -200,7 +201,7 @@ public class SyncData2Manager {
Objects.requireNonNull(key, "ResourceLocation key cannot be null"); Objects.requireNonNull(key, "ResourceLocation key cannot be null");
Objects.requireNonNull(classes, "Classes array cannot be null"); Objects.requireNonNull(classes, "Classes array cannot be null");
TypedSyncEntry<?, ?> entry = typedEntries.get(key); TypedSyncEntry<?, ?> entry = getTypedEntries().get(key);
if (entry != null && classes.length > 0) { if (entry != null && classes.length > 0) {
Arrays.asList(classes).forEach(entry.allowedClasses::remove); Arrays.asList(classes).forEach(entry.allowedClasses::remove);
} }
@ -217,7 +218,7 @@ public class SyncData2Manager {
Objects.requireNonNull(key, "ResourceLocation key cannot be null"); Objects.requireNonNull(key, "ResourceLocation key cannot be null");
Objects.requireNonNull(dataProvider, "Data provider cannot be null"); Objects.requireNonNull(dataProvider, "Data provider cannot be null");
TypedSyncEntry<?, ?> entry = typedEntries.get(key); TypedSyncEntry<?, ?> entry = getTypedEntries().get(key);
if (entry != null) { if (entry != null) {
// 更新现有条目的数据提供者 // 更新现有条目的数据提供者
updateDataProviderInEntry(key, entry, dataProvider); updateDataProviderInEntry(key, entry, dataProvider);
@ -245,7 +246,7 @@ public class SyncData2Manager {
public void unbindDataProvider(ResourceLocation key) { public void unbindDataProvider(ResourceLocation key) {
Objects.requireNonNull(key, "ResourceLocation key cannot be null"); Objects.requireNonNull(key, "ResourceLocation key cannot be null");
TypedSyncEntry<?, ?> entry = typedEntries.get(key); TypedSyncEntry<?, ?> entry = getTypedEntries().get(key);
if (entry != null) { if (entry != null) {
// 将数据提供者设置为null但保留管理器和其他配置 // 将数据提供者设置为null但保留管理器和其他配置
updateDataProviderInEntry(key, entry, null); updateDataProviderInEntry(key, entry, null);
@ -260,7 +261,7 @@ public class SyncData2Manager {
public void clearAllowedEntityClasses(ResourceLocation key) { public void clearAllowedEntityClasses(ResourceLocation key) {
Objects.requireNonNull(key, "ResourceLocation key cannot be null"); Objects.requireNonNull(key, "ResourceLocation key cannot be null");
TypedSyncEntry<?, ?> entry = typedEntries.get(key); TypedSyncEntry<?, ?> entry = getTypedEntries().get(key);
if (entry != null) { if (entry != null) {
entry.allowedClasses.clear(); entry.allowedClasses.clear();
} }
@ -277,11 +278,11 @@ public class SyncData2Manager {
Objects.requireNonNull(key, "ResourceLocation key cannot be null"); Objects.requireNonNull(key, "ResourceLocation key cannot be null");
Objects.requireNonNull(entityClass, "Entity class cannot be null"); Objects.requireNonNull(entityClass, "Entity class cannot be null");
TypedSyncEntry<?, ?> entry = typedEntries.get(key); TypedSyncEntry<?, ?> entry = getTypedEntries().get(key);
boolean isAllowed = false; boolean isAllowed = false;
if (entry != null) { if (entry != null) {
for (Class<?> allowedClass : entry.allowedClasses) { for (Class<?> allowedClass : entry.allowedClasses) {
if (entityClass.isAssignableFrom(allowedClass)) { if (allowedClass.isAssignableFrom(entityClass)) {
isAllowed = true; isAllowed = true;
break; break;
} }
@ -298,7 +299,7 @@ public class SyncData2Manager {
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void trackEntityForManager(Entity entity, ResourceLocation managerId) { public void trackEntityForManager(Entity entity, ResourceLocation managerId) {
TypedSyncEntry<UUID, ?> entry = (TypedSyncEntry<UUID, ?>) typedEntries.get(managerId); TypedSyncEntry<UUID, ?> entry = (TypedSyncEntry<UUID, ?>) getTypedEntries().get(managerId);
if (entry != null) { if (entry != null) {
trackEntityWithTypedEntry(entity, entry); trackEntityWithTypedEntry(entity, entry);
} }
@ -319,7 +320,7 @@ public class SyncData2Manager {
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void untrackEntityForManager(Entity entity, ResourceLocation managerId) { public void untrackEntityForManager(Entity entity, ResourceLocation managerId) {
TypedSyncEntry<UUID, ?> entry = (TypedSyncEntry<UUID, ?>) typedEntries.get(managerId); TypedSyncEntry<UUID, ?> entry = (TypedSyncEntry<UUID, ?>) getTypedEntries().get(managerId);
if (entry != null) { if (entry != null) {
untrackEntityWithTypedEntry(entity, entry); untrackEntityWithTypedEntry(entity, entry);
} }
@ -374,7 +375,7 @@ public class SyncData2Manager {
* @param managerId the manager id * @param managerId the manager id
*/ */
public void clearAllTrackedData(ResourceLocation managerId) { public void clearAllTrackedData(ResourceLocation managerId) {
TypedSyncEntry<?, ?> entry = typedEntries.get(managerId); TypedSyncEntry<?, ?> entry = getTypedEntries().get(managerId);
if (entry != null) { if (entry != null) {
clearTrackedDataForEntry(entry); clearTrackedDataForEntry(entry);
} }
@ -410,7 +411,7 @@ public class SyncData2Manager {
); );
newEntry.allowedClasses.addAll(entry.allowedClasses); newEntry.allowedClasses.addAll(entry.allowedClasses);
typedEntries.put(id, newEntry); getTypedEntries().put(id, (V) newEntry);
} }
/** /**
@ -419,7 +420,7 @@ public class SyncData2Manager {
* @return the registered keys * @return the registered keys
*/ */
public Set<ResourceLocation> getRegisteredKeys() { public Set<ResourceLocation> getRegisteredKeys() {
return Collections.unmodifiableSet(typedEntries.keySet()); return Collections.unmodifiableSet(getTypedEntries().keySet());
} }
/** /**
@ -429,7 +430,7 @@ public class SyncData2Manager {
*/ */
public void forEach(BiConsumer<ResourceLocation, ISyncManager<?,?>> consumer) { public void forEach(BiConsumer<ResourceLocation, ISyncManager<?,?>> consumer) {
Objects.requireNonNull(consumer, "Consumer cannot be null"); Objects.requireNonNull(consumer, "Consumer cannot be null");
typedEntries.forEach((key, entry) -> consumer.accept(key, entry.manager)); getTypedEntries().forEach((key, entry) -> consumer.accept(key, entry.manager));
} }
/** /**
@ -438,14 +439,14 @@ public class SyncData2Manager {
* @return the manager count * @return the manager count
*/ */
public int getManagerCount() { public int getManagerCount() {
return typedEntries.size(); return getTypedEntries().size();
} }
/** /**
* Clear all. * Clear all.
*/ */
public void clearAll() { public void clearAll() {
typedEntries.clear(); getTypedEntries().clear();
} }
/** /**
@ -455,6 +456,6 @@ public class SyncData2Manager {
*/ */
public void removeManager(ResourceLocation key) { public void removeManager(ResourceLocation key) {
Objects.requireNonNull(key, "ResourceLocation key cannot be null"); Objects.requireNonNull(key, "ResourceLocation key cannot be null");
typedEntries.remove(key); getTypedEntries().remove(key);
} }
} }

View File

@ -1,7 +1,7 @@
package top.r3944realms.lib39; package top.r3944realms.lib39;
import net.fabricmc.api.ModInitializer; import net.fabricmc.api.ModInitializer;
import top.r3944realms.lib39.core.event.CommonEventHandler; import top.r3944realms.lib39.core.event.FabricCommonEventHandler;
import top.r3944realms.lib39.core.register.*; import top.r3944realms.lib39.core.register.*;
import top.r3944realms.lib39.example.FabricLib39Example; import top.r3944realms.lib39.example.FabricLib39Example;
@ -15,7 +15,7 @@ public class Lib39Fabric implements ModInitializer {
FabricLib39Items.init(); FabricLib39Items.init();
FabricLib39BlockEntities.init(); FabricLib39BlockEntities.init();
FabricLib39SoundEvents.init(); FabricLib39SoundEvents.init();
CommonEventHandler.initCommon(); FabricCommonEventHandler.initCommon();
if (Lib39.shouldRegisterExamples()) { if (Lib39.shouldRegisterExamples()) {
Lib39.LOGGER.info("[Lib39-Fabric] Registering Examples"); Lib39.LOGGER.info("[Lib39-Fabric] Registering Examples");
registerExamples(); registerExamples();

View File

@ -6,8 +6,8 @@ import top.r3944realms.lib39.client.BlockEntityRendererRegistry;
import top.r3944realms.lib39.client.ItemRendererRegistry; import top.r3944realms.lib39.client.ItemRendererRegistry;
import top.r3944realms.lib39.client.LayerDefinitionRegistry; import top.r3944realms.lib39.client.LayerDefinitionRegistry;
import top.r3944realms.lib39.client.ShaderRegistry; import top.r3944realms.lib39.client.ShaderRegistry;
import top.r3944realms.lib39.core.event.CommonEventHandler; import top.r3944realms.lib39.core.event.FabricCommonEventHandler;
import top.r3944realms.lib39.core.network.NetworkHandler; import top.r3944realms.lib39.core.network.FabricNetworkHandler;
public class Lib39FabricClient implements ClientModInitializer { public class Lib39FabricClient implements ClientModInitializer {
@Override @Override
@ -17,8 +17,8 @@ public class Lib39FabricClient implements ClientModInitializer {
LayerDefinitionRegistry.register(); LayerDefinitionRegistry.register();
BlockEntityRendererRegistry.register(); BlockEntityRendererRegistry.register();
ItemRendererRegistry.register(); ItemRendererRegistry.register();
NetworkHandler.registerClientReceivers(); FabricNetworkHandler.registerClientReceivers();
CommonEventHandler.initClient(); FabricCommonEventHandler.initClient();
}); });
} }
} }

View File

@ -2,10 +2,13 @@ package top.r3944realms.lib39.core.event;
import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
import net.fabricmc.fabric.api.event.lifecycle.v1.CommonLifecycleEvents;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerEntityEvents; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerEntityEvents;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerWorldEvents; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerWorldEvents;
import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents; import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents;
import net.fabricmc.fabric.api.lookup.v1.entity.EntityApiLookup;
import net.fabricmc.loader.impl.launch.FabricLauncher;
import net.minecraft.Util; import net.minecraft.Util;
import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
@ -30,6 +33,9 @@ import top.r3944realms.lib39.content.item.DollItem;
import top.r3944realms.lib39.core.register.Lib39Items; import top.r3944realms.lib39.core.register.Lib39Items;
import top.r3944realms.lib39.core.sync.ISyncData; import top.r3944realms.lib39.core.sync.ISyncData;
import top.r3944realms.lib39.core.sync.SyncData2LookupManager; import top.r3944realms.lib39.core.sync.SyncData2LookupManager;
import top.r3944realms.lib39.example.content.data.AbstractedTestSyncData;
import top.r3944realms.lib39.example.content.data.FabricTestSyncData;
import top.r3944realms.lib39.example.content.data.FabricTestSyncLookupProvider;
import top.r3944realms.lib39.util.GameProfileHelper; import top.r3944realms.lib39.util.GameProfileHelper;
import top.r3944realms.lib39.util.IClientOnly; import top.r3944realms.lib39.util.IClientOnly;
import top.r3944realms.lib39.util.ILevelHelper; import top.r3944realms.lib39.util.ILevelHelper;
@ -40,7 +46,7 @@ import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Supplier; import java.util.function.Supplier;
public class CommonEventHandler { public class FabricCommonEventHandler {
static volatile SyncData2LookupManager syncData2Manager; static volatile SyncData2LookupManager syncData2Manager;
private static boolean isSync2MInitialized = false; private static boolean isSync2MInitialized = false;
private static ServerLevel sl; private static ServerLevel sl;
@ -63,7 +69,7 @@ public class CommonEventHandler {
} }
public static void onServerWorldLoad(MinecraftServer server, ServerLevel serverLevel) { public static void onServerWorldLoad(MinecraftServer server, ServerLevel serverLevel) {
if (!serverLevel.dimension().equals(Level.OVERWORLD)) return; if (!serverLevel.dimension().equals(Level.OVERWORLD)) return;
synchronized (CommonEventHandler.class) { synchronized (FabricCommonEventHandler.class) {
if (!isSync2MInitialized) { if (!isSync2MInitialized) {
syncData2Manager = new SyncData2LookupManager(); syncData2Manager = new SyncData2LookupManager();
isSync2MInitialized = true; isSync2MInitialized = true;
@ -151,18 +157,20 @@ public class CommonEventHandler {
return AnvilUpdateCallback.AnvilUpdateResult.withOutput(defaultInstance, 0, 0); return AnvilUpdateCallback.AnvilUpdateResult.withOutput(defaultInstance, 0, 0);
} }
}); });
ServerTickEvents.END_SERVER_TICK.register(CommonEventHandler::onServerTick); EntityApiLookup.get(FabricTestSyncData.ID, AbstractedTestSyncData.class, Void.class)
ServerWorldEvents.LOAD.register(CommonEventHandler::onServerWorldLoad); .registerFallback(FabricTestSyncLookupProvider.INSTANCE);
ServerWorldEvents.UNLOAD.register(CommonEventHandler::onServerWorldUnLoad); ServerTickEvents.END_SERVER_TICK.register(FabricCommonEventHandler::onServerTick);
ServerEntityEvents.ENTITY_LOAD.register(CommonEventHandler::onEntityJoinWorld); ServerWorldEvents.LOAD.register(FabricCommonEventHandler::onServerWorldLoad);
ServerEntityEvents.ENTITY_UNLOAD.register(CommonEventHandler::onEntityLeaveWorld); ServerWorldEvents.UNLOAD.register(FabricCommonEventHandler::onServerWorldUnLoad);
ServerEntityEvents.ENTITY_LOAD.register(FabricCommonEventHandler::onEntityJoinWorld);
ServerEntityEvents.ENTITY_UNLOAD.register(FabricCommonEventHandler::onEntityLeaveWorld);
CommandRegistrationCallback.EVENT.register((commandDispatcher, commandBuildContext, commandSelection) -> { CommandRegistrationCallback.EVENT.register((commandDispatcher, commandBuildContext, commandSelection) -> {
new Lib39HelpCommand(commandDispatcher, commandBuildContext); new Lib39HelpCommand(commandDispatcher, commandBuildContext);
}); });
} }
public static class ClientOpt implements IClientOnly { public static class ClientOpt implements IClientOnly {
public static void onClientWorldLoad(@NotNull ClientLevel clientLevel) { public static void onClientWorldLoad(@NotNull ClientLevel clientLevel) {
synchronized (CommonEventHandler.ClientOpt.class) { synchronized (FabricCommonEventHandler.ClientOpt.class) {
IClientOnly.check(() -> { IClientOnly.check(() -> {
if (!clientLevel.dimension().equals(Level.OVERWORLD)) return; if (!clientLevel.dimension().equals(Level.OVERWORLD)) return;
if (!isSync2MInitialized) { if (!isSync2MInitialized) {
@ -175,7 +183,7 @@ public class CommonEventHandler {
} }
} }
public static void onClientWorldUnLoad(@NotNull ClientLevel clientLevel) { public static void onClientWorldUnLoad(@NotNull ClientLevel clientLevel) {
synchronized (CommonEventHandler.ClientOpt.class) { synchronized (FabricCommonEventHandler.ClientOpt.class) {
IClientOnly.check(() -> ILevelHelper.LevelHelper.CLIENT.setLevel(null)); IClientOnly.check(() -> ILevelHelper.LevelHelper.CLIENT.setLevel(null));
} }
} }

View File

@ -1,10 +1,9 @@
package top.r3944realms.lib39.core.network; package top.r3944realms.lib39.core.network;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
import top.r3944realms.lib39.core.network.toClient.SyncNBTLookupDataEntityS2CPacket; import top.r3944realms.lib39.core.network.toClient.SyncNBTLookupDataEntityS2CPacket;
public class NetworkHandler { public class FabricNetworkHandler {
/** /**
* 注册客户端接收的数据包 * 注册客户端接收的数据包

View File

@ -12,7 +12,7 @@ import net.minecraft.world.level.Level;
import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import top.r3944realms.lib39.Lib39; import top.r3944realms.lib39.Lib39;
import top.r3944realms.lib39.core.event.CommonEventHandler; import top.r3944realms.lib39.core.event.FabricCommonEventHandler;
import top.r3944realms.lib39.core.sync.ISyncData; import top.r3944realms.lib39.core.sync.ISyncData;
import top.r3944realms.lib39.core.sync.NBTEntitySyncData; import top.r3944realms.lib39.core.sync.NBTEntitySyncData;
import top.r3944realms.lib39.core.sync.SyncData2Manager; import top.r3944realms.lib39.core.sync.SyncData2Manager;
@ -55,7 +55,7 @@ public record SyncNBTLookupDataEntityS2CPacket(int entityId, ResourceLocation id
Entity entity = level.getEntity(packet.entityId); Entity entity = level.getEntity(packet.entityId);
if (entity != null) { if (entity != null) {
Optional<SyncData2Manager.DataProvider<Entity, ISyncData<?>>> lookupOpt = Optional<SyncData2Manager.DataProvider<Entity, ISyncData<?>>> lookupOpt =
CommonEventHandler FabricCommonEventHandler
.getSyncData2Manager() .getSyncData2Manager()
.getDataProvider(packet.id); .getDataProvider(packet.id);
lookupOpt.flatMap(dataProvider -> dataProvider.getData(entity)) lookupOpt.flatMap(dataProvider -> dataProvider.getData(entity))

View File

@ -4,14 +4,14 @@ import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.players.PlayerList; import net.minecraft.server.players.PlayerList;
import top.r3944realms.lib39.core.event.CommonEventHandler; import top.r3944realms.lib39.core.event.FabricCommonEventHandler;
import top.r3944realms.lib39.core.network.toClient.SyncNBTLookupDataEntityS2CPacket; import top.r3944realms.lib39.core.network.toClient.SyncNBTLookupDataEntityS2CPacket;
import java.util.List; import java.util.List;
public interface IFabricUpdate extends IUpdate { public interface IFabricUpdate extends IUpdate {
default void update() { default void update() {
ServerLevel serverLevel = CommonEventHandler.getServerLevel(); ServerLevel serverLevel = FabricCommonEventHandler.getServerLevel();
if (serverLevel != null) { if (serverLevel != null) {
PlayerList playerList = serverLevel.getServer().getPlayerList(); PlayerList playerList = serverLevel.getServer().getPlayerList();
List<ServerPlayer> players = playerList.getPlayers(); List<ServerPlayer> players = playerList.getPlayers();

View File

@ -0,0 +1,37 @@
package top.r3944realms.lib39.core.sync;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.Tag;
import net.minecraft.world.entity.Entity;
import org.jetbrains.annotations.NotNull;
public interface ILib39SyncDataHolder {
CompoundTag lib39$getSyncData();
void lib39$setSyncData(CompoundTag tag);
default CompoundTag lib39$injectSaveSyncData(CompoundTag tag) {
if (lib39$getSyncData() != null && !lib39$getSyncData().isEmpty()) {
tag.put("Lib39Data", lib39$getSyncData());
}
return tag;
}
default void lib39$injectLoadSyncData(@NotNull CompoundTag tag) {
if (tag.contains("Lib39Data", Tag.TAG_COMPOUND)) {
lib39$setSyncData(tag.getCompound("Lib39Data"));
}
}
default void saveSyncData(@NotNull NBTEntitySyncData syncData) {
lib39$getSyncData().put(syncData.id.toDebugFileName(), syncData.serializeNBT());
}
default void loadSyncData(NBTEntitySyncData syncData) {
if (syncData != null && lib39$getSyncData().contains(syncData.id.toDebugFileName())) {
syncData.deserializeNBT(lib39$getSyncData().getCompound(syncData.id.toDebugFileName()));
}
}
static ILib39SyncDataHolder getHolder(Entity entity) {
return (ILib39SyncDataHolder) entity;
}
}

View File

@ -8,8 +8,14 @@ import org.jetbrains.annotations.Nullable;
import java.util.*; import java.util.*;
public class SyncData2LookupManager extends SyncData2Manager { public class SyncData2LookupManager extends SyncData2Manager<SyncData2LookupManager.TypedSyncEntry<? extends ISyncData<?>>> {
protected final Map<ResourceLocation, TypedSyncEntry<?>> typedEntries = Maps.newConcurrentMap(); protected final Map<ResourceLocation, TypedSyncEntry<?>> typedEntries = Maps.newConcurrentMap();
@Override
protected Map<ResourceLocation, TypedSyncEntry<?>> getTypedEntries() {
return typedEntries;
}
protected static class TypedSyncEntry<T extends ISyncData<?>> extends SyncData2Manager.TypedSyncEntry<Entity, T> { protected static class TypedSyncEntry<T extends ISyncData<?>> extends SyncData2Manager.TypedSyncEntry<Entity, T> {
/** /**
* Instantiates a new Typed sync entry for Fabric * Instantiates a new Typed sync entry for Fabric

View File

@ -0,0 +1,27 @@
package top.r3944realms.lib39.core.sync;
import net.fabricmc.fabric.api.lookup.v1.entity.EntityApiLookup;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.Entity;
import org.jetbrains.annotations.Nullable;
import top.r3944realms.lib39.core.event.FabricCommonEventHandler;
public abstract class SyncLookupProvider<T extends NBTEntitySyncData> implements EntityApiLookup.EntityApiProvider<T, Void> {
protected abstract T createEmptyLookup(Entity entity);
protected abstract ResourceLocation getId();
@SuppressWarnings("unchecked")
@Override
public @Nullable T find(Entity entity, Void context) {
return FabricCommonEventHandler.getSyncData2Manager().getManager(getId()).map(
objectISyncDataISyncManager -> {
ISyncData<?> iSyncData = objectISyncDataISyncManager.getSyncMap().get(entity.getUUID());
if (iSyncData instanceof NBTEntitySyncData syncData) {
return (T) syncData;
}
T defaultLookup = createEmptyLookup(entity);
ILib39SyncDataHolder.getHolder(entity).loadSyncData(defaultLookup);
return defaultLookup;
}
).orElse(createEmptyLookup(entity));
}
}

View File

@ -1,9 +1,9 @@
package top.r3944realms.lib39.example; package top.r3944realms.lib39.example;
import top.r3944realms.lib39.core.compat.CompatManager; import top.r3944realms.lib39.core.compat.CompatManager;
import top.r3944realms.lib39.example.core.compat.Lib39Compat; import top.r3944realms.lib39.example.core.compat.FabricLib39Compat;
import top.r3944realms.lib39.example.core.event.ExCommonEventHandler; import top.r3944realms.lib39.example.core.event.FabricExCommonEventHandler;
import top.r3944realms.lib39.example.core.network.ExNetworkHandler; import top.r3944realms.lib39.example.core.network.FabricExNetworkHandler;
import top.r3944realms.lib39.example.core.register.FabricExLib39Items; import top.r3944realms.lib39.example.core.register.FabricExLib39Items;
public class FabricLib39Example { public class FabricLib39Example {
@ -18,11 +18,11 @@ public class FabricLib39Example {
} }
} }
public void init() { public void init() {
ExCommonEventHandler.init(); FabricExCommonEventHandler.init();
FabricExLib39Items.init(); FabricExLib39Items.init();
ExNetworkHandler.registerServerReceivers(); FabricExNetworkHandler.registerServerReceivers();
CompatManager orCreateCompatManager = ExCommonEventHandler.getOrCreateCompatManager(); CompatManager orCreateCompatManager = FabricExCommonEventHandler.getOrCreateCompatManager();
orCreateCompatManager.registerCompat(Lib39Compat.ID, Lib39Compat.INSTANCE); orCreateCompatManager.registerCompat(FabricLib39Compat.ID, FabricLib39Compat.INSTANCE);
} }

View File

@ -19,7 +19,7 @@ import java.util.concurrent.atomic.AtomicReference;
* 测试同步数据实现 * 测试同步数据实现
*/ */
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class TestSyncData extends AbstractedTestSyncData implements IFabricUpdate { public class FabricTestSyncData extends AbstractedTestSyncData implements IFabricUpdate {
/** /**
* The constant ID. * The constant ID.
*/ */
@ -52,9 +52,10 @@ public class TestSyncData extends AbstractedTestSyncData implements IFabricUpdat
* *
* @param entity 关联的实体 * @param entity 关联的实体
*/ */
public TestSyncData(Entity entity) { public FabricTestSyncData(Entity entity) {
super(ID); super(ID);
this.self = entity; this.self = entity;
} }
/** /**
@ -63,7 +64,7 @@ public class TestSyncData extends AbstractedTestSyncData implements IFabricUpdat
* @param entityId 实体ID * @param entityId 实体ID
* @param self the self * @param self the self
*/ */
public TestSyncData(int entityId, Entity self) { public FabricTestSyncData(int entityId, Entity self) {
super(ID); super(ID);
this.self = self; this.self = self;
} }
@ -73,7 +74,7 @@ public class TestSyncData extends AbstractedTestSyncData implements IFabricUpdat
* *
* @param buf 字节缓冲区 * @param buf 字节缓冲区
*/ */
public TestSyncData(FriendlyByteBuf buf) { public FabricTestSyncData(FriendlyByteBuf buf) {
super(ID); super(ID);
this.self = null; // 实体在从数据包重建时可能为null需要在接收端设置 this.self = null; // 实体在从数据包重建时可能为null需要在接收端设置
fromBytes(buf); fromBytes(buf);
@ -154,8 +155,8 @@ public class TestSyncData extends AbstractedTestSyncData implements IFabricUpdat
* @return 新的 TestSyncData 实例 * @return 新的 TestSyncData 实例
*/ */
@Contract("_ -> new") @Contract("_ -> new")
public static @NotNull TestSyncData staticFromBytes(FriendlyByteBuf buf) { public static @NotNull FabricTestSyncData staticFromBytes(FriendlyByteBuf buf) {
return new TestSyncData(buf); return new FabricTestSyncData(buf);
} }
@Override @Override
@ -340,8 +341,8 @@ public class TestSyncData extends AbstractedTestSyncData implements IFabricUpdat
* *
* @return 不包含实体引用的副本 test sync data * @return 不包含实体引用的副本 test sync data
*/ */
public TestSyncData createNetworkCopy() { public FabricTestSyncData createNetworkCopy() {
TestSyncData copy = new TestSyncData((Entity) null); FabricTestSyncData copy = new FabricTestSyncData((Entity) null);
copy.testString = this.testString; copy.testString = this.testString;
copy.testInt = this.testInt; copy.testInt = this.testInt;
copy.testBoolean = this.testBoolean; copy.testBoolean = this.testBoolean;

View File

@ -0,0 +1,19 @@
package top.r3944realms.lib39.example.content.data;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.Entity;
import top.r3944realms.lib39.core.sync.SyncLookupProvider;
public class FabricTestSyncLookupProvider extends SyncLookupProvider<AbstractedTestSyncData> {
public static final FabricTestSyncLookupProvider INSTANCE = new FabricTestSyncLookupProvider();
@Override
protected AbstractedTestSyncData createEmptyLookup(Entity entity) {
return new FabricTestSyncData(entity);
}
@Override
protected ResourceLocation getId() {
return FabricTestSyncData.ID;
}
}

View File

@ -1,7 +1,9 @@
package top.r3944realms.lib39.example.content.item; package top.r3944realms.lib39.example.content.item;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.fabricmc.fabric.api.lookup.v1.entity.EntityApiLookup; import net.fabricmc.fabric.api.lookup.v1.entity.EntityApiLookup;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
import net.fabricmc.fabric.impl.screenhandler.client.ClientNetworking;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
@ -11,18 +13,16 @@ import net.minecraft.world.entity.LivingEntity;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import top.r3944realms.lib39.Lib39; import top.r3944realms.lib39.Lib39;
import top.r3944realms.lib39.core.event.CommonEventHandler; import top.r3944realms.lib39.core.event.FabricCommonEventHandler;
import top.r3944realms.lib39.core.network.toClient.SyncNBTLookupDataEntityS2CPacket;
import top.r3944realms.lib39.example.content.data.AbstractedTestSyncData; import top.r3944realms.lib39.example.content.data.AbstractedTestSyncData;
import top.r3944realms.lib39.example.content.data.TestSyncData; import top.r3944realms.lib39.example.content.data.FabricTestSyncData;
import top.r3944realms.lib39.example.content.item.AbstractFabricItem; import top.r3944realms.lib39.example.core.network.FabricClientDataPacket;
import top.r3944realms.lib39.example.core.network.ClientDataPacket;
import java.util.List; import java.util.List;
public class FabricItem extends AbstractFabricItem { public class FabricFabricItem extends AbstractFabricItem {
public FabricItem(Properties properties) { public FabricFabricItem(Properties properties) {
super(properties); super(properties);
} }
@ -33,22 +33,15 @@ public class FabricItem extends AbstractFabricItem {
@Override @Override
protected void sendClientDataToServer(AbstractedTestSyncData clientData, int targetEntityId) { protected void sendClientDataToServer(AbstractedTestSyncData clientData, int targetEntityId) {
ServerLevel serverLevel = CommonEventHandler.getServerLevel(); if (ClientPlayNetworking.canSend(FabricClientDataPacket.TYPE)) {
if (serverLevel != null) { ClientPlayNetworking.send(new FabricClientDataPacket(clientData, targetEntityId));
PlayerList playerList = serverLevel.getServer().getPlayerList();
List<ServerPlayer> players = playerList.getPlayers();
for (ServerPlayer player : players) {
if (ServerPlayNetworking.canSend(player, ClientDataPacket.TYPE)) {
ServerPlayNetworking.send(player, new ClientDataPacket(clientData, targetEntityId));
}
}
} }
} }
public static @Nullable AbstractedTestSyncData getStaticData(Entity target) { public static @Nullable AbstractedTestSyncData getStaticData(Entity target) {
try { try {
AbstractedTestSyncData abstractData = EntityApiLookup.get(TestSyncData.ID, AbstractedTestSyncData.class, Void.class).find(target, null); AbstractedTestSyncData abstractData = EntityApiLookup.get(FabricTestSyncData.ID, AbstractedTestSyncData.class, Void.class).find(target, null);
if (abstractData instanceof TestSyncData) { if (abstractData instanceof FabricTestSyncData) {
return abstractData; return abstractData;
} }
} catch (Exception e) { } catch (Exception e) {

View File

@ -3,17 +3,16 @@ package top.r3944realms.lib39.example.content.item;
import net.fabricmc.fabric.api.lookup.v1.entity.EntityApiLookup; import net.fabricmc.fabric.api.lookup.v1.entity.EntityApiLookup;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import top.r3944realms.lib39.example.content.data.AbstractedTestSyncData; import top.r3944realms.lib39.example.content.data.AbstractedTestSyncData;
import top.r3944realms.lib39.example.content.data.TestSyncData; import top.r3944realms.lib39.example.content.data.FabricTestSyncData;
import top.r3944realms.lib39.example.content.item.AbstractNeoForgeItem;
public class NeoForgeItem extends AbstractNeoForgeItem { public class FabricNeoForgeItem extends AbstractNeoForgeItem {
public NeoForgeItem(Properties properties) { public FabricNeoForgeItem(Properties properties) {
super(properties); super(properties);
} }
@Override @Override
protected AbstractedTestSyncData getData(Entity entity) { protected AbstractedTestSyncData getData(Entity entity) {
return EntityApiLookup.get(TestSyncData.ID, AbstractedTestSyncData.class, null).find(entity, null); return EntityApiLookup.get(FabricTestSyncData.ID, AbstractedTestSyncData.class, Void.class).find(entity, null);
} }
} }

View File

@ -8,12 +8,12 @@ import top.r3944realms.lib39.core.compat.ICompat;
/** /**
* The type Lib 39 compat. * The type Lib 39 compat.
*/ */
public class Lib39Compat implements ICompat { public class FabricLib39Compat implements ICompat {
boolean initialized = false; boolean initialized = false;
/** /**
* The constant INSTANCE. * The constant INSTANCE.
*/ */
public static Lib39Compat INSTANCE = new Lib39Compat(); public static FabricLib39Compat INSTANCE = new FabricLib39Compat();
/** /**
* The constant ID. * The constant ID.
*/ */

View File

@ -3,13 +3,13 @@ package top.r3944realms.lib39.example.core.compat;
import top.r3944realms.lib39.Lib39; import top.r3944realms.lib39.Lib39;
import top.r3944realms.lib39.core.compat.CompatManager; import top.r3944realms.lib39.core.compat.CompatManager;
public class Lib39CompatManager extends CompatManager { public class FabricLib39CompatManager extends CompatManager {
/** /**
* Instantiates a new Compat manager. * Instantiates a new Compat manager.
* *
* @param path the path * @param path the path
*/ */
public Lib39CompatManager(String path) { public FabricLib39CompatManager(String path) {
super(Lib39.rl(path)); super(Lib39.rl(path));
} }
} }

View File

@ -1,19 +1,20 @@
package top.r3944realms.lib39.example.core.event; package top.r3944realms.lib39.example.core.event;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import top.r3944realms.lib39.api.callback.ActionResult; import top.r3944realms.lib39.api.callback.ActionResult;
import top.r3944realms.lib39.api.callback.SyncManagerRegisterCallback; import top.r3944realms.lib39.api.callback.SyncManagerRegisterCallback;
import top.r3944realms.lib39.core.compat.CompatManager; import top.r3944realms.lib39.core.compat.CompatManager;
import top.r3944realms.lib39.core.event.CommonEventHandler; import top.r3944realms.lib39.core.event.FabricCommonEventHandler;
import top.r3944realms.lib39.core.sync.CachedSyncManager; import top.r3944realms.lib39.core.sync.CachedSyncManager;
import top.r3944realms.lib39.example.content.data.AbstractedTestSyncData; import top.r3944realms.lib39.example.content.data.AbstractedTestSyncData;
import top.r3944realms.lib39.example.content.data.TestSyncData; import top.r3944realms.lib39.example.content.data.FabricTestSyncData;
import top.r3944realms.lib39.example.core.compat.Lib39CompatManager; import top.r3944realms.lib39.example.core.compat.FabricLib39CompatManager;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
public class ExCommonEventHandler { public class FabricExCommonEventHandler {
/** /**
* Gets compat manager. * Gets compat manager.
* *
@ -21,9 +22,9 @@ public class ExCommonEventHandler {
*/ */
public static CompatManager getOrCreateCompatManager() { public static CompatManager getOrCreateCompatManager() {
if (compatManager == null) { if (compatManager == null) {
synchronized (CommonEventHandler.class) { synchronized (FabricCommonEventHandler.class) {
if (compatManager == null) { if (compatManager == null) {
compatManager = new Lib39CompatManager("compat"); compatManager = new FabricLib39CompatManager("compat");
} }
} }
} }
@ -37,7 +38,7 @@ public class ExCommonEventHandler {
public static void init() { public static void init() {
SyncManagerRegisterCallback.EVENT.register(registrar -> { SyncManagerRegisterCallback.EVENT.register(registrar -> {
registrar.register( registrar.register(
TestSyncData.ID, FabricTestSyncData.ID,
new CachedSyncManager<>() { new CachedSyncManager<>() {
private final Map<Entity, AbstractedTestSyncData> syncDataMap = new ConcurrentHashMap<>(); private final Map<Entity, AbstractedTestSyncData> syncDataMap = new ConcurrentHashMap<>();
@ -48,6 +49,7 @@ public class ExCommonEventHandler {
}, },
AbstractedTestSyncData.class AbstractedTestSyncData.class
); );
registrar.allowEntityClass(FabricTestSyncData.ID, LivingEntity.class);
return ActionResult.PASS; return ActionResult.PASS;
}); });
} }

View File

@ -9,18 +9,18 @@ import net.minecraft.server.level.ServerPlayer;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import top.r3944realms.lib39.Lib39; import top.r3944realms.lib39.Lib39;
import top.r3944realms.lib39.example.content.data.AbstractedTestSyncData; import top.r3944realms.lib39.example.content.data.AbstractedTestSyncData;
import top.r3944realms.lib39.example.content.data.TestSyncData; import top.r3944realms.lib39.example.content.data.FabricTestSyncData;
import top.r3944realms.lib39.example.content.item.FabricItem; import top.r3944realms.lib39.example.content.item.FabricFabricItem;
/** /**
* The type Client data packet. * The type Client data packet.
*/ */
public class ClientDataPacket implements FabricPacket { public class FabricClientDataPacket implements FabricPacket {
public static final ResourceLocation CLIENT_TEST_DATA = public static final ResourceLocation CLIENT_TEST_DATA =
Lib39.rl("client_test_data"); Lib39.rl("client_test_data");
public static final PacketType<ClientDataPacket> TYPE = PacketType.create( public static final PacketType<FabricClientDataPacket> TYPE = PacketType.create(
CLIENT_TEST_DATA, CLIENT_TEST_DATA,
ClientDataPacket::new FabricClientDataPacket::new
); );
private final AbstractedTestSyncData clientData; private final AbstractedTestSyncData clientData;
private final int targetEntityId; private final int targetEntityId;
@ -31,7 +31,7 @@ public class ClientDataPacket implements FabricPacket {
* @param clientData the client data * @param clientData the client data
* @param targetEntityId the target entity id * @param targetEntityId the target entity id
*/ */
public ClientDataPacket(AbstractedTestSyncData clientData, int targetEntityId) { public FabricClientDataPacket(AbstractedTestSyncData clientData, int targetEntityId) {
this.clientData = clientData; this.clientData = clientData;
this.targetEntityId = targetEntityId; this.targetEntityId = targetEntityId;
} }
@ -41,8 +41,8 @@ public class ClientDataPacket implements FabricPacket {
* *
* @param buf the buf * @param buf the buf
*/ */
public ClientDataPacket(FriendlyByteBuf buf) { public FabricClientDataPacket(FriendlyByteBuf buf) {
this.clientData = TestSyncData.staticFromBytes(buf); this.clientData = FabricTestSyncData.staticFromBytes(buf);
this.targetEntityId = buf.readInt(); this.targetEntityId = buf.readInt();
} }
@ -58,7 +58,7 @@ public class ClientDataPacket implements FabricPacket {
return TYPE; return TYPE;
} }
public static void receive(@NotNull ClientDataPacket packet, @NotNull ServerPlayer serverPlayer, PacketSender packetSender) { public static void receive(@NotNull FabricClientDataPacket packet, @NotNull ServerPlayer serverPlayer, PacketSender packetSender) {
FabricItem.handleClientDataFromPacket(serverPlayer, packet.clientData, packet.targetEntityId); FabricFabricItem.handleClientDataFromPacket(serverPlayer, packet.clientData, packet.targetEntityId);
} }
} }

View File

@ -2,14 +2,14 @@ package top.r3944realms.lib39.example.core.network;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
public class ExNetworkHandler { public class FabricExNetworkHandler {
/** /**
* 注册服务器接收的数据包 * 注册服务器接收的数据包
*/ */
public static void registerServerReceivers() { public static void registerServerReceivers() {
ServerPlayNetworking.registerGlobalReceiver( ServerPlayNetworking.registerGlobalReceiver(
ClientDataPacket.TYPE, FabricClientDataPacket.TYPE,
ClientDataPacket::receive FabricClientDataPacket::receive
); );
} }
} }

View File

@ -2,23 +2,21 @@ package top.r3944realms.lib39.example.core.register;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import top.r3944realms.lib39.core.register.FabricLib39Items; import top.r3944realms.lib39.core.register.FabricLib39Items;
import top.r3944realms.lib39.core.register.Lib39Items; import top.r3944realms.lib39.example.content.item.FabricFabricItem;
import top.r3944realms.lib39.example.content.item.FabricItem;
import top.r3944realms.lib39.example.content.item.ForgeItem; import top.r3944realms.lib39.example.content.item.ForgeItem;
import top.r3944realms.lib39.example.content.item.NeoForgeItem; import top.r3944realms.lib39.example.content.item.FabricNeoForgeItem;
import top.r3944realms.lib39.example.core.register.ExLib39Items;
/** /**
* The type Ex lib 39 items. * The type Ex lib 39 items.
*/ */
public class FabricExLib39Items { public class FabricExLib39Items {
public static void init() { public static void init() {
ExLib39Items.FABRIC = FabricLib39Items.register("fabric", new FabricItem( ExLib39Items.FABRIC = FabricLib39Items.register("fabric", new FabricFabricItem(
new Item.Properties() new Item.Properties()
.stacksTo(1) .stacksTo(1)
.fireResistant() .fireResistant()
)); ));
ExLib39Items.NEOFORGE = FabricLib39Items.register("neoforge", new NeoForgeItem( ExLib39Items.NEOFORGE = FabricLib39Items.register("neoforge", new FabricNeoForgeItem(
new Item.Properties() new Item.Properties()
.stacksTo(1) .stacksTo(1)
.fireResistant() .fireResistant()

View File

@ -0,0 +1,52 @@
package top.r3944realms.lib39.mixin;
import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.entity.Entity;
import org.jetbrains.annotations.NotNull;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import top.r3944realms.lib39.core.event.FabricCommonEventHandler;
import top.r3944realms.lib39.core.sync.*;
import java.util.UUID;
@Mixin(Entity.class)
public abstract class MixinEntity implements ILib39SyncDataHolder {
@Shadow public abstract UUID getUUID();
@Unique
private CompoundTag lib39$syncData;
@Override
public CompoundTag lib39$getSyncData() {
if (lib39$syncData == null) {
lib39$syncData = new CompoundTag();
}
return lib39$syncData;
}
@Override
public void lib39$setSyncData(CompoundTag tag) {
this.lib39$syncData = tag;
}
@WrapMethod(method = "saveWithoutId")
private CompoundTag wrapSave(CompoundTag compound, @NotNull Operation<CompoundTag> original) {
FabricCommonEventHandler.getSyncData2Manager().forEach((id, manager) -> {
ISyncData<?> o = manager.getSyncMap().get(getUUID());
if (o instanceof NBTEntitySyncData syncData) {
saveSyncData(syncData);
}
});
return lib39$injectSaveSyncData(original.call(compound));
}
@WrapMethod(method = "load")
private void warpLoad(CompoundTag compound, @NotNull Operation<Void> original) {
original.call(compound);
lib39$injectLoadSyncData(compound);
}
}

View File

@ -3,7 +3,7 @@ package top.r3944realms.lib39.util;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
import net.minecraft.world.item.CreativeModeTab; import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import top.r3944realms.lib39.core.event.CommonEventHandler; import top.r3944realms.lib39.core.event.FabricCommonEventHandler;
import top.r3944realms.lib39.util.block.BlockRegistryBuilder; import top.r3944realms.lib39.util.block.BlockRegistryBuilder;
import java.util.function.Supplier; import java.util.function.Supplier;
@ -12,6 +12,6 @@ public class FabricBlockRegistryBuilder extends BlockRegistryBuilder {
@SafeVarargs @SafeVarargs
@Override @Override
protected final void registerBlockItem(Supplier<Block> blockObject, ResourceKey<CreativeModeTab>... creativeTabs) { protected final void registerBlockItem(Supplier<Block> blockObject, ResourceKey<CreativeModeTab>... creativeTabs) {
CommonEventHandler.addItemToTabs(blockObject, creativeTabs); FabricCommonEventHandler.addItemToTabs(blockObject, creativeTabs);
} }
} }

View File

@ -5,6 +5,7 @@
"refmap": "${mod_id}.fabric.refmap.json", "refmap": "${mod_id}.fabric.refmap.json",
"compatibilityLevel": "JAVA_17", "compatibilityLevel": "JAVA_17",
"mixins": [ "mixins": [
"MixinEntity",
"callback.MixinAnvilMenu", "callback.MixinAnvilMenu",
"callback.MixinDedicateServer" "callback.MixinDedicateServer"
], ],

View File

@ -3,6 +3,7 @@ package top.r3944realms.lib39;
import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import top.r3944realms.lib39.core.network.NetworkHandler;
import top.r3944realms.lib39.core.register.ForgeLib39BlockEntities; import top.r3944realms.lib39.core.register.ForgeLib39BlockEntities;
import top.r3944realms.lib39.core.register.ForgeLib39Blocks; import top.r3944realms.lib39.core.register.ForgeLib39Blocks;
import top.r3944realms.lib39.core.register.ForgeLib39Items; import top.r3944realms.lib39.core.register.ForgeLib39Items;
@ -32,6 +33,7 @@ public class Lib39Forge {
ForgeLib39Items.register(modEventBus); ForgeLib39Items.register(modEventBus);
ForgeLib39BlockEntities.register(modEventBus); ForgeLib39BlockEntities.register(modEventBus);
ForgeLib39SoundEvents.register(modEventBus); ForgeLib39SoundEvents.register(modEventBus);
NetworkHandler.register();
if (Lib39.shouldRegisterExamples()) { if (Lib39.shouldRegisterExamples()) {
Lib39.LOGGER.info("[Lib39-Forge] Registering Examples"); Lib39.LOGGER.info("[Lib39-Forge] Registering Examples");
registerExamples(); registerExamples();

View File

@ -1,11 +1,9 @@
package top.r3944realms.lib39.core.event; package top.r3944realms.lib39.core.event;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.event.level.LevelEvent; import net.minecraftforge.event.level.LevelEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import top.r3944realms.lib39.Lib39; import top.r3944realms.lib39.Lib39;
import top.r3944realms.lib39.util.ILevelHelper; import top.r3944realms.lib39.util.ILevelHelper;
@ -29,7 +27,7 @@ public class ServerEventHandler {
* @param event the event * @param event the event
*/ */
@SubscribeEvent @SubscribeEvent
public static void registerLayerDefinitions(LevelEvent.Load event) { public static void onLoadLevel(LevelEvent.Load event) {
if (event.getLevel() != null && event.getLevel() instanceof ServerLevel level) { if (event.getLevel() != null && event.getLevel() instanceof ServerLevel level) {
ILevelHelper.LevelHelper.SERVER.setLevel(level); ILevelHelper.LevelHelper.SERVER.setLevel(level);
} }
@ -41,7 +39,7 @@ public class ServerEventHandler {
* @param event the event * @param event the event
*/ */
@SubscribeEvent @SubscribeEvent
public static void registerLayerDefinitions(LevelEvent.Unload event) { public static void onUnloadLevel(LevelEvent.Unload event) {
if (event.getLevel() != null && event.getLevel() instanceof ServerLevel) { if (event.getLevel() != null && event.getLevel() instanceof ServerLevel) {
ILevelHelper.LevelHelper.SERVER.setLevel(null); ILevelHelper.LevelHelper.SERVER.setLevel(null);
} }

View File

@ -11,8 +11,14 @@ import java.util.*;
* The type Sync data 2 manager. * The type Sync data 2 manager.
*/ */
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class SyncData2CapManager extends SyncData2Manager { public class SyncData2CapManager extends SyncData2Manager<SyncData2CapManager.TypedSyncEntry<? extends ISyncData<?>>> {
protected final Map<ResourceLocation, TypedSyncEntry<?>> typedEntries = Maps.newConcurrentMap(); protected final Map<ResourceLocation, TypedSyncEntry<?>> typedEntries = Maps.newConcurrentMap();
@Override
protected Map<ResourceLocation, TypedSyncEntry<?>> getTypedEntries() {
return typedEntries;
}
protected static class TypedSyncEntry<T extends ISyncData<?>> extends SyncData2Manager.TypedSyncEntry<Capability<T>, T> { protected static class TypedSyncEntry<T extends ISyncData<?>> extends SyncData2Manager.TypedSyncEntry<Capability<T>, T> {
/** /**
* Instantiates a new Typed sync entry. * Instantiates a new Typed sync entry.

View File

@ -13,9 +13,9 @@ import top.r3944realms.lib39.example.content.data.TestSyncData;
import top.r3944realms.lib39.example.core.network.ClientDataPacket; import top.r3944realms.lib39.example.core.network.ClientDataPacket;
import top.r3944realms.lib39.example.core.network.ExNetworkHandler; import top.r3944realms.lib39.example.core.network.ExNetworkHandler;
public class FabricItem extends AbstractFabricItem { public class ForgeFabricItem extends AbstractFabricItem {
public FabricItem(Properties properties) { public ForgeFabricItem(Properties properties) {
super(properties); super(properties);
} }

View File

@ -7,9 +7,9 @@ import top.r3944realms.lib39.example.content.data.AbstractedTestSyncData;
import top.r3944realms.lib39.example.content.data.ExCapabilityHandler; import top.r3944realms.lib39.example.content.data.ExCapabilityHandler;
import top.r3944realms.lib39.example.content.data.TestSyncData; import top.r3944realms.lib39.example.content.data.TestSyncData;
public class NeoForgeItem extends AbstractNeoForgeItem{ public class ForgeNeoForgeItem extends AbstractNeoForgeItem{
public NeoForgeItem(Properties properties) { public ForgeNeoForgeItem(Properties properties) {
super(properties); super(properties);
} }

View File

@ -1,5 +1,6 @@
package top.r3944realms.lib39.example.core.event; package top.r3944realms.lib39.example.core.event;
import net.minecraft.world.entity.LivingEntity;
import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.RegisterCapabilitiesEvent; import net.minecraftforge.common.capabilities.RegisterCapabilitiesEvent;
@ -60,6 +61,7 @@ public class ExCommonEventHandler {
ExCapabilityHandler.TEST_CAP ExCapabilityHandler.TEST_CAP
); );
event.addAllowEntityClass(TestSyncData.ID, LivingEntity.class);
} }
} }

View File

@ -5,7 +5,7 @@ import net.minecraft.server.level.ServerPlayer;
import net.minecraftforge.network.NetworkEvent; import net.minecraftforge.network.NetworkEvent;
import top.r3944realms.lib39.example.content.data.AbstractedTestSyncData; import top.r3944realms.lib39.example.content.data.AbstractedTestSyncData;
import top.r3944realms.lib39.example.content.data.TestSyncData; import top.r3944realms.lib39.example.content.data.TestSyncData;
import top.r3944realms.lib39.example.content.item.FabricItem; import top.r3944realms.lib39.example.content.item.ForgeFabricItem;
import java.util.function.Supplier; import java.util.function.Supplier;
@ -65,6 +65,6 @@ public class ClientDataPacket {
} }
private void handleClientData(ServerPlayer player, AbstractedTestSyncData clientData, int targetEntityId) { private void handleClientData(ServerPlayer player, AbstractedTestSyncData clientData, int targetEntityId) {
FabricItem.handleClientDataFromPacket(player, clientData, targetEntityId); ForgeFabricItem.handleClientDataFromPacket(player, clientData, targetEntityId);
} }
} }

View File

@ -5,8 +5,9 @@ import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.registries.DeferredRegister; import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries; import net.minecraftforge.registries.ForgeRegistries;
import top.r3944realms.lib39.Lib39; import top.r3944realms.lib39.Lib39;
import top.r3944realms.lib39.example.content.item.FabricItem; import top.r3944realms.lib39.example.content.item.ForgeFabricItem;
import top.r3944realms.lib39.example.content.item.NeoForgeItem; import top.r3944realms.lib39.example.content.item.ForgeItem;
import top.r3944realms.lib39.example.content.item.ForgeNeoForgeItem;
/** /**
* The type Ex lib 39 items. * The type Ex lib 39 items.
@ -20,7 +21,7 @@ public class ForgeExLib39Items {
static { static {
ExLib39Items.FABRIC = ITEMS.register( ExLib39Items.FABRIC = ITEMS.register(
"fabric", "fabric",
() -> new FabricItem( () -> new ForgeFabricItem(
new Item.Properties() new Item.Properties()
.stacksTo(1) .stacksTo(1)
.fireResistant() .fireResistant()
@ -28,14 +29,14 @@ public class ForgeExLib39Items {
); );
ExLib39Items.NEOFORGE = ExLib39Items.NEOFORGE =
ITEMS.register("neoforge", ITEMS.register("neoforge",
() -> new NeoForgeItem( () -> new ForgeNeoForgeItem(
new Item.Properties() new Item.Properties()
.stacksTo(1) .stacksTo(1)
.fireResistant() .fireResistant()
)); ));
ExLib39Items.FORGE = ExLib39Items.FORGE =
ITEMS.register("forge", ITEMS.register("forge",
() -> new NeoForgeItem( () -> new ForgeItem(
new Item.Properties() new Item.Properties()
.stacksTo(1) .stacksTo(1)
.fireResistant() .fireResistant()