First network test
This commit is contained in:
parent
eda626fe10
commit
30b7c8043a
9 changed files with 382 additions and 0 deletions
19
src/main/java/ru/bclib/api/dataexchange/Connector.java
Normal file
19
src/main/java/ru/bclib/api/dataexchange/Connector.java
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
package ru.bclib.api.dataexchange;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
abstract class Connector {
|
||||||
|
protected final DataExchangeAPI api;
|
||||||
|
protected final Set<DataHandlerDescriptor> descriptors;
|
||||||
|
|
||||||
|
Connector(DataExchangeAPI api) {
|
||||||
|
this.api = api;
|
||||||
|
descriptors = new HashSet<>();
|
||||||
|
}
|
||||||
|
public abstract boolean onClient();
|
||||||
|
|
||||||
|
public void addDescriptor(DataHandlerDescriptor desc){
|
||||||
|
this.descriptors.add(desc);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
package ru.bclib.api.dataexchange;
|
||||||
|
|
||||||
|
import net.fabricmc.api.EnvType;
|
||||||
|
import net.fabricmc.api.Environment;
|
||||||
|
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
|
||||||
|
import net.fabricmc.fabric.api.networking.v1.PacketSender;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.multiplayer.ClientPacketListener;
|
||||||
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
|
import ru.bclib.BCLib;
|
||||||
|
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
class ConnectorClientside extends Connector {
|
||||||
|
private Minecraft client;
|
||||||
|
ConnectorClientside(DataExchangeAPI api) {
|
||||||
|
super(api);
|
||||||
|
this.client = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onClient() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void onPlayInit(ClientPacketListener handler, Minecraft client){
|
||||||
|
if (this.client!=null && this.client != client){
|
||||||
|
BCLib.LOGGER.warning("Client changed!");
|
||||||
|
}
|
||||||
|
this.client = client;
|
||||||
|
for(DataHandlerDescriptor desc : descriptors){
|
||||||
|
ClientPlayNetworking.registerReceiver(desc.identifier, (_client, _handler, _buf, _responseSender)->{
|
||||||
|
receiveFromServer(desc, _client, _handler, _buf, _responseSender);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onPlayReady(ClientPacketListener handler, PacketSender sender, Minecraft client){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void onPlayDisconnect(ClientPacketListener handler, Minecraft client){
|
||||||
|
for(DataHandlerDescriptor desc : descriptors) {
|
||||||
|
ClientPlayNetworking.unregisterReceiver(desc.identifier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void receiveFromServer(DataHandlerDescriptor desc, Minecraft client, ClientPacketListener handler, FriendlyByteBuf buf, PacketSender responseSender){
|
||||||
|
DataHandler h = desc.instancer.get();
|
||||||
|
h.receiveFromServer(client, handler, buf, responseSender);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendToServer(DataHandler h){
|
||||||
|
if (client==null){
|
||||||
|
throw new RuntimeException("[internal error] Client not initialized yet!");
|
||||||
|
}
|
||||||
|
h.sendToServer(this.client);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
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.ServerPlayNetworking;
|
||||||
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import net.minecraft.server.network.ServerGamePacketListenerImpl;
|
||||||
|
import ru.bclib.BCLib;
|
||||||
|
|
||||||
|
@Environment(EnvType.SERVER)
|
||||||
|
class ConnectorServerside extends Connector {
|
||||||
|
private MinecraftServer server;
|
||||||
|
ConnectorServerside(DataExchangeAPI api) {
|
||||||
|
super(api);
|
||||||
|
server = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onClient() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void onPlayInit(ServerGamePacketListenerImpl handler, MinecraftServer server){
|
||||||
|
if (this.server!=null && this.server != server){
|
||||||
|
BCLib.LOGGER.warning("Server changed!");
|
||||||
|
}
|
||||||
|
this.server = server;
|
||||||
|
for(DataHandlerDescriptor desc : descriptors){
|
||||||
|
ServerPlayNetworking.registerReceiver(handler, desc.identifier, (_server, _player, _handler, _buf, _responseSender) -> {
|
||||||
|
receiveFromClient(desc, _server, _player, _handler, _buf, _responseSender);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onPlayReady(ServerGamePacketListenerImpl handler, PacketSender sender, MinecraftServer server){
|
||||||
|
for(DataHandlerDescriptor desc : descriptors){
|
||||||
|
if (desc.sendOnJoin){
|
||||||
|
DataHandler h = desc.instancer.get();
|
||||||
|
h.sendToClient(server, handler.player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onPlayDisconnect(ServerGamePacketListenerImpl handler, MinecraftServer server){
|
||||||
|
for(DataHandlerDescriptor desc : descriptors){
|
||||||
|
ServerPlayNetworking.unregisterReceiver(handler, desc.identifier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void receiveFromClient(DataHandlerDescriptor desc, MinecraftServer server, ServerPlayer player, ServerGamePacketListenerImpl handler, FriendlyByteBuf buf, PacketSender responseSender){
|
||||||
|
DataHandler h = desc.instancer.get();
|
||||||
|
h.receiveFromClient(server, player, handler, buf, responseSender);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendToClient(DataHandler h){
|
||||||
|
if (server==null){
|
||||||
|
throw new RuntimeException("[internal error] Server not initialized yet!");
|
||||||
|
}
|
||||||
|
h.sendToClient(this.server);
|
||||||
|
}
|
||||||
|
}
|
69
src/main/java/ru/bclib/api/dataexchange/DataExchangeAPI.java
Normal file
69
src/main/java/ru/bclib/api/dataexchange/DataExchangeAPI.java
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
package ru.bclib.api.dataexchange;
|
||||||
|
|
||||||
|
import net.fabricmc.api.EnvType;
|
||||||
|
import net.fabricmc.api.Environment;
|
||||||
|
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents;
|
||||||
|
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
|
||||||
|
|
||||||
|
public class DataExchangeAPI {
|
||||||
|
private static DataExchangeAPI instance;
|
||||||
|
private final ConnectorServerside server;
|
||||||
|
private final ConnectorClientside client;
|
||||||
|
|
||||||
|
public static DataExchangeAPI getInstance(){
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static DataExchangeAPI getOrCreateInstance(boolean isClient){
|
||||||
|
if (instance==null){
|
||||||
|
instance = new DataExchangeAPI(isClient);
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
private DataExchangeAPI(boolean isClient){
|
||||||
|
if (isClient){
|
||||||
|
client = new ConnectorClientside(this);
|
||||||
|
server = null;
|
||||||
|
|
||||||
|
ClientPlayConnectionEvents.INIT.register(client::onPlayInit);
|
||||||
|
ClientPlayConnectionEvents.JOIN.register(client::onPlayReady);
|
||||||
|
ClientPlayConnectionEvents.DISCONNECT.register(client::onPlayDisconnect);
|
||||||
|
} else {
|
||||||
|
client = null;
|
||||||
|
server = new ConnectorServerside(this);
|
||||||
|
|
||||||
|
ServerPlayConnectionEvents.INIT.register(server::onPlayInit);
|
||||||
|
ServerPlayConnectionEvents.JOIN.register(server::onPlayReady);
|
||||||
|
ServerPlayConnectionEvents.DISCONNECT.register(server::onPlayDisconnect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
public static void registerClientsideHandler(DataHandlerDescriptor desc){
|
||||||
|
DataExchangeAPI api = DataExchangeAPI.getOrCreateInstance(true);
|
||||||
|
if (api.client == null){
|
||||||
|
throw new RuntimeException("[Internal Error] DataExchangeAPI was already created as a Server");
|
||||||
|
}
|
||||||
|
api.client.addDescriptor(desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Environment(EnvType.SERVER)
|
||||||
|
public static void registerServersideHandler(DataHandlerDescriptor desc){
|
||||||
|
DataExchangeAPI api = DataExchangeAPI.getOrCreateInstance(false);
|
||||||
|
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){
|
||||||
|
if (h.getOriginatesOnServer()){
|
||||||
|
DataExchangeAPI.getInstance().server.sendToClient(h);
|
||||||
|
} else {
|
||||||
|
DataExchangeAPI.getInstance().client.sendToServer(h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
111
src/main/java/ru/bclib/api/dataexchange/DataHandler.java
Normal file
111
src/main/java/ru/bclib/api/dataexchange/DataHandler.java
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
package ru.bclib.api.dataexchange;
|
||||||
|
|
||||||
|
import net.fabricmc.api.EnvType;
|
||||||
|
import net.fabricmc.api.Environment;
|
||||||
|
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
|
||||||
|
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
|
||||||
|
import net.fabricmc.fabric.api.networking.v1.PacketSender;
|
||||||
|
import net.fabricmc.fabric.api.networking.v1.PlayerLookup;
|
||||||
|
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.multiplayer.ClientPacketListener;
|
||||||
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import net.minecraft.server.network.ServerGamePacketListenerImpl;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public abstract class DataHandler {
|
||||||
|
private final boolean originatesOnServer;
|
||||||
|
@NotNull
|
||||||
|
private final ResourceLocation identifier;
|
||||||
|
|
||||||
|
protected DataHandler(ResourceLocation identifier, boolean originatesOnServer){
|
||||||
|
this.originatesOnServer = originatesOnServer;
|
||||||
|
this.identifier = identifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
final public boolean getOriginatesOnServer(){
|
||||||
|
return originatesOnServer;
|
||||||
|
}
|
||||||
|
|
||||||
|
final public ResourceLocation getIdentifier(){
|
||||||
|
return identifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
void receiveFromServer(Minecraft client, ClientPacketListener handler, FriendlyByteBuf buf, PacketSender responseSender){
|
||||||
|
deserializeFromIncomingData(buf, responseSender, false);
|
||||||
|
client.execute(() -> runOnClient(client));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Environment(EnvType.SERVER)
|
||||||
|
void receiveFromClient(MinecraftServer server, ServerPlayer player, ServerGamePacketListenerImpl handler, FriendlyByteBuf buf, PacketSender responseSender){
|
||||||
|
deserializeFromIncomingData(buf, responseSender, true);
|
||||||
|
server.execute(() -> runOnServer(server));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void deserializeFromIncomingData(FriendlyByteBuf buf, PacketSender responseSender, boolean fromClient){
|
||||||
|
}
|
||||||
|
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
protected void runOnClient(Minecraft client){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Environment(EnvType.SERVER)
|
||||||
|
protected void runOnServer(MinecraftServer server){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void serializeData(FriendlyByteBuf buf) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Environment(EnvType.SERVER)
|
||||||
|
void sendToClient(MinecraftServer server){
|
||||||
|
FriendlyByteBuf buf = PacketByteBufs.create();
|
||||||
|
serializeData(buf);
|
||||||
|
|
||||||
|
for (ServerPlayer player : PlayerLookup.all(server)) {
|
||||||
|
ServerPlayNetworking.send(player, this.identifier, buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Environment(EnvType.SERVER)
|
||||||
|
void sendToClient(MinecraftServer server, ServerPlayer player){
|
||||||
|
FriendlyByteBuf buf = PacketByteBufs.create();
|
||||||
|
serializeData(buf);
|
||||||
|
ServerPlayNetworking.send(player, this.identifier, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
void sendToServer(Minecraft client){
|
||||||
|
FriendlyByteBuf buf = PacketByteBufs.create();
|
||||||
|
serializeData(buf);
|
||||||
|
ClientPlayNetworking.send(identifier, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
DataHandler that = (DataHandler) o;
|
||||||
|
return originatesOnServer == that.originatesOnServer && identifier.equals(that.identifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int hash = identifier.hashCode();
|
||||||
|
if (originatesOnServer) hash |= 0x80000000;
|
||||||
|
else hash &=0x7FFFFFFF;
|
||||||
|
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "DataHandler{" + "originatesOnServer=" + originatesOnServer + ", identifier=" + identifier + '}';
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
package ru.bclib.api.dataexchange;
|
||||||
|
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public class DataHandlerDescriptor {
|
||||||
|
public DataHandlerDescriptor(ResourceLocation identifier, Supplier<DataHandler> instancer){
|
||||||
|
this(identifier, instancer, false);
|
||||||
|
}
|
||||||
|
public DataHandlerDescriptor(ResourceLocation identifier, Supplier<DataHandler> instancer, boolean sendOnJoin){
|
||||||
|
this.instancer = instancer;
|
||||||
|
this.identifier = identifier;
|
||||||
|
this.sendOnJoin = sendOnJoin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final boolean sendOnJoin;
|
||||||
|
public final ResourceLocation identifier;
|
||||||
|
public final Supplier<DataHandler> instancer;
|
||||||
|
}
|
33
src/main/java/ru/bclib/api/dataexchange/TestHandler.java
Normal file
33
src/main/java/ru/bclib/api/dataexchange/TestHandler.java
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
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.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import ru.bclib.BCLib;
|
||||||
|
|
||||||
|
public class TestHandler extends DataHandler{
|
||||||
|
public static DataHandlerDescriptor DESCRIPTOR = new DataHandlerDescriptor(new ResourceLocation(BCLib.MOD_ID, "__test"), TestHandler::new, true);
|
||||||
|
|
||||||
|
public TestHandler() {
|
||||||
|
super(DESCRIPTOR.identifier, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void deserializeFromIncomingData(FriendlyByteBuf buf, PacketSender responseSender, boolean fromClient) {
|
||||||
|
BCLib.LOGGER.info("PROCESSING INCOMING TEST-DATA fromClient="+fromClient);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
protected void runOnClient(Minecraft client) {
|
||||||
|
BCLib.LOGGER.info("RUNNING INCOMING TEST-DATA ON CLIENT");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void serializeData(FriendlyByteBuf buf) {
|
||||||
|
BCLib.LOGGER.info("BUILDING OUTGOING TEST-DATA ON SERVER");
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,6 +3,8 @@ package ru.bclib.client;
|
||||||
import net.fabricmc.api.ClientModInitializer;
|
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.TestHandler;
|
||||||
import ru.bclib.registry.BaseBlockEntityRenders;
|
import ru.bclib.registry.BaseBlockEntityRenders;
|
||||||
|
|
||||||
public class BCLibClient implements ClientModInitializer {
|
public class BCLibClient implements ClientModInitializer {
|
||||||
|
@ -10,6 +12,8 @@ public class BCLibClient implements ClientModInitializer {
|
||||||
public void onInitializeClient() {
|
public void onInitializeClient() {
|
||||||
ModIntegrationAPI.registerAll();
|
ModIntegrationAPI.registerAll();
|
||||||
BaseBlockEntityRenders.register();
|
BaseBlockEntityRenders.register();
|
||||||
|
DataExchangeAPI.registerClientsideHandler(TestHandler.DESCRIPTOR);
|
||||||
|
|
||||||
PostInitAPI.postInit(true);
|
PostInitAPI.postInit(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,11 +3,14 @@ package ru.bclib.server;
|
||||||
import net.fabricmc.api.DedicatedServerModInitializer;
|
import net.fabricmc.api.DedicatedServerModInitializer;
|
||||||
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.*;
|
||||||
|
|
||||||
public class BCLibServer implements DedicatedServerModInitializer {
|
public class BCLibServer implements DedicatedServerModInitializer {
|
||||||
@Override
|
@Override
|
||||||
public void onInitializeServer() {
|
public void onInitializeServer() {
|
||||||
ModIntegrationAPI.registerAll();
|
ModIntegrationAPI.registerAll();
|
||||||
|
DataExchangeAPI.registerServersideHandler(TestHandler.DESCRIPTOR);
|
||||||
|
|
||||||
PostInitAPI.postInit(false);
|
PostInitAPI.postInit(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue