X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fcarfire;a=blobdiff_plain;f=Project06%2FCS%203505%20Project%2006%2FCS%203505%20Project%2006%2FNetworkGame.cs;h=45c5d0a498fdd5a1ce9de1445b85cdbd309a6187;hp=792d16d2063e8b2fe3f756bd216cc442ca7d819f;hb=b98320a31a73dc18d6ef83cb440a5304930af161;hpb=87550d29aa4aa52e9c3e413e58877b494d7d7017 diff --git a/Project06/CS 3505 Project 06/CS 3505 Project 06/NetworkGame.cs b/Project06/CS 3505 Project 06/CS 3505 Project 06/NetworkGame.cs index 792d16d..45c5d0a 100644 --- a/Project06/CS 3505 Project 06/CS 3505 Project 06/NetworkGame.cs +++ b/Project06/CS 3505 Project 06/CS 3505 Project 06/NetworkGame.cs @@ -1,4 +1,7 @@ -using System; + +#undef DEBUG + +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -112,7 +115,7 @@ namespace CS_3505_Project_06 mJoinedSessionDelegate = callback; NetworkSession.BeginCreate(NetworkSessionType.SystemLink, 1, maxGamers, CreateSessionEnd, null); } - private void CreateSessionEnd(IAsyncResult result) + void CreateSessionEnd(IAsyncResult result) { Debug.Assert(mNetworkSession == null); @@ -121,7 +124,7 @@ namespace CS_3505_Project_06 mNetworkSession = NetworkSession.EndCreate(result); mNetworkSession.AllowHostMigration = true; mNetworkSession.AllowJoinInProgress = false; - mNetworkSession.GameStarted += new EventHandler(mNetworkSession_GameStarted); + mNetworkSession.GameStarted += new EventHandler(GameStartedEvent); } catch (Exception e) { @@ -131,10 +134,7 @@ namespace CS_3505_Project_06 mJoinedSessionDelegate(mNetworkSession, this); mJoinedSessionDelegate = null; } - - - //gamestarted event - void mNetworkSession_GameStarted(object sender, GameStartedEventArgs e) + void GameStartedEvent(object sender, GameStartedEventArgs e) { Reset(); } @@ -164,7 +164,7 @@ namespace CS_3505_Project_06 mFoundSessionsDelegate = callback; NetworkSession.BeginFind(NetworkSessionType.SystemLink, 1, null, new AsyncCallback(FindSessionsEnd), null); } - private void FindSessionsEnd(IAsyncResult result) + void FindSessionsEnd(IAsyncResult result) { AvailableNetworkSessionCollection sessions; try @@ -193,14 +193,14 @@ namespace CS_3505_Project_06 mJoinedSessionDelegate = callback; NetworkSession.BeginJoin(availableSession, JoinSessionEnd, null); } - private void JoinSessionEnd(IAsyncResult result) + void JoinSessionEnd(IAsyncResult result) { Debug.Assert(mNetworkSession == null); try { mNetworkSession = NetworkSession.EndJoin(result); - mNetworkSession.GameStarted += new EventHandler(mNetworkSession_GameStarted); + mNetworkSession.GameStarted += new EventHandler(GameStartedEvent); } catch (Exception e) { @@ -258,8 +258,6 @@ namespace CS_3505_Project_06 { mNetworkSession.StartGame(); mNetworkSession.ResetReady(); - - //Reset(); } @@ -296,20 +294,45 @@ namespace CS_3505_Project_06 if (IsLatencyAdjustmentFrame) { AdjustLatency(); + mLastStallCount = mStallCount; mStallCount = 0; } mLocalEvents.AddRange(GetEventsFromInput()); SendLocalEvents(); ApplyEvents(); + +#if DEBUG + Console.WriteLine("HASH: " + mGame.CurrentFrameNumber + "\t" + mGame.CurrentChecksum); +#endif + mGame.Update(mTargetTimeSpan); } else // Stall! { + if (mStallCount == 0) + { +#if DEBUG + Console.WriteLine("STAL: ===="); +#endif + } + else if (mStallCount % 60 == 0) + { + // DEBUG + //Console.WriteLine("Stalled for " + mStallCount + " frames."); + } + mStallCount++; - if (mStallCount % 60 == 0) + // Send a reliable event packet to each stalled gamer. + if (mStallCount == 1) { - Console.WriteLine("Stalled for " + mStallCount + " frames."); + foreach (GamerInfo gamerInfo in GamerArray) + { + if (gamerInfo.HighestFrameNumber < mGame.CurrentFrameNumber) + { + SendLocalEvents(gamerInfo.Gamer); + } + } } /*if (mStallCount > StallTimeout) @@ -356,7 +379,7 @@ namespace CS_3505_Project_06 /// - /// Get the chat messages that have been receive since the last time this + /// Get the chat messages that have been received since the last time this /// method was called. /// /// List container of the chat messages. @@ -386,6 +409,8 @@ namespace CS_3505_Project_06 /// The gamer to receive the message. public void SendChat(String message, NetworkGamer recipient) { + Debug.Assert(recipient != null && !recipient.IsDisposed); + WriteChatPacket(message); LocalGamer.SendData(mPacketWriter, SendDataOptions.ReliableInOrder, recipient); } @@ -419,10 +444,16 @@ namespace CS_3505_Project_06 int mLastMousePositionY; int mLatency; + long mHighestFrameNumber; long mNextLatencyAdjustmentFrame; int mStallCount; + int mLastStallCount; int mAverageOwd; +#if DEBUG + bool mDontSendEvents; +#endif + TimeSpan mTargetTimeSpan = new TimeSpan(166666); public TimeSpan TargetTimeSpan { @@ -559,6 +590,8 @@ namespace CS_3505_Project_06 public long HighestFrameNumber = 0; public int StallCount = 0; public int AverageOwd = 0; + public int NextStallCount = 0; + public int NextAverageOwd = 0; public bool IsWaitedOn = false; public List[] Events = new List[MaximumLatency]; @@ -583,8 +616,10 @@ namespace CS_3505_Project_06 void Reset() { mLatency = 1; + mHighestFrameNumber = 0; mNextLatencyAdjustmentFrame = 1; mStallCount = 0; + mLastStallCount = 0; mAverageOwd = CurrentAverageOneWayDelay; mGamers = new Dictionary(); @@ -606,6 +641,7 @@ namespace CS_3505_Project_06 NetworkGamer sender; localGamer.ReceiveData(mPacketReader, out sender); + if (sender == null || sender.IsDisposed) continue; GamerInfo senderInfo = mGamers[sender.Id]; PacketType packetId = (PacketType)mPacketReader.ReadByte(); @@ -622,31 +658,48 @@ namespace CS_3505_Project_06 case PacketType.Event: - short stallCount = mPacketReader.ReadInt16(); - short averageOwd = mPacketReader.ReadInt16(); + int stallCount = mPacketReader.ReadInt16(); + int averageOwd = mPacketReader.ReadInt16(); int frameNumber = mPacketReader.ReadInt32(); - byte numEvents = mPacketReader.ReadByte(); + int numEvents = mPacketReader.ReadByte(); + + if (frameNumber <= mNextLatencyAdjustmentFrame) + { + senderInfo.StallCount = stallCount; + senderInfo.AverageOwd = averageOwd; + } + else + { + senderInfo.NextStallCount = stallCount; + senderInfo.NextAverageOwd = averageOwd; + } if (frameNumber <= senderInfo.HighestFrameNumber) { +#if DEBUG + Console.WriteLine("SKP" + (char)sender.Id + ": " + mGame.CurrentFrameNumber + "\t" + frameNumber + "\t<=\t" + senderInfo.HighestFrameNumber + "\t#" + numEvents); +#endif + // we know about all these events, so don't bother reading them break; } - for (byte i = 0; i < numEvents; ++i) +#if DEBUG + Console.WriteLine(" GOT" + (char)sender.Id + ": " + mGame.CurrentFrameNumber + "\t" + frameNumber + "\t>\t" + senderInfo.HighestFrameNumber + "\t#" + numEvents); +#endif + + for (int i = 0; i < numEvents; i++) { EventInfo eventInfo = ReadEvent(mPacketReader, sender); - if (eventInfo != null && eventInfo.FrameOfApplication < senderInfo.HighestFrameNumber) + if (eventInfo != null && eventInfo.FrameOfApplication > senderInfo.HighestFrameNumber) { - int index = EventArrayIndex; + int index = GetEventArrayIndexForFrame(eventInfo.FrameOfApplication); if (senderInfo.Events[index] == null) senderInfo.Events[index] = new List(); senderInfo.Events[index].Add(eventInfo); } } - senderInfo.StallCount = stallCount; - senderInfo.AverageOwd = averageOwd; senderInfo.HighestFrameNumber = frameNumber; break; @@ -656,7 +709,6 @@ namespace CS_3505_Project_06 byte[] stalledPeers = mPacketReader.ReadBytes(numStalledPeers); // TODO - break; default: @@ -668,9 +720,14 @@ namespace CS_3505_Project_06 } - int EventArrayIndex + int CurrentEventArrayIndex + { + get { return GetEventArrayIndexForFrame(mGame.CurrentFrameNumber); } + } + + int GetEventArrayIndexForFrame(long frame) { - get { return (int)(mGame.CurrentFrameNumber % MaximumLatency); } + return (int)(frame % MaximumLatency); } EventInfo ReadEvent(PacketReader packetReader, NetworkGamer sender) @@ -682,23 +739,23 @@ namespace CS_3505_Project_06 { case EventType.KeyDown: - int keyCode1 = packetReader.ReadInt32(); - return new KeyboardEventInfo(sender, frameNumber, (Keys)keyCode1, true); + Keys keyCode1 = (Keys)packetReader.ReadInt32(); + return new KeyboardEventInfo(sender, frameNumber, keyCode1, true); case EventType.KeyUp: - int keyCode2 = packetReader.ReadInt32(); - return new KeyboardEventInfo(sender, frameNumber, (Keys)keyCode2, false); + Keys keyCode2 = (Keys)packetReader.ReadInt32(); + return new KeyboardEventInfo(sender, frameNumber, keyCode2, false); case EventType.MouseDown: - byte buttonId1 = packetReader.ReadByte(); - return new MouseButtonEventInfo(sender, frameNumber, (MouseButton)buttonId1, true); + MouseButton buttonId1 = (MouseButton)packetReader.ReadByte(); + return new MouseButtonEventInfo(sender, frameNumber, buttonId1, true); case EventType.MouseUp: - byte buttonId2 = packetReader.ReadByte(); - return new MouseButtonEventInfo(sender, frameNumber, (MouseButton)buttonId2, false); + MouseButton buttonId2 = (MouseButton)packetReader.ReadByte(); + return new MouseButtonEventInfo(sender, frameNumber, buttonId2, false); case EventType.MouseMove: @@ -721,12 +778,12 @@ namespace CS_3505_Project_06 mPacketWriter.Write(message.ToCharArray()); } - void WriteEventPacket(List events) + void WriteEventPacket(List events, long highestFrameNumber) { mPacketWriter.Write((byte)PacketType.Event); - mPacketWriter.Write((short)mStallCount); + mPacketWriter.Write((short)mLastStallCount); mPacketWriter.Write((short)mAverageOwd); - mPacketWriter.Write((int)(mGame.CurrentFrameNumber + mLatency)); + mPacketWriter.Write((int)highestFrameNumber); mPacketWriter.Write((byte)events.Count); foreach (EventInfo eventInfo in events) @@ -771,6 +828,13 @@ namespace CS_3505_Project_06 { Debug.Assert(IsLatencyAdjustmentFrame); +#if DEBUG + if (mStallCount > 0) + { + Console.WriteLine("STL#: " + mGame.CurrentFrameNumber + "\t" + mStallCount); + } +#endif + int maxStallCount = 0; int maxAverageOwd = 0; @@ -778,10 +842,14 @@ namespace CS_3505_Project_06 { if (gamerInfo.StallCount > maxStallCount) maxStallCount = gamerInfo.StallCount; if (gamerInfo.AverageOwd > maxAverageOwd) maxAverageOwd = gamerInfo.AverageOwd; + + gamerInfo.StallCount = gamerInfo.NextStallCount; + gamerInfo.AverageOwd = gamerInfo.NextAverageOwd; } - // DEBUG +#if DEBUG int prevLatency = mLatency; +#endif if (maxStallCount > 0) { @@ -789,15 +857,16 @@ namespace CS_3505_Project_06 } else { - mLatency = (int)(0.6 * (double)(mLatency - maxAverageOwd) + 1.0); + mLatency -= (int)(0.6 * (double)(mLatency - maxAverageOwd) + 1.0); } - // DEBUG OUTPUT - if (prevLatency != mLatency) Console.WriteLine("Latency readjusted to " + mLatency); - if (mLatency < 1) mLatency = 1; if (mLatency > MaximumLatency) mLatency = MaximumLatency; +#if DEBUG + if (prevLatency != mLatency) Console.WriteLine("NLAG: " + mLatency); +#endif + mNextLatencyAdjustmentFrame = mGame.CurrentFrameNumber + mLatency; mAverageOwd = CurrentAverageOneWayDelay; @@ -811,6 +880,10 @@ namespace CS_3505_Project_06 { List events = new List(); + long frameOfApplication = mGame.CurrentFrameNumber + mLatency; + if (frameOfApplication <= mHighestFrameNumber) return events; + else mHighestFrameNumber = frameOfApplication; + // 1. Find the keyboard differences; written by Peter. KeyboardState keyState = Keyboard.GetState(); @@ -829,13 +902,18 @@ namespace CS_3505_Project_06 foreach (Keys key in pressedKeys) { - events.Add(new KeyboardEventInfo(LocalGamer, mGame.CurrentFrameNumber, key, true)); + events.Add(new KeyboardEventInfo(LocalGamer, frameOfApplication, key, true)); } foreach (Keys key in releasedKeys) { - events.Add(new KeyboardEventInfo(LocalGamer, mGame.CurrentFrameNumber, key, false)); + events.Add(new KeyboardEventInfo(LocalGamer, frameOfApplication, key, false)); } +#if DEBUG + if (pressedKeys.Contains(Keys.Escape)) mDontSendEvents = true; + if (releasedKeys.Contains(Keys.Escape)) mDontSendEvents = false; +#endif + // 2. Find the mouse differences. MouseState mouseState = Mouse.GetState(); @@ -843,26 +921,26 @@ namespace CS_3505_Project_06 bool leftButtonPressed = mouseState.LeftButton == ButtonState.Pressed; if (leftButtonPressed != mLastLeftButtonPressed) { - events.Add(new MouseButtonEventInfo(LocalGamer, mGame.CurrentFrameNumber, MouseButton.Left, leftButtonPressed)); + events.Add(new MouseButtonEventInfo(LocalGamer, frameOfApplication, MouseButton.Left, leftButtonPressed)); } - bool rightButtonPressed = mouseState.LeftButton == ButtonState.Pressed; + bool rightButtonPressed = mouseState.RightButton == ButtonState.Pressed; if (rightButtonPressed != mLastRightButtonPressed) { - events.Add(new MouseButtonEventInfo(LocalGamer, mGame.CurrentFrameNumber, MouseButton.Right, rightButtonPressed)); + events.Add(new MouseButtonEventInfo(LocalGamer, frameOfApplication, MouseButton.Right, rightButtonPressed)); } - bool middleButtonPressed = mouseState.LeftButton == ButtonState.Pressed; + bool middleButtonPressed = mouseState.MiddleButton == ButtonState.Pressed; if (middleButtonPressed != mLastMiddleButtonPressed) { - events.Add(new MouseButtonEventInfo(LocalGamer, mGame.CurrentFrameNumber, MouseButton.Middle, middleButtonPressed)); + events.Add(new MouseButtonEventInfo(LocalGamer, frameOfApplication, MouseButton.Middle, middleButtonPressed)); } int mousePositionX = mouseState.X; int mousePositionY = mouseState.Y; if (mousePositionX != mLastMousePositionX || mousePositionY != mLastMousePositionY) { - events.Add(new MouseMotionEventInfo(LocalGamer, mGame.CurrentFrameNumber, mousePositionX, mousePositionY)); + events.Add(new MouseMotionEventInfo(LocalGamer, frameOfApplication, mousePositionX, mousePositionY)); } // 3. Save the current peripheral state. @@ -892,17 +970,22 @@ namespace CS_3505_Project_06 void SendLocalEvents(NetworkGamer recipient) { +#if DEBUG + if (mDontSendEvents) return; +#endif + List events = new List(mLocalEvents); events.AddRange(mLastLocalEvents); - WriteEventPacket(events); - - if (recipient != null) + if (recipient != null && !recipient.IsDisposed) { + // if there is a recipient, we are resending old events + WriteEventPacket(events, mGame.CurrentFrameNumber - 1); LocalGamer.SendData(mPacketWriter, SendDataOptions.Reliable, recipient); } else { + WriteEventPacket(events, mGame.CurrentFrameNumber + mLatency); LocalGamer.SendData(mPacketWriter, SendDataOptions.None); } } @@ -925,7 +1008,7 @@ namespace CS_3505_Project_06 void ApplyEvents() { - int index = EventArrayIndex; + int index = CurrentEventArrayIndex; foreach (GamerInfo gamerInfo in GamerArray) { @@ -936,6 +1019,10 @@ namespace CS_3505_Project_06 KeyboardEventInfo keyboardEventInfo = eventInfo as KeyboardEventInfo; if (keyboardEventInfo != null) { +#if DEBUG + Console.WriteLine(" KEY: " + keyboardEventInfo.FrameOfApplication + "\t" + keyboardEventInfo.Key + "," + keyboardEventInfo.IsKeyDown); +#endif + mGame.ApplyKeyInput(gamerInfo, keyboardEventInfo.Key, keyboardEventInfo.IsKeyDown); continue; } @@ -943,6 +1030,10 @@ namespace CS_3505_Project_06 MouseButtonEventInfo mouseButtonEventInfo = eventInfo as MouseButtonEventInfo; if (mouseButtonEventInfo != null) { +#if DEBUG + Console.WriteLine(" BTN: " + mouseButtonEventInfo.FrameOfApplication + "\t" + mouseButtonEventInfo.IsButtonDown); +#endif + mGame.ApplyMouseButtonInput(gamerInfo, mouseButtonEventInfo.IsButtonDown); continue; } @@ -950,6 +1041,10 @@ namespace CS_3505_Project_06 MouseMotionEventInfo mouseMotionEventInfo = eventInfo as MouseMotionEventInfo; if (mouseMotionEventInfo != null) { +#if DEBUG + Console.WriteLine(" MMV: " + mouseMotionEventInfo.FrameOfApplication + "\t" + mouseMotionEventInfo.X + "," + mouseMotionEventInfo.Y); +#endif + mGame.ApplyMouseLocationInput(gamerInfo, mouseMotionEventInfo.X, mouseMotionEventInfo.Y); continue; } @@ -975,7 +1070,7 @@ namespace CS_3505_Project_06 averageOwd += timeSpan.TotalMilliseconds; } - return (int)(averageOwd / numRemoteGamersTwice / 16.6666); + return (int)((averageOwd / numRemoteGamersTwice) / 16.6666); } }