Skip to content

Commit

Permalink
chore: CoreRegistry removal from engine.network (#5033)
Browse files Browse the repository at this point in the history
Fixes some race conditions in MTE tests.

* test(network): ClientHandler's GameEngine reference is optional?

  seems sus, but it's only used for a disconnection event, so maybe.

* fix(network): don't replace this object every tick
  • Loading branch information
keturn committed Jun 6, 2022
1 parent 182f308 commit be0f9de
Show file tree
Hide file tree
Showing 18 changed files with 203 additions and 125 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2021 The Terasology Foundation
// Copyright 2022 The Terasology Foundation
// SPDX-License-Identifier: Apache-2.0
package org.terasology.engine;

Expand All @@ -11,6 +11,7 @@
import org.terasology.engine.audio.nullAudio.NullSound;
import org.terasology.engine.audio.nullAudio.NullStreamingSound;
import org.terasology.engine.config.Config;
import org.terasology.engine.config.PlayerConfig;
import org.terasology.engine.context.Context;
import org.terasology.engine.core.ComponentSystemManager;
import org.terasology.engine.core.EngineTime;
Expand All @@ -28,6 +29,7 @@
import org.terasology.engine.entitySystem.entity.internal.EngineEntityManager;
import org.terasology.engine.entitySystem.prefab.Prefab;
import org.terasology.engine.entitySystem.prefab.internal.PojoPrefab;
import org.terasology.engine.identity.storageServiceClient.StorageServiceWorker;
import org.terasology.engine.logic.behavior.asset.BehaviorTree;
import org.terasology.engine.network.NetworkSystem;
import org.terasology.engine.network.internal.NetworkSystemImpl;
Expand Down Expand Up @@ -256,6 +258,8 @@ protected void setupConfig() {
Config config = new Config(context);
config.loadDefaults();
context.put(Config.class, config);
context.put(StorageServiceWorker.class, mock(StorageServiceWorker.class));
context.put(PlayerConfig.class, mock(PlayerConfig.class));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ public <T, U extends T> void put(Class<T> type, U object) {
map.put(type, object);
}

public boolean isDirectDescendantOf(Context other) {
return parent == other;
}

@Override
public String toString() {
return MoreObjects.toStringHelper(this)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2021 The Terasology Foundation
// Copyright 2022 The Terasology Foundation
// SPDX-License-Identifier: Apache-2.0

package org.terasology.engine.core.modes;
Expand Down Expand Up @@ -52,6 +52,7 @@
import org.terasology.engine.game.GameManifest;
import org.terasology.engine.network.JoinStatus;
import org.terasology.engine.network.NetworkMode;
import org.terasology.engine.network.NetworkSystem;
import org.terasology.engine.registry.CoreRegistry;
import org.terasology.engine.rendering.nui.NUIManager;
import org.terasology.engine.rendering.nui.internal.NUIManagerInternal;
Expand Down Expand Up @@ -110,6 +111,7 @@ public void init(GameEngine engine) {
headless = context.get(DisplayDevice.class).isHeadless();

CoreRegistry.setContext(context);
context.getValue(NetworkSystem.class).setContext(context);
systemConfig = context.get(SystemConfig.class);

if (!headless) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
// Copyright 2021 The Terasology Foundation
// Copyright 2022 The Terasology Foundation
// SPDX-License-Identifier: Apache-2.0
package org.terasology.engine.core.subsystem.common;

import org.terasology.engine.context.Context;
import org.terasology.engine.core.EngineTime;
import org.terasology.engine.core.GameEngine;
import org.terasology.engine.core.Time;
import org.terasology.engine.core.modes.GameState;
Expand All @@ -23,7 +24,7 @@ public String getName() {

@Override
public void initialise(GameEngine engine, Context rootContext) {
networkSystem = new NetworkSystemImpl(rootContext.get(Time.class), rootContext);
networkSystem = new NetworkSystemImpl((EngineTime) rootContext.get(Time.class), rootContext);
rootContext.put(NetworkSystem.class, networkSystem);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2021 The Terasology Foundation
// Copyright 2022 The Terasology Foundation
// SPDX-License-Identifier: Apache-2.0

package org.terasology.engine.network;
Expand All @@ -11,12 +11,15 @@
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import org.terasology.engine.context.Context;
import org.terasology.engine.network.internal.ServerInfoRequestHandler;
import org.terasology.engine.network.internal.pipelineFactory.InfoRequestPipelineFactory;

import java.net.InetSocketAddress;
import java.util.concurrent.Future;

import static org.terasology.engine.registry.InjectionHelper.createWithConstructorInjection;

/**
* Performs temporary connections to one or more game servers.
*/
Expand All @@ -25,12 +28,12 @@ public class ServerInfoService implements AutoCloseable {
private final Bootstrap bootstrap;
private final EventLoopGroup eventLoopGroup;

public ServerInfoService() {
public ServerInfoService(Context context) {
eventLoopGroup = new NioEventLoopGroup();
bootstrap = new Bootstrap();
bootstrap.group(eventLoopGroup);
bootstrap.channel(NioSocketChannel.class);
bootstrap.handler(new InfoRequestPipelineFactory());
bootstrap.handler(createWithConstructorInjection(InfoRequestPipelineFactory.class, context));
bootstrap.option(ChannelOption.TCP_NODELAY, true);
bootstrap.option(ChannelOption.SO_KEEPALIVE, true);
bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2021 The Terasology Foundation
// Copyright 2022 The Terasology Foundation
// SPDX-License-Identifier: Apache-2.0
package org.terasology.engine.network.internal;

Expand All @@ -10,12 +10,12 @@
import org.slf4j.LoggerFactory;
import org.terasology.engine.config.Config;
import org.terasology.engine.config.PlayerConfig;
import org.terasology.engine.context.Context;
import org.terasology.engine.context.internal.ContextImpl;
import org.terasology.engine.core.EngineTime;
import org.terasology.engine.core.PathManager;
import org.terasology.engine.core.Time;
import org.terasology.engine.core.module.ModuleManager;
import org.terasology.engine.network.JoinStatus;
import org.terasology.engine.registry.CoreRegistry;
import org.terasology.gestalt.naming.Name;
import org.terasology.gestalt.naming.Version;
import org.terasology.protobuf.NetData;
Expand All @@ -29,15 +29,20 @@
import java.util.Set;
import java.util.Timer;

import static org.terasology.engine.registry.InjectionHelper.createWithConstructorInjection;

public class ClientConnectionHandler extends ChannelInboundHandlerAdapter {

private static final Logger logger = LoggerFactory.getLogger(ClientConnectionHandler.class);

private final Config config;
private final Context context;
private final JoinStatusImpl joinStatus;
private NetworkSystemImpl networkSystem;
private ServerImpl server;
private ModuleManager moduleManager;
private final ModuleManager moduleManager;
private final PlayerConfig playerConfig;
private final EngineTime time;

private ServerImpl server;
private Set<String> missingModules = Sets.newHashSet();
private NetData.ModuleDataHeader receivingModule;
private Path tempModuleLocation;
Expand All @@ -50,15 +55,17 @@ public class ClientConnectionHandler extends ChannelInboundHandlerAdapter {

/**
* Initialises: network system, join status, and module manager.
* @param joinStatus
* @param networkSystem
*/
public ClientConnectionHandler(JoinStatusImpl joinStatus, NetworkSystemImpl networkSystem) {
this.networkSystem = networkSystem;
public ClientConnectionHandler(JoinStatusImpl joinStatus, Config config, Context parentContext, ModuleManager moduleManager,
PlayerConfig playerConfig, EngineTime time) {
this.config = config;
this.context = new ContextImpl(parentContext);
this.moduleManager = moduleManager;
this.playerConfig = playerConfig;
this.time = time;
this.joinStatus = joinStatus;
// TODO: implement translation of errorMessage in messageReceived once context is available
// See https://github.com/MovingBlocks/Terasology/pull/3332#discussion_r187081375
this.moduleManager = CoreRegistry.get(ModuleManager.class);
}

/**
Expand All @@ -85,6 +92,12 @@ public void run() {
}, timeoutThreshold + 200);
}

@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
super.channelActive(ctx);
context.put(Channel.class, ctx.channel());
}

@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
// If we timed out, don't handle anymore messages.
Expand Down Expand Up @@ -257,8 +270,8 @@ private void completeJoin(ChannelHandlerContext channelHandlerContext, NetData.J
*/
private void receivedServerInfo(ChannelHandlerContext channelHandlerContext, NetData.ServerInfoMessage message) {
logger.info("Received server info");
((EngineTime) CoreRegistry.get(Time.class)).setGameTime(message.getTime());
this.server = new ServerImpl(networkSystem, channelHandlerContext.channel());
time.setGameTime(message.getTime());
this.server = createWithConstructorInjection(ServerImpl.class, context);
server.setServerInfo(message);

// Request missing modules
Expand Down Expand Up @@ -287,8 +300,6 @@ private void receivedServerInfo(ChannelHandlerContext channelHandlerContext, Net
* @param channelHandlerContext
*/
private void sendJoin(ChannelHandlerContext channelHandlerContext) {
Config config = CoreRegistry.get(Config.class);
PlayerConfig playerConfig = CoreRegistry.get(PlayerConfig.class);
NetData.JoinMessage.Builder bldr = NetData.JoinMessage.newBuilder();
NetData.Color.Builder clrbldr = NetData.Color.newBuilder();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2021 The Terasology Foundation
// Copyright 2022 The Terasology Foundation
// SPDX-License-Identifier: Apache-2.0

package org.terasology.engine.network.internal;
Expand All @@ -10,7 +10,8 @@
import org.slf4j.LoggerFactory;
import org.terasology.engine.core.GameEngine;
import org.terasology.engine.core.modes.StateMainMenu;
import org.terasology.engine.registry.CoreRegistry;

import java.util.Optional;

import static org.terasology.protobuf.NetData.NetMessage;

Expand All @@ -21,16 +22,19 @@ public class ClientHandler extends ChannelInboundHandlerAdapter {

private static final Logger logger = LoggerFactory.getLogger(ClientHandler.class);

private NetworkSystemImpl networkSystem;
private final GameEngine gameEngine;
private final NetworkSystemImpl networkSystem;

private ServerImpl server;

public ClientHandler(NetworkSystemImpl networkSystem) {
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
public ClientHandler(NetworkSystemImpl networkSystem, Optional<GameEngine> gameEngine) {
this.gameEngine = gameEngine.orElse(null);
this.networkSystem = networkSystem;
}

@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
GameEngine gameEngine = CoreRegistry.get(GameEngine.class);
if (gameEngine != null) {
gameEngine.changeState(new StateMainMenu("Disconnected From Server"));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2021 The Terasology Foundation
// Copyright 2022 The Terasology Foundation
// SPDX-License-Identifier: Apache-2.0
package org.terasology.engine.network.internal;

Expand All @@ -17,7 +17,6 @@
import org.terasology.engine.identity.storageServiceClient.StorageServiceWorker;
import org.terasology.engine.identity.storageServiceClient.StorageServiceWorkerStatus;
import org.terasology.protobuf.NetData;
import org.terasology.engine.registry.CoreRegistry;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
Expand All @@ -37,8 +36,9 @@ public class ClientHandshakeHandler extends ChannelInboundHandlerAdapter {
private static final Logger logger = LoggerFactory.getLogger(ClientHandshakeHandler.class);
private static final String AUTHENTICATION_FAILURE = "Authentication failure";

private Config config = CoreRegistry.get(Config.class);
private JoinStatusImpl joinStatus;
private final Config config;
private final StorageServiceWorker storageServiceWorker;
private final JoinStatusImpl joinStatus;

private byte[] serverRandom;
private byte[] clientRandom;
Expand All @@ -50,7 +50,9 @@ public class ClientHandshakeHandler extends ChannelInboundHandlerAdapter {
private ClientIdentity identity;
private PublicIdentityCertificate serverCertificate;

public ClientHandshakeHandler(JoinStatusImpl joinStatus) {
public ClientHandshakeHandler(Config config, StorageServiceWorker storageServiceWorker, JoinStatusImpl joinStatus) {
this.config = config;
this.storageServiceWorker = storageServiceWorker;
this.joinStatus = joinStatus;
}

Expand Down Expand Up @@ -151,7 +153,6 @@ private void processNewIdentity(NetData.ProvisionIdentity provisionIdentity, Cha
config.save();

//Try to upload the new identity to the identity storage service (if user is logged in)
StorageServiceWorker storageServiceWorker = CoreRegistry.get(StorageServiceWorker.class);
if (storageServiceWorker != null && storageServiceWorker.getStatus() == StorageServiceWorkerStatus.LOGGED_IN) {
storageServiceWorker.putIdentity(serverCertificate, identity);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2021 The Terasology Foundation
// Copyright 2022 The Terasology Foundation
// SPDX-License-Identifier: Apache-2.0

package org.terasology.engine.network.internal;
Expand All @@ -10,7 +10,6 @@
import org.terasology.engine.logic.common.DisplayNameComponent;
import org.terasology.engine.network.ClientComponent;
import org.terasology.engine.network.ColorComponent;
import org.terasology.engine.registry.CoreRegistry;
import org.terasology.engine.rendering.world.viewDistance.ViewDistance;
import org.terasology.engine.world.chunks.Chunk;
import org.terasology.gestalt.entitysystem.event.Event;
Expand All @@ -22,15 +21,18 @@
*/
public class LocalClient extends AbstractClient {

private Config config = CoreRegistry.get(Config.class);
private final Config config;

/**
* Creates an entity for the new local client.
*
* @param preferredName Clients preferred name.
* @param color Clients preferred color.
* @param entityManager Entity manager for the clients entity creation.
* @param config
*/
public LocalClient(String preferredName, Color color, EntityManager entityManager) {
public LocalClient(String preferredName, Color color, EntityManager entityManager, Config config) {
this.config = config;
createEntity(preferredName, color, entityManager);
}

Expand Down

0 comments on commit be0f9de

Please sign in to comment.