LibJF/libjf-config-network-v0/src/main/java/io/gitlab/jfronny/libjf/config/impl/network/server/JfConfigNetworkServer.java

202 lines
9.2 KiB
Java

package io.gitlab.jfronny.libjf.config.impl.network.server;
import io.gitlab.jfronny.libjf.config.api.v2.*;
import io.gitlab.jfronny.libjf.config.api.v2.type.Type;
import io.gitlab.jfronny.libjf.config.impl.network.packet.ConfigurationCompletePacket;
import io.gitlab.jfronny.libjf.config.impl.network.packet.ConfigurationPacket;
import io.gitlab.jfronny.libjf.config.impl.network.RequestRouter;
import io.gitlab.jfronny.libjf.config.impl.network.rci.entry.Datatype;
import io.gitlab.jfronny.libjf.config.impl.network.rci.entry.MirrorEntryInfo;
import net.fabricmc.fabric.api.networking.v1.*;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.network.packet.Packet;
import net.minecraft.server.network.ServerPlayerConfigurationTask;
import net.minecraft.server.network.ServerPlayerEntity;
import java.util.*;
import java.util.function.Consumer;
public class JfConfigNetworkServer {
public static void initialize() {
ServerPlayNetworking.registerGlobalReceiver(RequestRouter.REQUEST_ID, (server, player, handler, buf, responseSender) -> {
if (authenticate(player)) RequestRouter.acceptRequest(buf, responseSender);
else RequestRouter.deny(buf, responseSender);
});
ServerPlayNetworking.registerGlobalReceiver(RequestRouter.RESPONSE_ID, (server, player, handler, buf, responseSender) -> {
if (authenticate(player)) RequestRouter.acceptResponse(buf, responseSender);
else RequestRouter.deny(buf, responseSender);
});
ServerConfigurationNetworking.registerGlobalReceiver(ConfigurationCompletePacket.PACKET_TYPE, (packet, networkHandler, responseSender) -> {
networkHandler.completeTask(JfConfigNetworkConfigurationTask.KEY);
});
ServerConfigurationConnectionEvents.CONFIGURE.register((handler, server) -> {
if (ServerConfigurationNetworking.canSend(handler, ConfigurationPacket.PACKET_TYPE)) {
handler.addTask(new JfConfigNetworkConfigurationTask());
}
});
registerRPC();
}
public record JfConfigNetworkConfigurationTask() implements ServerPlayerConfigurationTask {
public static final Key KEY = new Key(ConfigurationPacket.ID.toString());
@Override
public void sendPacket(Consumer<Packet<?>> sender) {
sender.accept(ServerConfigurationNetworking.createS2CPacket(new ConfigurationPacket(RequestRouter.PROTOCOL_VERSION)));
}
@Override
public Key getKey() {
return KEY;
}
}
public static void registerRPC() {
ConfigHolder ch = ConfigHolder.getInstance();
RequestRouter.registerHandler("getRegistered", (buf, followupSender) -> {
PacketByteBuf resp = PacketByteBufs.create();
resp.writeCollection(ch.getRegistered().keySet(), PacketByteBuf::writeString);
return resp;
});
RequestRouter.registerHandler("isRegistered", (buf, followupSender) -> {
PacketByteBuf resp = PacketByteBufs.create();
resp.writeBoolean(ch.isRegistered(buf.readString()));
return resp;
});
RequestRouter.registerHandler("migrateFiles", (buf, followupSender) -> {
ch.migrateFiles(buf.readString());
return null;
});
RequestRouter.registerHandler("load", (buf, followupSender) -> {
readInstance(ch, buf).load();
return null;
});
RequestRouter.registerHandler("write", (buf, followupSender) -> {
readInstance(ch, buf).write();
return null;
});
RequestRouter.registerHandler("getPresets", (buf, followupSender) -> {
PacketByteBuf resp = PacketByteBufs.create();
resp.writeCollection(readCategory(ch, buf).getPresets().keySet(), PacketByteBuf::writeString);
return resp;
});
RequestRouter.registerHandler("runPreset", (buf, followupSender) -> {
Objects.requireNonNull(readCategory(ch, buf).getPresets().get(buf.readString())).run();
return null;
});
RequestRouter.registerHandler("getReferencedConfigs", (buf, followupSender) -> {
PacketByteBuf resp = PacketByteBufs.create();
resp.writeCollection(readCategory(ch, buf).getReferencedConfigs(), (b, ci) -> {
b.writeBoolean(Objects.equals(ch.get(ci.getId()), ci));
b.writeString(ci.getId());
});
return resp;
});
RequestRouter.registerHandler("getCategories", (buf, followupSender) -> {
PacketByteBuf resp = PacketByteBufs.create();
resp.writeCollection(readCategory(ch, buf).getCategories().keySet(), PacketByteBuf::writeString);
return resp;
});
RequestRouter.registerHandler("getEntries", (buf, followupSender) -> {
PacketByteBuf resp = PacketByteBufs.create();
resp.writeCollection(readCategory(ch, buf).getEntries(), (b, s) -> {
b.writeString(s.getName());
if (s.supportsRepresentation()) {
Type type = s.getValueType();
boolean foundType = true;
if (type.isInt()) {
b.writeInt(Datatype.INT.ordinal());
} else if (type.isLong()) {
b.writeInt(Datatype.LONG.ordinal());
} else if (type.isFloat()) {
b.writeInt(Datatype.FLOAT.ordinal());
} else if (type.isDouble()) {
b.writeInt(Datatype.DOUBLE.ordinal());
} else if (type.isString()) {
b.writeInt(Datatype.STRING.ordinal());
} else if (type.isBool()) {
b.writeInt(Datatype.BOOL.ordinal());
} else if (type.isEnum()) {
b.writeInt(Datatype.ENUM.ordinal());
b.writeCollection(Arrays.stream(type.asEnum().options()).map(Object::toString).toList(), PacketByteBuf::writeString);
} else {
foundType = false;
b.writeInt(-1);
}
if (foundType) {
MirrorEntryInfo.write(b, type, s.getDefault());
b.writeInt(s.getWidth());
b.writeDouble(s.getMinValue());
b.writeDouble(s.getMaxValue());
}
} else {
b.writeInt(-1);
}
});
return resp;
});
RequestRouter.registerHandler("fixEntry", (buf, followupSender) -> {
readEntry(ch, buf).fix();
return null;
});
RequestRouter.registerHandler("resetEntry", (buf, followupSender) -> {
readEntry(ch, buf).reset();
return null;
});
RequestRouter.registerHandler("getEntryValue", (buf, followupSender) -> {
PacketByteBuf resp = PacketByteBufs.create();
EntryInfo entryInfo = readEntry(ch, buf);
MirrorEntryInfo.write(resp, entryInfo.getValueType(), entryInfo.getValue());
return resp;
});
RequestRouter.registerHandler("setEntryValue", (buf, followupSender) -> {
EntryInfo entryInfo = readEntry(ch, buf);
entryInfo.setValue(MirrorEntryInfo.read(buf, entryInfo.getValueType()));
return null;
});
}
private static ConfigInstance readInstance(ConfigHolder ch, PacketByteBuf buf) {
List<List<String>> parentPaths = buf.readList(s -> s.readList(PacketByteBuf::readString));
String id = buf.readString();
if (parentPaths.isEmpty()) return Objects.requireNonNull(ch.get(id));
parentPaths = new LinkedList<>(parentPaths);
ConfigCategory ci = null;
for (List<String> parentPath : parentPaths) {
ci = ci == null
? ch.get(parentPath.get(0))
: getReferencedConfig(ci, parentPath.get(0));
for (String segment : parentPath.subList(1, parentPath.size() - 1)) {
ci = Objects.requireNonNull(ci.getCategories().get(segment));
}
}
return getReferencedConfig(Objects.requireNonNull(ci), id);
}
private static ConfigInstance getReferencedConfig(ConfigCategory category, String id) {
return category.getReferencedConfigs()
.stream()
.filter(s -> s.getId().equals(id))
.findFirst()
.orElseThrow();
}
private static ConfigCategory readCategory(ConfigHolder ch, PacketByteBuf buf) {
ConfigCategory result = readInstance(ch, buf);
for (String s : buf.readList(PacketByteBuf::readString)) {
result = Objects.requireNonNull(result.getCategories().get(s));
}
return result;
}
private static EntryInfo readEntry(ConfigHolder ch, PacketByteBuf buf) {
ConfigCategory cat = readCategory(ch, buf);
String name = buf.readString();
return cat.getEntries().stream().filter(s -> s.getName().equals(name)).findFirst().orElseThrow();
}
private static boolean authenticate(ServerPlayerEntity player) {
return player.hasPermissionLevel(2);
}
}