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

View File

@ -1,7 +1,7 @@
package top.r3944realms.lib39;
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.example.FabricLib39Example;
@ -15,7 +15,7 @@ public class Lib39Fabric implements ModInitializer {
FabricLib39Items.init();
FabricLib39BlockEntities.init();
FabricLib39SoundEvents.init();
CommonEventHandler.initCommon();
FabricCommonEventHandler.initCommon();
if (Lib39.shouldRegisterExamples()) {
Lib39.LOGGER.info("[Lib39-Fabric] Registering Examples");
registerExamples();

View File

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

View File

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

View File

@ -1,10 +1,9 @@
package top.r3944realms.lib39.core.network;
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;
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.NotNull;
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.NBTEntitySyncData;
import top.r3944realms.lib39.core.sync.SyncData2Manager;
@ -55,7 +55,7 @@ public record SyncNBTLookupDataEntityS2CPacket(int entityId, ResourceLocation id
Entity entity = level.getEntity(packet.entityId);
if (entity != null) {
Optional<SyncData2Manager.DataProvider<Entity, ISyncData<?>>> lookupOpt =
CommonEventHandler
FabricCommonEventHandler
.getSyncData2Manager()
.getDataProvider(packet.id);
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.ServerPlayer;
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 java.util.List;
public interface IFabricUpdate extends IUpdate {
default void update() {
ServerLevel serverLevel = CommonEventHandler.getServerLevel();
ServerLevel serverLevel = FabricCommonEventHandler.getServerLevel();
if (serverLevel != null) {
PlayerList playerList = serverLevel.getServer().getPlayerList();
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.*;
public class SyncData2LookupManager extends SyncData2Manager {
public class SyncData2LookupManager extends SyncData2Manager<SyncData2LookupManager.TypedSyncEntry<? extends ISyncData<?>>> {
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> {
/**
* 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;
import top.r3944realms.lib39.core.compat.CompatManager;
import top.r3944realms.lib39.example.core.compat.Lib39Compat;
import top.r3944realms.lib39.example.core.event.ExCommonEventHandler;
import top.r3944realms.lib39.example.core.network.ExNetworkHandler;
import top.r3944realms.lib39.example.core.compat.FabricLib39Compat;
import top.r3944realms.lib39.example.core.event.FabricExCommonEventHandler;
import top.r3944realms.lib39.example.core.network.FabricExNetworkHandler;
import top.r3944realms.lib39.example.core.register.FabricExLib39Items;
public class FabricLib39Example {
@ -18,11 +18,11 @@ public class FabricLib39Example {
}
}
public void init() {
ExCommonEventHandler.init();
FabricExCommonEventHandler.init();
FabricExLib39Items.init();
ExNetworkHandler.registerServerReceivers();
CompatManager orCreateCompatManager = ExCommonEventHandler.getOrCreateCompatManager();
orCreateCompatManager.registerCompat(Lib39Compat.ID, Lib39Compat.INSTANCE);
FabricExNetworkHandler.registerServerReceivers();
CompatManager orCreateCompatManager = FabricExCommonEventHandler.getOrCreateCompatManager();
orCreateCompatManager.registerCompat(FabricLib39Compat.ID, FabricLib39Compat.INSTANCE);
}

View File

@ -19,7 +19,7 @@ import java.util.concurrent.atomic.AtomicReference;
* 测试同步数据实现
*/
@SuppressWarnings("unused")
public class TestSyncData extends AbstractedTestSyncData implements IFabricUpdate {
public class FabricTestSyncData extends AbstractedTestSyncData implements IFabricUpdate {
/**
* The constant ID.
*/
@ -52,9 +52,10 @@ public class TestSyncData extends AbstractedTestSyncData implements IFabricUpdat
*
* @param entity 关联的实体
*/
public TestSyncData(Entity entity) {
public FabricTestSyncData(Entity entity) {
super(ID);
this.self = entity;
}
/**
@ -63,7 +64,7 @@ public class TestSyncData extends AbstractedTestSyncData implements IFabricUpdat
* @param entityId 实体ID
* @param self the self
*/
public TestSyncData(int entityId, Entity self) {
public FabricTestSyncData(int entityId, Entity self) {
super(ID);
this.self = self;
}
@ -73,7 +74,7 @@ public class TestSyncData extends AbstractedTestSyncData implements IFabricUpdat
*
* @param buf 字节缓冲区
*/
public TestSyncData(FriendlyByteBuf buf) {
public FabricTestSyncData(FriendlyByteBuf buf) {
super(ID);
this.self = null; // 实体在从数据包重建时可能为null需要在接收端设置
fromBytes(buf);
@ -154,8 +155,8 @@ public class TestSyncData extends AbstractedTestSyncData implements IFabricUpdat
* @return 新的 TestSyncData 实例
*/
@Contract("_ -> new")
public static @NotNull TestSyncData staticFromBytes(FriendlyByteBuf buf) {
return new TestSyncData(buf);
public static @NotNull FabricTestSyncData staticFromBytes(FriendlyByteBuf buf) {
return new FabricTestSyncData(buf);
}
@Override
@ -340,8 +341,8 @@ public class TestSyncData extends AbstractedTestSyncData implements IFabricUpdat
*
* @return 不包含实体引用的副本 test sync data
*/
public TestSyncData createNetworkCopy() {
TestSyncData copy = new TestSyncData((Entity) null);
public FabricTestSyncData createNetworkCopy() {
FabricTestSyncData copy = new FabricTestSyncData((Entity) null);
copy.testString = this.testString;
copy.testInt = this.testInt;
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;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.fabricmc.fabric.api.lookup.v1.entity.EntityApiLookup;
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.server.level.ServerLevel;
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.Nullable;
import top.r3944realms.lib39.Lib39;
import top.r3944realms.lib39.core.event.CommonEventHandler;
import top.r3944realms.lib39.core.network.toClient.SyncNBTLookupDataEntityS2CPacket;
import top.r3944realms.lib39.core.event.FabricCommonEventHandler;
import top.r3944realms.lib39.example.content.data.AbstractedTestSyncData;
import top.r3944realms.lib39.example.content.data.TestSyncData;
import top.r3944realms.lib39.example.content.item.AbstractFabricItem;
import top.r3944realms.lib39.example.core.network.ClientDataPacket;
import top.r3944realms.lib39.example.content.data.FabricTestSyncData;
import top.r3944realms.lib39.example.core.network.FabricClientDataPacket;
import java.util.List;
public class FabricItem extends AbstractFabricItem {
public class FabricFabricItem extends AbstractFabricItem {
public FabricItem(Properties properties) {
public FabricFabricItem(Properties properties) {
super(properties);
}
@ -33,22 +33,15 @@ public class FabricItem extends AbstractFabricItem {
@Override
protected void sendClientDataToServer(AbstractedTestSyncData clientData, int targetEntityId) {
ServerLevel serverLevel = CommonEventHandler.getServerLevel();
if (serverLevel != null) {
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));
}
}
if (ClientPlayNetworking.canSend(FabricClientDataPacket.TYPE)) {
ClientPlayNetworking.send(new FabricClientDataPacket(clientData, targetEntityId));
}
}
public static @Nullable AbstractedTestSyncData getStaticData(Entity target) {
try {
AbstractedTestSyncData abstractData = EntityApiLookup.get(TestSyncData.ID, AbstractedTestSyncData.class, Void.class).find(target, null);
if (abstractData instanceof TestSyncData) {
AbstractedTestSyncData abstractData = EntityApiLookup.get(FabricTestSyncData.ID, AbstractedTestSyncData.class, Void.class).find(target, null);
if (abstractData instanceof FabricTestSyncData) {
return abstractData;
}
} 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.minecraft.world.entity.Entity;
import top.r3944realms.lib39.example.content.data.AbstractedTestSyncData;
import top.r3944realms.lib39.example.content.data.TestSyncData;
import top.r3944realms.lib39.example.content.item.AbstractNeoForgeItem;
import top.r3944realms.lib39.example.content.data.FabricTestSyncData;
public class NeoForgeItem extends AbstractNeoForgeItem {
public class FabricNeoForgeItem extends AbstractNeoForgeItem {
public NeoForgeItem(Properties properties) {
public FabricNeoForgeItem(Properties properties) {
super(properties);
}
@Override
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.
*/
public class Lib39Compat implements ICompat {
public class FabricLib39Compat implements ICompat {
boolean initialized = false;
/**
* The constant INSTANCE.
*/
public static Lib39Compat INSTANCE = new Lib39Compat();
public static FabricLib39Compat INSTANCE = new FabricLib39Compat();
/**
* 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.core.compat.CompatManager;
public class Lib39CompatManager extends CompatManager {
public class FabricLib39CompatManager extends CompatManager {
/**
* Instantiates a new Compat manager.
*
* @param path the path
*/
public Lib39CompatManager(String path) {
public FabricLib39CompatManager(String path) {
super(Lib39.rl(path));
}
}

View File

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

View File

@ -9,18 +9,18 @@ import net.minecraft.server.level.ServerPlayer;
import org.jetbrains.annotations.NotNull;
import top.r3944realms.lib39.Lib39;
import top.r3944realms.lib39.example.content.data.AbstractedTestSyncData;
import top.r3944realms.lib39.example.content.data.TestSyncData;
import top.r3944realms.lib39.example.content.item.FabricItem;
import top.r3944realms.lib39.example.content.data.FabricTestSyncData;
import top.r3944realms.lib39.example.content.item.FabricFabricItem;
/**
* The type Client data packet.
*/
public class ClientDataPacket implements FabricPacket {
public class FabricClientDataPacket implements FabricPacket {
public static final ResourceLocation 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,
ClientDataPacket::new
FabricClientDataPacket::new
);
private final AbstractedTestSyncData clientData;
private final int targetEntityId;
@ -31,7 +31,7 @@ public class ClientDataPacket implements FabricPacket {
* @param clientData the client data
* @param targetEntityId the target entity id
*/
public ClientDataPacket(AbstractedTestSyncData clientData, int targetEntityId) {
public FabricClientDataPacket(AbstractedTestSyncData clientData, int targetEntityId) {
this.clientData = clientData;
this.targetEntityId = targetEntityId;
}
@ -41,8 +41,8 @@ public class ClientDataPacket implements FabricPacket {
*
* @param buf the buf
*/
public ClientDataPacket(FriendlyByteBuf buf) {
this.clientData = TestSyncData.staticFromBytes(buf);
public FabricClientDataPacket(FriendlyByteBuf buf) {
this.clientData = FabricTestSyncData.staticFromBytes(buf);
this.targetEntityId = buf.readInt();
}
@ -58,7 +58,7 @@ public class ClientDataPacket implements FabricPacket {
return TYPE;
}
public static void receive(@NotNull ClientDataPacket packet, @NotNull ServerPlayer serverPlayer, PacketSender packetSender) {
FabricItem.handleClientDataFromPacket(serverPlayer, packet.clientData, packet.targetEntityId);
public static void receive(@NotNull FabricClientDataPacket packet, @NotNull ServerPlayer serverPlayer, PacketSender packetSender) {
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;
public class ExNetworkHandler {
public class FabricExNetworkHandler {
/**
* 注册服务器接收的数据包
*/
public static void registerServerReceivers() {
ServerPlayNetworking.registerGlobalReceiver(
ClientDataPacket.TYPE,
ClientDataPacket::receive
FabricClientDataPacket.TYPE,
FabricClientDataPacket::receive
);
}
}

View File

@ -2,23 +2,21 @@ package top.r3944realms.lib39.example.core.register;
import net.minecraft.world.item.Item;
import top.r3944realms.lib39.core.register.FabricLib39Items;
import top.r3944realms.lib39.core.register.Lib39Items;
import top.r3944realms.lib39.example.content.item.FabricItem;
import top.r3944realms.lib39.example.content.item.FabricFabricItem;
import top.r3944realms.lib39.example.content.item.ForgeItem;
import top.r3944realms.lib39.example.content.item.NeoForgeItem;
import top.r3944realms.lib39.example.core.register.ExLib39Items;
import top.r3944realms.lib39.example.content.item.FabricNeoForgeItem;
/**
* The type Ex lib 39 items.
*/
public class FabricExLib39Items {
public static void init() {
ExLib39Items.FABRIC = FabricLib39Items.register("fabric", new FabricItem(
ExLib39Items.FABRIC = FabricLib39Items.register("fabric", new FabricFabricItem(
new Item.Properties()
.stacksTo(1)
.fireResistant()
));
ExLib39Items.NEOFORGE = FabricLib39Items.register("neoforge", new NeoForgeItem(
ExLib39Items.NEOFORGE = FabricLib39Items.register("neoforge", new FabricNeoForgeItem(
new Item.Properties()
.stacksTo(1)
.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.world.item.CreativeModeTab;
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 java.util.function.Supplier;
@ -12,6 +12,6 @@ public class FabricBlockRegistryBuilder extends BlockRegistryBuilder {
@SafeVarargs
@Override
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",
"compatibilityLevel": "JAVA_17",
"mixins": [
"MixinEntity",
"callback.MixinAnvilMenu",
"callback.MixinDedicateServer"
],

View File

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

View File

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

View File

@ -11,8 +11,14 @@ import java.util.*;
* The type Sync data 2 manager.
*/
@SuppressWarnings("unused")
public class SyncData2CapManager extends SyncData2Manager {
public class SyncData2CapManager extends SyncData2Manager<SyncData2CapManager.TypedSyncEntry<? extends ISyncData<?>>> {
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> {
/**
* Instantiates a new Typed sync entry.

View File

@ -33,7 +33,7 @@ public class ExCapabilityHandler {
*/
public static void attachCapability(@NotNull AttachCapabilitiesEvent<?> event) {
Object object = event.getObject();
if(object instanceof Entity entity ) {
if(object instanceof Entity entity) {
event.addCapability(TestSyncCapProvider.TEST_SYNC_REL, new TestSyncCapProvider(entity));
}
}

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.ExNetworkHandler;
public class FabricItem extends AbstractFabricItem {
public class ForgeFabricItem extends AbstractFabricItem {
public FabricItem(Properties properties) {
public ForgeFabricItem(Properties 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.TestSyncData;
public class NeoForgeItem extends AbstractNeoForgeItem{
public class ForgeNeoForgeItem extends AbstractNeoForgeItem{
public NeoForgeItem(Properties properties) {
public ForgeNeoForgeItem(Properties properties) {
super(properties);
}

View File

@ -1,5 +1,6 @@
package top.r3944realms.lib39.example.core.event;
import net.minecraft.world.entity.LivingEntity;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.RegisterCapabilitiesEvent;
@ -60,6 +61,7 @@ public class ExCommonEventHandler {
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 top.r3944realms.lib39.example.content.data.AbstractedTestSyncData;
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;
@ -65,6 +65,6 @@ public class ClientDataPacket {
}
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.ForgeRegistries;
import top.r3944realms.lib39.Lib39;
import top.r3944realms.lib39.example.content.item.FabricItem;
import top.r3944realms.lib39.example.content.item.NeoForgeItem;
import top.r3944realms.lib39.example.content.item.ForgeFabricItem;
import top.r3944realms.lib39.example.content.item.ForgeItem;
import top.r3944realms.lib39.example.content.item.ForgeNeoForgeItem;
/**
* The type Ex lib 39 items.
@ -20,7 +21,7 @@ public class ForgeExLib39Items {
static {
ExLib39Items.FABRIC = ITEMS.register(
"fabric",
() -> new FabricItem(
() -> new ForgeFabricItem(
new Item.Properties()
.stacksTo(1)
.fireResistant()
@ -28,14 +29,14 @@ public class ForgeExLib39Items {
);
ExLib39Items.NEOFORGE =
ITEMS.register("neoforge",
() -> new NeoForgeItem(
() -> new ForgeNeoForgeItem(
new Item.Properties()
.stacksTo(1)
.fireResistant()
));
ExLib39Items.FORGE =
ITEMS.register("forge",
() -> new NeoForgeItem(
() -> new ForgeItem(
new Item.Properties()
.stacksTo(1)
.fireResistant()