Get rid of teamownerId since rejoin feature makes it virtually useless, as you cannot rely on it anymore. Should fix recently experienced server crashes.
authorunc0rr
Tue, 30 Dec 2014 22:59:15 +0300
changeset 10732 7c4f9e5e447c
parent 10730 eac6a4d53752
child 10734 8fadc4305df0
Get rid of teamownerId since rejoin feature makes it virtually useless, as you cannot rely on it anymore. Should fix recently experienced server crashes.
gameServer/Actions.hs
gameServer/CoreTypes.hs
gameServer/HWProtoInRoomState.hs
--- a/gameServer/Actions.hs	Tue Dec 30 22:12:07 2014 +0300
+++ b/gameServer/Actions.hs	Tue Dec 30 22:59:15 2014 +0300
@@ -415,11 +415,12 @@
 processAction RemoveClientTeams = do
     (Just ci) <- gets clientIndex
     rnc <- gets roomsClients
+    n <- client's nick
 
     removeTeamActions <- io $ do
         rId <- clientRoomM rnc ci
         roomTeams <- room'sM rnc teams rId
-        return . Prelude.map (RemoveTeam . teamname) . Prelude.filter (\t -> teamownerId t == ci) $ roomTeams
+        return . Prelude.map (RemoveTeam . teamname) . Prelude.filter (\t -> teamowner t == n) $ roomTeams
 
     mapM_ processAction removeTeamActions
 
--- a/gameServer/CoreTypes.hs	Tue Dec 30 22:12:07 2014 +0300
+++ b/gameServer/CoreTypes.hs	Tue Dec 30 22:59:15 2014 +0300
@@ -162,7 +162,6 @@
 data TeamInfo =
     TeamInfo
     {
-        teamownerId :: ClientIndex,
         teamowner :: B.ByteString,
         teamname :: B.ByteString,
         teamcolor :: B.ByteString,
@@ -170,6 +169,7 @@
         teamfort :: B.ByteString,
         teamvoicepack :: B.ByteString,
         teamflag :: B.ByteString,
+        isOwnerRegistered :: Bool,
         difficulty :: Int,
         hhnum :: Int,
         hedgehogs :: [HedgehogInfo]
--- a/gameServer/HWProtoInRoomState.hs	Tue Dec 30 22:12:07 2014 +0300
+++ b/gameServer/HWProtoInRoomState.hs	Tue Dec 30 22:59:15 2014 +0300
@@ -41,7 +41,7 @@
     chans <- roomClientsChans
 
     let nicks = map (nick . client rnc) . roomClients rnc $ clientRoom rnc ci
-    let allPlayersRegistered = all ((<) 0 . B.length . webPassword . client rnc . teamownerId) $ teams rm
+    let allPlayersRegistered = all isOwnerRegistered $ teams rm
 
     if (playersIn rm == readyPlayers rm || clientProto cl > 43) && not (isJust $ gameInfo rm) then
         if enoughClans rm then
@@ -107,11 +107,13 @@
     | otherwise = do
         (ci, _) <- ask
         rm <- thisRoom
+        cl <- thisClient
         clNick <- clientNick
         clChan <- thisClientChans
         othChans <- roomOthersChans
         roomChans <- roomClientsChans
         cl <- thisClient
+        let isRegistered = (<) 0 . B.length . webPassword $ cl
         teamColor <-
             if clientProto cl < 42 then
                 return color
@@ -119,7 +121,7 @@
                 liftM (head . (L.\\) (map B.singleton ['0'..]) . map teamcolor . teams) thisRoom
         let roomTeams = teams rm
         let hhNum = let p = if not $ null roomTeams then minimum [hhnum $ head roomTeams, canAddNumber roomTeams] else 4 in newTeamHHNum roomTeams p
-        let newTeam = clNick `seq` TeamInfo ci clNick tName teamColor grave fort voicepack flag dif hhNum (hhsList hhsInfo)
+        let newTeam = clNick `seq` TeamInfo clNick tName teamColor grave fort voicepack flag isRegistered dif hhNum (hhsList hhsInfo)
         return $
             if not . null . drop (maxTeams rm - 1) $ roomTeams then
                 [Warning $ loc "too many teams"]
@@ -156,6 +158,7 @@
 handleCmd_inRoom ["REMOVE_TEAM", tName] = do
         (ci, _) <- ask
         r <- thisRoom
+        clNick <- clientNick
 
         let maybeTeam = findTeam r
         let team = fromJust maybeTeam
@@ -163,18 +166,18 @@
         return $
             if isNothing $ maybeTeam then
                 [Warning $ loc "REMOVE_TEAM: no such team"]
-            else if ci /= teamownerId team then
+            else if clNick /= teamowner team then
                 [ProtocolError $ loc "Not team owner!"]
             else
                 [RemoveTeam tName,
                 ModifyClient
                     (\c -> c{
                         teamsInGame = teamsInGame c - 1,
-                        clientClan = if teamsInGame c == 1 then Nothing else Just $ anotherTeamClan ci team r
+                        clientClan = if teamsInGame c == 1 then Nothing else Just $ anotherTeamClan clNick team r
                     })
                 ]
     where
-        anotherTeamClan ci team = teamcolor . fromMaybe (error "CHECKPOINT 011") . find (\t -> (teamownerId t == ci) && (t /= team)) . teams
+        anotherTeamClan clNick team = teamcolor . fromMaybe (error "CHECKPOINT 011") . find (\t -> (teamowner t == clNick) && (t /= team)) . teams
         findTeam = find (\t -> tName == teamname t) . teams
 
 
@@ -211,16 +214,18 @@
 
     let maybeTeam = findTeam r
     let team = fromJust maybeTeam
+    maybeClientId <- clientByNick $ teamowner team
+    let teamOwnerId = fromJust maybeClientId
 
     return $
         if not $ isMaster cl then
             [ProtocolError $ loc "Not room master"]
-        else if isNothing maybeTeam then
+        else if isNothing maybeTeam || isNothing maybeClientId then
             []
         else
             [ModifyRoom $ modifyTeam team{teamcolor = newColor},
             AnswerClients others ["TEAM_COLOR", teamName, newColor],
-            ModifyClient2 (teamownerId team) (\c -> c{clientClan = Just newColor})]
+            ModifyClient2 teamOwnerId (\c -> c{clientClan = Just newColor})]
     where
         findTeam = find (\t -> teamName == teamname t) . teams