X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=Project06%2FCS%203505%20Project%2006%2FCS%203505%20Project%2006%2FNetworkGame.cs;h=55d8b2e0a0d3df33920b8ac9da526ea642e36659;hb=904f5665bb8ea18a6a32d10632e2a0da2244b494;hp=72a588cf62f6fcbab846b40794fd387dbf529a52;hpb=0e2cd798178ca471d26ea33ee849365c3b9b593e;p=chaz%2Fcarfire
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 72a588c..55d8b2e 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
@@ -36,6 +36,21 @@ namespace CS_3505_Project_06
public delegate void FoundSessionsDelegate(AvailableNetworkSessionCollection sessions, NetworkGame networkGame);
+ ///
+ /// Called when an exception is thrown during an asynchronous operation.
+ ///
+ /// The exception that was thrown.
+ /// The NetworkGame that errored.
+ public delegate void CaughtErrorDelegate(Exception exception, NetworkGame networkGame);
+
+ ///
+ /// Get and set the error delegate, called when an exception is thrown during
+ /// and asynchronous operation. This will occur if you try to create or join a
+ /// session without being logged into a profile.
+ ///
+ public CaughtErrorDelegate ErrorDelegate;
+
+
///
/// Construct a NetworkGame with a lobby and a game.
///
@@ -97,20 +112,26 @@ 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);
- mNetworkSession = NetworkSession.EndCreate(result);
- mNetworkSession.AllowHostMigration = true;
- mNetworkSession.AllowJoinInProgress = false;
- mNetworkSession.GameStarted += new EventHandler(mNetworkSession_GameStarted);
+ try
+ {
+ mNetworkSession = NetworkSession.EndCreate(result);
+ mNetworkSession.AllowHostMigration = true;
+ mNetworkSession.AllowJoinInProgress = false;
+ mNetworkSession.GameStarted += new EventHandler(GameStartedEvent);
+ }
+ catch (Exception e)
+ {
+ if (ErrorDelegate != null) ErrorDelegate(e, this);
+ return;
+ }
mJoinedSessionDelegate(mNetworkSession, this);
+ mJoinedSessionDelegate = null;
}
-
-
- //gamestarted event
- void mNetworkSession_GameStarted(object sender, GameStartedEventArgs e)
+ void GameStartedEvent(object sender, GameStartedEventArgs e)
{
Reset();
}
@@ -140,10 +161,20 @@ 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 = NetworkSession.EndFind(result);
+ AvailableNetworkSessionCollection sessions;
+ try
+ {
+ sessions = NetworkSession.EndFind(result);
+ }
+ catch (Exception e)
+ {
+ if (ErrorDelegate != null) ErrorDelegate(e, this);
+ return;
+ }
mFoundSessionsDelegate(sessions, this);
+ mFoundSessionsDelegate = null;
}
///
@@ -159,16 +190,22 @@ 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);
- mNetworkSession = NetworkSession.EndJoin(result);
-
+ try
+ {
+ mNetworkSession = NetworkSession.EndJoin(result);
+ mNetworkSession.GameStarted += new EventHandler(GameStartedEvent);
+ }
+ catch (Exception e)
+ {
+ if (ErrorDelegate != null) ErrorDelegate(e, this);
+ return;
+ }
mJoinedSessionDelegate(mNetworkSession, this);
mJoinedSessionDelegate = null;
-
- mNetworkSession.GameStarted += new EventHandler(mNetworkSession_GameStarted);
}
@@ -218,8 +255,6 @@ namespace CS_3505_Project_06
{
mNetworkSession.StartGame();
mNetworkSession.ResetReady();
-
- //Reset();
}
@@ -256,6 +291,7 @@ namespace CS_3505_Project_06
if (IsLatencyAdjustmentFrame)
{
AdjustLatency();
+ mLastStallCount = mStallCount;
mStallCount = 0;
}
mLocalEvents.AddRange(GetEventsFromInput());
@@ -265,11 +301,27 @@ namespace CS_3505_Project_06
}
else // Stall!
{
+ if (mStallCount == 0)
+ {
+ Console.WriteLine("===== STALL =====");
+ }
+ else if (mStallCount % 60 == 0)
+ {
+ 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)
@@ -379,10 +431,15 @@ namespace CS_3505_Project_06
int mLastMousePositionY;
int mLatency;
+ long mHighestFrameNumber;
long mNextLatencyAdjustmentFrame;
int mStallCount;
+ int mLastStallCount;
int mAverageOwd;
+ // DEBUG
+ bool mDontSendEvents;
+
TimeSpan mTargetTimeSpan = new TimeSpan(166666);
public TimeSpan TargetTimeSpan
{
@@ -516,9 +573,11 @@ namespace CS_3505_Project_06
class GamerInfo
{
public NetworkGamer Gamer;
- public long HighestFrameNumber = 0;
+ public long HighestFrameNumber = -1;
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];
@@ -543,8 +602,10 @@ namespace CS_3505_Project_06
void Reset()
{
mLatency = 1;
+ mHighestFrameNumber = -1;
mNextLatencyAdjustmentFrame = 1;
mStallCount = 0;
+ mLastStallCount = 0;
mAverageOwd = CurrentAverageOneWayDelay;
mGamers = new Dictionary();
@@ -582,10 +643,10 @@ 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 <= senderInfo.HighestFrameNumber)
{
@@ -593,20 +654,28 @@ namespace CS_3505_Project_06
break;
}
- for (byte i = 0; i < numEvents; ++i)
+ 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;
+ if (frameNumber <= mNextLatencyAdjustmentFrame)
+ {
+ senderInfo.StallCount = stallCount;
+ senderInfo.AverageOwd = averageOwd;
+ }
+ else
+ {
+ senderInfo.NextStallCount = stallCount;
+ senderInfo.NextAverageOwd = averageOwd;
+ }
senderInfo.HighestFrameNumber = frameNumber;
break;
@@ -616,7 +685,6 @@ namespace CS_3505_Project_06
byte[] stalledPeers = mPacketReader.ReadBytes(numStalledPeers);
// TODO
-
break;
default:
@@ -628,9 +696,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)
@@ -642,23 +715,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:
@@ -684,7 +757,7 @@ namespace CS_3505_Project_06
void WriteEventPacket(List events)
{
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((byte)events.Count);
@@ -738,6 +811,9 @@ 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
@@ -771,6 +847,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();
@@ -789,13 +869,17 @@ 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));
}
+ // DEBUG
+ if (pressedKeys.Contains(Keys.Escape)) mDontSendEvents = true;
+ if (releasedKeys.Contains(Keys.Escape)) mDontSendEvents = false;
+
// 2. Find the mouse differences.
MouseState mouseState = Mouse.GetState();
@@ -803,26 +887,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;
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;
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.
@@ -852,12 +936,15 @@ namespace CS_3505_Project_06
void SendLocalEvents(NetworkGamer recipient)
{
+ // DEBUG
+ if (mDontSendEvents) return;
+
List events = new List(mLocalEvents);
events.AddRange(mLastLocalEvents);
WriteEventPacket(events);
- if (recipient != null)
+ if (recipient != null && !recipient.IsDisposed)
{
LocalGamer.SendData(mPacketWriter, SendDataOptions.Reliable, recipient);
}
@@ -885,7 +972,7 @@ namespace CS_3505_Project_06
void ApplyEvents()
{
- int index = EventArrayIndex;
+ int index = CurrentEventArrayIndex;
foreach (GamerInfo gamerInfo in GamerArray)
{
@@ -896,6 +983,7 @@ namespace CS_3505_Project_06
KeyboardEventInfo keyboardEventInfo = eventInfo as KeyboardEventInfo;
if (keyboardEventInfo != null)
{
+ Console.WriteLine(keyboardEventInfo.FrameOfApplication + " KEY: " + keyboardEventInfo.Key + "," + keyboardEventInfo.IsKeyDown);
mGame.ApplyKeyInput(gamerInfo, keyboardEventInfo.Key, keyboardEventInfo.IsKeyDown);
continue;
}
@@ -904,6 +992,7 @@ namespace CS_3505_Project_06
if (mouseButtonEventInfo != null)
{
mGame.ApplyMouseButtonInput(gamerInfo, mouseButtonEventInfo.IsButtonDown);
+ Console.WriteLine(mouseButtonEventInfo.FrameOfApplication + " BTN: " + mouseButtonEventInfo.IsButtonDown);
continue;
}
@@ -911,6 +1000,7 @@ namespace CS_3505_Project_06
if (mouseMotionEventInfo != null)
{
mGame.ApplyMouseLocationInput(gamerInfo, mouseMotionEventInfo.X, mouseMotionEventInfo.Y);
+ Console.WriteLine(mouseMotionEventInfo.FrameOfApplication + " MMV: " + mouseMotionEventInfo.X + "," + mouseMotionEventInfo.Y);
continue;
}
}
@@ -935,7 +1025,7 @@ namespace CS_3505_Project_06
averageOwd += timeSpan.TotalMilliseconds;
}
- return (int)(averageOwd / numRemoteGamersTwice / 16.6666);
+ return (int)((averageOwd / numRemoteGamersTwice) / 16.6666);
}
}