Trying to convert old code into using the new approval flow but itis not working, not sure why.
I followed the code in the docs:
https://docs.unity3d.com/Packages/com.unity.netcode@1.3/manual/network-connection.html
(scroll down to connection approval section)
I set RequireConnectionApproval = true on both the server and client right before calling Listen and Connect.
My client connection request system:
[BurstCompile]
[WorldSystemFilter(WorldSystemFilterFlags.ClientSimulation | WorldSystemFilterFlags.ThinClientSimulation)]
public partial struct ClientConnectionRequestSystem : ISystem
{
//private EntityQuery m_pendingNetworkIdQuery;
//================================================================
[BurstCompile]
public void OnCreate(ref SystemState state)
{
//var builder = new EntityQueryBuilder(Allocator.Temp).WithAll<NetworkId>().WithNone<NetworkStreamInGame>();
//m_pendingNetworkIdQuery = state.GetEntityQuery(builder);
//state.RequireForUpdate(m_pendingNetworkIdQuery);
state.RequireForUpdate<ClientLoginCredentialsComponent>();
state.RequireForUpdate<RpcCollection>();
}
//================================================================
[BurstCompile]
public void OnUpdate(ref SystemState state)
{
var clientLoginCredentials = SystemAPI.GetSingleton<ClientLoginCredentialsComponent>();
var ecb = new EntityCommandBuffer(Allocator.Temp);
//var pendingNetworkIds = m_pendingNetworkIdQuery.ToEntityArray(Allocator.Temp);
//foreach (var pendingNetworkId in pendingNetworkIds) {
foreach (var (connection, entity) in SystemAPI.Query<RefRW<NetworkStreamConnection>>().WithNone<NetworkId>().WithNone<ClientApprovalStartedComponent>().WithEntityAccess()) {
//ecb.AddComponent<NetworkStreamInGame>(pendingNetworkId);
Logger.log_debug($"Creating Entity for RequestServerConnectionRPC");
var requestServerConnection = ecb.CreateEntity();
ecb.AddComponent(requestServerConnection, new RequestServerConnectionRPC {
ServerPassword = clientLoginCredentials.Password,
PlayerSessionToken = clientLoginCredentials.SessionToken,
PlayerID = clientLoginCredentials.PlayerID,
PlayerUsername = clientLoginCredentials.Username
});
//ecb.AddComponent(requestServerConnection, new SendRpcCommandRequest { TargetConnection = pendingNetworkId });
ecb.AddComponent<SendRpcCommandRequest>(requestServerConnection);
ecb.AddComponent<ClientApprovalStartedComponent>(entity);
Logger.log_debug($"Sending RequestServerConnectionRPC");
}
ecb.Playback(state.EntityManager);
}
}
RequestServerConnectionRPC is an IApprovalRpcCommand
Server System:
//================================================================
[BurstCompile]
public void OnCreate(ref SystemState state)
{
//var builder = new EntityQueryBuilder(Allocator.Temp).WithAll<RequestServerConnectionRPC, ReceiveRpcCommandRequest>();
//state.RequireForUpdate(state.GetEntityQuery(builder));
m_playerQuery = state.GetEntityQuery(ComponentType.ReadOnly<PlayerComponent>());
m_AdminQuery = state.GetEntityQuery(ComponentType.ReadOnly<AdminComponent>());
m_GameMasterQuery = state.GetEntityQuery(ComponentType.ReadOnly<GameMasterComponent>());
}
//================================================================
[BurstCompile]
public void OnUpdate(ref SystemState state)
{
var ecb = new EntityCommandBuffer(Allocator.Temp);
var serverLoginCredentials = SystemAPI.GetSingleton<ServerLoginCredentialsComponent>();
var serverInfo = SystemAPI.GetSingletonRW<MultiplayerServerRecordComponent>().ValueRW;
//foreach (var (requestServerConnection, requestSource, requestEntity) in SystemAPI.Query<RequestServerConnectionRPC, ReceiveRpcCommandRequest>().WithEntityAccess()) {
Logger.log_info($"Connection request OnUpdate");
foreach (var (receiveRpc, requestServerConnection, requestEntity) in SystemAPI.Query<RefRO<ReceiveRpcCommandRequest>, RefRW<RequestServerConnectionRPC>>().WithEntityAccess()) {
Logger.log_info($"Connection request...");
var connectionEntity = receiveRpc.ValueRO.SourceConnection;
Logger.log_info($"Connection request from {requestServerConnection.ValueRO.PlayerUsername}");
int currentPlayerCount = m_playerQuery.CalculateEntityCount();
PlayerType playerType = handle_player_login(requestServerConnection.ValueRO, serverLoginCredentials, currentPlayerCount);
if (playerType != PlayerType.Invalid) {
ecb.AddComponent<ConnectionApproved>(connectionEntity);
PlayerInfoComponent playerInfo = new PlayerInfoComponent {
PlayerType = playerType,
PlayerId = requestServerConnection.ValueRO.PlayerID,
Username = requestServerConnection.ValueRO.PlayerUsername
};
ecb.AddComponent(connectionEntity, playerInfo);
ecb.DestroyEntity(requestEntity);
send_connection_notifications(ecb, playerType, requestServerConnection.ValueRO, connectionEntity, serverInfo);
} else {
//Connection failed validation, drop them.
Logger.log_info($"Login failed validation");
ecb.AddComponent<NetworkStreamRequestDisconnect>(connectionEntity);
}
}
ecb.Playback(state.EntityManager);
}
Client sends the request and I can see both the “Creating Entity for RequestServerConnectionRPC” and “Sending RequestServerConnectionRPC” logs appear.
The server never generates the “Connection request…” log at all indicating the foreach was never entered, yet this is using the same query code specified in the docs.
I get a log message for Netcode saying the approval timed out after 5000ms. My connection tests are entirely localhost/127.0.0.1 so 5 seconds should be more than enough time to resolve. If I turn connectionApproval back off and restore my original ‘manual’ approval code, everything works fine.
