# HG changeset patch # User unc0rr # Date 1223924667 0 # Node ID aa7aefec5c1b5b0926d2c9908ed05e801eb1dd5d # Parent 99a921e292f4ee37296d82dc7c12def3460dea4c Add partial implementation of handling disconnects while playing via network diff -r 99a921e292f4 -r aa7aefec5c1b QTfrontend/newnetclient.cpp --- 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")); } diff -r 99a921e292f4 -r aa7aefec5c1b doc/protocol.txt --- 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 вылетела в сетевой игре фронтенд клиенту: 'e' + <команда> выполнить "/<команда>" diff -r 99a921e292f4 -r aa7aefec5c1b hedgewars/uIO.pas --- 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} diff -r 99a921e292f4 -r aa7aefec5c1b hedgewars/uTeams.pas --- 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 diff -r 99a921e292f4 -r aa7aefec5c1b netserver/HWProto.hs --- 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