Use ConfigBasedLogger

Add sub-sectioning to server networking section
This commit is contained in:
s809
2024-02-03 22:24:34 +05:00
parent 7d72e82325
commit 0cfbe09558
8 changed files with 86 additions and 41 deletions
@@ -802,8 +802,6 @@ public class Config
public static class Multiplayer
{
public static ConfigCategory serverNetworking = new ConfigCategory.Builder().set(ServerNetworking.class).build();
public static ConfigEntry<EServerFolderNameMode> serverFolderNameMode = new ConfigEntry.Builder<EServerFolderNameMode>()
.set(EServerFolderNameMode.NAME_ONLY)
.comment(""
@@ -849,8 +847,11 @@ public class Config
+ "")
.build();
public static ConfigCategory serverNetworking = new ConfigCategory.Builder().set(ServerNetworking.class).build();
public static class ServerNetworking
{
public static ConfigUIComment generalSectionNote = new ConfigUIComment();
public static ConfigEntry<Boolean> enableServerNetworking = new ConfigEntry.Builder<Boolean>()
.setServersideShortName("enableServerNetworking")
.set(true)
@@ -884,6 +885,7 @@ public class Config
.build();
public static ConfigUIComment generationSectionNote = new ConfigUIComment();
public static ConfigEntry<Integer> generationRequestRCLimit = new ConfigEntry.Builder<Integer>()
.setServersideShortName("generationRequestRCLimit")
.setMinDefaultMax(1, 20, 100)
@@ -909,6 +911,7 @@ public class Config
.build();
public static ConfigUIComment realTimeUpdatesSectionNote = new ConfigUIComment();
public static ConfigEntry<Boolean> enableRealTimeUpdates = new ConfigEntry.Builder<Boolean>()
.setServersideShortName("enableRealTimeUpdates")
.set(false)
@@ -918,6 +921,7 @@ public class Config
.build();
public static ConfigUIComment loginDataSyncSectionNote = new ConfigUIComment();
public static ConfigEntry<Boolean> enableLoginDataSync = new ConfigEntry.Builder<Boolean>()
.setServersideShortName("enableLoginDataSync")
.set(false)
@@ -1,5 +1,7 @@
package com.seibel.distanthorizons.core.network;
import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.logging.ConfigBasedLogger;
import com.seibel.distanthorizons.core.network.messages.base.CloseReasonMessage;
import com.seibel.distanthorizons.core.network.protocol.FutureTrackableNetworkMessage;
import com.seibel.distanthorizons.core.network.protocol.NetworkMessage;
@@ -7,14 +9,14 @@ import io.netty.channel.ChannelException;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.net.SocketAddress;
import java.util.concurrent.CompletableFuture;
public interface IConnection
{
Logger LOGGER = LogManager.getLogger();
ConfigBasedLogger LOGGER = new ConfigBasedLogger(LogManager.getLogger(),
() -> Config.Client.Advanced.Logging.logNetworkEvent.get());
ChannelHandlerContext getChannelContext();
NetworkEventSource getRequestHandler();
@@ -26,7 +28,7 @@ public interface IConnection
default CompletableFuture<Void> sendMessage(NetworkMessage message)
{
LOGGER.trace("Sending message: " + message);
LOGGER.debug("Sending message: " + message);
CompletableFuture<Void> future = new CompletableFuture<>();
ChannelHandlerContext ctx = this.getChannelContext();
@@ -19,19 +19,19 @@
package com.seibel.distanthorizons.core.network;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.logging.ConfigBasedLogger;
import com.seibel.distanthorizons.core.network.messages.base.CloseEvent;
import com.seibel.distanthorizons.core.network.messages.base.CloseReasonMessage;
import com.seibel.distanthorizons.core.network.messages.base.HelloMessage;
import com.seibel.distanthorizons.core.network.protocol.MessageHandler;
import com.seibel.distanthorizons.core.network.protocol.NetworkChannelInitializer;
import com.seibel.distanthorizons.core.network.protocol.NetworkMessage;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.util.concurrent.DefaultThreadFactory;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import java.net.InetSocketAddress;
import java.util.EnumSet;
@@ -40,7 +40,8 @@ import java.util.concurrent.TimeUnit;
public class NetworkClient extends NetworkEventSource implements IConnection, AutoCloseable
{
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
private static final ConfigBasedLogger LOGGER = new ConfigBasedLogger(LogManager.getLogger(),
() -> Config.Client.Advanced.Logging.logNetworkEvent.get());
private enum EConnectionState
{
@@ -67,7 +68,7 @@ public class NetworkClient extends NetworkEventSource implements IConnection, Au
public boolean isClosed() { return closedStates.contains(this.connectionState); }
private boolean ready;
/** Indicates whether the connection is established and first message is sent. */
public boolean isReady() { return ready; }
public boolean isReady() { return this.ready; }
private final EventLoopGroup workerGroup = new NioEventLoopGroup(0, new DefaultThreadFactory("DH-Network - Client Thread"));
private final Bootstrap clientBootstrap = new Bootstrap()
@@ -98,7 +99,7 @@ public class NetworkClient extends NetworkEventSource implements IConnection, Au
{
this.registerHandler(CloseReasonMessage.class, closeReasonMessage ->
{
LOGGER.info(closeReasonMessage.reason);
LOGGER.warn(closeReasonMessage.reason);
this.connectionState = EConnectionState.CLOSING;
});
@@ -114,7 +115,10 @@ public class NetworkClient extends NetworkEventSource implements IConnection, Au
public void startConnecting()
{
if (!isInitialState()) return;
if (!this.isInitialState())
{
return;
}
this.connect();
}
@@ -123,8 +127,6 @@ public class NetworkClient extends NetworkEventSource implements IConnection, Au
LOGGER.info("Connecting to server: "+this.address);
this.connectionState = EConnectionState.OPEN;
// FIXME sometimes this causes the MC connection to crash
// this might happen if the URL can't be converted to a IP (IE UnknownHostException)
ChannelFuture connectFuture = this.clientBootstrap.connect(this.address);
this.channel = connectFuture.channel();
@@ -132,23 +134,25 @@ public class NetworkClient extends NetworkEventSource implements IConnection, Au
{
if (!channelFuture.isSuccess())
{
LOGGER.warn("Connection failed: "+channelFuture.cause());
LOGGER.info("Connection failed: " + channelFuture.cause());
return;
}
sendMessage(new HelloMessage());
ready = true;
this.sendMessage(new HelloMessage());
this.ready = true;
});
this.channel.closeFuture().addListener((ChannelFuture channelFuture) ->
{
ready = false;
this.ready = false;
this.completeAllFuturesExceptionally(channelFuture.cause() != null
? channelFuture.cause()
: new ChannelException("Channel is closed."));
if (this.connectionState != EConnectionState.OPEN)
{
return;
}
this.reconnectAttempts--;
LOGGER.info("Reconnection attempts left: [" + this.reconnectAttempts + "] of [" + FAILURE_RECONNECT_ATTEMPTS + "].");
@@ -19,7 +19,8 @@
package com.seibel.distanthorizons.core.network;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.logging.ConfigBasedLogger;
import com.seibel.distanthorizons.core.network.messages.base.CancelMessage;
import com.seibel.distanthorizons.core.network.messages.base.CloseEvent;
import com.seibel.distanthorizons.core.network.messages.base.ExceptionMessage;
@@ -27,7 +28,7 @@ import com.seibel.distanthorizons.core.network.protocol.FutureTrackableNetworkMe
import com.seibel.distanthorizons.core.network.protocol.MessageRegistry;
import com.seibel.distanthorizons.core.network.protocol.NetworkMessage;
import io.netty.channel.ChannelException;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import java.io.InvalidClassException;
import java.util.HashSet;
@@ -40,7 +41,8 @@ import java.util.function.Consumer;
public abstract class NetworkEventSource
{
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
private static final ConfigBasedLogger LOGGER = new ConfigBasedLogger(LogManager.getLogger(),
() -> Config.Client.Advanced.Logging.logNetworkEvent.get());
protected final ConcurrentMap<Class<? extends NetworkMessage>, Set<Consumer<NetworkMessage>>> handlers = new ConcurrentHashMap<>();
private final ConcurrentMap<IConnection, ConcurrentMap<Long, FutureResponseData>> pendingFutures = new ConcurrentHashMap<>();
@@ -67,7 +69,7 @@ public abstract class NetworkEventSource
if (message instanceof FutureTrackableNetworkMessage)
{
FutureTrackableNetworkMessage trackableMessage = (FutureTrackableNetworkMessage)message;
ConcurrentMap<Long, FutureResponseData> subMap = pendingFutures.get(message.getConnection());
ConcurrentMap<Long, FutureResponseData> subMap = this.pendingFutures.get(message.getConnection());
if (subMap != null)
{
FutureResponseData responseData = subMap.get(trackableMessage.futureId);
@@ -76,17 +78,25 @@ public abstract class NetworkEventSource
handled = true;
if (message instanceof ExceptionMessage)
{
responseData.future.completeExceptionally(((ExceptionMessage) message).exception);
}
else if (message.getClass() != responseData.responseClass)
{
responseData.future.completeExceptionally(new InvalidClassException("Response with invalid type: expected " + responseData.responseClass.getSimpleName() + ", got:" + message));
}
else
{
responseData.future.complete(trackableMessage);
}
}
}
}
if (!handled && message.warnWhenUnhandled())
{
LOGGER.warn("Unhandled message: " + message);
}
}
protected void addNewConnection(IConnection connection)
@@ -101,7 +111,9 @@ public abstract class NetworkEventSource
{
// Will throw if the handler class is not found
if (handlerClass != CloseEvent.class)
{
MessageRegistry.INSTANCE.getMessageId(handlerClass);
}
return new HashSet<>();
})
.add((Consumer<NetworkMessage>) handlerImplementation);
@@ -123,16 +135,20 @@ public abstract class NetworkEventSource
{
if (!(throwable instanceof ChannelException))
{
ConcurrentMap<Long, FutureResponseData> subMap = pendingFutures.get(connection);
ConcurrentMap<Long, FutureResponseData> subMap = this.pendingFutures.get(connection);
if (subMap != null)
{
subMap.remove(msg.futureId);
}
}
if (throwable instanceof CancellationException)
{
msg.sendResponse(new CancelMessage());
}
});
ConcurrentMap<Long, FutureResponseData> subMap = pendingFutures.get(connection);
ConcurrentMap<Long, FutureResponseData> subMap = this.pendingFutures.get(connection);
if (subMap == null)
{
// Was deleted before adding
@@ -140,9 +156,10 @@ public abstract class NetworkEventSource
return responseFuture;
}
subMap.put(msg.futureId, new FutureResponseData(responseClass, responseFuture));
if (!pendingFutures.containsKey(connection))
if (!this.pendingFutures.containsKey(connection))
{
// Was deleted while adding
// Note: removal from subMap will happen in whenComplete above
responseFuture.completeExceptionally(connection.getCloseReason());
return responseFuture;
}
@@ -153,23 +170,30 @@ public abstract class NetworkEventSource
protected final void completeAllFuturesExceptionally(IConnection connection, Throwable cause)
{
ConcurrentMap<Long, FutureResponseData> map = pendingFutures.remove(connection);
if (map == null) return;
ConcurrentMap<Long, FutureResponseData> map = this.pendingFutures.remove(connection);
if (map == null)
{
return;
}
for (FutureResponseData responseData : map.values())
{
responseData.future.completeExceptionally(cause);
}
}
protected final void completeAllFuturesExceptionally(Throwable cause)
{
for (IConnection connection : pendingFutures.keySet())
for (IConnection connection : this.pendingFutures.keySet())
{
this.completeAllFuturesExceptionally(connection, cause);
}
}
public void close()
{
this.handlers.clear();
completeAllFuturesExceptionally(new ChannelException(this.getClass().getSimpleName()+" is closed."));
this.completeAllFuturesExceptionally(new ChannelException(this.getClass().getSimpleName() + " is closed."));
}
private static class FutureResponseData
@@ -20,28 +20,32 @@
package com.seibel.distanthorizons.core.network;
import com.google.common.collect.MapMaker;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.logging.ConfigBasedLogger;
import com.seibel.distanthorizons.core.network.messages.base.CloseEvent;
import com.seibel.distanthorizons.core.network.messages.base.HelloMessage;
import com.seibel.distanthorizons.core.network.protocol.MessageHandler;
import com.seibel.distanthorizons.core.network.protocol.NetworkChannelInitializer;
import com.seibel.distanthorizons.core.network.protocol.NetworkMessage;
import com.seibel.distanthorizons.coreapi.ModInfo;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.util.concurrent.DefaultThreadFactory;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicBoolean;
public class NetworkServer extends NetworkEventSource implements AutoCloseable
{
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
private static final ConfigBasedLogger LOGGER = new ConfigBasedLogger(LogManager.getLogger(),
() -> Config.Client.Advanced.Logging.logNetworkEvent.get());
private final int port;
@@ -19,12 +19,13 @@
package com.seibel.distanthorizons.core.network.protocol;
import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.logging.ConfigBasedLogger;
import com.seibel.distanthorizons.core.network.messages.base.CloseEvent;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.NotNull;
import java.util.function.BiConsumer;
@@ -33,7 +34,8 @@ import java.util.function.Consumer;
@ChannelHandler.Sharable
public class MessageHandler extends SimpleChannelInboundHandler<NetworkMessage>
{
private static final Logger LOGGER = LogManager.getLogger();
private static final ConfigBasedLogger LOGGER = new ConfigBasedLogger(LogManager.getLogger(),
() -> Config.Client.Advanced.Logging.logNetworkEvent.get());
private final BiConsumer<ChannelHandlerContext, NetworkMessage> messageConsumer;
private final Consumer<ChannelHandlerContext> channelActiveConsumer;
@@ -47,7 +49,7 @@ public class MessageHandler extends SimpleChannelInboundHandler<NetworkMessage>
@Override
protected void channelRead0(ChannelHandlerContext channelContext, NetworkMessage message)
{
LOGGER.trace("Received message: " + message);
LOGGER.debug("Received message: " + message);
this.messageConsumer.accept(channelContext, message);
}
@@ -19,14 +19,16 @@
package com.seibel.distanthorizons.core.network.protocol;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.logging.ConfigBasedLogger;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
public class NetworkExceptionHandler extends ChannelInboundHandlerAdapter
{
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
private static final ConfigBasedLogger LOGGER = new ConfigBasedLogger(LogManager.getLogger(),
() -> Config.Client.Advanced.Logging.logNetworkEvent.get());
@Override
public void exceptionCaught(ChannelHandlerContext channelContext, Throwable cause)
@@ -345,19 +345,22 @@
"Multiplayer",
"distanthorizons.config.client.advanced.multiplayer.serverNetworking": "Server Networking",
"distanthorizons.config.client.advanced.multiplayer.serverNetworking.generalSectionNote": " \u25cf General",
"distanthorizons.config.client.advanced.multiplayer.serverNetworking.enableServerNetworking": "Enable Server Networking",
"distanthorizons.config.client.advanced.multiplayer.serverNetworking.enableServerNetworking.@tooltip": "§6Attention:§r this feature is not fully implemented. \n\nIf true Distant Horizons will attempt to communicate with the connected \nserver in order to load LODs outside your vanilla render distance. \n\nNote: This requires DH to be installed on the server in order to function.",
"distanthorizons.config.client.advanced.multiplayer.serverNetworking.serverPort": "Server Port",
"distanthorizons.config.client.advanced.multiplayer.serverNetworking.serverPort.@tooltip": "The port on the server that's used for sending LOD data.",
"distanthorizons.config.client.advanced.multiplayer.serverNetworking.generationSectionNote": " \u25cf Generation",
"distanthorizons.config.client.advanced.multiplayer.serverNetworking.generationRequestRCLimit": "Gen task rate/concurrency limit",
"distanthorizons.config.client.advanced.multiplayer.serverNetworking.generationRequestRCLimit.@tooltip": "Limits the amount of generation requests sent by client and processed by server.",
"distanthorizons.config.client.advanced.multiplayer.serverNetworking.genTaskPriorityRequestRateLimit": "Gen task priority check rate limit",
"distanthorizons.config.client.advanced.multiplayer.serverNetworking.genTaskPriorityRequestRateLimit.@tooltip": "Limits the amount of LOD sections that the client can request states for, per second.",
"distanthorizons.config.client.advanced.multiplayer.serverNetworking.generationRequestBeginDelay": "Generation request begin delay",
"distanthorizons.config.client.advanced.multiplayer.serverNetworking.generationRequestBeginDelay.@tooltip": "Adds a delay in seconds before sending LOD requests, when generation is enabled. \nIncrease this value if initial generation starts too far away.",
"distanthorizons.config.client.advanced.multiplayer.serverNetworking.realTimeUpdatesSectionNote": " \u25cf Real Time Updates",
"distanthorizons.config.client.advanced.multiplayer.serverNetworking.enableRealTimeUpdates": "Enable Real Time Updates",
"distanthorizons.config.client.advanced.multiplayer.serverNetworking.enableRealTimeUpdates.@tooltip": "Enables real time updates from server.",
"distanthorizons.config.client.advanced.multiplayer.serverNetworking.loginDataSyncSectionNote": " \u25cf Login Data Sync",
"distanthorizons.config.client.advanced.multiplayer.serverNetworking.enableLoginDataSync": "Synchronize LODs on Login",
"distanthorizons.config.client.advanced.multiplayer.serverNetworking.enableLoginDataSync.@tooltip": "Enables updating of saved LODs after login.",
"distanthorizons.config.client.advanced.multiplayer.serverNetworking.loginDataSyncRCLimit": "Login sync rate/concurrency limit",