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);
        }
Esempio n. 2
0
        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));
 }