Use level keys
This commit is contained in:
@@ -50,7 +50,6 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrap
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||
import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Mat4f;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -132,6 +131,8 @@ public class ClientApi
|
||||
DhClientWorld world = new DhClientWorld();
|
||||
SharedApi.setDhWorld(world);
|
||||
|
||||
this.pluginChannelApi.onJoin(world.networkState.getSession());
|
||||
world.networkState.sendConfigMessage();
|
||||
|
||||
LOGGER.info("Loading [" + this.waitingClientLevels.size() + "] waiting client level wrappers.");
|
||||
for (IClientLevelWrapper level : this.waitingClientLevels)
|
||||
@@ -140,8 +141,6 @@ public class ClientApi
|
||||
}
|
||||
|
||||
this.waitingClientLevels.clear();
|
||||
|
||||
this.pluginChannelApi.onJoin(world.networkState.getSession());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -206,17 +205,20 @@ public class ClientApi
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!this.pluginChannelApi.allowLoadingLevel())
|
||||
{
|
||||
LOGGER.info("Levels in this connection are managed by the server and loading is not allowed, ignoring auto-load.");
|
||||
return;
|
||||
}
|
||||
|
||||
LOGGER.info("Loading client level [" + level + "]-["+level.getDimensionType().getDimensionName()+"].");
|
||||
|
||||
AbstractDhWorld world = SharedApi.getAbstractDhWorld();
|
||||
if (world != null)
|
||||
{
|
||||
if (!this.pluginChannelApi.allowLevelAutoload())
|
||||
{
|
||||
LOGGER.info("Levels in this connection are managed by the server, skipping auto-load.");
|
||||
|
||||
// Instead of attempting to load themselves, send config and wait for level key.
|
||||
((DhClientWorld) world).networkState.sendConfigMessage();
|
||||
return;
|
||||
}
|
||||
|
||||
world.getOrLoadLevel(level);
|
||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiLevelLoadEvent.class, new DhApiLevelLoadEvent.EventParam(level));
|
||||
|
||||
|
||||
+7
-9
@@ -7,18 +7,17 @@ import com.seibel.distanthorizons.core.level.IServerKeyedClientLevel;
|
||||
import com.seibel.distanthorizons.core.logging.ConfigBasedLogger;
|
||||
import com.seibel.distanthorizons.core.network.messages.plugin.PluginCloseEvent;
|
||||
import com.seibel.distanthorizons.core.network.messages.plugin.CurrentLevelKeyMessage;
|
||||
import com.seibel.distanthorizons.core.network.messages.plugin.base.ClientHelloMessage;
|
||||
import com.seibel.distanthorizons.core.network.plugin.PluginChannelSession;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* This class is used to manage the level keys.
|
||||
* Its purpose is to separate MC's and plugin channel's event handling.
|
||||
*/
|
||||
public class ClientPluginChannelApi
|
||||
{
|
||||
@@ -33,7 +32,7 @@ public class ClientPluginChannelApi
|
||||
public PluginChannelSession session;
|
||||
|
||||
|
||||
public boolean allowLoadingLevel()
|
||||
public boolean allowLevelAutoload()
|
||||
{
|
||||
return (KEYED_CLIENT_LEVEL_MANAGER.isEnabled() && KEYED_CLIENT_LEVEL_MANAGER.getServerKeyedLevel() != null)
|
||||
|| !KEYED_CLIENT_LEVEL_MANAGER.isEnabled();
|
||||
@@ -44,15 +43,12 @@ public class ClientPluginChannelApi
|
||||
{
|
||||
this.levelUnloadHandler = levelUnloadHandler;
|
||||
this.multiverseLevelLoadHandler = levelLoadHandler;
|
||||
|
||||
}
|
||||
|
||||
public void onJoin(PluginChannelSession session)
|
||||
public void onJoin(@NonNull PluginChannelSession session)
|
||||
{
|
||||
Objects.requireNonNull(session);
|
||||
this.session = session;
|
||||
|
||||
this.session.sendMessage(new ClientHelloMessage());
|
||||
|
||||
this.session.registerHandler(CurrentLevelKeyMessage.class, this::onCurrentLevelKeyMessage);
|
||||
this.session.registerHandler(PluginCloseEvent.class, this::onClose);
|
||||
}
|
||||
@@ -71,7 +67,9 @@ public class ClientPluginChannelApi
|
||||
|
||||
if (clientLevel != null)
|
||||
{
|
||||
// In either case only one of them will have an effect.
|
||||
this.levelUnloadHandler.accept(clientLevel);
|
||||
this.levelUnloadHandler.accept(KEYED_CLIENT_LEVEL_MANAGER.getServerKeyedLevel());
|
||||
}
|
||||
|
||||
IServerKeyedClientLevel keyedLevel = KEYED_CLIENT_LEVEL_MANAGER.setServerKeyedLevel(clientLevel, msg.levelKey);
|
||||
|
||||
@@ -899,6 +899,28 @@ public class Config
|
||||
.build();
|
||||
|
||||
|
||||
|
||||
public static ConfigEntry<Boolean> sendLevelKeys = new ConfigEntry.Builder<Boolean>()
|
||||
.setServersideShortName("sendLevelKeys")
|
||||
.setAppearance(EConfigEntryAppearance.ONLY_IN_FILE)
|
||||
.set(true)
|
||||
.comment(""
|
||||
+ "Makes the server send level keys for each world.\n"
|
||||
+ "Disable this if you use alternative ways to send level keys.\n"
|
||||
+ "")
|
||||
.build();
|
||||
public static ConfigEntry<String> levelKeyPrefix = new ConfigEntry.Builder<String>()
|
||||
.setServersideShortName("levelKeyPrefix")
|
||||
.setAppearance(EConfigEntryAppearance.ONLY_IN_FILE)
|
||||
.set("")
|
||||
.comment(""
|
||||
+ "Prefix of the level keys sent to the clients.\n"
|
||||
+ "Should be set to a unique value for each backend server behind a proxy,\n"
|
||||
+ "or empty if you don't use a proxy.\n"
|
||||
+ "")
|
||||
.build();
|
||||
|
||||
|
||||
public static ConfigUIComment generationSectionNote = new ConfigUIComment();
|
||||
public static ConfigEntry<Integer> generationRequestRCLimit = new ConfigEntry.Builder<Integer>()
|
||||
.setServersideShortName("generationRequestRCLimit")
|
||||
|
||||
+2
-2
@@ -24,7 +24,7 @@ public class ClientNetworkState implements Closeable
|
||||
|
||||
public MultiplayerConfig config = new MultiplayerConfig();
|
||||
private volatile boolean configReceived = false;
|
||||
private final MultiplayerConfigChangeListener configChangeListener = new MultiplayerConfigChangeListener(this::onConfigChanged);
|
||||
private final MultiplayerConfigChangeListener configChangeListener = new MultiplayerConfigChangeListener(this::sendConfigMessage);
|
||||
public boolean isReady() { return this.configReceived; }
|
||||
|
||||
private final F3Screen.NestedMessage f3Message = new F3Screen.NestedMessage(this::f3Log);
|
||||
@@ -55,7 +55,7 @@ public class ClientNetworkState implements Closeable
|
||||
});
|
||||
}
|
||||
|
||||
private void onConfigChanged()
|
||||
public void sendConfigMessage()
|
||||
{
|
||||
this.configReceived = false;
|
||||
this.getSession().sendMessage(new RemotePlayerConfigMessage(new MultiplayerConfig()));
|
||||
|
||||
-3
@@ -9,7 +9,6 @@ public abstract class AbstractMultiplayerConfig implements INetworkObject
|
||||
public abstract int getRenderDistanceRadius();
|
||||
public abstract boolean isDistantGenerationEnabled();
|
||||
public abstract int getFullDataRequestConcurrencyLimit();
|
||||
public abstract int getGenTaskPriorityRequestRateLimit();
|
||||
public abstract boolean isRealTimeUpdatesEnabled();
|
||||
public abstract boolean isLoginDataSyncEnabled();
|
||||
public abstract int getLoginDataSyncRCLimit();
|
||||
@@ -20,7 +19,6 @@ public abstract class AbstractMultiplayerConfig implements INetworkObject
|
||||
out.writeInt(this.getRenderDistanceRadius());
|
||||
out.writeBoolean(this.isDistantGenerationEnabled());
|
||||
out.writeInt(this.getFullDataRequestConcurrencyLimit());
|
||||
out.writeInt(this.getGenTaskPriorityRequestRateLimit());
|
||||
out.writeBoolean(this.isRealTimeUpdatesEnabled());
|
||||
out.writeBoolean(this.isLoginDataSyncEnabled());
|
||||
out.writeInt(this.getLoginDataSyncRCLimit());
|
||||
@@ -34,7 +32,6 @@ public abstract class AbstractMultiplayerConfig implements INetworkObject
|
||||
.add("renderDistanceRadius", this.getRenderDistanceRadius())
|
||||
.add("distantGenerationEnabled", this.isDistantGenerationEnabled())
|
||||
.add("fullDataRequestConcurrencyLimit", this.getFullDataRequestConcurrencyLimit())
|
||||
.add("genTaskPriorityRequestRateLimit", this.getGenTaskPriorityRequestRateLimit())
|
||||
.add("realTimeUpdatesEnabled", this.isRealTimeUpdatesEnabled())
|
||||
.add("loginDataSyncEnabled", this.isLoginDataSyncEnabled())
|
||||
.add("loginDataSyncRCLimit", this.getLoginDataSyncRCLimit())
|
||||
|
||||
-4
@@ -16,9 +16,6 @@ public class MultiplayerConfig extends AbstractMultiplayerConfig
|
||||
public int fullDataRequestConcurrencyLimit = Config.Client.Advanced.Multiplayer.ServerNetworking.generationRequestRCLimit.get();
|
||||
@Override public int getFullDataRequestConcurrencyLimit() { return this.fullDataRequestConcurrencyLimit; }
|
||||
|
||||
public int genTaskPriorityRequestRateLimit = Config.Client.Advanced.Multiplayer.ServerNetworking.genTaskPriorityRequestRateLimit.get();
|
||||
@Override public int getGenTaskPriorityRequestRateLimit() { return this.genTaskPriorityRequestRateLimit; }
|
||||
|
||||
public boolean realTimeUpdatesEnabled = Config.Client.Advanced.Multiplayer.ServerNetworking.enableRealTimeUpdates.get();
|
||||
@Override public boolean isRealTimeUpdatesEnabled() { return this.realTimeUpdatesEnabled; }
|
||||
|
||||
@@ -35,7 +32,6 @@ public class MultiplayerConfig extends AbstractMultiplayerConfig
|
||||
this.renderDistanceRadius = in.readInt();
|
||||
this.distantGenerationEnabled = in.readBoolean();
|
||||
this.fullDataRequestConcurrencyLimit = in.readInt();
|
||||
this.genTaskPriorityRequestRateLimit = in.readInt();
|
||||
this.realTimeUpdatesEnabled = in.readBoolean();
|
||||
this.loginDataSyncEnabled = in.readBoolean();
|
||||
this.loginDataSyncRCLimit = in.readInt();
|
||||
|
||||
-6
@@ -30,12 +30,6 @@ public class ConstrainedMultiplayerConfig extends AbstractMultiplayerConfig
|
||||
return Math.min(this.clientConfig.fullDataRequestConcurrencyLimit, Config.Client.Advanced.Multiplayer.ServerNetworking.generationRequestRCLimit.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getGenTaskPriorityRequestRateLimit()
|
||||
{
|
||||
return Math.min(this.clientConfig.genTaskPriorityRequestRateLimit, Config.Client.Advanced.Multiplayer.ServerNetworking.genTaskPriorityRequestRateLimit.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRealTimeUpdatesEnabled()
|
||||
{
|
||||
|
||||
-6
@@ -1,20 +1,14 @@
|
||||
package com.seibel.distanthorizons.core.multiplayer.server;
|
||||
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.logging.ConfigBasedLogger;
|
||||
import com.seibel.distanthorizons.core.network.plugin.PluginChannelMessage;
|
||||
import com.seibel.distanthorizons.core.network.plugin.PluginChannelSession;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IServerPlayerWrapper;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
public class RemotePlayerConnectionHandler
|
||||
{
|
||||
private static final ConfigBasedLogger LOGGER = new ConfigBasedLogger(LogManager.getLogger(),
|
||||
() -> Config.Client.Advanced.Logging.logNetworkEvent.get());
|
||||
|
||||
private final ConcurrentMap<IServerPlayerWrapper, ServerPlayerState> connectedPlayers = new ConcurrentHashMap<>();
|
||||
|
||||
|
||||
|
||||
+20
-6
@@ -5,9 +5,9 @@ import com.seibel.distanthorizons.core.level.DhServerLevel;
|
||||
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.network.messages.plugin.CurrentLevelKeyMessage;
|
||||
import com.seibel.distanthorizons.core.network.messages.plugin.session.RemotePlayerConfigMessage;
|
||||
import com.seibel.distanthorizons.core.network.messages.plugin.PluginCloseEvent;
|
||||
import com.seibel.distanthorizons.core.network.messages.plugin.base.ClientHelloMessage;
|
||||
import com.seibel.distanthorizons.core.network.exceptions.RateLimitedException;
|
||||
import com.seibel.distanthorizons.core.network.messages.plugin.fullData.FullDataSourceRequestMessage;
|
||||
import com.seibel.distanthorizons.core.network.plugin.PluginChannelSession;
|
||||
@@ -22,9 +22,6 @@ import static com.seibel.distanthorizons.core.config.Config.Client.Advanced.Mult
|
||||
|
||||
public class ServerPlayerState
|
||||
{
|
||||
private static final ConfigBasedLogger LOGGER = new ConfigBasedLogger(LogManager.getLogger(),
|
||||
() -> Config.Client.Advanced.Logging.logNetworkEvent.get());
|
||||
|
||||
public final PluginChannelSession session;
|
||||
public IServerPlayerWrapper serverPlayer() { return this.session.serverPlayer; }
|
||||
|
||||
@@ -51,11 +48,28 @@ public class ServerPlayerState
|
||||
this.session.registerHandler(RemotePlayerConfigMessage.class, remotePlayerConfigMessage ->
|
||||
{
|
||||
this.config.clientConfig = (MultiplayerConfig) remotePlayerConfigMessage.payload;
|
||||
|
||||
if (ServerNetworking.sendLevelKeys.get())
|
||||
{
|
||||
String levelKeyPrefix = ServerNetworking.levelKeyPrefix.get();
|
||||
String dimensionName = serverPlayer.getLevel().getDimensionType().getDimensionName();
|
||||
|
||||
String levelKey;
|
||||
if (!levelKeyPrefix.isEmpty())
|
||||
{
|
||||
levelKey = levelKeyPrefix + "_" + dimensionName;
|
||||
}
|
||||
else
|
||||
{
|
||||
levelKey = dimensionName;
|
||||
}
|
||||
|
||||
this.session.sendMessage(new CurrentLevelKeyMessage(levelKey));
|
||||
}
|
||||
|
||||
this.session.sendMessage(new RemotePlayerConfigMessage(this.config));
|
||||
});
|
||||
|
||||
this.session.registerHandler(ClientHelloMessage.class, msg -> this.onConfigChanged());
|
||||
|
||||
this.session.registerHandler(PluginCloseEvent.class, event -> {
|
||||
// Noop
|
||||
});
|
||||
|
||||
+6
-8
@@ -22,7 +22,6 @@ package com.seibel.distanthorizons.core.network.messages;
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import com.seibel.distanthorizons.core.network.messages.plugin.CurrentLevelKeyMessage;
|
||||
import com.seibel.distanthorizons.core.network.messages.plugin.base.ClientHelloMessage;
|
||||
import com.seibel.distanthorizons.core.network.messages.plugin.base.CancelMessage;
|
||||
import com.seibel.distanthorizons.core.network.messages.plugin.base.CloseReasonMessage;
|
||||
import com.seibel.distanthorizons.core.network.messages.plugin.base.ExceptionMessage;
|
||||
@@ -49,20 +48,19 @@ public class PluginMessageRegistry
|
||||
{
|
||||
// Note: Messages must have parameterless constructors
|
||||
|
||||
// Always sent by the client
|
||||
this.registerMessage(ClientHelloMessage.class, ClientHelloMessage::new);
|
||||
// When the communication is about to be stopped, either side can send this message
|
||||
this.registerMessage(CloseReasonMessage.class, CloseReasonMessage::new);
|
||||
|
||||
// Multiverse support
|
||||
// Level keys
|
||||
this.registerMessage(CurrentLevelKeyMessage.class, CurrentLevelKeyMessage::new);
|
||||
|
||||
// Core
|
||||
// Config (for full DH support)
|
||||
this.registerMessage(RemotePlayerConfigMessage.class, RemotePlayerConfigMessage::new);
|
||||
|
||||
// Requests
|
||||
this.registerMessage(CancelMessage.class, CancelMessage::new);
|
||||
this.registerMessage(ExceptionMessage.class, ExceptionMessage::new);
|
||||
|
||||
// ID & config
|
||||
this.registerMessage(RemotePlayerConfigMessage.class, RemotePlayerConfigMessage::new);
|
||||
|
||||
// Full data requests & updates
|
||||
this.registerMessage(FullDataSourceRequestMessage.class, FullDataSourceRequestMessage::new);
|
||||
this.registerMessage(FullDataSourceResponseMessage.class, FullDataSourceResponseMessage::new);
|
||||
|
||||
+2
-7
@@ -7,27 +7,23 @@ import io.netty.buffer.ByteBuf;
|
||||
public class CurrentLevelKeyMessage extends PluginChannelMessage
|
||||
{
|
||||
public String levelKey;
|
||||
public boolean deleteExistingData;
|
||||
|
||||
public CurrentLevelKeyMessage() { }
|
||||
public CurrentLevelKeyMessage(String levelKey, boolean deleteExistingData)
|
||||
public CurrentLevelKeyMessage(String levelKey)
|
||||
{
|
||||
this.levelKey = levelKey;
|
||||
this.deleteExistingData = deleteExistingData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(ByteBuf out)
|
||||
{
|
||||
this.writeString(this.levelKey, out);
|
||||
out.writeBoolean(this.deleteExistingData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decode(ByteBuf in)
|
||||
{
|
||||
this.levelKey = this.readString(in);
|
||||
this.deleteExistingData = in.readBoolean();
|
||||
}
|
||||
|
||||
|
||||
@@ -35,8 +31,7 @@ public class CurrentLevelKeyMessage extends PluginChannelMessage
|
||||
public MoreObjects.ToStringHelper toStringHelper()
|
||||
{
|
||||
return super.toStringHelper()
|
||||
.add("levelKey", this.levelKey)
|
||||
.add("deleteExistingData", this.deleteExistingData);
|
||||
.add("levelKey", this.levelKey);
|
||||
}
|
||||
|
||||
}
|
||||
-22
@@ -1,22 +0,0 @@
|
||||
package com.seibel.distanthorizons.core.network.messages.plugin.base;
|
||||
|
||||
import com.seibel.distanthorizons.core.network.plugin.PluginChannelMessage;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
/**
|
||||
* Serves as a trigger for the server to send some useful data to the client.
|
||||
* Not integral to establishing a session.
|
||||
*/
|
||||
public class ClientHelloMessage extends PluginChannelMessage
|
||||
{
|
||||
@Override
|
||||
public void encode(ByteBuf out)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decode(ByteBuf in)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
-6
@@ -74,12 +74,6 @@ public class PluginChannelSession extends NetworkEventSource
|
||||
{
|
||||
LOGGER.debug("Sending message: {}", message);
|
||||
|
||||
Consumer<ByteBuf> encoder = buffer -> {
|
||||
buffer.writeShort(ModInfo.PROTOCOL_VERSION);
|
||||
buffer.writeShort(PluginMessageRegistry.INSTANCE.getMessageId(message));
|
||||
message.encode(buffer);
|
||||
};
|
||||
|
||||
if (this.serverPlayer != null)
|
||||
{
|
||||
PACKET_SENDER.sendPluginPacketServer(this.serverPlayer, message);
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
package com.seibel.distanthorizons.core.world;
|
||||
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.file.structure.ClientOnlySaveStructure;
|
||||
import com.seibel.distanthorizons.core.level.DhClientLevel;
|
||||
import com.seibel.distanthorizons.core.level.IDhLevel;
|
||||
|
||||
@@ -24,12 +24,10 @@ import com.seibel.distanthorizons.core.level.DhServerLevel;
|
||||
import com.seibel.distanthorizons.core.level.IDhLevel;
|
||||
import com.seibel.distanthorizons.core.multiplayer.server.RemotePlayerConnectionHandler;
|
||||
import com.seibel.distanthorizons.core.multiplayer.server.ServerPlayerState;
|
||||
import com.seibel.distanthorizons.core.network.plugin.PluginChannelMessage;
|
||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IServerPlayerWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
Reference in New Issue
Block a user