202 lines
9.2 KiB
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);
|
|
}
|
|
}
|