Add partial implementation of handling disconnects while playing via network
authorunc0rr
Mon, 13 Oct 2008 19:04:27 +0000
changeset 1351 aa7aefec5c1b
parent 1350 99a921e292f4
child 1352 405ad07cf875
Add partial implementation of handling disconnects while playing via network
QTfrontend/newnetclient.cpp
doc/protocol.txt
hedgewars/uIO.pas
hedgewars/uTeams.pas
netserver/HWProto.hs
--- a/QTfrontend/newnetclient.cpp	Mon Oct 13 18:37:59 2008 +0000
+++ b/QTfrontend/newnetclient.cpp	Mon Oct 13 19:04:27 2008 +0000
@@ -262,6 +262,12 @@
 			return;
 		}
 		m_pTeamSelWidget->removeNetTeam(HWTeam(lst[1]));
+		if (netClientState == 5) // we're in game, need to tell the engine about this
+		{
+			QByteArray em;
+			HWProto::addStringToBuffer(em, "F" + lst[1]);
+			emit FromNet(em);
+		}
 		return;
 	}
 
@@ -297,6 +303,7 @@
 	}
 
 	if (lst[0] == "RUN_GAME") {
+		netClientState = 5;
 		RunGame();
 		return;
 	}
@@ -381,18 +388,18 @@
 		return;
 	}
 
-  if (lst[0] == "GAMEMSG") {
-    if(lst.size() < 2)
-    {
-      qWarning("Net: Bad GAMEMSG message");
-      return;
-    }
-    QByteArray em = QByteArray::fromBase64(lst[1].toAscii());
-    emit FromNet(em);
-    return;
-  }
+	if (lst[0] == "GAMEMSG") {
+		if(lst.size() < 2)
+		{
+			qWarning("Net: Bad GAMEMSG message");
+			return;
+		}
+		QByteArray em = QByteArray::fromBase64(lst[1].toAscii());
+		emit FromNet(em);
+		return;
+	}
 
-  qWarning() << "Net: Unknown message:" << lst;
+	qWarning() << "Net: Unknown message:" << lst;
 }
 
 
@@ -494,5 +501,6 @@
 
 void HWNewNet::gameFinished()
 {
+	netClientState = 3;
 	RawSendNet(QString("ROUNDFINISHED"));
 }
--- a/doc/protocol.txt	Mon Oct 13 18:37:59 2008 +0000
+++ b/doc/protocol.txt	Mon Oct 13 19:04:27 2008 +0000
@@ -20,6 +20,7 @@
 	'Q'             выход через команду /quit
 	'q'             выход по причине окончания игры
 	't' + №        /taunt №
+	'F' + <team>    команда team вылетела в сетевой игре
 
 фронтенд клиенту:
 	'e' + <команда> выполнить "/<команда>"
--- a/hedgewars/uIO.pas	Mon Oct 13 18:37:59 2008 +0000
+++ b/hedgewars/uIO.pas	Mon Oct 13 19:04:27 2008 +0000
@@ -37,7 +37,7 @@
 var hiTicks: Word = 0;
 
 implementation
-uses uConsole, uConsts, uWorld, uMisc, uLand, uChat;
+uses uConsole, uConsts, uWorld, uMisc, uLand, uChat, uTeams;
 const isPonged: boolean = false;
 
 type PCmd = ^TCmd;
@@ -64,7 +64,7 @@
 FillChar(Result^, sizeof(TCmd), 0);
 Result^.Time:= Time;
 Result^.str:= str;
-dec(Result^.len, 2); // cut timestamp
+if Result^.cmd <> 'F' then dec(Result^.len, 2); // cut timestamp
 if headcmd = nil then
    begin
    headcmd:= Result;
@@ -216,7 +216,10 @@
 begin
 tmpflag:= true;
 
-while (headcmd <> nil) and ((GameTicks = headcmd^.Time) or (headcmd^.cmd = 's')) do
+while (headcmd <> nil)
+	and ((GameTicks = headcmd^.Time)
+		or (headcmd^.cmd = 's')
+		or (headcmd^.cmd = 'F')) do
 	begin
 	case headcmd^.cmd of
 		'+': ; // do nothing - it's just empty packet
@@ -239,6 +242,7 @@
 			AddChatString(s);
 			WriteLnToConsole(s)
 			end;
+		'F': TeamGone(copy(headcmd^.str, 2, Pred(headcmd^.len)));
 		'N': begin
 			tmpflag:= false;
 			{$IFDEF DEBUGFILE}AddFileLog('got cmd "N": time '+inttostr(headcmd^.Time)){$ENDIF}
--- a/hedgewars/uTeams.pas	Mon Oct 13 18:37:59 2008 +0000
+++ b/hedgewars/uTeams.pas	Mon Oct 13 19:04:27 2008 +0000
@@ -65,7 +65,7 @@
 			DrawHealthY: LongInt;
 			AttackBar: LongWord;
 			HedgehogsNumber: Longword;
-			hasSurrendered: boolean;
+			hasGone: boolean;
 			end;
 			
 	TClan = record
@@ -94,9 +94,10 @@
 procedure RecountTeamHealth(team: PTeam);
 procedure RestoreTeamsFromSave;
 function  CheckForWin: boolean;
+procedure TeamGone(s: shortstring);
 
 implementation
-uses uMisc, uWorld, uAI, uLocale, uConsole, uAmmos, uSound;
+uses uMisc, uWorld, uAI, uLocale, uConsole, uAmmos, uSound, uChat;
 const MaxTeamHealth: LongInt = 0;
 
 procedure FreeTeamsList; forward;
@@ -174,8 +175,9 @@
 		end;
 
 	with ClansArray[c]^ do
+		begin
+		PrevTeam:= CurrTeam;
 		repeat
-			PrevTeam:= CurrTeam;
 			CurrTeam:= Succ(CurrTeam) mod TeamsNumber;
 			CurrentTeam:= Teams[CurrTeam];
 			with CurrentTeam^ do
@@ -185,8 +187,9 @@
 					CurrHedgehog:= Succ(CurrHedgehog) mod HedgehogsNumber;
 				until (Hedgehogs[CurrHedgehog].Gear <> nil) or (CurrHedgehog = PrevHH)
 				end
-		until ((CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil) and (not CurrentTeam^.hasSurrendered)) or (PrevTeam = CurrTeam);
-until CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil;
+		until ((CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil) and (not CurrentTeam^.hasGone)) or (PrevTeam = CurrTeam);
+		end
+until (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil) and (not CurrentTeam^.hasGone);
 
 CurrentHedgehog:= @(CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog])
 end;
@@ -351,6 +354,24 @@
    TeamsArray[t]^.ExtDriven:= false
 end;
 
+procedure TeamGone(s: shortstring);
+var i: integer;
+begin
+i:= 0;
+
+while (i < cMaxTeams)
+	and (TeamsArray[i] <> nil)
+	and (TeamsArray[i]^.TeamName <> s) do inc(i);
+if (i = cMaxTeams) or (TeamsArray[i] = nil) then exit;
+
+with TeamsArray[i]^ do
+	begin
+	AddChatString('* '+ TeamName + ' is gone');
+	//for i:= 0 to cMaxHHIndex do Hedgehogs[i].Gear:= nil;
+	hasGone:= true
+	end
+end;
+
 initialization
 
 finalization
--- a/netserver/HWProto.hs	Mon Oct 13 18:37:59 2008 +0000
+++ b/netserver/HWProto.hs	Mon Oct 13 19:04:27 2008 +0000
@@ -58,14 +58,11 @@
 	else if isMaster client then
 		(noChangeClients, removeRoom (room client), answerQuit ++ answerAbandoned) -- core disconnects clients on ROOMABANDONED answer
 	else
-		(noChangeClients, modifyRoom clRoom{teams = othersTeams}, answerQuit ++ (answerQuitInform $ nick client) ++ answerRemoveClientTeams ++ answerLostTeams)
+		(noChangeClients, modifyRoom clRoom{teams = othersTeams}, answerQuit ++ (answerQuitInform $ nick client) ++ answerRemoveClientTeams)
 	where
 		clRoom = roomByName (room client) rooms
 		answerRemoveClientTeams = map (\tn -> (othersInRoom, ["REMOVE_TEAM", teamname tn])) clientTeams
 		(clientTeams, othersTeams) = partition (\t -> teamowner t == nick client) $ teams clRoom
-		answerLostTeams = if gameinprogress clRoom then answerInGameLostTeams clientTeams else []
-		answerInGameLostTeams teams = []
-
 
 
 -- check state and call state-dependent commmand handlers