/// <inheritdoc/> public async Task<JoinResult> JoinAsync(GameClientInfo clientInfo, IGameClientStub clientStub) { using (await _clientsLock.LockAsync()) { if (_clients.Values.Any(conn => conn.ClientInfo.PlayerId == clientInfo.PlayerId.ToString())) return new JoinResult(false, Point.Zero, "Another client is already connected using the same player ID"); var connection = new ClientConnection(clientInfo, clientStub); var playerEntity = new PlayerEntity(clientInfo.PlayerId, Point.North); // Check if the player is playing this map for the first time if (Map.Metadata.Players.IsKnown(clientInfo.PlayerId)) { // Try to spawn player at its last known position. var playerInfo = Map.Metadata.Players[clientInfo.PlayerId]; var spawnTransaction = new TransactionWithMoveSupport(MoveInitiator.Empty); var spawnResult = await Map.SpawnAsync(playerEntity, playerInfo.Position, spawnTransaction); if (spawnResult.IsSuccessful) { // TODO: What if a player spawns within a level some others are currently trying to solve? await CommitAndBroadcastAsync(spawnResult.Transaction, spawnResult.FollowUpEvents, connection); _clients.Add(clientInfo.PlayerId, connection); Map.Emit(new PlayerJoinEvent(clientInfo)); return new JoinResult(true, playerInfo.Position); } else { // If that fails, // option 1: spawn at default spawn area // option 2: return false throw new NotImplementedException(); } } else { // Unknown player: Spawn player somewhere in default spawn area, add to list of known players var spawnPositions = await Map.GetCoherentPositionsAsync(Map.Metadata.Regions.DefaultRegion.SpawnPosition); var spawnTransaction = new TransactionWithMoveSupport(MoveInitiator.Empty); var spawnResult = await Map.SpawnAsync(playerEntity, spawnPositions, spawnTransaction); if (spawnResult.IsSuccessful) { await CommitAndBroadcastAsync(spawnResult.Transaction, spawnResult.FollowUpEvents, connection); var playerInfo = new PlayerInfo(clientInfo.PlayerId, clientInfo.PlayerDisplayName, spawnResult.SpawnPosition); Map.Metadata.Players.Add(playerInfo); _clients.Add(clientInfo.PlayerId, connection); Map.Emit(new PlayerJoinEvent(clientInfo)); return new JoinResult(true, spawnResult.SpawnPosition); } else { // TODO: What now? We could not spawn the player! throw new NotImplementedException(); } } } }
public async Task InitializeAsync() { try { var random = new Random(); var number = random.Next(1, 100); var playerInfo = new GameClientInfo($"Player{number}", $"Player {number}"); _client = new NetGameClient(playerInfo); await _client.JoinAsync(_serverInfo); } catch { Debugger.Break(); } }
public PlayerLeaveEvent(GameClientInfo playerInfo) { PlayerInfo = playerInfo; }
public GameClientBase(GameClientInfo playerInfo) { PlayerInfo = playerInfo; }
public PlayerJoinEvent(GameClientInfo playerInfo) { PlayerInfo = playerInfo; }
public ClientConnection(GameClientInfo clientInfo, IGameClientStub clientStub) { ClientInfo = clientInfo; ClientStub = clientStub; }