]> Dogcows Code - chaz/carfire/blobdiff - Project06/CS 3505 Project 06/CS 3505 Project 06/NetworkGame.cs
Added a basic timeout feature so you'll at least get bumped back to the lobby after...
[chaz/carfire] / Project06 / CS 3505 Project 06 / CS 3505 Project 06 / NetworkGame.cs
index c69e2fb71fc6f2beb58cf66f0baed10eec3b2535..869812e58ad6147528dfc35b5770d72b38625c23 100644 (file)
@@ -1,4 +1,9 @@
-using System;\r
+\r
+// Make sure DEBUG is undefined when turning in the project\r
+// or the grader will wonder why it's so laggy.\r
+#undef DEBUG\r
+\r
+using System;\r
 using System.Collections.Generic;\r
 using System.Linq;\r
 using System.Text;\r
@@ -279,12 +284,17 @@ namespace CS_3505_Project_06
                 }\r
                 else if (mNetworkSession.SessionState == NetworkSessionState.Playing)\r
                 {\r
-                    if (mGame.IsGameOver(LocalGamerInfo) || mGame.IsTerminated(LocalGamerInfo))\r
+                    if (mGame.IsTerminated(LocalGamerInfo))\r
                     {\r
-                        // TODO: Should support moving back to the session lobby.\r
                         LeaveSession();\r
                         return;\r
                     }\r
+                    else if (mGame.IsGameOver(LocalGamerInfo))\r
+                    {\r
+                        ApplyEvents(LocalGamerInfo, GetEventsFromInput());\r
+                        mGame.Update(mTargetTimeSpan);\r
+                        return;\r
+                    }\r
 \r
                     if (HaveNeededEvents)\r
                     {\r
@@ -297,24 +307,24 @@ namespace CS_3505_Project_06
                         mLocalEvents.AddRange(GetEventsFromInput());\r
                         SendLocalEvents();\r
                         ApplyEvents();\r
+\r
+#if DEBUG\r
+                        Console.WriteLine("HASH: " + mGame.CurrentFrameNumber + "\t" + mGame.CurrentChecksum);\r
+#endif\r
+\r
                         mGame.Update(mTargetTimeSpan);\r
                     }\r
                     else // Stall!\r
                     {\r
-                        if (mStallCount == 0)\r
-                        {\r
-                            Console.WriteLine("===== STALL =====");\r
-                        }\r
-                        else if (mStallCount % 60 == 0)\r
-                        {\r
-                            Console.WriteLine("Stalled for " + mStallCount + " frames.");\r
-                        }\r
-\r
                         mStallCount++;\r
 \r
                         // Send a reliable event packet to each stalled gamer.\r
                         if (mStallCount == 1)\r
                         {\r
+#if DEBUG\r
+                            Console.WriteLine("STAL: ====");\r
+#endif\r
+\r
                             foreach (GamerInfo gamerInfo in GamerArray)\r
                             {\r
                                 if (gamerInfo.HighestFrameNumber < mGame.CurrentFrameNumber)\r
@@ -323,19 +333,11 @@ namespace CS_3505_Project_06
                                 }\r
                             }\r
                         }\r
-\r
-                        /*if (mStallCount > StallTimeout)\r
-                        {\r
-                            DropLostGamers();\r
-                            mStallCount = 0;\r
-                        }\r
-                        else if (mStallCount == 1)\r
+                        else if (mStallCount > 600)\r
                         {\r
-                            SendLocalEvents\r
+                            Console.WriteLine("One or more players have stalled excessively.  Leaving session...");\r
+                            LeaveSession();\r
                         }\r
-                        else if (mStallCount % 60 == 0)\r
-                        {\r
-                        } TODO */\r
                     }\r
                 }\r
             }\r
@@ -439,8 +441,9 @@ namespace CS_3505_Project_06
         int mLastStallCount;\r
         int mAverageOwd;\r
 \r
-        // DEBUG\r
+#if DEBUG\r
         bool mDontSendEvents;\r
+#endif\r
 \r
         TimeSpan mTargetTimeSpan = new TimeSpan(166666);\r
         public TimeSpan TargetTimeSpan\r
@@ -481,8 +484,7 @@ namespace CS_3505_Project_06
         enum PacketType\r
         {\r
             Chat = 1,\r
-            Event = 2,\r
-            Stall = 3\r
+            Event = 2\r
         }\r
 \r
         enum EventType\r
@@ -575,7 +577,7 @@ namespace CS_3505_Project_06
         class GamerInfo\r
         {\r
             public NetworkGamer Gamer;\r
-            public long HighestFrameNumber = -1;\r
+            public long HighestFrameNumber = 0;\r
             public int StallCount = 0;\r
             public int AverageOwd = 0;\r
             public int NextStallCount = 0;\r
@@ -604,7 +606,7 @@ namespace CS_3505_Project_06
         void Reset()\r
         {\r
             mLatency = 1;\r
-            mHighestFrameNumber = -1;\r
+            mHighestFrameNumber = 0;\r
             mNextLatencyAdjustmentFrame = 1;\r
             mStallCount = 0;\r
             mLastStallCount = 0;\r
@@ -629,7 +631,6 @@ namespace CS_3505_Project_06
                 NetworkGamer sender;\r
 \r
                 localGamer.ReceiveData(mPacketReader, out sender);\r
-                GamerInfo senderInfo = mGamers[sender.Id];\r
 \r
                 PacketType packetId = (PacketType)mPacketReader.ReadByte();\r
                 switch (packetId)\r
@@ -645,17 +646,38 @@ namespace CS_3505_Project_06
 \r
                     case PacketType.Event:\r
 \r
+                        GamerInfo senderInfo = mGamers[sender.Id];\r
+\r
                         int stallCount = mPacketReader.ReadInt16();\r
                         int averageOwd = mPacketReader.ReadInt16();\r
                         int frameNumber = mPacketReader.ReadInt32();\r
                         int numEvents = mPacketReader.ReadByte();\r
 \r
+                        if (frameNumber <= mNextLatencyAdjustmentFrame)\r
+                        {\r
+                            senderInfo.StallCount = stallCount;\r
+                            senderInfo.AverageOwd = averageOwd;\r
+                        }\r
+                        else\r
+                        {\r
+                            senderInfo.NextStallCount = stallCount;\r
+                            senderInfo.NextAverageOwd = averageOwd;\r
+                        }\r
+\r
                         if (frameNumber <= senderInfo.HighestFrameNumber)\r
                         {\r
+#if DEBUG\r
+                            Console.WriteLine("SKP" + (char)sender.Id + ": " + mGame.CurrentFrameNumber + "\t" + frameNumber + "\t<=\t" + senderInfo.HighestFrameNumber + "\t#" + numEvents);\r
+#endif\r
+\r
                             // we know about all these events, so don't bother reading them\r
                             break;\r
                         }\r
 \r
+#if DEBUG\r
+                        Console.WriteLine(" GOT" + (char)sender.Id + ": " + mGame.CurrentFrameNumber + "\t" + frameNumber + "\t>\t" + senderInfo.HighestFrameNumber + "\t#" + numEvents);\r
+#endif\r
+\r
                         for (int i = 0; i < numEvents; i++)\r
                         {\r
                             EventInfo eventInfo = ReadEvent(mPacketReader, sender);\r
@@ -668,27 +690,9 @@ namespace CS_3505_Project_06
                             }\r
                         }\r
 \r
-                        if (frameNumber <= mNextLatencyAdjustmentFrame)\r
-                        {\r
-                            senderInfo.StallCount = stallCount;\r
-                            senderInfo.AverageOwd = averageOwd;\r
-                        }\r
-                        else\r
-                        {\r
-                            senderInfo.NextStallCount = stallCount;\r
-                            senderInfo.NextAverageOwd = averageOwd;\r
-                        }\r
                         senderInfo.HighestFrameNumber = frameNumber;\r
                         break;\r
 \r
-                    case PacketType.Stall:\r
-\r
-                        byte numStalledPeers = mPacketReader.ReadByte();\r
-                        byte[] stalledPeers = mPacketReader.ReadBytes(numStalledPeers);\r
-\r
-                        // TODO\r
-                        break;\r
-\r
                     default:\r
 \r
                         Console.WriteLine("Received unknown packet type: " + (int)packetId);\r
@@ -756,12 +760,12 @@ namespace CS_3505_Project_06
             mPacketWriter.Write(message.ToCharArray());\r
         }\r
 \r
-        void WriteEventPacket(List<EventInfo> events)\r
+        void WriteEventPacket(List<EventInfo> events, long highestFrameNumber)\r
         {\r
             mPacketWriter.Write((byte)PacketType.Event);\r
             mPacketWriter.Write((short)mLastStallCount);\r
             mPacketWriter.Write((short)mAverageOwd);\r
-            mPacketWriter.Write((int)(mGame.CurrentFrameNumber + mLatency));\r
+            mPacketWriter.Write((int)highestFrameNumber);\r
             mPacketWriter.Write((byte)events.Count);\r
 \r
             foreach (EventInfo eventInfo in events)\r
@@ -806,6 +810,13 @@ namespace CS_3505_Project_06
         {\r
             Debug.Assert(IsLatencyAdjustmentFrame);\r
 \r
+#if DEBUG\r
+            if (mStallCount > 0)\r
+            {\r
+                Console.WriteLine("STL#: " + mGame.CurrentFrameNumber + "\t" + mStallCount);\r
+            }\r
+#endif\r
+\r
             int maxStallCount = 0;\r
             int maxAverageOwd = 0;\r
 \r
@@ -818,8 +829,9 @@ namespace CS_3505_Project_06
                 gamerInfo.AverageOwd = gamerInfo.NextAverageOwd;\r
             }\r
 \r
-            // DEBUG\r
+#if DEBUG\r
             int prevLatency = mLatency;\r
+#endif\r
 \r
             if (maxStallCount > 0)\r
             {\r
@@ -827,15 +839,16 @@ namespace CS_3505_Project_06
             }\r
             else\r
             {\r
-                mLatency = (int)(0.6 * (double)(mLatency - maxAverageOwd) + 1.0);\r
+                mLatency -= (int)(0.6 * (double)(mLatency - maxAverageOwd) + 1.0);\r
             }\r
 \r
-            // DEBUG OUTPUT\r
-            if (prevLatency != mLatency) Console.WriteLine("Latency readjusted to " + mLatency);\r
-\r
             if (mLatency < 1) mLatency = 1;\r
             if (mLatency > MaximumLatency) mLatency = MaximumLatency;\r
 \r
+#if DEBUG\r
+            if (prevLatency != mLatency) Console.WriteLine("NLAG: " + mLatency);\r
+#endif\r
+\r
             mNextLatencyAdjustmentFrame = mGame.CurrentFrameNumber + mLatency;\r
             mAverageOwd = CurrentAverageOneWayDelay;\r
 \r
@@ -878,9 +891,10 @@ namespace CS_3505_Project_06
                 events.Add(new KeyboardEventInfo(LocalGamer, frameOfApplication, key, false));\r
             }\r
 \r
-            // DEBUG\r
+#if DEBUG\r
             if (pressedKeys.Contains(Keys.Escape)) mDontSendEvents = true;\r
             if (releasedKeys.Contains(Keys.Escape)) mDontSendEvents = false;\r
+#endif\r
 \r
             // 2. Find the mouse differences.\r
 \r
@@ -938,20 +952,22 @@ namespace CS_3505_Project_06
 \r
         void SendLocalEvents(NetworkGamer recipient)\r
         {\r
-            // DEBUG\r
+#if DEBUG\r
             if (mDontSendEvents) return;\r
+#endif\r
 \r
             List<EventInfo> events = new List<EventInfo>(mLocalEvents);\r
             events.AddRange(mLastLocalEvents);\r
 \r
-            WriteEventPacket(events);\r
-\r
             if (recipient != null && !recipient.IsDisposed)\r
             {\r
+                // if there is a recipient, we are resending old events\r
+                WriteEventPacket(events, mGame.CurrentFrameNumber - 1);\r
                 LocalGamer.SendData(mPacketWriter, SendDataOptions.Reliable, recipient);\r
             }\r
             else\r
             {\r
+                WriteEventPacket(events, mGame.CurrentFrameNumber + mLatency);\r
                 LocalGamer.SendData(mPacketWriter, SendDataOptions.None);\r
             }\r
         }\r
@@ -965,6 +981,7 @@ namespace CS_3505_Project_06
 \r
                 foreach (GamerInfo gamerInfo in mGamers.Values)\r
                 {\r
+                    if (mGame.IsGameOver(gamerInfo)) continue;\r
                     if (gamerInfo.HighestFrameNumber < currentFrame) return false;\r
                 }\r
 \r
@@ -979,35 +996,47 @@ namespace CS_3505_Project_06
             foreach (GamerInfo gamerInfo in GamerArray)\r
             {\r
                 if (gamerInfo.Events[index] == null) continue;\r
+                ApplyEvents(gamerInfo, gamerInfo.Events[index]);\r
+                gamerInfo.Events[index] = null;\r
+            }\r
+        }\r
 \r
-                foreach (EventInfo eventInfo in gamerInfo.Events[index])\r
+        void ApplyEvents(GamerInfo gamerInfo, List<EventInfo> events)\r
+        {\r
+            foreach (EventInfo eventInfo in events)\r
+            {\r
+                KeyboardEventInfo keyboardEventInfo = eventInfo as KeyboardEventInfo;\r
+                if (keyboardEventInfo != null)\r
                 {\r
-                    KeyboardEventInfo keyboardEventInfo = eventInfo as KeyboardEventInfo;\r
-                    if (keyboardEventInfo != null)\r
-                    {\r
-                        Console.WriteLine(keyboardEventInfo.FrameOfApplication + " KEY: " + keyboardEventInfo.Key + "," + keyboardEventInfo.IsKeyDown);\r
-                        mGame.ApplyKeyInput(gamerInfo, keyboardEventInfo.Key, keyboardEventInfo.IsKeyDown);\r
-                        continue;\r
-                    }\r
+#if DEBUG\r
+                    Console.WriteLine(" KEY: " + keyboardEventInfo.FrameOfApplication + "\t" + keyboardEventInfo.Key + "," + keyboardEventInfo.IsKeyDown);\r
+#endif\r
 \r
-                    MouseButtonEventInfo mouseButtonEventInfo = eventInfo as MouseButtonEventInfo;\r
-                    if (mouseButtonEventInfo != null)\r
-                    {\r
-                        mGame.ApplyMouseButtonInput(gamerInfo, mouseButtonEventInfo.IsButtonDown);\r
-                        Console.WriteLine(mouseButtonEventInfo.FrameOfApplication + " BTN: " + mouseButtonEventInfo.IsButtonDown);\r
-                        continue;\r
-                    }\r
+                    mGame.ApplyKeyInput(gamerInfo, keyboardEventInfo.Key, keyboardEventInfo.IsKeyDown);\r
+                    continue;\r
+                }\r
 \r
-                    MouseMotionEventInfo mouseMotionEventInfo = eventInfo as MouseMotionEventInfo;\r
-                    if (mouseMotionEventInfo != null)\r
-                    {\r
-                        mGame.ApplyMouseLocationInput(gamerInfo, mouseMotionEventInfo.X, mouseMotionEventInfo.Y);\r
-                        Console.WriteLine(mouseMotionEventInfo.FrameOfApplication + " MMV: " + mouseMotionEventInfo.X + "," + mouseMotionEventInfo.Y);\r
-                        continue;\r
-                    }\r
+                MouseButtonEventInfo mouseButtonEventInfo = eventInfo as MouseButtonEventInfo;\r
+                if (mouseButtonEventInfo != null)\r
+                {\r
+#if DEBUG\r
+                    Console.WriteLine(" BTN: " + mouseButtonEventInfo.FrameOfApplication + "\t" + mouseButtonEventInfo.IsButtonDown);\r
+#endif\r
+\r
+                    mGame.ApplyMouseButtonInput(gamerInfo, mouseButtonEventInfo.IsButtonDown);\r
+                    continue;\r
                 }\r
 \r
-                gamerInfo.Events[index] = null;\r
+                MouseMotionEventInfo mouseMotionEventInfo = eventInfo as MouseMotionEventInfo;\r
+                if (mouseMotionEventInfo != null)\r
+                {\r
+#if DEBUG\r
+                    Console.WriteLine(" MMV: " + mouseMotionEventInfo.FrameOfApplication + "\t" + mouseMotionEventInfo.X + "," + mouseMotionEventInfo.Y);\r
+#endif\r
+\r
+                    mGame.ApplyMouseLocationInput(gamerInfo, mouseMotionEventInfo.X, mouseMotionEventInfo.Y);\r
+                    continue;\r
+                }\r
             }\r
         }\r
 \r
This page took 0.036944 seconds and 4 git commands to generate.