Refactor session config

This commit is contained in:
s809
2024-09-08 19:05:42 +05:00
parent 576d0f5666
commit 8ca2052748
14 changed files with 199 additions and 225 deletions
@@ -32,7 +32,7 @@ public final class ModInfo
// region Protocol versions
// Incremented every time any packets are added, changed or removed, with a few exceptions.
public static final int PROTOCOL_VERSION = 3;
public static final int PROTOCOL_VERSION = 4;
public static final String WRAPPER_PACKET_PATH = "message";
// endregion
@@ -22,7 +22,7 @@ public class WorldRemoteGenerationQueue extends AbstractFullDataRequestQueue imp
@Override
protected int getRequestRateLimit() { return this.networkState.config.generationRequestRateLimit; }
protected int getRequestRateLimit() { return this.networkState.config.getGenerationRequestRateLimit(); }
@Override
protected String getQueueName() { return "World Remote Generation Queue"; }
@@ -190,7 +190,7 @@ public class DhClientLevel extends AbstractDhLevel implements IDhClientLevel
}
boolean shouldDoWorldGen = isClientUsable
&& networkState.config.distantGenerationEnabled
&& networkState.config.isDistantGenerationEnabled()
&& isAllowedDimension
&& this.clientside.isRendering();
@@ -289,7 +289,7 @@ public class DhClientLevel extends AbstractDhLevel implements IDhClientLevel
if (this.syncOnLoginRequestQueue != null)
{
assert this.networkState != null;
if (this.networkState.config.synchronizeOnLogin)
if (this.networkState.config.getSynchronizeOnLogin())
{
this.syncOnLoginRequestQueue.addDebugMenuStringsToList(messageList);
}
@@ -3,14 +3,13 @@ package com.seibel.distanthorizons.core.multiplayer.client;
import com.google.common.cache.CacheBuilder;
import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.logging.ConfigBasedLogger;
import com.seibel.distanthorizons.core.multiplayer.config.MultiplayerConfig;
import com.seibel.distanthorizons.core.multiplayer.config.MultiplayerConfigChangeListener;
import com.seibel.distanthorizons.core.multiplayer.config.SessionConfig;
import com.seibel.distanthorizons.core.network.INetworkObject;
import com.seibel.distanthorizons.core.network.event.ScopedNetworkEventSource;
import com.seibel.distanthorizons.core.network.event.internal.CloseEvent;
import com.seibel.distanthorizons.core.network.event.internal.IncompatibleMessageEvent;
import com.seibel.distanthorizons.core.network.messages.base.CurrentLevelKeyMessage;
import com.seibel.distanthorizons.core.network.messages.base.RemotePlayerConfigMessage;
import com.seibel.distanthorizons.core.network.messages.base.SessionConfigMessage;
import com.seibel.distanthorizons.core.network.messages.fullData.FullDataChunkMessage;
import com.seibel.distanthorizons.core.network.messages.fullData.FullDataPartialUpdateMessage;
import com.seibel.distanthorizons.core.network.messages.fullData.FullDataPayload;
@@ -40,9 +39,9 @@ public class ClientNetworkState implements Closeable
*/
public Session getSession() { return this.session; }
public MultiplayerConfig config = new MultiplayerConfig();
public SessionConfig config = new SessionConfig();
private volatile boolean configReceived = false;
private final MultiplayerConfigChangeListener configChangeListener = new MultiplayerConfigChangeListener(this::sendConfigMessage);
private final SessionConfig.ChangeListener configChangeListener = new SessionConfig.ChangeListener(this::sendConfigMessage);
public boolean isReady() { return this.configReceived; }
private EServerSupportStatus serverSupportStatus = EServerSupportStatus.NONE;
@@ -78,12 +77,12 @@ public class ClientNetworkState implements Closeable
}
});
this.session.registerHandler(RemotePlayerConfigMessage.class, msg ->
this.session.registerHandler(SessionConfigMessage.class, msg ->
{
this.serverSupportStatus = EServerSupportStatus.FULL;
LOGGER.info("Connection config has been changed: " + msg.payload);
this.config = (MultiplayerConfig) msg.payload;
LOGGER.info("Connection config has been changed: {}", msg.config);
this.config = msg.config;
this.configReceived = true;
});
@@ -133,7 +132,7 @@ public class ClientNetworkState implements Closeable
public void sendConfigMessage()
{
this.configReceived = false;
this.getSession().sendMessage(new RemotePlayerConfigMessage(new MultiplayerConfig()));
this.getSession().sendMessage(new SessionConfigMessage(new SessionConfig()));
}
public void addDebugMenuStringsToList(List<String> messageList)
@@ -12,7 +12,7 @@ public class SyncOnLoginRequestQueue extends AbstractFullDataRequestQueue
}
@Override
protected int getRequestRateLimit() { return this.networkState.config.syncOnLoginRateLimit; }
protected int getRequestRateLimit() { return this.networkState.config.getSyncOnLoginRateLimit(); }
@Override
protected String getQueueName() { return "Sync On Login Queue"; }
@@ -20,7 +20,7 @@ public class SyncOnLoginRequestQueue extends AbstractFullDataRequestQueue
@Override
public boolean tick(DhBlockPos2D targetPos)
{
if (!this.networkState.config.synchronizeOnLogin)
if (!this.networkState.config.getSynchronizeOnLogin())
{
return false;
}
@@ -1,41 +0,0 @@
package com.seibel.distanthorizons.core.multiplayer.config;
import com.google.common.base.MoreObjects;
import com.seibel.distanthorizons.core.network.INetworkObject;
import io.netty.buffer.ByteBuf;
public abstract class AbstractMultiplayerConfig implements INetworkObject
{
public abstract int getRenderDistanceRadius();
public abstract boolean isDistantGenerationEnabled();
public abstract int getGenerationRequestRateLimit();
public abstract boolean isRealTimeUpdatesEnabled();
public abstract boolean getSynchronizeOnLogin();
public abstract int getSyncOnLoginRateLimit();
@Override
public void encode(ByteBuf out)
{
out.writeInt(this.getRenderDistanceRadius());
out.writeBoolean(this.isDistantGenerationEnabled());
out.writeInt(this.getGenerationRequestRateLimit());
out.writeBoolean(this.isRealTimeUpdatesEnabled());
out.writeBoolean(this.getSynchronizeOnLogin());
out.writeInt(this.getSyncOnLoginRateLimit());
}
@Override
public String toString()
{
return MoreObjects.toStringHelper(this)
.add("renderDistanceRadius", this.getRenderDistanceRadius())
.add("distantGenerationEnabled", this.isDistantGenerationEnabled())
.add("generationRequestRateLimit", this.getGenerationRequestRateLimit())
.add("realTimeUpdatesEnabled", this.isRealTimeUpdatesEnabled())
.add("synchronizeOnLogin", this.getSynchronizeOnLogin())
.add("syncOnLoginRateLimit", this.getSyncOnLoginRateLimit())
.toString();
}
}
@@ -1,40 +0,0 @@
package com.seibel.distanthorizons.core.multiplayer.config;
import com.seibel.distanthorizons.core.config.Config;
import io.netty.buffer.ByteBuf;
public class MultiplayerConfig extends AbstractMultiplayerConfig
{
// IMPORTANT: Once you added/removed config fields, modify MultiplayerConfigChangeListener accordingly.
public int renderDistanceRadius = Config.Client.Advanced.Graphics.Quality.lodChunkRenderDistanceRadius.get();
@Override public int getRenderDistanceRadius() { return this.renderDistanceRadius; }
public boolean distantGenerationEnabled = Config.Client.Advanced.WorldGenerator.enableDistantGeneration.get();
@Override public boolean isDistantGenerationEnabled() { return this.distantGenerationEnabled; }
public int generationRequestRateLimit = Config.Client.Advanced.Multiplayer.ServerNetworking.generationRequestRateLimit.get();
@Override public int getGenerationRequestRateLimit() { return this.generationRequestRateLimit; }
public boolean realTimeUpdatesEnabled = Config.Client.Advanced.Multiplayer.ServerNetworking.enableRealTimeUpdates.get();
@Override public boolean isRealTimeUpdatesEnabled() { return this.realTimeUpdatesEnabled; }
public boolean synchronizeOnLogin = Config.Client.Advanced.Multiplayer.ServerNetworking.synchronizeOnLogin.get();
@Override public boolean getSynchronizeOnLogin() { return this.synchronizeOnLogin; }
public int syncOnLoginRateLimit = Config.Client.Advanced.Multiplayer.ServerNetworking.syncOnLoginRateLimit.get();
@Override public int getSyncOnLoginRateLimit() { return this.syncOnLoginRateLimit; }
@Override
public void decode(ByteBuf in)
{
this.renderDistanceRadius = in.readInt();
this.distantGenerationEnabled = in.readBoolean();
this.generationRequestRateLimit = in.readInt();
this.realTimeUpdatesEnabled = in.readBoolean();
this.synchronizeOnLogin = in.readBoolean();
this.syncOnLoginRateLimit = in.readInt();
}
}
@@ -1,43 +0,0 @@
package com.seibel.distanthorizons.core.multiplayer.config;
import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.config.types.ConfigEntry;
import com.seibel.distanthorizons.core.config.listeners.ConfigChangeListener;
import java.io.Closeable;
import java.util.ArrayList;
@SuppressWarnings({"rawtypes", "unchecked"})
public class MultiplayerConfigChangeListener implements Closeable
{
private static final ConfigEntry[] CONFIG_ENTRIES = new ConfigEntry[] {
Config.Client.Advanced.Graphics.Quality.lodChunkRenderDistanceRadius,
Config.Client.Advanced.WorldGenerator.enableDistantGeneration,
Config.Client.Advanced.Multiplayer.ServerNetworking.generationRequestRateLimit,
Config.Client.Advanced.Multiplayer.ServerNetworking.enableRealTimeUpdates,
Config.Client.Advanced.Multiplayer.ServerNetworking.synchronizeOnLogin,
Config.Client.Advanced.Multiplayer.ServerNetworking.syncOnLoginRateLimit,
};
private final ArrayList<ConfigChangeListener> changeListeners;
public MultiplayerConfigChangeListener(Runnable runnable)
{
this.changeListeners = new ArrayList<>(CONFIG_ENTRIES.length);
for (ConfigEntry entry : CONFIG_ENTRIES)
{
this.changeListeners.add(new ConfigChangeListener(entry, ignored -> runnable.run()));
}
}
@Override
public void close()
{
for (ConfigChangeListener changeListener : this.changeListeners)
{
changeListener.close();
}
this.changeListeners.clear();
}
}
@@ -0,0 +1,145 @@
package com.seibel.distanthorizons.core.multiplayer.config;
import com.google.common.base.MoreObjects;
import com.seibel.distanthorizons.core.config.listeners.ConfigChangeListener;
import com.seibel.distanthorizons.core.config.types.ConfigEntry;
import com.seibel.distanthorizons.core.network.INetworkObject;
import io.netty.buffer.ByteBuf;
import java.io.Closeable;
import java.util.*;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Collectors;
import static com.seibel.distanthorizons.core.config.Config.Client.Advanced.*;
public class SessionConfig implements INetworkObject
{
private static final Map<String, Entry> CONFIG_ENTRIES = new HashMap<>();
private static <T> void registerConfigEntry(ConfigEntry<T> configEntry, BiFunction<T, T, T> valueConstrainer)
{
CONFIG_ENTRIES.put(Objects.requireNonNull(configEntry.getServersideShortName()), new Entry(configEntry, valueConstrainer));
}
private final SortedMap<String, Object> values = new ConcurrentSkipListMap<>();
public SessionConfig constrainingConfig;
static
{
// Note: config values are ordered by serversideShortName when transmitted
registerConfigEntry(Graphics.Quality.lodChunkRenderDistanceRadius, Math::min);
registerConfigEntry(WorldGenerator.enableDistantGeneration, (x, y) -> x && y);
registerConfigEntry(Multiplayer.ServerNetworking.generationRequestRateLimit, Math::min);
registerConfigEntry(Multiplayer.ServerNetworking.enableRealTimeUpdates, (x, y) -> x && y);
registerConfigEntry(Multiplayer.ServerNetworking.synchronizeOnLogin, (x, y) -> x && y);
registerConfigEntry(Multiplayer.ServerNetworking.syncOnLoginRateLimit, Math::min);
}
public int getRenderDistanceRadius() { return this.getValue(Graphics.Quality.lodChunkRenderDistanceRadius); }
public boolean isDistantGenerationEnabled() { return this.getValue(WorldGenerator.enableDistantGeneration); }
public int getGenerationRequestRateLimit() { return this.getValue(Multiplayer.ServerNetworking.generationRequestRateLimit); }
public boolean isRealTimeUpdatesEnabled() { return this.getValue(Multiplayer.ServerNetworking.enableRealTimeUpdates); }
public boolean getSynchronizeOnLogin() { return this.getValue(Multiplayer.ServerNetworking.synchronizeOnLogin); }
public int getSyncOnLoginRateLimit() { return this.getValue(Multiplayer.ServerNetworking.syncOnLoginRateLimit); }
@SuppressWarnings("unchecked")
private <T> T getValue(String name)
{
Entry entry = CONFIG_ENTRIES.get(name);
T value = (T) this.values.get(name);
if (value == null)
{
value = (T) entry.supplier.get();
}
return (this.constrainingConfig != null
? (T) entry.valueConstrainer.apply(value, this.constrainingConfig.getValue(name))
: value);
}
private <T> T getValue(ConfigEntry<T> configEntry)
{
return this.getValue(configEntry.getServersideShortName());
}
private Map<String, ?> getValues()
{
return CONFIG_ENTRIES.keySet().stream().collect(Collectors.toMap(Function.identity(), this::getValue));
}
@Override
public void encode(ByteBuf out)
{
this.writeFixedLengthCollection(out, this.getValues().values());
}
@Override
public void decode(ByteBuf in)
{
for (String key : CONFIG_ENTRIES.keySet())
{
Object currentValue = this.getValue(key);
Object newValue = Codec.getCodec(currentValue.getClass()).decode.apply(currentValue, in);
this.values.put(key, newValue);
}
}
@Override
public String toString()
{
return MoreObjects.toStringHelper(this)
.add("values", this.getValues())
.toString();
}
private static class Entry
{
public final ConfigEntry<Object> supplier;
public final BiFunction<Object, Object, Object> valueConstrainer;
@SuppressWarnings("unchecked")
private <T> Entry(ConfigEntry<T> supplier, BiFunction<T, T, T> valueConstrainer)
{
this.supplier = (ConfigEntry<Object>) supplier;
this.valueConstrainer = (BiFunction<Object, Object, Object>) valueConstrainer;
}
}
public static class ChangeListener implements Closeable
{
private final ArrayList<ConfigChangeListener<?>> changeListeners;
public ChangeListener(Runnable runnable)
{
this.changeListeners = new ArrayList<>(CONFIG_ENTRIES.size());
for (Entry entry : CONFIG_ENTRIES.values())
{
this.changeListeners.add(new ConfigChangeListener<>(entry.supplier, ignored -> runnable.run()));
}
}
@Override
public void close()
{
for (ConfigChangeListener<?> changeListener : this.changeListeners)
{
changeListener.close();
}
this.changeListeners.clear();
}
}
}
@@ -1,57 +0,0 @@
package com.seibel.distanthorizons.core.multiplayer.server;
import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.multiplayer.config.AbstractMultiplayerConfig;
import com.seibel.distanthorizons.core.multiplayer.config.MultiplayerConfig;
import io.netty.buffer.ByteBuf;
/**
* Used for constraining the client config to the server config.
*/
public class ConstrainedMultiplayerConfig extends AbstractMultiplayerConfig
{
public MultiplayerConfig clientConfig = new MultiplayerConfig();
@Override
public int getRenderDistanceRadius()
{
return Math.min(this.clientConfig.renderDistanceRadius, Config.Client.Advanced.Graphics.Quality.lodChunkRenderDistanceRadius.get());
}
@Override
public boolean isDistantGenerationEnabled()
{
return this.clientConfig.distantGenerationEnabled && Config.Client.Advanced.WorldGenerator.enableDistantGeneration.get();
}
@Override
public int getGenerationRequestRateLimit()
{
return Math.min(this.clientConfig.generationRequestRateLimit, Config.Client.Advanced.Multiplayer.ServerNetworking.generationRequestRateLimit.get());
}
@Override
public boolean isRealTimeUpdatesEnabled()
{
return this.clientConfig.realTimeUpdatesEnabled && Config.Client.Advanced.Multiplayer.ServerNetworking.enableRealTimeUpdates.get();
}
@Override
public boolean getSynchronizeOnLogin()
{
return this.clientConfig.synchronizeOnLogin && Config.Client.Advanced.Multiplayer.ServerNetworking.synchronizeOnLogin.get();
}
@Override
public int getSyncOnLoginRateLimit()
{
return Math.min(this.clientConfig.syncOnLoginRateLimit, Config.Client.Advanced.Multiplayer.ServerNetworking.syncOnLoginRateLimit.get());
}
@Override
public void decode(ByteBuf in)
{
throw new UnsupportedOperationException("Decoding is not supported for server-only class.");
}
}
@@ -2,10 +2,9 @@ package com.seibel.distanthorizons.core.multiplayer.server;
import com.seibel.distanthorizons.core.config.listeners.ConfigChangeListener;
import com.seibel.distanthorizons.core.level.DhServerLevel;
import com.seibel.distanthorizons.core.multiplayer.config.MultiplayerConfig;
import com.seibel.distanthorizons.core.multiplayer.config.MultiplayerConfigChangeListener;
import com.seibel.distanthorizons.core.multiplayer.config.SessionConfig;
import com.seibel.distanthorizons.core.network.messages.base.CurrentLevelKeyMessage;
import com.seibel.distanthorizons.core.network.messages.base.RemotePlayerConfigMessage;
import com.seibel.distanthorizons.core.network.messages.base.SessionConfigMessage;
import com.seibel.distanthorizons.core.network.event.internal.CloseEvent;
import com.seibel.distanthorizons.core.network.exceptions.RateLimitedException;
import com.seibel.distanthorizons.core.network.messages.fullData.FullDataSourceRequestMessage;
@@ -24,8 +23,8 @@ public class ServerPlayerState
public IServerPlayerWrapper serverPlayer() { return this.session.serverPlayer; }
@NotNull
public ConstrainedMultiplayerConfig config = new ConstrainedMultiplayerConfig();
private final MultiplayerConfigChangeListener configChangeListener = new MultiplayerConfigChangeListener(this::onConfigChanged);
public SessionConfig config = new SessionConfig();
private final SessionConfig.ChangeListener configChangeListener = new SessionConfig.ChangeListener(this::onConfigChanged);
private String lastLevelKey = "";
private final ConfigChangeListener<String> levelKeyPrefixChangeListener = new ConfigChangeListener<>(ServerNetworking.levelKeyPrefix, this::sendLevelKey);
@@ -46,11 +45,11 @@ public class ServerPlayerState
{
this.session = new Session(serverPlayer);
this.session.registerHandler(RemotePlayerConfigMessage.class, remotePlayerConfigMessage ->
this.session.registerHandler(SessionConfigMessage.class, sessionConfigMessage ->
{
this.config.clientConfig = (MultiplayerConfig) remotePlayerConfigMessage.payload;
this.config.constrainingConfig = sessionConfigMessage.config;
this.sendLevelKey(null);
this.session.sendMessage(new RemotePlayerConfigMessage(this.config));
this.session.sendMessage(new SessionConfigMessage(this.config));
});
this.session.registerHandler(CloseEvent.class, event -> {
@@ -74,7 +73,7 @@ public class ServerPlayerState
private void onConfigChanged()
{
this.session.sendMessage(new RemotePlayerConfigMessage(this.config));
this.session.sendMessage(new SessionConfigMessage(this.config));
}
public void close()
@@ -66,13 +66,23 @@ public interface INetworkObject
}
default void writeString(String inputString, ByteBuf outputByteBuf)
{
INetworkObject.writeStringStatic(inputString, outputByteBuf);
}
default String readString(ByteBuf inputByteBuf)
{
return INetworkObject.readStringStatic(inputByteBuf);
}
static void writeStringStatic(String inputString, ByteBuf outputByteBuf)
{
byte[] bytes = inputString.getBytes(StandardCharsets.UTF_8);
outputByteBuf.writeShort(bytes.length);
outputByteBuf.writeBytes(bytes);
}
default String readString(ByteBuf inputByteBuf)
static String readStringStatic(ByteBuf inputByteBuf)
{
int length = inputByteBuf.readUnsignedShort();
return inputByteBuf.readSlice(length).toString(StandardCharsets.UTF_8);
@@ -81,14 +91,13 @@ public interface INetworkObject
default <T> void writeCollection(ByteBuf outputByteBuf, Collection<T> collection)
{
outputByteBuf.writeInt(collection.size());
Codec codec = null;
this.writeFixedLengthCollection(outputByteBuf, collection);
}
default <T> void writeFixedLengthCollection(ByteBuf outputByteBuf, Collection<T> collection)
{
for (T item : collection)
{
if (codec == null)
{
codec = Codec.getCodec(item.getClass());
}
Codec codec = Codec.getCodec(item.getClass());
codec.encode.accept(item, outputByteBuf);
}
}
@@ -134,6 +143,8 @@ public interface INetworkObject
{{
// Primitives must be added manually here
this.put(Integer.class, new Codec((obj, out) -> out.writeInt((int)obj), (obj, in) -> in.readInt()));
this.put(Boolean.class, new Codec((obj, out) -> out.writeBoolean((boolean) obj), (obj, in) -> in.readBoolean()));
this.put(String.class, new Codec((obj, out) -> INetworkObject.writeStringStatic((String) obj, out), (obj, in) -> INetworkObject.readStringStatic(in)));
this.put(INetworkObject.class, new Codec(INetworkObject::encode, INetworkObject::decodeToInstance));
this.put(Map.Entry.class, new Codec(
@@ -162,7 +173,8 @@ public interface INetworkObject
this.decode = (BiFunction<Object, ByteBuf, Object>) decode;
}
public static Codec getCodec(Class<?> clazz) {
public static <T> Codec getCodec(Class<T> clazz)
{
return codecMap.computeIfAbsent(clazz, ignored -> {
for (Map.Entry<Class<?>, Codec> entry : codecMap.entrySet())
{
@@ -172,8 +184,9 @@ public interface INetworkObject
}
}
throw new AssertionError("Class has no compatible codec: "+clazz.getSimpleName());
throw new AssertionError("Class has no compatible codec: " + clazz.getSimpleName());
});
}
}
}
@@ -23,7 +23,7 @@ import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.seibel.distanthorizons.core.network.messages.base.CodecCrashMessage;
import com.seibel.distanthorizons.core.network.messages.base.CurrentLevelKeyMessage;
import com.seibel.distanthorizons.core.network.messages.base.RemotePlayerConfigMessage;
import com.seibel.distanthorizons.core.network.messages.base.SessionConfigMessage;
import com.seibel.distanthorizons.core.network.messages.fullData.FullDataChunkMessage;
import com.seibel.distanthorizons.core.network.messages.requests.CancelMessage;
import com.seibel.distanthorizons.core.network.messages.base.CloseReasonMessage;
@@ -59,7 +59,7 @@ public class MessageRegistry
this.registerMessage(CurrentLevelKeyMessage.class, CurrentLevelKeyMessage::new);
// Config (for full DH support)
this.registerMessage(RemotePlayerConfigMessage.class, RemotePlayerConfigMessage::new);
this.registerMessage(SessionConfigMessage.class, SessionConfigMessage::new);
// Requests
this.registerMessage(CancelMessage.class, CancelMessage::new);
@@ -20,31 +20,30 @@
package com.seibel.distanthorizons.core.network.messages.base;
import com.google.common.base.MoreObjects;
import com.seibel.distanthorizons.core.multiplayer.config.AbstractMultiplayerConfig;
import com.seibel.distanthorizons.core.multiplayer.config.MultiplayerConfig;
import com.seibel.distanthorizons.core.multiplayer.config.SessionConfig;
import com.seibel.distanthorizons.core.network.INetworkObject;
import com.seibel.distanthorizons.core.network.messages.NetworkMessage;
import io.netty.buffer.ByteBuf;
public class RemotePlayerConfigMessage extends NetworkMessage
public class SessionConfigMessage extends NetworkMessage
{
public AbstractMultiplayerConfig payload;
public SessionConfig config;
public RemotePlayerConfigMessage() { }
public RemotePlayerConfigMessage(AbstractMultiplayerConfig payload) { this.payload = payload; }
public SessionConfigMessage() { }
public SessionConfigMessage(SessionConfig config) { this.config = config; }
@Override
public void encode(ByteBuf out) { this.payload.encode(out); }
public void encode(ByteBuf out) { this.config.encode(out); }
@Override
public void decode(ByteBuf in) { this.payload = INetworkObject.decodeToInstance(new MultiplayerConfig(), in); }
public void decode(ByteBuf in) { this.config = INetworkObject.decodeToInstance(new SessionConfig(), in); }
@Override
public MoreObjects.ToStringHelper toStringHelper()
{
return super.toStringHelper()
.add("payload", this.payload);
.add("config", this.config);
}
}