Refactor session config
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
+1
-1
@@ -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);
|
||||
}
|
||||
|
||||
+8
-9
@@ -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)
|
||||
|
||||
+2
-2
@@ -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;
|
||||
}
|
||||
|
||||
-41
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
-40
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
-43
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
+145
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
-57
@@ -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.");
|
||||
}
|
||||
|
||||
}
|
||||
+8
-9
@@ -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());
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -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);
|
||||
|
||||
+8
-9
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user