Changed config format. Added serializers. Removed static fields from registry classes

This commit is contained in:
Nanit
2020-11-27 14:19:05 +02:00
parent fa27356bac
commit cc7009caf1
20 changed files with 661 additions and 442 deletions

View File

@@ -0,0 +1,34 @@
package ru.nanit.limbo.server;
import ru.nanit.limbo.connection.ClientConnection;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
public final class Connections {
private final Map<UUID, ClientConnection> connections;
public Connections(){
connections = new ConcurrentHashMap<>();
}
public Collection<ClientConnection> getAllConnections(){
return Collections.unmodifiableCollection(connections.values());
}
public int getCount(){
return connections.size();
}
public void addConnection(ClientConnection connection){
connections.put(connection.getUuid(), connection);
}
public void removeConnection(ClientConnection connection){
connections.remove(connection.getUuid());
}
}

View File

@@ -3,40 +3,43 @@ package ru.nanit.limbo.server;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import ru.nanit.limbo.LimboConfig;
import napi.configurate.serializing.NodeSerializers;
import ru.nanit.limbo.configuration.LimboConfig;
import ru.nanit.limbo.configuration.SocketAddressSerializer;
import ru.nanit.limbo.connection.ClientChannelInitializer;
import ru.nanit.limbo.connection.ClientConnection;
import ru.nanit.limbo.protocol.packets.play.PacketBossBar;
import ru.nanit.limbo.protocol.packets.play.PacketChatMessage;
import ru.nanit.limbo.server.data.*;
import ru.nanit.limbo.util.Logger;
import ru.nanit.limbo.world.DimensionRegistry;
import java.net.SocketAddress;
import java.nio.file.Paths;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public final class LimboServer {
private final Map<UUID, ClientConnection> connections = new ConcurrentHashMap<>();
private final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
private LimboConfig config;
private Connections connections;
private DimensionRegistry dimensionRegistry;
private PacketChatMessage joinMessage;
private PacketBossBar joinBossBar;
public int getConnectionsCount(){
return connections.size();
public LimboConfig getConfig(){
return config;
}
public void addConnection(ClientConnection connection){
connections.put(connection.getUuid(), connection);
public Connections getConnections(){
return connections;
}
public void removeConnection(ClientConnection connection){
connections.remove(connection.getUuid());
public DimensionRegistry getDimensionRegistry() {
return dimensionRegistry;
}
public PacketChatMessage getJoinMessage() {
@@ -50,47 +53,54 @@ public final class LimboServer {
public void start() throws Exception {
Logger.info("Starting server...");
LimboConfig.load(Paths.get("./settings.properties"));
DimensionRegistry.init(LimboConfig.getDimensionType());
NodeSerializers.register(SocketAddress.class, new SocketAddressSerializer());
NodeSerializers.register(InfoForwarding.class, new InfoForwarding.Serializer());
NodeSerializers.register(PingData.class, new PingData.Serializer());
NodeSerializers.register(BossBar.class, new BossBar.Serializer());
NodeSerializers.register(Position.class, new Position.Serializer());
initializeInGameData();
config = new LimboConfig(Paths.get("./"));
config.load();
Logger.setLevel(config.getDebugLevel());
dimensionRegistry = new DimensionRegistry();
dimensionRegistry.load(config.getDimensionType());
connections = new Connections();
initInGameData();
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
executor.scheduleAtFixedRate(this::broadcastKeepAlive, 0L, 5L, TimeUnit.SECONDS);
ServerBootstrap bootstrap = new ServerBootstrap()
new ServerBootstrap()
.group(new NioEventLoopGroup(), new NioEventLoopGroup())
.channel(NioServerSocketChannel.class)
.childHandler(new ClientChannelInitializer(this));
.childHandler(new ClientChannelInitializer(this))
.localAddress(config.getAddress())
.bind();
if (LimboConfig.getHost().isEmpty()){
bootstrap.bind(LimboConfig.getPort());
} else {
bootstrap.bind(LimboConfig.getHost(), LimboConfig.getPort());
}
Logger.info("Server started on %s:%d", LimboConfig.getHost(), LimboConfig.getPort());
Logger.info("Server started on %s", config.getAddress());
}
private void initializeInGameData(){
if (LimboConfig.getJoinMessages().getChatMessage() != null){
private void initInGameData(){
if (config.isUseJoinMessage()){
joinMessage = new PacketChatMessage();
joinMessage.setJsonData(LimboConfig.getJoinMessages().getChatMessage());
joinMessage.setJsonData(config.getJoinMessage());
joinMessage.setPosition(PacketChatMessage.Position.CHAT);
joinMessage.setSender(UUID.randomUUID());
}
if (LimboConfig.getJoinMessages().getBossBarText() != null){
if (config.isUseBossBar()){
joinBossBar = new PacketBossBar();
joinBossBar.setTitle(LimboConfig.getJoinMessages().getBossBarText());
joinBossBar.setHealth(LimboConfig.getJoinMessages().getBossBarHealth());
joinBossBar.setColor(LimboConfig.getJoinMessages().getBossBarColor());
joinBossBar.setDivision(LimboConfig.getJoinMessages().getBossBarDivision());
joinBossBar.setBossBar(config.getBossBar());
joinBossBar.setUuid(UUID.randomUUID());
}
}
private void broadcastKeepAlive(){
connections.values().forEach(ClientConnection::sendKeepAlive);
connections.getAllConnections().forEach(ClientConnection::sendKeepAlive);
}
}

View File

@@ -0,0 +1,119 @@
package ru.nanit.limbo.server.data;
import napi.configurate.data.ConfigNode;
import napi.configurate.serializing.NodeSerializer;
import napi.configurate.serializing.NodeSerializingException;
import ru.nanit.limbo.util.Colors;
public class BossBar {
private String text;
private float health;
private Color color;
private Division division;
public String getText() {
return text;
}
public float getHealth() {
return health;
}
public Color getColor() {
return color;
}
public Division getDivision() {
return division;
}
public void setText(String text) {
this.text = text;
}
public void setHealth(float health) {
this.health = health;
}
public void setColor(Color color) {
this.color = color;
}
public void setDivision(Division division) {
this.division = division;
}
public enum Color {
PINK(0),
BLUE(1),
RED(2),
GREEN(3),
YELLOW(4),
PURPLE(5),
WHITE(6);
private final int index;
Color(int index) {
this.index = index;
}
public int getIndex() {
return index;
}
}
public enum Division {
SOLID(0),
DASHES_6(1),
DASHES_10(2),
DASHES_12(3),
DASHES_20(4);
private final int index;
Division(int index) {
this.index = index;
}
public int getIndex() {
return index;
}
}
public static class Serializer implements NodeSerializer<BossBar>{
@Override
public BossBar deserialize(ConfigNode node) throws NodeSerializingException {
BossBar bossBar = new BossBar();
bossBar.setText(Colors.of(node.getNode("text").getString()));
bossBar.setHealth(node.getNode("health").getFloat());
if (bossBar.getHealth() < 0 || bossBar.getHealth() > 1)
throw new NodeSerializingException("BossBar health value must be between 0.0 and 1.0");
try {
bossBar.setColor(Color.valueOf(node.getNode("color").getString().toUpperCase()));
} catch (IllegalArgumentException e){
throw new NodeSerializingException("Invalid bossbar color");
}
try {
bossBar.setDivision(Division.valueOf(node.getNode("division").getString().toUpperCase()));
} catch (IllegalArgumentException e){
throw new NodeSerializingException("Invalid bossbar division");
}
return bossBar;
}
@Override
public void serialize(BossBar bossBar, ConfigNode configNode) {
}
}
}

View File

@@ -0,0 +1,53 @@
package ru.nanit.limbo.server.data;
import napi.configurate.data.ConfigNode;
import napi.configurate.serializing.NodeSerializer;
import napi.configurate.serializing.NodeSerializingException;
import java.util.Optional;
public class InfoForwarding {
private Type type;
private String secret;
public Type getType() {
return type;
}
public Optional<String> getSecret() {
return Optional.ofNullable(secret);
}
public enum Type {
NONE,
LEGACY,
MODERN
}
public static class Serializer implements NodeSerializer<InfoForwarding> {
@Override
public InfoForwarding deserialize(ConfigNode node) throws NodeSerializingException {
InfoForwarding forwarding = new InfoForwarding();
try {
forwarding.type = Type.valueOf(node.getNode("type").getString().toUpperCase());
} catch (IllegalArgumentException e){
throw new NodeSerializingException("Undefined info forwarding type");
}
if (forwarding.type == Type.MODERN){
forwarding.secret = node.getNode("secret").getString();
}
return forwarding;
}
@Override
public void serialize(InfoForwarding infoForwarding, ConfigNode configNode) throws NodeSerializingException {
}
}
}

View File

@@ -0,0 +1,43 @@
package ru.nanit.limbo.server.data;
import napi.configurate.data.ConfigNode;
import napi.configurate.serializing.NodeSerializer;
import ru.nanit.limbo.util.Colors;
public class PingData {
private String version;
private String description;
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public static class Serializer implements NodeSerializer<PingData> {
@Override
public PingData deserialize(ConfigNode node) {
PingData pingData = new PingData();
pingData.setDescription(Colors.of(node.getNode("description").getString()));
pingData.setVersion(Colors.of(node.getNode("version").getString()));
return pingData;
}
@Override
public void serialize(PingData pingData, ConfigNode configNode) {
}
}
}

View File

@@ -0,0 +1,72 @@
package ru.nanit.limbo.server.data;
import napi.configurate.data.ConfigNode;
import napi.configurate.serializing.NodeSerializer;
public class Position {
private double x;
private double y;
private double z;
private float yaw;
private float pitch;
public double getX() {
return x;
}
public double getY() {
return y;
}
public double getZ() {
return z;
}
public float getYaw() {
return yaw;
}
public float getPitch() {
return pitch;
}
public void setX(double x) {
this.x = x;
}
public void setY(double y) {
this.y = y;
}
public void setZ(double z) {
this.z = z;
}
public void setYaw(float yaw) {
this.yaw = yaw;
}
public void setPitch(float pitch) {
this.pitch = pitch;
}
public static class Serializer implements NodeSerializer<Position> {
@Override
public Position deserialize(ConfigNode node) {
Position position = new Position();
position.setX(node.getNode("x").getDouble());
position.setY(node.getNode("y").getDouble());
position.setZ(node.getNode("z").getDouble());
position.setYaw(node.getNode("yaw").getFloat());
position.setPitch(node.getNode("pitch").getFloat());
return position;
}
@Override
public void serialize(Position position, ConfigNode configNode) {
}
}
}