Fix (quite rare) spectators queue error when joining game with teams left the game.
authorunc0rr
Wed, 21 Oct 2009 19:41:24 +0000
changeset 2574 2f3e5c57359c
parent 2573 a7db29d7e2d0
child 2575 d06e0e829828
Fix (quite rare) spectators queue error when joining game with teams left the game. Could be applied to 0.9.12 without breaking compatibility.
hedgewars/uIO.pas
--- a/hedgewars/uIO.pas	Wed Oct 21 16:50:02 2009 +0000
+++ b/hedgewars/uIO.pas	Wed Oct 21 19:41:24 2009 +0000
@@ -45,7 +45,7 @@
 type PCmd = ^TCmd;
      TCmd = packed record
             Next: PCmd;
-            Time: LongWord;
+            loTime: Word;
             case byte of
             1: (len: byte;
                 cmd: Char;
@@ -63,12 +63,12 @@
 	SendEmptyPacketTicks: LongWord = 0;
 
 
-function AddCmd(Time: Longword; str: shortstring): PCmd;
+function AddCmd(Time: Word; str: shortstring): PCmd;
 var Result: PCmd;
 begin
 new(Result);
 FillChar(Result^, sizeof(TCmd), 0);
-Result^.Time:= Time;
+Result^.loTime:= Time;
 Result^.str:= str;
 if Result^.cmd <> 'F' then dec(Result^.len, 2); // cut timestamp
 if headcmd = nil then
@@ -121,7 +121,6 @@
 case s[1] of
      '!': begin {$IFDEF DEBUGFILE}AddFileLog('Ping? Pong!');{$ENDIF}isPonged:= true; end;
      '?': SendIPC('!');
-     '#': inc(hiTicks);
      'e': ParseCommand(copy(s, 2, Length(s) - 1), true);
      'E': OutError(copy(s, 2, Length(s) - 1), true);
      'W': OutError(copy(s, 2, Length(s) - 1), false);
@@ -134,8 +133,8 @@
                else OutError(errmsgIncorrectUse + ' IPC "T" :' + s[2], true) end;
      else
      loTicks:= SDLNet_Read16(@s[byte(s[0]) - 1]);
-     AddCmd(hiTicks shl 16 + loTicks, s);
-     {$IFDEF DEBUGFILE}AddFileLog('IPC in: '+s[1]+' ticks '+inttostr(lastcmd^.Time));{$ENDIF}
+     AddCmd(loTicks, s);
+     {$IFDEF DEBUGFILE}AddFileLog('IPC in: '+s[1]+' ticks '+inttostr(lastcmd^.loTime));{$ENDIF}
      end
 end;
 
@@ -265,14 +264,16 @@
 tmpflag:= true;
 
 while (headcmd <> nil)
-	and tmpflag
-	and ((GameTicks = headcmd^.Time)
-		or (headcmd^.cmd = 's')
-		or (headcmd^.cmd = 'b')
+	and (tmpflag or (headcmd^.cmd = '#')) // '#' is the only cmd which can be sent within same tick after 'N'
+	and ((GameTicks = hiTicks shl 16 + headcmd^.loTime)
+		or (headcmd^.cmd = 's') // for these commands time isn't specified
+		or (headcmd^.cmd = '#')
+ 		or (headcmd^.cmd = 'b')
 		or (headcmd^.cmd = 'F')) do
 	begin
 	case headcmd^.cmd of
-		'+': ; // do nothing - it is just empty packet
+		'+': ; // do nothing - it is just an empty packet
+		'#': inc(hiTicks);
 		'L': ParseCommand('+left', true);
 		'l': ParseCommand('-left', true);
 		'R': ParseCommand('+right', true);
@@ -302,7 +303,7 @@
 		'F': TeamGone(copy(headcmd^.str, 2, Pred(headcmd^.len)));
 		'N': begin
 			tmpflag:= false;
-			{$IFDEF DEBUGFILE}AddFileLog('got cmd "N": time '+inttostr(headcmd^.Time)){$ENDIF}
+			{$IFDEF DEBUGFILE}AddFileLog('got cmd "N": time '+inttostr(hiTicks shl 16 + headcmd^.loTime)){$ENDIF}
 			end;
 		'p': begin
 			TargetPoint.X:= SDLNet_Read16(@(headcmd^.X));
@@ -311,8 +312,8 @@
 			end;
 		'P': begin
 			// these are equations solved for CursorPoint
-			// SDLNet_Read16(@(headcmd^.X)):= CursorPoint.X - WorldDx;
-			// SDLNet_Read16(@(headcmd^.Y)):= cScreenHeight - CursorPoint.Y - WorldDy;
+			// SDLNet_Read16(@(headcmd^.X)) == CursorPoint.X - WorldDx;
+			// SDLNet_Read16(@(headcmd^.Y)) == cScreenHeight - CursorPoint.Y - WorldDy;
 			CursorPoint.X:= SDLNet_Read16(@(headcmd^.X)) + WorldDx;
 			CursorPoint.Y:= cScreenHeight - SDLNet_Read16(@(headcmd^.Y)) - WorldDy;
 			end;
@@ -328,11 +329,11 @@
 	RemoveCmd
 	end;
 
-if (headcmd <> nil) and tmpflag then
-	TryDo(GameTicks < headcmd^.Time,
+if (headcmd <> nil) and tmpflag and (not CurrentTeam^.hasGone) then
+	TryDo(GameTicks < hiTicks shl 16 + headcmd^.loTime,
 			'oops, queue error. in buffer: ' + headcmd^.cmd +
 			' (' + inttostr(GameTicks) + ' > ' +
-			inttostr(headcmd^.Time) + ')',
+			inttostr(hiTicks shl 16 + headcmd^.loTime) + ')',
 			true);
 
 isInLag:= (headcmd = nil) and tmpflag and (not CurrentTeam^.hasGone);