changes to run on non dedicated servers as well

This commit is contained in:
Frank Bauer 2021-07-29 10:01:02 +02:00
parent 7632c4e498
commit 2260d547dc
11 changed files with 99 additions and 72 deletions

View file

@ -6,6 +6,8 @@ import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import ru.bclib.api.TagAPI; import ru.bclib.api.TagAPI;
import ru.bclib.api.WorldDataAPI; import ru.bclib.api.WorldDataAPI;
import ru.bclib.api.dataexchange.DataExchangeAPI;
import ru.bclib.api.dataexchange.TestHandler;
import ru.bclib.config.Configs; import ru.bclib.config.Configs;
import ru.bclib.recipes.CraftingRecipes; import ru.bclib.recipes.CraftingRecipes;
import ru.bclib.registry.BaseBlockEntities; import ru.bclib.registry.BaseBlockEntities;
@ -26,6 +28,7 @@ public class BCLib implements ModInitializer {
CraftingRecipes.init(); CraftingRecipes.init();
WorldDataAPI.registerModCache(MOD_ID); WorldDataAPI.registerModCache(MOD_ID);
Configs.save(); Configs.save();
DataExchangeAPI.registerDescriptor(TestHandler.DESCRIPTOR);
} }
public static boolean isDevEnvironment() { public static boolean isDevEnvironment() {

View file

@ -1,19 +1,16 @@
package ru.bclib.api.dataexchange; package ru.bclib.api.dataexchange;
import java.util.HashSet;
import java.util.Set; import java.util.Set;
abstract class Connector { abstract class Connector {
protected final DataExchangeAPI api; protected final DataExchangeAPI api;
protected final Set<DataHandlerDescriptor> descriptors;
Connector(DataExchangeAPI api) { Connector(DataExchangeAPI api) {
this.api = api; this.api = api;
descriptors = new HashSet<>();
} }
public abstract boolean onClient(); public abstract boolean onClient();
public void addDescriptor(DataHandlerDescriptor desc){ protected Set<DataHandlerDescriptor> getDescriptors(){
this.descriptors.add(desc); return api.descriptors;
} }
} }

View file

@ -28,25 +28,32 @@ class ConnectorClientside extends Connector {
BCLib.LOGGER.warning("Client changed!"); BCLib.LOGGER.warning("Client changed!");
} }
this.client = client; this.client = client;
for(DataHandlerDescriptor desc : descriptors){ for(DataHandlerDescriptor desc : getDescriptors()){
ClientPlayNetworking.registerReceiver(desc.identifier, (_client, _handler, _buf, _responseSender)->{ ClientPlayNetworking.registerReceiver(desc.IDENTIFIER, (_client, _handler, _buf, _responseSender)->{
receiveFromServer(desc, _client, _handler, _buf, _responseSender); receiveFromServer(desc, _client, _handler, _buf, _responseSender);
}); });
} }
} }
void onPlayReady(ClientPacketListener handler, PacketSender sender, Minecraft client){ void onPlayReady(ClientPacketListener handler, PacketSender sender, Minecraft client){
for(DataHandlerDescriptor desc : getDescriptors()){
if (desc.sendOnJoin){
DataHandler h = desc.JOIN_INSTANCE.get();
if (!h.getOriginatesOnServer()) {
h.sendToServer(client);
}
}
}
} }
void onPlayDisconnect(ClientPacketListener handler, Minecraft client){ void onPlayDisconnect(ClientPacketListener handler, Minecraft client){
for(DataHandlerDescriptor desc : descriptors) { for(DataHandlerDescriptor desc : getDescriptors()) {
ClientPlayNetworking.unregisterReceiver(desc.identifier); ClientPlayNetworking.unregisterReceiver(desc.IDENTIFIER);
} }
} }
void receiveFromServer(DataHandlerDescriptor desc, Minecraft client, ClientPacketListener handler, FriendlyByteBuf buf, PacketSender responseSender){ void receiveFromServer(DataHandlerDescriptor desc, Minecraft client, ClientPacketListener handler, FriendlyByteBuf buf, PacketSender responseSender){
DataHandler h = desc.instancer.get(); DataHandler h = desc.INSTANCE.get();
h.receiveFromServer(client, handler, buf, responseSender); h.receiveFromServer(client, handler, buf, responseSender);
} }

View file

@ -1,7 +1,5 @@
package ru.bclib.api.dataexchange; package ru.bclib.api.dataexchange;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.networking.v1.PacketSender; import net.fabricmc.fabric.api.networking.v1.PacketSender;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.FriendlyByteBuf;
@ -10,7 +8,6 @@ import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.network.ServerGamePacketListenerImpl; import net.minecraft.server.network.ServerGamePacketListenerImpl;
import ru.bclib.BCLib; import ru.bclib.BCLib;
@Environment(EnvType.SERVER)
class ConnectorServerside extends Connector { class ConnectorServerside extends Connector {
private MinecraftServer server; private MinecraftServer server;
ConnectorServerside(DataExchangeAPI api) { ConnectorServerside(DataExchangeAPI api) {
@ -28,30 +25,32 @@ class ConnectorServerside extends Connector {
BCLib.LOGGER.warning("Server changed!"); BCLib.LOGGER.warning("Server changed!");
} }
this.server = server; this.server = server;
for(DataHandlerDescriptor desc : descriptors){ for(DataHandlerDescriptor desc : getDescriptors()){
ServerPlayNetworking.registerReceiver(handler, desc.identifier, (_server, _player, _handler, _buf, _responseSender) -> { ServerPlayNetworking.registerReceiver(handler, desc.IDENTIFIER, (_server, _player, _handler, _buf, _responseSender) -> {
receiveFromClient(desc, _server, _player, _handler, _buf, _responseSender); receiveFromClient(desc, _server, _player, _handler, _buf, _responseSender);
}); });
} }
} }
void onPlayReady(ServerGamePacketListenerImpl handler, PacketSender sender, MinecraftServer server){ void onPlayReady(ServerGamePacketListenerImpl handler, PacketSender sender, MinecraftServer server){
for(DataHandlerDescriptor desc : descriptors){ for(DataHandlerDescriptor desc : getDescriptors()){
if (desc.sendOnJoin){ if (desc.sendOnJoin){
DataHandler h = desc.instancer.get(); DataHandler h = desc.JOIN_INSTANCE.get();
h.sendToClient(server, handler.player); if (h.getOriginatesOnServer()) {
h.sendToClient(server, handler.player);
}
} }
} }
} }
void onPlayDisconnect(ServerGamePacketListenerImpl handler, MinecraftServer server){ void onPlayDisconnect(ServerGamePacketListenerImpl handler, MinecraftServer server){
for(DataHandlerDescriptor desc : descriptors){ for(DataHandlerDescriptor desc : getDescriptors()){
ServerPlayNetworking.unregisterReceiver(handler, desc.identifier); ServerPlayNetworking.unregisterReceiver(handler, desc.IDENTIFIER);
} }
} }
void receiveFromClient(DataHandlerDescriptor desc, MinecraftServer server, ServerPlayer player, ServerGamePacketListenerImpl handler, FriendlyByteBuf buf, PacketSender responseSender){ void receiveFromClient(DataHandlerDescriptor desc, MinecraftServer server, ServerPlayer player, ServerGamePacketListenerImpl handler, FriendlyByteBuf buf, PacketSender responseSender){
DataHandler h = desc.instancer.get(); DataHandler h = desc.INSTANCE.get();
h.receiveFromClient(server, player, handler, buf, responseSender); h.receiveFromClient(server, player, handler, buf, responseSender);
} }

View file

@ -5,57 +5,62 @@ import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents;
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents; import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
import java.util.HashSet;
import java.util.Set;
public class DataExchangeAPI { public class DataExchangeAPI {
private static DataExchangeAPI instance; private static DataExchangeAPI instance;
private final ConnectorServerside server; private ConnectorServerside server;
private final ConnectorClientside client; private ConnectorClientside client;
protected final Set<DataHandlerDescriptor> descriptors;
private DataExchangeAPI(){
descriptors = new HashSet<>();
}
public static DataExchangeAPI getInstance(){ public static DataExchangeAPI getInstance(){
return instance;
}
private static DataExchangeAPI getOrCreateInstance(boolean isClient){
if (instance==null){ if (instance==null){
instance = new DataExchangeAPI(isClient); instance = new DataExchangeAPI();
} }
return instance; return instance;
} }
private DataExchangeAPI(boolean isClient){ @Environment(EnvType.CLIENT)
if (isClient){ private void initClientside(){
client = new ConnectorClientside(this); if (client!=null) return;
server = null; client = new ConnectorClientside(this);
ClientPlayConnectionEvents.INIT.register(client::onPlayInit); ClientPlayConnectionEvents.INIT.register(client::onPlayInit);
ClientPlayConnectionEvents.JOIN.register(client::onPlayReady); ClientPlayConnectionEvents.JOIN.register(client::onPlayReady);
ClientPlayConnectionEvents.DISCONNECT.register(client::onPlayDisconnect); ClientPlayConnectionEvents.DISCONNECT.register(client::onPlayDisconnect);
} else { }
client = null;
server = new ConnectorServerside(this); private void initServerSide(){
if (server!=null) return;
ServerPlayConnectionEvents.INIT.register(server::onPlayInit); server = new ConnectorServerside(this);
ServerPlayConnectionEvents.JOIN.register(server::onPlayReady);
ServerPlayConnectionEvents.DISCONNECT.register(server::onPlayDisconnect); ServerPlayConnectionEvents.INIT.register(server::onPlayInit);
} ServerPlayConnectionEvents.JOIN.register(server::onPlayReady);
ServerPlayConnectionEvents.DISCONNECT.register(server::onPlayDisconnect);
}
public static void registerDescriptor(DataHandlerDescriptor desc){
DataExchangeAPI api = DataExchangeAPI.getInstance();
api.descriptors.add(desc);
} }
@Environment(EnvType.CLIENT) @Environment(EnvType.CLIENT)
public static void registerClientsideHandler(DataHandlerDescriptor desc){ public static void prepareClientside(){
DataExchangeAPI api = DataExchangeAPI.getOrCreateInstance(true); DataExchangeAPI api = DataExchangeAPI.getInstance();
if (api.client == null){ api.initClientside();
throw new RuntimeException("[Internal Error] DataExchangeAPI was already created as a Server");
}
api.client.addDescriptor(desc);
} }
@Environment(EnvType.SERVER) public static void prepareServerside(){
public static void registerServersideHandler(DataHandlerDescriptor desc){ DataExchangeAPI api = DataExchangeAPI.getInstance();
DataExchangeAPI api = DataExchangeAPI.getOrCreateInstance(false); api.initServerSide();
if (api.server == null){
throw new RuntimeException("[Internal Error] DataExchangeAPI was already created as a Client");
}
api.server.addDescriptor(desc);
} }
public static void send(DataHandler h){ public static void send(DataHandler h){
@ -66,4 +71,5 @@ public class DataExchangeAPI {
} }
} }
} }

View file

@ -40,7 +40,6 @@ public abstract class DataHandler {
client.execute(() -> runOnClient(client)); client.execute(() -> runOnClient(client));
} }
@Environment(EnvType.SERVER)
void receiveFromClient(MinecraftServer server, ServerPlayer player, ServerGamePacketListenerImpl handler, FriendlyByteBuf buf, PacketSender responseSender){ void receiveFromClient(MinecraftServer server, ServerPlayer player, ServerGamePacketListenerImpl handler, FriendlyByteBuf buf, PacketSender responseSender){
deserializeFromIncomingData(buf, responseSender, true); deserializeFromIncomingData(buf, responseSender, true);
server.execute(() -> runOnServer(server)); server.execute(() -> runOnServer(server));
@ -54,7 +53,6 @@ public abstract class DataHandler {
} }
@Environment(EnvType.SERVER)
protected void runOnServer(MinecraftServer server){ protected void runOnServer(MinecraftServer server){
} }
@ -63,7 +61,6 @@ public abstract class DataHandler {
} }
@Environment(EnvType.SERVER)
void sendToClient(MinecraftServer server){ void sendToClient(MinecraftServer server){
FriendlyByteBuf buf = PacketByteBufs.create(); FriendlyByteBuf buf = PacketByteBufs.create();
serializeData(buf); serializeData(buf);
@ -73,7 +70,6 @@ public abstract class DataHandler {
} }
} }
@Environment(EnvType.SERVER)
void sendToClient(MinecraftServer server, ServerPlayer player){ void sendToClient(MinecraftServer server, ServerPlayer player){
FriendlyByteBuf buf = PacketByteBufs.create(); FriendlyByteBuf buf = PacketByteBufs.create();
serializeData(buf); serializeData(buf);

View file

@ -6,15 +6,22 @@ import java.util.function.Supplier;
public class DataHandlerDescriptor { public class DataHandlerDescriptor {
public DataHandlerDescriptor(ResourceLocation identifier, Supplier<DataHandler> instancer){ public DataHandlerDescriptor(ResourceLocation identifier, Supplier<DataHandler> instancer){
this(identifier, instancer, false); this(identifier, instancer, instancer, false);
} }
public DataHandlerDescriptor(ResourceLocation identifier, Supplier<DataHandler> instancer, boolean sendOnJoin){ public DataHandlerDescriptor(ResourceLocation identifier, Supplier<DataHandler> instancer, boolean sendOnJoin){
this.instancer = instancer; this(identifier, instancer, instancer, sendOnJoin);
this.identifier = identifier; }
public DataHandlerDescriptor(ResourceLocation identifier, Supplier<DataHandler> receiv_instancer, Supplier<DataHandler> join_instancer, boolean sendOnJoin){
this.INSTANCE = receiv_instancer;
this.JOIN_INSTANCE = join_instancer;
this.IDENTIFIER = identifier;
this.sendOnJoin = sendOnJoin; this.sendOnJoin = sendOnJoin;
} }
public final boolean sendOnJoin; public final boolean sendOnJoin;
public final ResourceLocation identifier; public final ResourceLocation IDENTIFIER;
public final Supplier<DataHandler> instancer; public final Supplier<DataHandler> INSTANCE;
public final Supplier<DataHandler> JOIN_INSTANCE;
} }

View file

@ -14,7 +14,7 @@ public class TestHandler extends DataHandler{
public static DataHandlerDescriptor DESCRIPTOR = new DataHandlerDescriptor(new ResourceLocation(BCLib.MOD_ID, "__test"), TestHandler::new, true); public static DataHandlerDescriptor DESCRIPTOR = new DataHandlerDescriptor(new ResourceLocation(BCLib.MOD_ID, "__test"), TestHandler::new, true);
public TestHandler() { public TestHandler() {
super(DESCRIPTOR.identifier, true); super(DESCRIPTOR.IDENTIFIER, true);
} }
@Override @Override

View file

@ -4,7 +4,6 @@ import net.fabricmc.api.ClientModInitializer;
import ru.bclib.api.ModIntegrationAPI; import ru.bclib.api.ModIntegrationAPI;
import ru.bclib.api.PostInitAPI; import ru.bclib.api.PostInitAPI;
import ru.bclib.api.dataexchange.DataExchangeAPI; import ru.bclib.api.dataexchange.DataExchangeAPI;
import ru.bclib.api.dataexchange.TestHandler;
import ru.bclib.registry.BaseBlockEntityRenders; import ru.bclib.registry.BaseBlockEntityRenders;
public class BCLibClient implements ClientModInitializer { public class BCLibClient implements ClientModInitializer {
@ -12,7 +11,7 @@ public class BCLibClient implements ClientModInitializer {
public void onInitializeClient() { public void onInitializeClient() {
ModIntegrationAPI.registerAll(); ModIntegrationAPI.registerAll();
BaseBlockEntityRenders.register(); BaseBlockEntityRenders.register();
DataExchangeAPI.registerClientsideHandler(TestHandler.DESCRIPTOR); DataExchangeAPI.prepareClientside();
PostInitAPI.postInit(true); PostInitAPI.postInit(true);
} }

View file

@ -1,12 +1,20 @@
package ru.bclib.mixin.common; package ru.bclib.mixin.common;
import com.mojang.authlib.GameProfileRepository;
import com.mojang.authlib.minecraft.MinecraftSessionService;
import com.mojang.datafixers.DataFixer;
import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.core.RegistryAccess.RegistryHolder;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.server.ServerResources; import net.minecraft.server.ServerResources;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.progress.ChunkProgressListenerFactory;
import net.minecraft.server.packs.repository.PackRepository;
import net.minecraft.server.players.GameProfileCache;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.storage.LevelStorageSource; import net.minecraft.world.level.storage.LevelStorageSource;
import net.minecraft.world.level.storage.LevelStorageSource.LevelStorageAccess;
import net.minecraft.world.level.storage.WorldData; import net.minecraft.world.level.storage.WorldData;
import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
@ -16,8 +24,10 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import ru.bclib.api.BiomeAPI; import ru.bclib.api.BiomeAPI;
import ru.bclib.api.dataexchange.DataExchangeAPI;
import ru.bclib.recipes.BCLRecipeManager; import ru.bclib.recipes.BCLRecipeManager;
import java.net.Proxy;
import java.util.Collection; import java.util.Collection;
import java.util.Map; import java.util.Map;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
@ -34,7 +44,10 @@ public class MinecraftServerMixin {
@Final @Final
@Shadow @Shadow
protected WorldData worldData; protected WorldData worldData;
@Inject(method = "<init>*", at = @At("TAIL"))
private void bclib_onServerInit(Thread thread, RegistryHolder registryHolder, LevelStorageAccess levelStorageAccess, WorldData worldData, PackRepository packRepository, Proxy proxy, DataFixer dataFixer, ServerResources serverResources, MinecraftSessionService minecraftSessionService, GameProfileRepository gameProfileRepository, GameProfileCache gameProfileCache, ChunkProgressListenerFactory chunkProgressListenerFactory, CallbackInfo ci){
DataExchangeAPI.prepareServerside();
}
@Inject(method="convertFromRegionFormatIfNeeded", at = @At("HEAD")) @Inject(method="convertFromRegionFormatIfNeeded", at = @At("HEAD"))
private static void bclib_applyPatches(LevelStorageSource.LevelStorageAccess session, CallbackInfo ci){ private static void bclib_applyPatches(LevelStorageSource.LevelStorageAccess session, CallbackInfo ci){

View file

@ -9,7 +9,7 @@ public class BCLibServer implements DedicatedServerModInitializer {
@Override @Override
public void onInitializeServer() { public void onInitializeServer() {
ModIntegrationAPI.registerAll(); ModIntegrationAPI.registerAll();
DataExchangeAPI.registerServersideHandler(TestHandler.DESCRIPTOR); DataExchangeAPI.prepareServerside();
PostInitAPI.postInit(false); PostInitAPI.postInit(false);
} }