Example #1
0
        /// <summary>
        /// Initialize the vector war game.  This initializes the game state and
        /// the video renderer and creates a new network session.
        /// </summary>
        /// <param name="localPort"></param>
        /// <param name="numPlayers"></param>
        /// <param name="players"></param>
        /// <param name="numSpectators"></param>
        public void Init(int localPort, int numPlayers, GGPOPlayer[] players, int numSpectators)
        {
            // Initialize the game state
            InitializeGameState(numPlayers);

            //ggpo = new PeerToPeerBackend(this, new ConsoleLogger(), localPort, numPlayers, 4);
            ggpo = new PeerToPeerBackend(this, new RollingBufferFileLogger("vectorwar"), localPort, numPlayers, 4);

            // automatically disconnect clients after 3000 ms and start our count-down timer
            // for disconnects after 1000 ms.   To completely disable disconnects, simply use
            // a value of 0 for ggpo_set_disconnect_timeout.
            ggpo.SetDisconnectTimeout(3000);
            ggpo.SetDisconnectNotifyStart(1000);

            for (int i = 0; i < numPlayers + numSpectators; i++)
            {
                ggpo.AddPlayer(players[i], out int playerHandle);
                ngs.players[i].playerHandle = playerHandle;
                ngs.players[i].type         = players[i].type;
                if (players[i].type == GGPOPlayerType.Local)
                {
                    ngs.players[i].connectProgress = 100;
                    ngs.LocalPlayerHandle          = playerHandle;
                    ngs.SetConnectState(playerHandle, PlayerConnectState.Connecting);
                    ggpo.SetFrameDelay(playerHandle, Constants.FrameDelay);
                }
                else
                {
                    ngs.players[i].connectProgress = 0;
                }
            }

            lblStatus.Text = "Connecting to peers.";
            Task.Factory.StartNew(() => HandleApplicationIdle(this, ggpo), TaskCreationOptions.LongRunning);
        }
Example #2
0
        public void Update(GGPOSession ggpo, int[] players, int numPlayers)
        {
            var stats = new GGPONetworkStats();
            int i     = 0;

            this.numPlayers = numPlayers;

            if (graphSize < MaxGraphSize)
            {
                i = graphSize++;
            }
            else
            {
                i = firstGraphIndex;
                firstGraphIndex = (firstGraphIndex + 1) % MaxGraphSize;
            }

            for (int j = 0; j < numPlayers; j++)
            {
                ggpo.GetNetworkStats(players[j], out stats);

                // Ping
                pingGraph[j][i] = (int)stats.Ping;

                // Frame Advantage
                localFairnessGraph[j][i]  = stats.LocalFramesBehind;
                remoteFairnessGraph[j][i] = stats.RemoteFramesBehind;
                if (stats.LocalFramesBehind < 0 && stats.RemoteFramesBehind < 0)
                {
                    // Both think it's unfair (which, ironically, is fair).  Scale both and subtrace.
                    fairnessGraph[i] = Math.Abs(Math.Abs(stats.LocalFramesBehind) - Math.Abs(stats.RemoteFramesBehind));
                }
                else if (stats.LocalFramesBehind > 0 && stats.RemoteFramesBehind > 0)
                {
                    // Impossible!  Unless the network has negative transmit time.  Odd....
                    fairnessGraph[i] = 0;
                }
                else
                {
                    // They disagree.  Add.
                    fairnessGraph[i] = Math.Abs(stats.LocalFramesBehind) + Math.Abs(stats.RemoteFramesBehind);
                }
            }

            long now = Utility.GetCurrentTime();

            if (now > lastTextUpdateTime + 500)
            {
                lblNetworkLag.Text  = $"{stats.Ping} ms";
                lblFrameLag.Text    = $"{stats.Ping * 60 / 1000f:F1}";
                lblBandwidth.Text   = $"{stats.KbpsSent / 8f:F2} kilobytes/sec";
                lblLocalAhead.Text  = $"{stats.LocalFramesBehind} frames";
                lblRemoteAhead.Text = $"{stats.RemoteFramesBehind} frames";

                lastTextUpdateTime = now;
            }
        }
Example #3
0
        /// <summary>
        /// Create a new spectator session.
        /// </summary>
        /// <param name="localPort"></param>
        /// <param name="numPlayers"></param>
        /// <param name="hostIp"></param>
        /// <param name="hostPort"></param>
        public void InitSpectator(int localPort, int numPlayers, string hostIp, int hostPort)
        {
            // Initialize the game state
            InitializeGameState(numPlayers);

            //ggpo = new SpectatorBackend(this, new ConsoleLogger(), localPort, numPlayers, 4, hostIp, hostPort);
            ggpo = new SpectatorBackend(this, new RollingBufferFileLogger("vectorwar"), localPort, numPlayers, 4, hostIp, hostPort);

            lblStatus.Text = "Starting new spectator session";
            Task.Factory.StartNew(() => HandleApplicationIdle(this, ggpo), TaskCreationOptions.LongRunning);
        }
Example #4
0
 /// <summary>
 /// Runs the game loop inside the form.
 /// </summary>
 async Task HandleApplicationIdle(VectorWar form, GGPOSession ggpo)
 {
     while (true)
     {
         while (IsApplicationIdle())
         {
             now = Utility.GetCurrentTime();
             await(Task) form.Invoke((TaskMethodInvoker) delegate { ggpo.Idle((int)Math.Max(0, next - now - 1)); return(Task.CompletedTask); });
             if (now >= next)
             {
                 await(Task) form.Invoke((TaskMethodInvoker) delegate { GameUpdate(); return(Task.CompletedTask); });
                 await(Task) form.Invoke((TaskMethodInvoker) delegate { Refresh(); return(Task.CompletedTask); });
                 next = now + (uint)(1000 / 60f);
             }
         }
     }
 }