LAN multiplayer kinda works

This commit is contained in:
s809
2024-09-23 00:02:31 +05:00
parent b18460b825
commit 6c278ea3b1
9 changed files with 53 additions and 79 deletions
@@ -149,7 +149,7 @@ public class ServerApi
public void serverPlayerJoinEvent(IServerPlayerWrapper player)
{
IDhServerWorld serverWorld = SharedApi.getIDhServerWorld();
LOGGER.info("Player [" + player.getName() + "] joined.");
LOGGER.info("Player [${player.getName()}] joined.");
if (serverWorld != null)
{
serverWorld.addPlayer(player);
@@ -158,7 +158,7 @@ public class ServerApi
public void serverPlayerDisconnectEvent(IServerPlayerWrapper player)
{
IDhServerWorld serverWorld = SharedApi.getIDhServerWorld();
LOGGER.info("Player [" + player.getName() + "] disconnected.");
LOGGER.info("Player [${player.getName()}] disconnected.");
if (serverWorld != null)
{
serverWorld.removePlayer(player);
@@ -167,7 +167,7 @@ public class ServerApi
public void serverPlayerLevelChangeEvent(IServerPlayerWrapper player, IServerLevelWrapper originLevel, IServerLevelWrapper destinationLevel)
{
IDhServerWorld serverWorld = SharedApi.getIDhServerWorld();
LOGGER.info("Player [" + player.getName() + "] changed level: [" + originLevel.getKeyedLevelDimensionName() + "] -> [" + destinationLevel.getKeyedLevelDimensionName() + "].");
LOGGER.info("Player [${player.getName()}] changed level: [${originLevel.getKeyedLevelDimensionName()}] -> [${destinationLevel.getKeyedLevelDimensionName()}].");
if (serverWorld != null)
{
serverWorld.changePlayerLevel(player, originLevel, destinationLevel);
@@ -64,12 +64,10 @@ public abstract class AbstractDhServerLevel extends AbstractDhLevel implements I
// constructor //
//=============//
public AbstractDhServerLevel(
AbstractSaveStructure saveStructure,
IServerLevelWrapper serverLevelWrapper,
ServerPlayerStateManager serverPlayerStateManager
)
{ this(saveStructure, serverLevelWrapper, serverPlayerStateManager, true); }
public AbstractDhServerLevel(AbstractSaveStructure saveStructure, IServerLevelWrapper serverLevelWrapper, ServerPlayerStateManager serverPlayerStateManager)
{
this(saveStructure, serverLevelWrapper, serverPlayerStateManager, true);
}
public AbstractDhServerLevel(
AbstractSaveStructure saveStructure,
IServerLevelWrapper serverLevelWrapper,
@@ -89,7 +87,7 @@ public abstract class AbstractDhServerLevel extends AbstractDhLevel implements I
this.runRepoReliantSetup();
}
LOGGER.info("Started " + this.getClass().getSimpleName() + " for [" + serverLevelWrapper + "] at [" + saveStructure + "].");
LOGGER.info("Started ${this.getClass().getSimpleName()} for $serverLevelWrapper at $saveStructure.");
this.serverPlayerStateManager = serverPlayerStateManager;
}
@@ -113,7 +111,7 @@ public abstract class AbstractDhServerLevel extends AbstractDhLevel implements I
continue;
}
NETWORK_LOGGER.debug("[" + this.serverLevelWrapper.getDimensionName() + "] Fulfilled request group [" + entry.getKey() + "]");
NETWORK_LOGGER.debug("[${this.serverLevelWrapper.getDimensionName()}] Fulfilled request group [${entry.getKey()}]");
// Make this group unavailable for adding into
this.requestGroupByPos.remove(entry.getKey());
@@ -148,7 +146,10 @@ public abstract class AbstractDhServerLevel extends AbstractDhLevel implements I
}
@Override
public abstract boolean shouldDoWorldGen();
public boolean shouldDoWorldGen()
{
return Config.Client.Advanced.WorldGenerator.enableDistantGeneration.get() && !this.worldGenPlayerCenteringQueue.isEmpty();
}
@Override
@Nullable
@@ -224,7 +225,7 @@ public abstract class AbstractDhServerLevel extends AbstractDhLevel implements I
FullDataSourceRequestMessage requestMessage = requestGroup.requestMessages.remove(msg.futureId);
if (requestGroup.requestMessages.isEmpty())
{
NETWORK_LOGGER.debug("[" + this.serverLevelWrapper.getDimensionName() + "] Cancelled request group [" + DhSectionPos.toString(requestMessage.sectionPos) + "].");
NETWORK_LOGGER.debug("[${this.serverLevelWrapper.getDimensionName()}] Cancelled request group [${DhSectionPos.toString(requestMessage.sectionPos)}].");
this.requestGroupByPos.remove(requestMessage.sectionPos);
this.serverside.fullDataFileHandler.removeRetrievalRequestIf(pos -> pos == requestMessage.sectionPos);
}
@@ -300,7 +301,7 @@ public abstract class AbstractDhServerLevel extends AbstractDhLevel implements I
{
DataSourceRequestGroup newGroup = new DataSourceRequestGroup();
this.tryFulfillDataSourceRequestGroup(newGroup, pos);
NETWORK_LOGGER.debug("[" + this.serverLevelWrapper.getDimensionName() + "] Created request group for pos [" + DhSectionPos.toString(pos) + "].");
NETWORK_LOGGER.debug("[${serverLevelWrapper.getDimensionName()}] Created request group for pos [${DhSectionPos.toString(pos)}].");
return newGroup;
});
@@ -324,7 +325,7 @@ public abstract class AbstractDhServerLevel extends AbstractDhLevel implements I
{
if (!(message instanceof ILevelRelatedMessage))
{
LodUtil.assertNotReach("Received message [" + ILevelRelatedMessage.class.getSimpleName() + "] does not implement [" + message.getClass().getSimpleName() + "]");
LodUtil.assertNotReach("Received message [$message] does not implement [${ILevelRelatedMessage.class.getSimpleName()}]");
}
// Only handle requests for this level
@@ -345,9 +346,9 @@ public abstract class AbstractDhServerLevel extends AbstractDhLevel implements I
((AbstractTrackableMessage) message).sendResponse(
new InvalidLevelException(
"Generation not allowed. " +
"Requested dimension: [" + ((ILevelRelatedMessage) message).getLevelName() + "], " +
"player dimension: [" + message.getSession().serverPlayer.getLevel().getDimensionName() + "], " +
"handler dimension: [" + this.getLevelWrapper().getDimensionName() + "]"
"Requested dimension: [${((ILevelRelatedMessage) message).getLevelName()}], " +
"player dimension: [${message.getSession().serverPlayer.getLevel().getDimensionName()}], " +
"handler dimension: [${this.getLevelWrapper().getDimensionName()}]"
)
);
}
@@ -495,11 +496,9 @@ public abstract class AbstractDhServerLevel extends AbstractDhLevel implements I
public FullDataSourceV2 fullDataSource;
/**
* These semaphores prevent a given thread from accidentally locking on the same group
* multiple times, as the semaphore is tied to the given thread. <br>
* Reentrant Lock isn't used since it would allow the thread to lock on the same group. <br>
* the Short.MAX_VALUE is just a very large number that should be larger than the number of
* threads we'll have.
* These two Semaphores are used to prevent all threads from locking on the group after it being fulfilled,
* as opposed to ReentrantReadWriteLocks which would allow the locking thread continue using it anyway. <br>
* Short.MAX_VALUE is chosen as a large enough number so non-exclusive accesses never block each other.
*/
public final Semaphore requestAddSemaphore = new Semaphore(Short.MAX_VALUE, true);
/** @see DataSourceRequestGroup#requestAddSemaphore */
@@ -28,7 +28,6 @@ import com.seibel.distanthorizons.core.render.RenderBufferHandler;
import com.seibel.distanthorizons.core.render.renderer.DebugRenderer;
import com.seibel.distanthorizons.core.file.structure.AbstractSaveStructure;
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos;
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos2D;
import com.seibel.distanthorizons.core.render.renderer.generic.GenericObjectRenderer;
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper;
@@ -36,7 +35,6 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftCli
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
import java.util.List;
@@ -48,7 +46,6 @@ public class DhClientServerLevel extends AbstractDhServerLevel implements IDhCli
private static final IMinecraftClientWrapper MC_CLIENT = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
public final ClientLevelModule clientside;
private int localPlayerWorldGenPosInQueue = 0;
@@ -82,28 +79,6 @@ public class DhClientServerLevel extends AbstractDhServerLevel implements IDhCli
public void renderDeferred(DhApiRenderParam renderEventParam, IProfilerWrapper profiler)
{ this.clientside.renderDeferred(renderEventParam, profiler); }
@Override
public boolean shouldDoWorldGen()
{
return this.serverside.worldGeneratorEnabledConfig.get() && this.clientside.isRendering() || !this.worldGenPlayerCenteringQueue.isEmpty();
}
@Override
@Nullable
public DhBlockPos2D getTargetPosForGeneration()
{
if (this.localPlayerWorldGenPosInQueue > 0)
{
this.localPlayerWorldGenPosInQueue--;
return super.getTargetPosForGeneration();
}
else
{
this.localPlayerWorldGenPosInQueue = this.worldGenPlayerCenteringQueue.size();
return new DhBlockPos2D(MC_CLIENT.getPlayerBlockPos());
}
}
//========//
// render //
//========//
@@ -78,8 +78,7 @@ public class DhServerLevel extends AbstractDhServerLevel
@Override
public void addDebugMenuStringsToList(List<String> messageList)
{
String dimName = this.serverLevelWrapper.getDimensionName();
messageList.add("["+dimName+"]");
messageList.add("[${this.serverLevelWrapper.getDimensionName()}]");
}
@@ -93,7 +92,7 @@ public class DhServerLevel extends AbstractDhServerLevel
{
super.close();
this.serverside.close();
LOGGER.info("Closed DHLevel for ["+this.getLevelWrapper()+"].");
LOGGER.info("Closed DHLevel for [${this.getLevelWrapper()}].");
}
}
@@ -37,7 +37,6 @@ public class ServerLevelModule implements AutoCloseable
private final IDhServerLevel parentServerLevel;
public final AbstractSaveStructure saveStructure;
public final GeneratedFullDataSourceProvider fullDataFileHandler;
public final AppliedConfigState<Boolean> worldGeneratorEnabledConfig;
public final WorldGenModule worldGenModule;
@@ -52,7 +51,6 @@ public class ServerLevelModule implements AutoCloseable
this.parentServerLevel = parentServerLevel;
this.saveStructure = saveStructure;
this.fullDataFileHandler = new GeneratedFullDataSourceProvider(parentServerLevel, saveStructure);
this.worldGeneratorEnabledConfig = new AppliedConfigState<>(Config.Client.Advanced.WorldGenerator.enableDistantGeneration);
this.worldGenModule = new WorldGenModule(this.parentServerLevel, this.fullDataFileHandler, () -> new ServerLevelModule.WorldGenState(this.parentServerLevel));
}
@@ -1,7 +1,6 @@
package com.seibel.distanthorizons.core.multiplayer.server;
import com.seibel.distanthorizons.core.network.messages.AbstractNetworkMessage;
import com.seibel.distanthorizons.core.network.session.NetworkSession;
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IServerPlayerWrapper;
import org.jetbrains.annotations.Nullable;
@@ -26,10 +25,6 @@ public class ServerPlayerStateManager
{
ServerPlayerState playerState = new ServerPlayerState(serverPlayer);
this.connectedPlayerStateByPlayerWrapper.put(serverPlayer, playerState);
MessageQueueState messageQueue = this.messageQueueByPlayerWrapper.computeIfAbsent(serverPlayer, k -> new MessageQueueState());
this.handlePluginMessagesFromQueue(playerState, messageQueue);
return playerState;
}
@@ -60,6 +55,12 @@ public class ServerPlayerStateManager
}
}
public void handlePluginMessagesFromQueue(ServerPlayerState playerState)
{
MessageQueueState messageQueue = this.messageQueueByPlayerWrapper.computeIfAbsent(playerState.getServerPlayer(), k -> new MessageQueueState());
this.handlePluginMessagesFromQueue(playerState, messageQueue);
}
private void handlePluginMessagesFromQueue(ServerPlayerState playerState, MessageQueueState messageQueueState)
{
while (!messageQueueState.messageQueue.isEmpty() && messageQueueState.isBeingDrained.compareAndSet(false, true))
@@ -14,7 +14,7 @@ import java.util.HashMap;
public abstract class AbstractDhServerWorld<TDhServerLevel extends AbstractDhServerLevel> extends AbstractDhWorld implements IDhServerWorld
{
protected final HashMap<ILevelWrapper, TDhServerLevel> levelWrapperByDhLevel = new HashMap<>();
protected final HashMap<ILevelWrapper, TDhServerLevel> dhLevelByLevelWrapper = new HashMap<>();
public final LocalSaveStructure saveStructure = new LocalSaveStructure();
private final ServerPlayerStateManager serverPlayerStateManager;
@@ -43,10 +43,12 @@ public abstract class AbstractDhServerWorld<TDhServerLevel extends AbstractDhSer
ServerPlayerState playerState = this.serverPlayerStateManager.registerJoinedPlayer(serverPlayer);
this.getLevel(serverPlayer.getLevel()).addPlayer(serverPlayer);
for (TDhServerLevel level : this.levelWrapperByDhLevel.values())
for (TDhServerLevel level : (Iterable<? extends TDhServerLevel>) this.dhLevelByLevelWrapper.values().stream().distinct()::iterator)
{
level.registerNetworkHandlers(playerState);
}
this.serverPlayerStateManager.handlePluginMessagesFromQueue(playerState);
}
@Override
@@ -72,11 +74,11 @@ public abstract class AbstractDhServerWorld<TDhServerLevel extends AbstractDhSer
//================//
@Override
public TDhServerLevel getLevel(@NotNull ILevelWrapper wrapper) { return this.levelWrapperByDhLevel.get(wrapper); }
public TDhServerLevel getLevel(@NotNull ILevelWrapper wrapper) { return this.dhLevelByLevelWrapper.get(wrapper); }
@Override
public Iterable<? extends IDhLevel> getAllLoadedLevels() { return this.levelWrapperByDhLevel.values(); }
public Iterable<? extends IDhLevel> getAllLoadedLevels() { return this.dhLevelByLevelWrapper.values(); }
@Override
public int getLoadedLevelCount() { return this.levelWrapperByDhLevel.size(); }
public int getLoadedLevelCount() { return this.dhLevelByLevelWrapper.size(); }
@@ -85,10 +87,10 @@ public abstract class AbstractDhServerWorld<TDhServerLevel extends AbstractDhSer
//==============//
@Override
public void serverTick() { this.levelWrapperByDhLevel.values().forEach(TDhServerLevel::serverTick); }
public void serverTick() { this.dhLevelByLevelWrapper.values().forEach(TDhServerLevel::serverTick); }
@Override
public void worldGenTick() { this.levelWrapperByDhLevel.values().forEach(TDhServerLevel::worldGenTick); }
public void worldGenTick() { this.dhLevelByLevelWrapper.values().forEach(TDhServerLevel::worldGenTick); }
@@ -99,7 +101,7 @@ public abstract class AbstractDhServerWorld<TDhServerLevel extends AbstractDhSer
@Override
public void close()
{
for (TDhServerLevel level : this.levelWrapperByDhLevel.values())
for (TDhServerLevel level : this.dhLevelByLevelWrapper.values())
{
LOGGER.info("Unloading level [" + level.getLevelWrapper().getDimensionName() + "].");
@@ -113,7 +115,7 @@ public abstract class AbstractDhServerWorld<TDhServerLevel extends AbstractDhSer
level.close();
}
this.levelWrapperByDhLevel.clear();
this.dhLevelByLevelWrapper.clear();
LOGGER.info("Closed DhWorld of type [" + this.environment + "].");
}
@@ -64,7 +64,7 @@ public class DhClientServerWorld extends AbstractDhServerWorld<DhClientServerLev
{
if (wrapper instanceof IServerLevelWrapper)
{
return this.levelWrapperByDhLevel.computeIfAbsent(wrapper, (levelWrapper) ->
return this.dhLevelByLevelWrapper.computeIfAbsent(wrapper, (levelWrapper) ->
{
File levelFile = this.saveStructure.getLevelFolder(levelWrapper);
LodUtil.assertTrue(levelFile != null);
@@ -75,7 +75,7 @@ public class DhClientServerWorld extends AbstractDhServerWorld<DhClientServerLev
}
else
{
return this.levelWrapperByDhLevel.computeIfAbsent(wrapper, (levelWrapper) ->
return this.dhLevelByLevelWrapper.computeIfAbsent(wrapper, (levelWrapper) ->
{
IClientLevelWrapper clientLevelWrapper = (IClientLevelWrapper) levelWrapper;
IServerLevelWrapper serverLevelWrapper = clientLevelWrapper.tryGetServerSideWrapper();
@@ -86,7 +86,7 @@ public class DhClientServerWorld extends AbstractDhServerWorld<DhClientServerLev
}
DhClientServerLevel level = this.levelWrapperByDhLevel.get(serverLevelWrapper);
DhClientServerLevel level = this.dhLevelByLevelWrapper.get(serverLevelWrapper);
if (level == null)
{
return null;
@@ -102,14 +102,14 @@ public class DhClientServerWorld extends AbstractDhServerWorld<DhClientServerLev
@Override
public void unloadLevel(@NotNull ILevelWrapper wrapper)
{
if (this.levelWrapperByDhLevel.containsKey(wrapper))
if (this.dhLevelByLevelWrapper.containsKey(wrapper))
{
if (wrapper instanceof IServerLevelWrapper)
{
LOGGER.info("Unloading level " + this.levelWrapperByDhLevel.get(wrapper));
LOGGER.info("Unloading level " + this.dhLevelByLevelWrapper.get(wrapper));
wrapper.onUnload();
DhClientServerLevel clientServerLevel = this.levelWrapperByDhLevel.remove(wrapper);
DhClientServerLevel clientServerLevel = this.dhLevelByLevelWrapper.remove(wrapper);
clientServerLevel.close();
this.dhLevels.remove(clientServerLevel);
}
@@ -118,7 +118,7 @@ public class DhClientServerWorld extends AbstractDhServerWorld<DhClientServerLev
// If the level wrapper is a Client Level Wrapper, then that means the client side leaves the level,
// but note that the server side still has the level loaded. So, we don't want to unload the level,
// we just want to stop rendering it.
this.levelWrapperByDhLevel.remove(wrapper).stopRenderer(); // Ignore resource warning. The level obj is referenced elsewhere.
this.dhLevelByLevelWrapper.remove(wrapper).stopRenderer(); // Ignore resource warning. The level obj is referenced elsewhere.
}
}
}
@@ -163,7 +163,7 @@ public class DhClientServerWorld extends AbstractDhServerWorld<DhClientServerLev
}
}
this.levelWrapperByDhLevel.clear();
this.dhLevelByLevelWrapper.clear();
this.eventLoop.close();
LOGGER.info("Closed DhWorld of type " + this.environment);
}
@@ -52,7 +52,7 @@ public class DhServerWorld extends AbstractDhServerWorld<DhServerLevel>
return null;
}
return this.levelWrapperByDhLevel.computeIfAbsent(wrapper, (serverLevelWrapper) ->
return this.dhLevelByLevelWrapper.computeIfAbsent(wrapper, (serverLevelWrapper) ->
{
File levelFile = this.saveStructure.getLevelFolder(wrapper);
LodUtil.assertTrue(levelFile != null);
@@ -68,11 +68,11 @@ public class DhServerWorld extends AbstractDhServerWorld<DhServerLevel>
return;
}
if (this.levelWrapperByDhLevel.containsKey(wrapper))
if (this.dhLevelByLevelWrapper.containsKey(wrapper))
{
LOGGER.info("Unloading level {} ", this.levelWrapperByDhLevel.get(wrapper));
LOGGER.info("Unloading level {} ", this.dhLevelByLevelWrapper.get(wrapper));
wrapper.onUnload();
this.levelWrapperByDhLevel.remove(wrapper).close();
this.dhLevelByLevelWrapper.remove(wrapper).close();
}
}