Example #1
0
        private void GetGameUpdates(UdpClient client)
        {
            Log("Receiving GameSteps");

            try {
                while (!_shutdown)
                {
                    IPEndPoint endPoint = null;
                    var        msg      = client.Receive(ref endPoint);

                    using (var br = new BinaryReader(new MemoryStream(msg))) {
                        if ((SC_Message)msg[0] == SC_Message.GameStepCollection)
                        {
                            GameStepCollection gsc = new GameStepCollection(br);

                            foreach (var gs in gsc.GameSteps)
                            {
                                if (gs.StepNumber > _highestGameStepNum + 8)
                                {
                                    Log("Disconnected!");
                                    throw new Exception("Disconnected!");
                                }

                                _highestGameStepNum = Math.Max(gs.StepNumber, _highestGameStepNum);

                                lock (_gameHistory) {
                                    _gameHistory.Add(gs);
                                }

                                if (gs.PlayerInputs.Any())
                                {
                                    var msgs = gs.PlayerInputs
                                               .Select(pi =>
                                                       pi.Key +
                                                       ":" +
                                                       String.Join("|", pi.Value.Inputs.Select(k => k.Key + ":" + k.Value).ToArray()))
                                               .Aggregate((a, e) => a + "," + e);

                                    //Log("[" + gs.StepNumber + "] " + msgs);
                                }
                            }
                        }
                        else
                        {
                            Log("Invalid Message!");
                        }
                    }
                }
            }
            catch (Exception e) {
                Log(e.ToString());
            }

            Log("GetGameSteps Exit");
        }
Example #2
0
        private void BroadcastGameStepCollection(GameStepCollection gsc)
        {
            bw.Seek(0, SeekOrigin.Begin);
            gsc.SerializeToBuff(bw);
            bw.Flush();

            var tasks = _playersById.Select(async player => {
                try {
                    //if (new Random().Next(0, 100) <= 6) return; // 7% packet loss
                    await player.UdpClient.SendAsync(tempBuff, (int)ms.Position, player.RemoteEndPoint);
                }
                catch (Exception e) {
                    Console.WriteLine(e);
                }
            })
                        .AsParallel()
                        .ToArray();

            Task.WaitAll(tasks);
        }
Example #3
0
        private void SendPlayerUpdates()
        {
            Console.WriteLine("Starting Broadcasts");
            _lastStepBroadcast = DateTime.UtcNow;

            DateTime start           = DateTime.UtcNow;
            int      sleepIntervalMs = GameStepIntervalMs;

            try {
                while (true)
                {
                    if (sleepIntervalMs > 0)
                    {
                        Thread.Sleep(sleepIntervalMs);
                    }

                    start = DateTime.UtcNow;

                    GameStep gameStep;
                    lock (_gameLock) {
                        byte ellapsed = (byte)Math.Min((DateTime.UtcNow - _lastStepBroadcast).TotalMilliseconds, byte.MaxValue);

                        // Create new GameStep to broadcast
                        gameStep = new GameStep(_stepNumber, ellapsed);

                        GameStep lastGameStep;
                        // If previous GameSteps exit
                        if (_gameHistory.Count > 0 && _gameHistory.TryGet((UInt16)(_stepNumber - 1), out lastGameStep))
                        {
                            foreach (var currentInput in _curPlayerInputs)
                            {
                                // If Player input exists from last game update, take XOR of last player input and current player input
                                PlayerInputs lastInput;
                                if (lastGameStep.PlayerInputs.TryGetValue(currentInput.Key, out lastInput))
                                {
                                    var changed = currentInput.Value.Inputs
                                                  .Where(i => !lastInput.Inputs.ContainsKey(i.Key) || lastInput.Inputs[i.Key] != i.Value)
                                                  .ToDictionary(k => k.Key, k => k.Value);

                                    PlayerInputs pi = new PlayerInputs()
                                    {
                                        PlayerId = currentInput.Key,
                                        Inputs   = changed
                                    };

                                    gameStep.PlayerInputs.Add(pi.PlayerId, pi);
                                }
                                // If no last game update for this player, just send current inputs
                                else
                                {
                                    gameStep.PlayerInputs.Add(currentInput.Key, currentInput.Value);
                                }
                            }

                            _curPlayerInputs.Clear();
                        }
                        // If no previous GameSteps exist
                        else
                        {
                            gameStep.PlayerInputs = _curPlayerInputs;
                        }

                        _gameHistory.Add(gameStep);
                    }

                    GameStepCollection gsc = new GameStepCollection(3);
                    gsc.GameSteps.Add(gameStep);

                    // Send Redundant Step #1
                    if (_stepNumber >= 1)
                    {
                        UInt16   idx = (UInt16)Math.Max(_stepNumber - 2, 0);
                        GameStep redundant;
                        if (_gameHistory.TryGet(idx, out redundant))
                        {
                            gsc.GameSteps.Add(redundant);
                        }
                    }

                    // Send Redundant Step #2
                    if (_stepNumber >= 3)
                    {
                        UInt16   idx = (UInt16)Math.Max(_stepNumber - 8, 0);
                        GameStep redundant;
                        if (_gameHistory.TryGet(idx, out redundant))
                        {
                            gsc.GameSteps.Add(redundant);
                        }
                    }

                    BroadcastGameStepCollection(gsc);

                    // Calculate next Sleep Interval
                    _lastStepBroadcast = DateTime.UtcNow;
                    _stepNumber++;
                    TimeSpan broadcastDuration = (_lastStepBroadcast - start);
                    sleepIntervalMs = Math.Max(GameStepIntervalMs - (int)broadcastDuration.TotalMilliseconds, 0);
                }
            }
            catch (Exception e) {
                Console.Write(e);
            }
        }