mirror of
https://github.com/Nan1t/NanoLimbo.git
synced 2025-07-16 22:20:14 +02:00
Changed config format. Added serializers. Removed static fields from registry classes
This commit is contained in:
parent
fa27356bac
commit
cc7009caf1
@ -11,13 +11,15 @@ repositories {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
testCompile group: 'junit', name: 'junit', version: '4.12'
|
testCompile group: 'junit', name: 'junit', version: '4.12'
|
||||||
|
compile group: 'org.yaml', name: 'snakeyaml', version: '1.27'
|
||||||
|
compile files('libs/napi-configurate-yaml-1.0.jar')
|
||||||
compile group: 'io.netty', name: 'netty-all', version: '4.1.54.Final'
|
compile group: 'io.netty', name: 'netty-all', version: '4.1.54.Final'
|
||||||
compile group: 'net.kyori', name: 'adventure-nbt', version: '4.1.1'
|
compile group: 'net.kyori', name: 'adventure-nbt', version: '4.1.1'
|
||||||
}
|
}
|
||||||
|
|
||||||
jar {
|
jar {
|
||||||
manifest {
|
manifest {
|
||||||
attributes("Main-Class": "ru.nanit.limbo.NanoLimbo")
|
attributes('Main-Class': 'ru.nanit.limbo.NanoLimbo')
|
||||||
}
|
}
|
||||||
|
|
||||||
from {
|
from {
|
||||||
|
BIN
libs/napi-configurate-yaml-1.0.jar
Normal file
BIN
libs/napi-configurate-yaml-1.0.jar
Normal file
Binary file not shown.
@ -1,217 +0,0 @@
|
|||||||
package ru.nanit.limbo;
|
|
||||||
|
|
||||||
import ru.nanit.limbo.protocol.packets.play.PacketBossBar;
|
|
||||||
import ru.nanit.limbo.util.Colors;
|
|
||||||
import ru.nanit.limbo.util.Logger;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
public final class LimboConfig {
|
|
||||||
|
|
||||||
private static String host;
|
|
||||||
private static int port;
|
|
||||||
private static int maxPlayers;
|
|
||||||
private static String dimensionType;
|
|
||||||
private static SpawnPosition spawnPosition;
|
|
||||||
private static IpForwardingType ipForwardingType;
|
|
||||||
private static long readTimeout;
|
|
||||||
private static PingData pingData;
|
|
||||||
private static int debugLevel = 3;
|
|
||||||
private static JoinMessages joinMessages;
|
|
||||||
|
|
||||||
public static void load(Path file) throws IOException {
|
|
||||||
if (!Files.exists(file)){
|
|
||||||
Files.copy(NanoLimbo.getResource("/settings.properties"), file);
|
|
||||||
}
|
|
||||||
|
|
||||||
Properties props = new Properties();
|
|
||||||
props.load(Files.newInputStream(file));
|
|
||||||
|
|
||||||
host = props.getProperty("host");
|
|
||||||
port = Integer.parseInt(props.getProperty("port"));
|
|
||||||
|
|
||||||
maxPlayers = Integer.parseInt(props.getProperty("max-players"));
|
|
||||||
|
|
||||||
dimensionType = props.getProperty("dimension");
|
|
||||||
|
|
||||||
String[] posData = props.getProperty("spawn-position").split(",");
|
|
||||||
|
|
||||||
if (posData.length != 3){
|
|
||||||
throw new IOException("Invalid spawn position. Check it in the settings.properties file");
|
|
||||||
}
|
|
||||||
|
|
||||||
spawnPosition = new SpawnPosition(Double.parseDouble(posData[0]),
|
|
||||||
Double.parseDouble(posData[1]),
|
|
||||||
Double.parseDouble(posData[2]));
|
|
||||||
|
|
||||||
ipForwardingType = IpForwardingType.valueOf(props.getProperty("ip-forwarding").toUpperCase());
|
|
||||||
readTimeout = Long.parseLong(props.getProperty("read-timeout"));
|
|
||||||
|
|
||||||
pingData = new PingData();
|
|
||||||
pingData.setVersion(props.getProperty("ping-version"));
|
|
||||||
pingData.setDescription(Colors.of(props.getProperty("ping-description")));
|
|
||||||
|
|
||||||
debugLevel = Integer.parseInt(props.getProperty("debug-level"));
|
|
||||||
|
|
||||||
joinMessages = new JoinMessages();
|
|
||||||
|
|
||||||
if(props.containsKey("join-message")){
|
|
||||||
joinMessages.setChatMessage(Colors.of(props.getProperty("join-message")));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(props.containsKey("join-bossbar-text")){
|
|
||||||
joinMessages.setBossBarText(Colors.of(props.getProperty("join-bossbar-text")));
|
|
||||||
joinMessages.setBossBarHealth(Float.parseFloat(props.getProperty("join-bossbar-health")));
|
|
||||||
joinMessages.setBossBarColor(PacketBossBar.Color.valueOf(
|
|
||||||
props.getProperty("join-bossbar-color").toUpperCase()));
|
|
||||||
joinMessages.setBossBarDivision(PacketBossBar.Division.valueOf(
|
|
||||||
props.getProperty("join-bossbar-division").toUpperCase()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getHost() {
|
|
||||||
return host;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getPort() {
|
|
||||||
return port;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getMaxPlayers() {
|
|
||||||
return maxPlayers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getDimensionType() {
|
|
||||||
return dimensionType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static SpawnPosition getSpawnPosition() {
|
|
||||||
return spawnPosition;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IpForwardingType getIpForwardingType() {
|
|
||||||
return ipForwardingType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long getReadTimeout() {
|
|
||||||
return readTimeout;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PingData getPingData() {
|
|
||||||
return pingData;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getDebugLevel() {
|
|
||||||
return debugLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static JoinMessages getJoinMessages() {
|
|
||||||
return joinMessages;
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum IpForwardingType {
|
|
||||||
NONE,
|
|
||||||
LEGACY,
|
|
||||||
MODERN
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class SpawnPosition {
|
|
||||||
|
|
||||||
private final double x;
|
|
||||||
private final double y;
|
|
||||||
private final double z;
|
|
||||||
|
|
||||||
public SpawnPosition(double x, double y, double z) {
|
|
||||||
this.x = x;
|
|
||||||
this.y = y;
|
|
||||||
this.z = z;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getX() {
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getY() {
|
|
||||||
return y;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getZ() {
|
|
||||||
return z;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static 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 JoinMessages {
|
|
||||||
|
|
||||||
private String chatMessage;
|
|
||||||
private String bossBarText;
|
|
||||||
private float bossBarHealth;
|
|
||||||
private PacketBossBar.Color bossBarColor;
|
|
||||||
private PacketBossBar.Division bossBarDivision;
|
|
||||||
|
|
||||||
public String getChatMessage() {
|
|
||||||
return chatMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setChatMessage(String chatMessage) {
|
|
||||||
this.chatMessage = chatMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getBossBarText() {
|
|
||||||
return bossBarText;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBossBarText(String bossBarText) {
|
|
||||||
this.bossBarText = bossBarText;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getBossBarHealth() {
|
|
||||||
return bossBarHealth;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBossBarHealth(float bossBarHealth) {
|
|
||||||
this.bossBarHealth = bossBarHealth;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PacketBossBar.Color getBossBarColor() {
|
|
||||||
return bossBarColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBossBarColor(PacketBossBar.Color bossBarColor) {
|
|
||||||
this.bossBarColor = bossBarColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PacketBossBar.Division getBossBarDivision() {
|
|
||||||
return bossBarDivision;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBossBarDivision(PacketBossBar.Division bossBarDivision) {
|
|
||||||
this.bossBarDivision = bossBarDivision;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -3,8 +3,6 @@ package ru.nanit.limbo;
|
|||||||
import ru.nanit.limbo.server.LimboServer;
|
import ru.nanit.limbo.server.LimboServer;
|
||||||
import ru.nanit.limbo.util.Logger;
|
import ru.nanit.limbo.util.Logger;
|
||||||
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
public final class NanoLimbo {
|
public final class NanoLimbo {
|
||||||
|
|
||||||
public static void main(String[] args){
|
public static void main(String[] args){
|
||||||
@ -15,7 +13,4 @@ public final class NanoLimbo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static InputStream getResource(String path){
|
|
||||||
return NanoLimbo.class.getResourceAsStream(path);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
109
src/main/java/ru/nanit/limbo/configuration/LimboConfig.java
Normal file
109
src/main/java/ru/nanit/limbo/configuration/LimboConfig.java
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
package ru.nanit.limbo.configuration;
|
||||||
|
|
||||||
|
import napi.configurate.Configuration;
|
||||||
|
import napi.configurate.source.ConfigSources;
|
||||||
|
import napi.configurate.yaml.YamlConfiguration;
|
||||||
|
import ru.nanit.limbo.server.data.*;
|
||||||
|
import ru.nanit.limbo.util.Colors;
|
||||||
|
|
||||||
|
import java.net.SocketAddress;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
public final class LimboConfig {
|
||||||
|
|
||||||
|
private final Path root;
|
||||||
|
|
||||||
|
private SocketAddress address;
|
||||||
|
private int maxPlayers;
|
||||||
|
private PingData pingData;
|
||||||
|
|
||||||
|
private String dimensionType;
|
||||||
|
private Position spawnPosition;
|
||||||
|
|
||||||
|
private boolean useJoinMessage;
|
||||||
|
private boolean useBossBar;
|
||||||
|
private String joinMessage;
|
||||||
|
private BossBar bossBar;
|
||||||
|
|
||||||
|
private InfoForwarding infoForwarding;
|
||||||
|
private long readTimeout;
|
||||||
|
private int debugLevel = 3;
|
||||||
|
|
||||||
|
public LimboConfig(Path root){
|
||||||
|
this.root = root;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void load() throws Exception {
|
||||||
|
Configuration conf = YamlConfiguration.builder()
|
||||||
|
.source(ConfigSources.resource("/limbo.yml", this).copyTo(root))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
conf.reload();
|
||||||
|
|
||||||
|
address = conf.getNode("bind").getValue(SocketAddress.class);
|
||||||
|
maxPlayers = conf.getNode("maxPlayers").getInt();
|
||||||
|
pingData = conf.getNode("ping").getValue(PingData.class);
|
||||||
|
dimensionType = conf.getNode("dimension").getString();
|
||||||
|
spawnPosition = conf.getNode("spawnPosition").getValue(Position.class);
|
||||||
|
useJoinMessage = conf.getNode("joinMessage", "enable").getBoolean();
|
||||||
|
useBossBar = conf.getNode("bossBar", "enable").getBoolean();
|
||||||
|
|
||||||
|
if (useJoinMessage)
|
||||||
|
joinMessage = Colors.of(conf.getNode("joinMessage", "text").getString());
|
||||||
|
|
||||||
|
if (useBossBar)
|
||||||
|
bossBar = conf.getNode("bossBar").getValue(BossBar.class);
|
||||||
|
|
||||||
|
infoForwarding = conf.getNode("infoForwarding").getValue(InfoForwarding.class);
|
||||||
|
readTimeout = conf.getNode("readTimeout").getLong();
|
||||||
|
debugLevel = conf.getNode("debugLevel").getInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
public SocketAddress getAddress() {
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxPlayers() {
|
||||||
|
return maxPlayers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PingData getPingData() {
|
||||||
|
return pingData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDimensionType() {
|
||||||
|
return dimensionType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Position getSpawnPosition() {
|
||||||
|
return spawnPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public InfoForwarding getInfoForwarding() {
|
||||||
|
return infoForwarding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getReadTimeout() {
|
||||||
|
return readTimeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDebugLevel() {
|
||||||
|
return debugLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isUseJoinMessage() {
|
||||||
|
return useJoinMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isUseBossBar() {
|
||||||
|
return useBossBar;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getJoinMessage() {
|
||||||
|
return joinMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BossBar getBossBar() {
|
||||||
|
return bossBar;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
package ru.nanit.limbo.configuration;
|
||||||
|
|
||||||
|
import napi.configurate.data.ConfigNode;
|
||||||
|
import napi.configurate.serializing.NodeSerializer;
|
||||||
|
import napi.configurate.serializing.NodeSerializingException;
|
||||||
|
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.SocketAddress;
|
||||||
|
|
||||||
|
public class SocketAddressSerializer implements NodeSerializer<SocketAddress> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SocketAddress deserialize(ConfigNode node) {
|
||||||
|
String ip = node.getNode("ip").getString();
|
||||||
|
int port = node.getNode("port").getInt();
|
||||||
|
SocketAddress address;
|
||||||
|
|
||||||
|
if (ip == null || ip.isEmpty()){
|
||||||
|
address = new InetSocketAddress(port);
|
||||||
|
} else {
|
||||||
|
address = new InetSocketAddress(ip, port);
|
||||||
|
}
|
||||||
|
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void serialize(SocketAddress socketAddress, ConfigNode configNode) throws NodeSerializingException {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -4,7 +4,7 @@ import io.netty.channel.Channel;
|
|||||||
import io.netty.channel.ChannelInitializer;
|
import io.netty.channel.ChannelInitializer;
|
||||||
import io.netty.channel.ChannelPipeline;
|
import io.netty.channel.ChannelPipeline;
|
||||||
import io.netty.handler.timeout.ReadTimeoutHandler;
|
import io.netty.handler.timeout.ReadTimeoutHandler;
|
||||||
import ru.nanit.limbo.LimboConfig;
|
import ru.nanit.limbo.configuration.LimboConfig;
|
||||||
import ru.nanit.limbo.protocol.pipeline.VarIntFrameDecoder;
|
import ru.nanit.limbo.protocol.pipeline.VarIntFrameDecoder;
|
||||||
import ru.nanit.limbo.protocol.pipeline.PacketDecoder;
|
import ru.nanit.limbo.protocol.pipeline.PacketDecoder;
|
||||||
import ru.nanit.limbo.protocol.pipeline.PacketEncoder;
|
import ru.nanit.limbo.protocol.pipeline.PacketEncoder;
|
||||||
@ -25,7 +25,8 @@ public class ClientChannelInitializer extends ChannelInitializer<Channel> {
|
|||||||
protected void initChannel(Channel channel) {
|
protected void initChannel(Channel channel) {
|
||||||
ChannelPipeline pipeline = channel.pipeline();
|
ChannelPipeline pipeline = channel.pipeline();
|
||||||
|
|
||||||
pipeline.addLast("timeout", new ReadTimeoutHandler(LimboConfig.getReadTimeout(), TimeUnit.MILLISECONDS));
|
pipeline.addLast("timeout", new ReadTimeoutHandler(server.getConfig().getReadTimeout(),
|
||||||
|
TimeUnit.MILLISECONDS));
|
||||||
pipeline.addLast("frame_decoder", new VarIntFrameDecoder());
|
pipeline.addLast("frame_decoder", new VarIntFrameDecoder());
|
||||||
pipeline.addLast("frame_encoder", new VarIntLengthEncoder());
|
pipeline.addLast("frame_encoder", new VarIntLengthEncoder());
|
||||||
pipeline.addLast("decoder", new PacketDecoder());
|
pipeline.addLast("decoder", new PacketDecoder());
|
||||||
|
@ -4,7 +4,6 @@ import io.netty.channel.Channel;
|
|||||||
import io.netty.channel.ChannelFutureListener;
|
import io.netty.channel.ChannelFutureListener;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||||
import ru.nanit.limbo.LimboConfig;
|
|
||||||
import ru.nanit.limbo.protocol.packets.login.*;
|
import ru.nanit.limbo.protocol.packets.login.*;
|
||||||
import ru.nanit.limbo.protocol.packets.play.*;
|
import ru.nanit.limbo.protocol.packets.play.*;
|
||||||
import ru.nanit.limbo.protocol.pipeline.PacketDecoder;
|
import ru.nanit.limbo.protocol.pipeline.PacketDecoder;
|
||||||
@ -18,7 +17,6 @@ import ru.nanit.limbo.protocol.registry.Version;
|
|||||||
import ru.nanit.limbo.server.LimboServer;
|
import ru.nanit.limbo.server.LimboServer;
|
||||||
import ru.nanit.limbo.util.Logger;
|
import ru.nanit.limbo.util.Logger;
|
||||||
import ru.nanit.limbo.util.UuidUtil;
|
import ru.nanit.limbo.util.UuidUtil;
|
||||||
import ru.nanit.limbo.world.DimensionRegistry;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.ThreadLocalRandom;
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
@ -50,7 +48,7 @@ public class ClientConnection extends ChannelInboundHandlerAdapter {
|
|||||||
@Override
|
@Override
|
||||||
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
|
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
|
||||||
if (state.equals(State.PLAY)){
|
if (state.equals(State.PLAY)){
|
||||||
server.removeConnection(this);
|
server.getConnections().removeConnection(this);
|
||||||
Logger.info("Player %s disconnected", this.username);
|
Logger.info("Player %s disconnected", this.username);
|
||||||
}
|
}
|
||||||
super.channelInactive(ctx);
|
super.channelInactive(ctx);
|
||||||
@ -73,10 +71,11 @@ public class ClientConnection extends ChannelInboundHandlerAdapter {
|
|||||||
PacketHandshake handshake = (PacketHandshake) packet;
|
PacketHandshake handshake = (PacketHandshake) packet;
|
||||||
updateState(State.getById(handshake.getNextState()));
|
updateState(State.getById(handshake.getNextState()));
|
||||||
clientVersion = handshake.getVersion();
|
clientVersion = handshake.getVersion();
|
||||||
|
Logger.debug("Pinged from " + handshake.getHost() + ":" + handshake.getPort());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (packet instanceof PacketStatusRequest){
|
if (packet instanceof PacketStatusRequest){
|
||||||
sendPacket(new PacketStatusResponse(server.getConnectionsCount()));
|
sendPacket(new PacketStatusResponse(server));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (packet instanceof PacketStatusPing){
|
if (packet instanceof PacketStatusPing){
|
||||||
@ -84,7 +83,7 @@ public class ClientConnection extends ChannelInboundHandlerAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (packet instanceof PacketLoginStart){
|
if (packet instanceof PacketLoginStart){
|
||||||
if (server.getConnectionsCount() >= LimboConfig.getMaxPlayers()){
|
if (server.getConnections().getCount() >= server.getConfig().getMaxPlayers()){
|
||||||
disconnect("Too many players connected");
|
disconnect("Too many players connected");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -105,7 +104,7 @@ public class ClientConnection extends ChannelInboundHandlerAdapter {
|
|||||||
sendPacket(loginSuccess);
|
sendPacket(loginSuccess);
|
||||||
updateState(State.PLAY);
|
updateState(State.PLAY);
|
||||||
|
|
||||||
server.addConnection(this);
|
server.getConnections().addConnection(this);
|
||||||
Logger.info("Player %s connected (%s)", this.username, channel.remoteAddress());
|
Logger.info("Player %s connected (%s)", this.username, channel.remoteAddress());
|
||||||
|
|
||||||
sendJoinPackets();
|
sendJoinPackets();
|
||||||
@ -120,7 +119,7 @@ public class ClientConnection extends ChannelInboundHandlerAdapter {
|
|||||||
joinGame.setFlat(false);
|
joinGame.setFlat(false);
|
||||||
joinGame.setGameMode(2);
|
joinGame.setGameMode(2);
|
||||||
joinGame.setHardcore(false);
|
joinGame.setHardcore(false);
|
||||||
joinGame.setMaxPlayers(LimboConfig.getMaxPlayers());
|
joinGame.setMaxPlayers(server.getConfig().getMaxPlayers());
|
||||||
joinGame.setPreviousGameMode(-1);
|
joinGame.setPreviousGameMode(-1);
|
||||||
joinGame.setReducedDebugInfo(false);
|
joinGame.setReducedDebugInfo(false);
|
||||||
joinGame.setDebug(false);
|
joinGame.setDebug(false);
|
||||||
@ -128,16 +127,16 @@ public class ClientConnection extends ChannelInboundHandlerAdapter {
|
|||||||
joinGame.setWorldName("minecraft:world");
|
joinGame.setWorldName("minecraft:world");
|
||||||
joinGame.setWorldNames("minecraft:world");
|
joinGame.setWorldNames("minecraft:world");
|
||||||
joinGame.setHashedSeed(0);
|
joinGame.setHashedSeed(0);
|
||||||
joinGame.setDimensionCodec(DimensionRegistry.getCodec());
|
joinGame.setDimensionCodec(server.getDimensionRegistry().getCodec());
|
||||||
joinGame.setDimension(DimensionRegistry.getDefaultDimension());
|
joinGame.setDimension(server.getDimensionRegistry().getDefaultDimension());
|
||||||
|
|
||||||
PacketPlayerPositionAndLook positionAndLook = new PacketPlayerPositionAndLook();
|
PacketPlayerPositionAndLook positionAndLook = new PacketPlayerPositionAndLook();
|
||||||
|
|
||||||
positionAndLook.setX(LimboConfig.getSpawnPosition().getX());
|
positionAndLook.setX(server.getConfig().getSpawnPosition().getX());
|
||||||
positionAndLook.setY(LimboConfig.getSpawnPosition().getY());
|
positionAndLook.setY(server.getConfig().getSpawnPosition().getY());
|
||||||
positionAndLook.setZ(LimboConfig.getSpawnPosition().getZ());
|
positionAndLook.setZ(server.getConfig().getSpawnPosition().getZ());
|
||||||
positionAndLook.setYaw(90.0F);
|
positionAndLook.setYaw(server.getConfig().getSpawnPosition().getYaw());
|
||||||
positionAndLook.setPitch(0.0F);
|
positionAndLook.setPitch(server.getConfig().getSpawnPosition().getPitch());
|
||||||
positionAndLook.setTeleportId(ThreadLocalRandom.current().nextInt());
|
positionAndLook.setTeleportId(ThreadLocalRandom.current().nextInt());
|
||||||
|
|
||||||
PacketPlayerInfo info = new PacketPlayerInfo();
|
PacketPlayerInfo info = new PacketPlayerInfo();
|
||||||
|
@ -2,36 +2,22 @@ package ru.nanit.limbo.protocol.packets.play;
|
|||||||
|
|
||||||
import ru.nanit.limbo.protocol.ByteMessage;
|
import ru.nanit.limbo.protocol.ByteMessage;
|
||||||
import ru.nanit.limbo.protocol.PacketOut;
|
import ru.nanit.limbo.protocol.PacketOut;
|
||||||
|
import ru.nanit.limbo.server.data.BossBar;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class PacketBossBar implements PacketOut {
|
public class PacketBossBar implements PacketOut {
|
||||||
|
|
||||||
private UUID uuid;
|
private UUID uuid;
|
||||||
private String title;
|
private BossBar bossBar;
|
||||||
private float health;
|
|
||||||
private Color color;
|
|
||||||
private Division division;
|
|
||||||
private int flags;
|
private int flags;
|
||||||
|
|
||||||
public void setUuid(UUID uuid) {
|
public void setUuid(UUID uuid) {
|
||||||
this.uuid = uuid;
|
this.uuid = uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTitle(String title) {
|
public void setBossBar(BossBar bossBar) {
|
||||||
this.title = title;
|
this.bossBar = bossBar;
|
||||||
}
|
|
||||||
|
|
||||||
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 void setFlags(int flags) {
|
public void setFlags(int flags) {
|
||||||
@ -42,43 +28,11 @@ public class PacketBossBar implements PacketOut {
|
|||||||
public void encode(ByteMessage msg) {
|
public void encode(ByteMessage msg) {
|
||||||
msg.writeUuid(uuid);
|
msg.writeUuid(uuid);
|
||||||
msg.writeVarInt(0); // Create bossbar
|
msg.writeVarInt(0); // Create bossbar
|
||||||
msg.writeString(title);
|
msg.writeString(bossBar.getText());
|
||||||
msg.writeFloat(health);
|
msg.writeFloat(bossBar.getHealth());
|
||||||
msg.writeVarInt(color.index);
|
msg.writeVarInt(bossBar.getColor().getIndex());
|
||||||
msg.writeVarInt(division.index);
|
msg.writeVarInt(bossBar.getDivision().getIndex());
|
||||||
msg.writeByte(flags);
|
msg.writeByte(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
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 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,27 +1,28 @@
|
|||||||
package ru.nanit.limbo.protocol.packets.status;
|
package ru.nanit.limbo.protocol.packets.status;
|
||||||
|
|
||||||
import ru.nanit.limbo.LimboConfig;
|
|
||||||
import ru.nanit.limbo.protocol.*;
|
import ru.nanit.limbo.protocol.*;
|
||||||
import ru.nanit.limbo.protocol.registry.Version;
|
import ru.nanit.limbo.protocol.registry.Version;
|
||||||
|
import ru.nanit.limbo.server.LimboServer;
|
||||||
|
|
||||||
public class PacketStatusResponse implements PacketOut {
|
public class PacketStatusResponse implements PacketOut {
|
||||||
|
|
||||||
private static final String TEMPLATE = "{ \"version\": { \"name\": \"%s\", \"protocol\": %d }, \"players\": { \"max\": %d, \"online\": %d, \"sample\": [] }, \"description\": %s }";
|
private static final String TEMPLATE = "{ \"version\": { \"name\": \"%s\", \"protocol\": %d }, \"players\": { \"max\": %d, \"online\": %d, \"sample\": [] }, \"description\": %s }";
|
||||||
|
|
||||||
private int online;
|
private LimboServer server;
|
||||||
|
|
||||||
public PacketStatusResponse(){ }
|
public PacketStatusResponse(){ }
|
||||||
|
|
||||||
public PacketStatusResponse(int online){
|
public PacketStatusResponse(LimboServer server){
|
||||||
this.online = online;
|
this.server = server;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void encode(ByteMessage msg) {
|
public void encode(ByteMessage msg) {
|
||||||
String ver = LimboConfig.getPingData().getVersion();
|
String ver = server.getConfig().getPingData().getVersion();
|
||||||
String desc = LimboConfig.getPingData().getDescription();
|
String desc = server.getConfig().getPingData().getDescription();
|
||||||
String json = getResponseJson(ver, Version.getCurrentSupported().getProtocolNumber(),
|
String json = getResponseJson(ver, Version.getCurrentSupported().getProtocolNumber(),
|
||||||
LimboConfig.getMaxPlayers(), online, desc);
|
server.getConfig().getMaxPlayers(), server.getConnections().getCount(), desc);
|
||||||
|
|
||||||
msg.writeString(json);
|
msg.writeString(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
34
src/main/java/ru/nanit/limbo/server/Connections.java
Normal file
34
src/main/java/ru/nanit/limbo/server/Connections.java
Normal 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());
|
||||||
|
}
|
||||||
|
}
|
@ -3,40 +3,43 @@ package ru.nanit.limbo.server;
|
|||||||
import io.netty.bootstrap.ServerBootstrap;
|
import io.netty.bootstrap.ServerBootstrap;
|
||||||
import io.netty.channel.nio.NioEventLoopGroup;
|
import io.netty.channel.nio.NioEventLoopGroup;
|
||||||
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
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.ClientChannelInitializer;
|
||||||
import ru.nanit.limbo.connection.ClientConnection;
|
import ru.nanit.limbo.connection.ClientConnection;
|
||||||
import ru.nanit.limbo.protocol.packets.play.PacketBossBar;
|
import ru.nanit.limbo.protocol.packets.play.PacketBossBar;
|
||||||
import ru.nanit.limbo.protocol.packets.play.PacketChatMessage;
|
import ru.nanit.limbo.protocol.packets.play.PacketChatMessage;
|
||||||
|
import ru.nanit.limbo.server.data.*;
|
||||||
import ru.nanit.limbo.util.Logger;
|
import ru.nanit.limbo.util.Logger;
|
||||||
import ru.nanit.limbo.world.DimensionRegistry;
|
import ru.nanit.limbo.world.DimensionRegistry;
|
||||||
|
|
||||||
|
import java.net.SocketAddress;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
public final class LimboServer {
|
public final class LimboServer {
|
||||||
|
|
||||||
private final Map<UUID, ClientConnection> connections = new ConcurrentHashMap<>();
|
private LimboConfig config;
|
||||||
private final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
|
private Connections connections;
|
||||||
|
private DimensionRegistry dimensionRegistry;
|
||||||
|
|
||||||
private PacketChatMessage joinMessage;
|
private PacketChatMessage joinMessage;
|
||||||
private PacketBossBar joinBossBar;
|
private PacketBossBar joinBossBar;
|
||||||
|
|
||||||
public int getConnectionsCount(){
|
public LimboConfig getConfig(){
|
||||||
return connections.size();
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addConnection(ClientConnection connection){
|
public Connections getConnections(){
|
||||||
connections.put(connection.getUuid(), connection);
|
return connections;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeConnection(ClientConnection connection){
|
public DimensionRegistry getDimensionRegistry() {
|
||||||
connections.remove(connection.getUuid());
|
return dimensionRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PacketChatMessage getJoinMessage() {
|
public PacketChatMessage getJoinMessage() {
|
||||||
@ -50,47 +53,54 @@ public final class LimboServer {
|
|||||||
public void start() throws Exception {
|
public void start() throws Exception {
|
||||||
Logger.info("Starting server...");
|
Logger.info("Starting server...");
|
||||||
|
|
||||||
LimboConfig.load(Paths.get("./settings.properties"));
|
NodeSerializers.register(SocketAddress.class, new SocketAddressSerializer());
|
||||||
DimensionRegistry.init(LimboConfig.getDimensionType());
|
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);
|
executor.scheduleAtFixedRate(this::broadcastKeepAlive, 0L, 5L, TimeUnit.SECONDS);
|
||||||
|
|
||||||
ServerBootstrap bootstrap = new ServerBootstrap()
|
new ServerBootstrap()
|
||||||
.group(new NioEventLoopGroup(), new NioEventLoopGroup())
|
.group(new NioEventLoopGroup(), new NioEventLoopGroup())
|
||||||
.channel(NioServerSocketChannel.class)
|
.channel(NioServerSocketChannel.class)
|
||||||
.childHandler(new ClientChannelInitializer(this));
|
.childHandler(new ClientChannelInitializer(this))
|
||||||
|
.localAddress(config.getAddress())
|
||||||
|
.bind();
|
||||||
|
|
||||||
if (LimboConfig.getHost().isEmpty()){
|
Logger.info("Server started on %s", config.getAddress());
|
||||||
bootstrap.bind(LimboConfig.getPort());
|
|
||||||
} else {
|
|
||||||
bootstrap.bind(LimboConfig.getHost(), LimboConfig.getPort());
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger.info("Server started on %s:%d", LimboConfig.getHost(), LimboConfig.getPort());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initializeInGameData(){
|
private void initInGameData(){
|
||||||
if (LimboConfig.getJoinMessages().getChatMessage() != null){
|
if (config.isUseJoinMessage()){
|
||||||
joinMessage = new PacketChatMessage();
|
joinMessage = new PacketChatMessage();
|
||||||
joinMessage.setJsonData(LimboConfig.getJoinMessages().getChatMessage());
|
joinMessage.setJsonData(config.getJoinMessage());
|
||||||
joinMessage.setPosition(PacketChatMessage.Position.CHAT);
|
joinMessage.setPosition(PacketChatMessage.Position.CHAT);
|
||||||
joinMessage.setSender(UUID.randomUUID());
|
joinMessage.setSender(UUID.randomUUID());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LimboConfig.getJoinMessages().getBossBarText() != null){
|
if (config.isUseBossBar()){
|
||||||
joinBossBar = new PacketBossBar();
|
joinBossBar = new PacketBossBar();
|
||||||
joinBossBar.setTitle(LimboConfig.getJoinMessages().getBossBarText());
|
joinBossBar.setBossBar(config.getBossBar());
|
||||||
joinBossBar.setHealth(LimboConfig.getJoinMessages().getBossBarHealth());
|
|
||||||
joinBossBar.setColor(LimboConfig.getJoinMessages().getBossBarColor());
|
|
||||||
joinBossBar.setDivision(LimboConfig.getJoinMessages().getBossBarDivision());
|
|
||||||
joinBossBar.setUuid(UUID.randomUUID());
|
joinBossBar.setUuid(UUID.randomUUID());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void broadcastKeepAlive(){
|
private void broadcastKeepAlive(){
|
||||||
connections.values().forEach(ClientConnection::sendKeepAlive);
|
connections.getAllConnections().forEach(ClientConnection::sendKeepAlive);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
119
src/main/java/ru/nanit/limbo/server/data/BossBar.java
Normal file
119
src/main/java/ru/nanit/limbo/server/data/BossBar.java
Normal 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) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
53
src/main/java/ru/nanit/limbo/server/data/InfoForwarding.java
Normal file
53
src/main/java/ru/nanit/limbo/server/data/InfoForwarding.java
Normal 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 {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
43
src/main/java/ru/nanit/limbo/server/data/PingData.java
Normal file
43
src/main/java/ru/nanit/limbo/server/data/PingData.java
Normal 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) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
72
src/main/java/ru/nanit/limbo/server/data/Position.java
Normal file
72
src/main/java/ru/nanit/limbo/server/data/Position.java
Normal 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) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,22 +1,25 @@
|
|||||||
package ru.nanit.limbo.util;
|
package ru.nanit.limbo.util;
|
||||||
|
|
||||||
import ru.nanit.limbo.LimboConfig;
|
|
||||||
|
|
||||||
import java.time.LocalTime;
|
import java.time.LocalTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
||||||
public final class Logger {
|
public final class Logger {
|
||||||
|
|
||||||
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("hh:mm:ss");
|
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("hh:mm:ss");
|
||||||
|
private static int debugLevel = 3;
|
||||||
|
|
||||||
private Logger(){}
|
private Logger(){}
|
||||||
|
|
||||||
|
public static void setLevel(int level){
|
||||||
|
debugLevel = level;
|
||||||
|
}
|
||||||
|
|
||||||
public static void info(Object msg, Object... args){
|
public static void info(Object msg, Object... args){
|
||||||
print(Level.INFO, msg, null, args);
|
print(Level.INFO, msg, null, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void info(Object msg, Throwable t, Object... args){
|
public static void debug(Object msg, Object... args){
|
||||||
print(Level.INFO, msg, t, args);
|
print(Level.INFO, msg, null, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void warning(Object msg, Object... args){
|
public static void warning(Object msg, Object... args){
|
||||||
@ -36,7 +39,7 @@ public final class Logger {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void print(Level level, Object msg, Throwable t, Object... args){
|
public static void print(Level level, Object msg, Throwable t, Object... args){
|
||||||
if (LimboConfig.getDebugLevel() >= level.getIndex()){
|
if (debugLevel >= level.getIndex()){
|
||||||
System.out.println(String.format("%s: %s", getPrefix(level), String.format(msg.toString(), args)));
|
System.out.println(String.format("%s: %s", getPrefix(level), String.format(msg.toString(), args)));
|
||||||
if (t != null) t.printStackTrace();
|
if (t != null) t.printStackTrace();
|
||||||
}
|
}
|
||||||
@ -52,7 +55,8 @@ public final class Logger {
|
|||||||
|
|
||||||
public enum Level {
|
public enum Level {
|
||||||
|
|
||||||
INFO ("INFO", 1),
|
INFO ("INFO", 0),
|
||||||
|
DEBUG ("DEBUG", 1),
|
||||||
WARNING("WARNING", 2),
|
WARNING("WARNING", 2),
|
||||||
ERROR("ERROR", 3);
|
ERROR("ERROR", 3);
|
||||||
|
|
||||||
|
@ -6,11 +6,55 @@ import ru.nanit.limbo.util.Logger;
|
|||||||
|
|
||||||
public final class DimensionRegistry {
|
public final class DimensionRegistry {
|
||||||
|
|
||||||
private static CompoundBinaryTag codec;
|
private CompoundBinaryTag defaultDimension;
|
||||||
private static CompoundBinaryTag defaultDimension;
|
|
||||||
|
|
||||||
public static void init(String defaultDimensionName){
|
private CompoundBinaryTag codec;
|
||||||
CompoundBinaryTag overworld = CompoundBinaryTag.builder()
|
private CompoundBinaryTag overWorld;
|
||||||
|
private CompoundBinaryTag theEnd;
|
||||||
|
private CompoundBinaryTag nether;
|
||||||
|
|
||||||
|
public CompoundBinaryTag getCodec(){
|
||||||
|
return codec;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompoundBinaryTag getDefaultDimension() {
|
||||||
|
return defaultDimension;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompoundBinaryTag getOverWorld() {
|
||||||
|
return overWorld;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompoundBinaryTag getTheEnd() {
|
||||||
|
return theEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompoundBinaryTag getNether() {
|
||||||
|
return nether;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void load(String def){
|
||||||
|
initDimensions();
|
||||||
|
|
||||||
|
switch (def.toLowerCase()){
|
||||||
|
case "overworld":
|
||||||
|
defaultDimension = overWorld;
|
||||||
|
break;
|
||||||
|
case "nether":
|
||||||
|
defaultDimension = nether;
|
||||||
|
break;
|
||||||
|
case "the_end":
|
||||||
|
defaultDimension = theEnd;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
defaultDimension = theEnd;
|
||||||
|
Logger.warning("Undefined dimension type: '%s'. Using THE_END as default", def);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initDimensions(){
|
||||||
|
overWorld = CompoundBinaryTag.builder()
|
||||||
.putString("name", "minecraft:overworld")
|
.putString("name", "minecraft:overworld")
|
||||||
.putByte("piglin_safe", (byte) 0)
|
.putByte("piglin_safe", (byte) 0)
|
||||||
.putByte("natural", (byte) 0)
|
.putByte("natural", (byte) 0)
|
||||||
@ -28,7 +72,7 @@ public final class DimensionRegistry {
|
|||||||
.putByte("has_ceiling", (byte) 0)
|
.putByte("has_ceiling", (byte) 0)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
CompoundBinaryTag nether = CompoundBinaryTag.builder()
|
nether = CompoundBinaryTag.builder()
|
||||||
.putString("name", "minecraft:the_nether")
|
.putString("name", "minecraft:the_nether")
|
||||||
.putByte("piglin_safe", (byte) 0)
|
.putByte("piglin_safe", (byte) 0)
|
||||||
.putByte("natural", (byte) 0)
|
.putByte("natural", (byte) 0)
|
||||||
@ -46,7 +90,7 @@ public final class DimensionRegistry {
|
|||||||
.putByte("has_ceiling", (byte) 0)
|
.putByte("has_ceiling", (byte) 0)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
CompoundBinaryTag theEnd = CompoundBinaryTag.builder()
|
theEnd = CompoundBinaryTag.builder()
|
||||||
.putString("name", "minecraft:the_end")
|
.putString("name", "minecraft:the_end")
|
||||||
.putByte("piglin_safe", (byte) 0)
|
.putByte("piglin_safe", (byte) 0)
|
||||||
.putByte("natural", (byte) 0)
|
.putByte("natural", (byte) 0)
|
||||||
@ -64,10 +108,10 @@ public final class DimensionRegistry {
|
|||||||
.putByte("has_ceiling", (byte) 0)
|
.putByte("has_ceiling", (byte) 0)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
CompoundBinaryTag overworldData = CompoundBinaryTag.builder()
|
CompoundBinaryTag overWorldData = CompoundBinaryTag.builder()
|
||||||
.putString("name", "minecraft:overworld")
|
.putString("name", "minecraft:overworld")
|
||||||
.putInt("id", 2)
|
.putInt("id", 2)
|
||||||
.put("element", overworld)
|
.put("element", overWorld)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
CompoundBinaryTag netherData = CompoundBinaryTag.builder()
|
CompoundBinaryTag netherData = CompoundBinaryTag.builder()
|
||||||
@ -111,7 +155,7 @@ public final class DimensionRegistry {
|
|||||||
.put("minecraft:dimension_type", CompoundBinaryTag.builder()
|
.put("minecraft:dimension_type", CompoundBinaryTag.builder()
|
||||||
.putString("type", "minecraft:dimension_type")
|
.putString("type", "minecraft:dimension_type")
|
||||||
.put("value", ListBinaryTag.builder()
|
.put("value", ListBinaryTag.builder()
|
||||||
.add(overworldData)
|
.add(overWorldData)
|
||||||
.add(netherData)
|
.add(netherData)
|
||||||
.add(endData)
|
.add(endData)
|
||||||
.build())
|
.build())
|
||||||
@ -123,29 +167,5 @@ public final class DimensionRegistry {
|
|||||||
.build())
|
.build())
|
||||||
.build())
|
.build())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
switch (defaultDimensionName.toLowerCase()){
|
|
||||||
case "overworld":
|
|
||||||
defaultDimension = overworld;
|
|
||||||
break;
|
|
||||||
case "nether":
|
|
||||||
defaultDimension = nether;
|
|
||||||
break;
|
|
||||||
case "the_end":
|
|
||||||
defaultDimension = theEnd;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
defaultDimension = theEnd;
|
|
||||||
Logger.error("Undefined dimension type: '%s'. Using THE_END as default", defaultDimensionName);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static CompoundBinaryTag getCodec(){
|
|
||||||
return codec;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static CompoundBinaryTag getDefaultDimension() {
|
|
||||||
return defaultDimension;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
60
src/main/resources/limbo.yml
Normal file
60
src/main/resources/limbo.yml
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
#
|
||||||
|
# NanoLimbo configuration
|
||||||
|
#
|
||||||
|
|
||||||
|
# Server's host address and port. Set ip empty to use public address
|
||||||
|
bind:
|
||||||
|
ip: 'localhost'
|
||||||
|
port: 65535
|
||||||
|
|
||||||
|
# Max amount of players can join to server
|
||||||
|
maxPlayers: 100
|
||||||
|
|
||||||
|
# Server's data in servers list
|
||||||
|
ping:
|
||||||
|
description: '{"text": "&9NanoLimbo"}'
|
||||||
|
version: 'NanoLimbo'
|
||||||
|
|
||||||
|
# Available dimensions: OVERWORLD, NETHER, THE_END
|
||||||
|
dimension: THE_END
|
||||||
|
|
||||||
|
# Spawn position in the world
|
||||||
|
spawnPosition:
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
yaw: 0.0
|
||||||
|
pitch: 0.0
|
||||||
|
|
||||||
|
# Message sends when player join to server
|
||||||
|
joinMessage:
|
||||||
|
enable: true
|
||||||
|
text: '{"text": "&eWelcome to the Limbo!"}'
|
||||||
|
|
||||||
|
# Bossbar sends when player join to server
|
||||||
|
bossBar:
|
||||||
|
enable: true
|
||||||
|
text: '{"text": "Welcome to the Limbo!"}'
|
||||||
|
health: 1.0
|
||||||
|
# Available colors: PINK, BLUE, RED, GREEN, YELLOW, PURPLE, WHITE
|
||||||
|
color: PINK
|
||||||
|
# Available divisions: SOLID, DASHES_6, DASHES_10, DASHES_12, DASHES_20
|
||||||
|
division: SOLID
|
||||||
|
|
||||||
|
# Player info forwarding support. Available types: NONE, LEGACY, MODERN
|
||||||
|
# Don't use secret if you not use MODERN type
|
||||||
|
infoForwarding:
|
||||||
|
type: LEGACY
|
||||||
|
secret: '<YOUR_SECRET_HERE>'
|
||||||
|
|
||||||
|
# Read timeout for connections in milliseconds
|
||||||
|
readTimeout: 30000
|
||||||
|
|
||||||
|
# Define debug level. On release, i recommend to use 0 level, since
|
||||||
|
# there are many useless for release information about ping, received packets, etc.
|
||||||
|
# Levels:
|
||||||
|
# 0 - Display only useful info
|
||||||
|
# 1 - Display info and some debug
|
||||||
|
# 2 - Display info and warnings
|
||||||
|
# 3 - Display info, warnings, errors
|
||||||
|
debugLevel: 3
|
@ -1,71 +0,0 @@
|
|||||||
# ======= General Data ======= #
|
|
||||||
|
|
||||||
# Server's host address. Set it empty to use public address
|
|
||||||
host=localhost
|
|
||||||
|
|
||||||
# Server's port
|
|
||||||
port=65535
|
|
||||||
|
|
||||||
# Max amount of players can join to server
|
|
||||||
max-players=100
|
|
||||||
|
|
||||||
# Available dimensions: OVERWORLD, NETHER, THE_END
|
|
||||||
dimension=THE_END
|
|
||||||
|
|
||||||
# Spawn position in the world in format x,y,z
|
|
||||||
spawn-position=0.0,65.0,0.0
|
|
||||||
|
|
||||||
# Version string when client version is not compatible with server one
|
|
||||||
ping-version=NanoLimbo
|
|
||||||
|
|
||||||
# Server's description component
|
|
||||||
ping-description={"text": "&9NanoLimbo"}
|
|
||||||
|
|
||||||
# Player info forwarding support. Available types: NONE, LEGACY, MODERN
|
|
||||||
# MODERN - Velocity native forwarding type.
|
|
||||||
# LEGACY - BungeeCord forwarding type (Velocity supports it too)
|
|
||||||
ip-forwarding=LEGACY
|
|
||||||
|
|
||||||
# If you use MODERN type of forwarding, enter your secret code here
|
|
||||||
ip-forwarding-secret=<YOUR_SECRET_HERE>
|
|
||||||
|
|
||||||
# Read timeout for connections in milliseconds
|
|
||||||
read-timeout=30000
|
|
||||||
|
|
||||||
# Define debug level. On release, i recommend to use 1 level, since
|
|
||||||
# there are many useless for release warnings about undefined packets and other.
|
|
||||||
# Levels:
|
|
||||||
# 0 - Display nothing
|
|
||||||
# 1 - Display only useful info
|
|
||||||
# 2 - Display info and warnings
|
|
||||||
# 3 - Display info, warnings, errors
|
|
||||||
debug-level=3
|
|
||||||
|
|
||||||
# ======= In-game Data ======= #
|
|
||||||
|
|
||||||
# Message when player join to server. Comment this parameter to disable
|
|
||||||
join-message={"text": "&eWelcome to the Limbo!"}
|
|
||||||
|
|
||||||
# Bossbar text. Comment this parameter to disable bossbar
|
|
||||||
join-bossbar-text={"text": "Welcome to the Limbo!"}
|
|
||||||
|
|
||||||
# Bossbar percentage between 0.0 and 1.0 inclusive
|
|
||||||
join-bossbar-health=1.0
|
|
||||||
|
|
||||||
# Available bossbar colors:
|
|
||||||
# - PINK
|
|
||||||
# - BLUE
|
|
||||||
# - RED
|
|
||||||
# - GREEN
|
|
||||||
# - YELLOW
|
|
||||||
# - PURPLE
|
|
||||||
# - WHITE
|
|
||||||
join-bossbar-color=PINK
|
|
||||||
|
|
||||||
# Available bossbar divisions:
|
|
||||||
# - SOLID
|
|
||||||
# - DASHES_6
|
|
||||||
# - DASHES_10
|
|
||||||
# - DASHES_12
|
|
||||||
# - DASHES_20
|
|
||||||
join-bossbar-division=SOLID
|
|
Loading…
x
Reference in New Issue
Block a user