public void ReceiveReplica(string gameId, List <Atom <Record> > records) { var replicatedGame = new ReplicatedGameContext(gameId, m_HubConnection.GetConnectionId(), records); m_Games.Add(replicatedGame); // Send out any writes we make to this replicated game from the client. Observable.Merge(replicatedGame.replicatedData.ObserveThisReplicaAdded().AsUnitObservable(), replicatedGame.replicatedData.ObserveThisReplicaReplaced().AsUnitObservable(), replicatedGame.replicatedData.ObserveThisReplicaRemoved().AsUnitObservable()) .SelectMany(event_ => OnReplicationEvent(gameId, replicatedGame)) .Subscribe() .AddTo(m_CompositeDisposable); }
public Task <string> Matchmake(string peerId, CancellationToken cancellationToken = default) { var thisTask = new TaskCompletionSource <string>(TaskCreationOptions.RunContinuationsAsynchronously); lock (queue) { if (queue.Count + 1 == playersPerGame) { // Create the game var gameId = Guid.NewGuid().ToString(); var game = new ReplicatedGameContext(gameId, HostReplicaId); // Populate useful base data var rec = new Record() { game = new World() { name = $"Game {gameId}", gameId = gameId, status = GameStatus.Ready, utcStartTime = DateTime.UtcNow.Ticks } }; game.replicatedData.SetId(ref rec); game.replicatedData.Add(rec); queue.Add(new QueueEntry() { matchmakingEntry = thisTask, peerId = peerId }); // Creates a player record for each peer that is now in this game foreach (var record in queue.Select((peer, i) => { var rec2 = new Record() { player = new PlayerRecord() { name = $"Peer {peer.peerId}", peerId = peer.peerId, playerId = i } }; game.replicatedData.SetId(ref rec2); return(rec2); })) { game.replicatedData.Add(record); } // Call the game's create game hook game.OnMatchmakingCreatesGame(); games.Add(gameId, game); // Finish matchmaking for all players foreach (var record in queue) { record.matchmakingEntry.SetResult(gameId); } // Clears the "matchmaking" queue queue.Clear(); // This is completed return(thisTask.Task); } // Queue up queue.Add(new QueueEntry() { peerId = peerId, matchmakingEntry = thisTask }); } return(thisTask.Task); }
private IObservable <Unit> OnReplicationEvent(string gameId, ReplicatedGameContext replicatedGameContext) { return(m_HubConnection.InvokeAsync(nameof(ReplicationHub.SendReplicationOp), gameId, replicatedGameContext.replicatedData.lastOp.Value).ToObservable().Take(1)); }