- Special rooms which stay even when last player quits. Not useful for now, and can't be removed at all.
authorunc0rr
Thu, 05 Dec 2013 00:51:27 +0400
changeset 9753 9579596cf471
parent 9752 656c511ab0f3
child 9754 12702ab1ba5f
- Special rooms which stay even when last player quits. Not useful for now, and can't be removed at all. - Define default value for SCRIPT in room config - Allow server admins to join 'registered users only' room
gameServer/Actions.hs
gameServer/CoreTypes.hs
gameServer/HWProtoCore.hs
gameServer/HWProtoInRoomState.hs
gameServer/HWProtoLobbyState.hs
gameServer/Utils.hs
--- a/gameServer/Actions.hs	Wed Dec 04 12:28:04 2013 +0100
+++ b/gameServer/Actions.hs	Thu Dec 05 00:51:27 2013 +0400
@@ -21,6 +21,7 @@
 import System.Process
 import Network.Socket
 import System.Random
+import qualified Data.Traversable as DT
 -----------------------------
 #if defined(OFFICIAL_SERVER)
 import OfficialServer.GameReplayStore
@@ -187,13 +188,14 @@
     ri <- clientRoomA
     rnc <- gets roomsClients
     playersNum <- io $ room'sM rnc playersIn ri
+    specialRoom <- io $ room'sM rnc isSpecial ri
     master <- client's isMaster
 --    client <- client's id
     clNick <- client's nick
     chans <- othersChans
 
     if master then
-        if playersNum > 1 then
+        if (playersNum > 1) || specialRoom then
             mapM_ processAction [ChangeMaster Nothing, NoticeMessage AdminLeft, RemoveClientTeams, AnswerClients chans ["LEFT", clNick, msg]]
             else
             processAction RemoveRoom
@@ -205,7 +207,7 @@
 
     -- when not removing room
     ready <- client's isReady
-    when (not master || playersNum > 1) . io $ do
+    when (not master || playersNum > 1 || specialRoom) . io $ do
         modifyRoom rnc (\r -> r{
                 playersIn = playersIn r - 1,
                 readyPlayers = if ready then readyPlayers r - 1 else readyPlayers r
@@ -218,31 +220,40 @@
     proto <- client's clientProto
     ri <- clientRoomA
     rnc <- gets roomsClients
-    newMasterId <- liftM (\ids -> fromMaybe (last . filter (/= ci) $ ids) delegateId) . io $ roomClientsIndicesM rnc ri
-    newMaster <- io $ client'sM rnc id newMasterId
+    specialRoom <- io $ room'sM rnc isSpecial ri
+    newMasterId <- liftM (\ids -> fromMaybe (listToMaybe . reverse . filter (/= ci) $ ids) $ liftM Just delegateId) . io $ roomClientsIndicesM rnc ri
+    newMaster <- io $ client'sM rnc id `DT.mapM` newMasterId
     oldMasterId <- io $ room'sM rnc masterID ri
-    oldMaster <- io $ client'sM rnc id oldMasterId
     oldRoomName <- io $ room'sM rnc name ri
     kicked <- client's isKickedFromServer
     thisRoomChans <- liftM (map sendChan) $ roomClientsS ri
-    let newRoomName = if (proto < 42) || kicked then nick newMaster else oldRoomName
-    mapM_ processAction [
+    let newRoomName = if ((proto < 42) || kicked) && (not specialRoom) then maybeNick newMaster else oldRoomName
+
+    when (isJust oldMasterId) $ do
+        oldMasterNick <- io $ client'sM rnc nick (fromJust oldMasterId)
+        mapM_ processAction [
+            ModifyClient2 (fromJust oldMasterId) (\c -> c{isMaster = False})
+            , AnswerClients thisRoomChans ["CLIENT_FLAGS", "-h", oldMasterNick]
+            ]
+
+    when (isJust newMasterId) $
+        mapM_ processAction [
+          ModifyClient2 (fromJust newMasterId) (\c -> c{isMaster = True})
+        , AnswerClients [sendChan $ fromJust newMaster] ["ROOM_CONTROL_ACCESS", "1"]
+        , AnswerClients thisRoomChans ["CLIENT_FLAGS", "+h", nick $ fromJust newMaster]
+        ]
+
+    processAction $
         ModifyRoom (\r -> r{masterID = newMasterId
                 , name = newRoomName
                 , isRestrictedJoins = False
                 , isRestrictedTeams = False
-                , isRegisteredOnly = False}
+                , isRegisteredOnly = isSpecial r}
                 )
-        , ModifyClient2 newMasterId (\c -> c{isMaster = True})
-        , ModifyClient2 oldMasterId (\c -> c{isMaster = False})
-        , AnswerClients [sendChan newMaster] ["ROOM_CONTROL_ACCESS", "1"]
-        , AnswerClients thisRoomChans ["CLIENT_FLAGS", "-h", nick oldMaster]
-        , AnswerClients thisRoomChans ["CLIENT_FLAGS", "+h", nick newMaster]
-        ]
 
     newRoom' <- io $ room'sM rnc id ri
     chans <- liftM (map sendChan) $! sameProtoClientsS proto
-    processAction $ AnswerClients chans ("ROOM" : "UPD" : oldRoomName : roomInfo proto(nick newMaster) newRoom')
+    processAction $ AnswerClients chans ("ROOM" : "UPD" : oldRoomName : roomInfo proto (maybeNick newMaster) newRoom')
 
 
 processAction (AddRoom roomName roomPassword) = do
@@ -252,7 +263,7 @@
     n <- client's nick
 
     let rm = newRoom{
-            masterID = clId,
+            masterID = Just clId,
             name = roomName,
             password = roomPassword,
             roomProto = proto
@@ -292,9 +303,9 @@
     rnc <- gets roomsClients
     ri <- io $ clientRoomM rnc clId
     rm <- io $ room'sM rnc id ri
-    n <- io $ client'sM rnc nick (masterID rm)
+    masterCl <- io $ client'sM rnc id `DT.mapM` (masterID rm)
     chans <- liftM (map sendChan) $! sameProtoClientsS proto
-    processAction $ AnswerClients chans ("ROOM" : "UPD" : name rm : roomInfo proto n rm)
+    processAction $ AnswerClients chans ("ROOM" : "UPD" : name rm : roomInfo proto (maybeNick masterCl) rm)
 
 
 processAction UnreadyRoomClients = do
--- a/gameServer/CoreTypes.hs	Wed Dec 04 12:28:04 2013 +0100
+++ b/gameServer/CoreTypes.hs	Thu Dec 05 00:51:27 2013 +0400
@@ -170,7 +170,7 @@
 data RoomInfo =
     RoomInfo
     {
-        masterID :: ClientIndex,
+        masterID :: Maybe ClientIndex,
         name :: B.ByteString,
         password :: B.ByteString,
         roomProto :: Word16,
@@ -181,6 +181,7 @@
         isRestrictedJoins :: Bool,
         isRestrictedTeams :: Bool,
         isRegisteredOnly :: Bool,
+        isSpecial :: Bool,
         roomBansList :: ![B.ByteString],
         mapParams :: Map.Map B.ByteString B.ByteString,
         params :: Map.Map B.ByteString [B.ByteString]
@@ -189,7 +190,7 @@
 newRoom :: RoomInfo
 newRoom =
     RoomInfo
-        (error "No room master defined")
+        Nothing
         ""
         ""
         0
@@ -200,13 +201,19 @@
         False
         False
         False
+        False
         []
         (
-            Map.fromList $ Prelude.zipWith (,)
+            Map.fromList $ Prelude.zip
                 ["MAP", "MAPGEN", "MAZE_SIZE", "SEED", "TEMPLATE"]
                 ["+rnd+", "0", "0", "seed", "0"]
         )
-        (Map.singleton "SCHEME" ["Default"])
+        (
+            Map.fromList $ Prelude.zip
+                ["SCHEME", "SCRIPT"]
+                [["Default"], ["Normal"]]
+        )
+
 
 data StatisticsInfo =
     StatisticsInfo
--- a/gameServer/HWProtoCore.hs	Wed Dec 04 12:28:04 2013 +0100
+++ b/gameServer/HWProtoCore.hs	Thu Dec 05 00:51:27 2013 +0400
@@ -51,6 +51,7 @@
             let chans = map (sendChan . client rnc) $ allClients rnc
             return [AnswerClients chans ["CHAT", "[global notice]", p] | isAdministrator cl]
         h "WATCH" f = return [QueryReplay f]
+        h "FIX" _ = handleCmd ["FIX"]
         h c p = return [Warning $ B.concat ["Unknown cmd: /", c, p]]
 
 handleCmd cmd = do
--- a/gameServer/HWProtoInRoomState.hs	Wed Dec 04 12:28:04 2013 +0100
+++ b/gameServer/HWProtoInRoomState.hs	Thu Dec 05 00:51:27 2013 +0400
@@ -43,6 +43,7 @@
                 else
                 r{params = Map.insert paramName paramStrs (params r)}
 
+
 handleCmd_inRoom ("ADD_TEAM" : tName : color : grave : fort : voicepack : flag : difStr : hhsInfo)
     | length hhsInfo /= 16 = return [ProtocolError $ loc "Corrupted hedgehogs info"]
     | otherwise = do
@@ -290,6 +291,9 @@
         if illegalName newName then 
             [Warning $ loc "Illegal room name"]
         else
+        if isSpecial rm then 
+            [Warning $ loc "Restricted"]
+        else
         if isJust $ find (\r -> newName == name r) rs then
             [Warning $ loc "Room with such name already exists"]
         else
@@ -331,7 +335,7 @@
             (master || serverAdmin)
                 && isJust maybeClientId
                 && ((newAdminId /= thisClientId) || (serverAdmin && not master))
-                && (newAdminId /= thisRoomMasterId)
+                && (Just newAdminId /= thisRoomMasterId)
                 && sameRoom]
 
 
@@ -362,6 +366,11 @@
     s <- roomClientsChans
     return [AnswerClients s ["CHAT", n, B.unwords $ "/rnd" : rs], Random s rs]
 
+handleCmd_inRoom ["FIX"] = do
+    cl <- thisClient
+    return [ModifyRoom (\r -> r{isSpecial = True}) | isAdministrator cl]
+
+
 handleCmd_inRoom ["LIST"] = return [] -- for old clients (<= 0.9.17)
 
 handleCmd_inRoom (s:_) = return [ProtocolError $ "Incorrect command '" `B.append` s `B.append` "' (state: in room)"]
--- a/gameServer/HWProtoLobbyState.hs	Wed Dec 04 12:28:04 2013 +0100
+++ b/gameServer/HWProtoLobbyState.hs	Thu Dec 05 00:51:27 2013 +0400
@@ -21,10 +21,9 @@
     (ci, irnc) <- ask
     let cl = irnc `client` ci
     rooms <- allRoomInfos
-    let roomsInfoList = concatMap (\r -> roomInfo (clientProto cl) (nick $ irnc `client` masterID r) r) . filter (\r -> (roomProto r == clientProto cl))
+    let roomsInfoList = concatMap (\r -> roomInfo (clientProto cl) (maybeNick . liftM (client irnc) $ masterID r) r) . filter (\r -> (roomProto r == clientProto cl))
     return [AnswerClients [sendChan cl] ("ROOMS" : roomsInfoList rooms)]
 
-
 handleCmd_lobby ["CHAT", msg] = do
     n <- clientNick
     s <- roomOthersChans
@@ -60,7 +59,7 @@
     let sameProto = clientProto cl == roomProto jRoom
     let jRoomClients = map (client irnc) $ roomClients irnc jRI
     let nicks = map nick jRoomClients
-    let ownerNick = nick . fromJust $ find isMaster jRoomClients
+    let owner = find isMaster jRoomClients
     let chans = map sendChan (cl : jRoomClients)
     let isBanned = host cl `elem` roomBansList jRoom
     return $
@@ -70,24 +69,25 @@
             [Warning $ loc "Room version incompatible to your hedgewars version"]
             else if isRestrictedJoins jRoom then
             [Warning $ loc "Joining restricted"]
-            else if isRegisteredOnly jRoom && (B.null . webPassword $ cl) then
+            else if isRegisteredOnly jRoom && (B.null . webPassword $ cl) && not (isAdministrator cl) then
             [Warning $ loc "Registered users only"]
             else if isBanned then
             [Warning $ loc "You are banned in this room"]
             else if roomPassword /= password jRoom then
             [NoticeMessage WrongPassword]
             else
-            [
+            (
                 MoveToRoom jRI
-                , ModifyClient (\c -> c{isJoinedMidGame = isJust $ gameInfo jRoom})
-                , AnswerClients [sendChan cl] $ "JOINED" : nicks
-                , AnswerClients chans ["CLIENT_FLAGS", "-r", nick cl]
-                , AnswerClients [sendChan cl] $ ["CLIENT_FLAGS", "+h", ownerNick]
-            ]
+                : ModifyClient (\c -> c{isJoinedMidGame = isJust $ gameInfo jRoom})
+                : (AnswerClients [sendChan cl] $ "JOINED" : nicks)
+                : AnswerClients chans ["CLIENT_FLAGS", "-r", nick cl]
+                : [AnswerClients [sendChan cl] $ ["CLIENT_FLAGS", "+h", nick $ fromJust owner] | isJust owner]
+            )
             ++ (if clientProto cl < 38 then map (readynessMessage cl) jRoomClients else [sendStateFlags cl jRoomClients])
             ++ answerFullConfig cl jRoom
             ++ answerTeams cl jRoom
             ++ watchRound cl jRoom chans
+            ++ []
 
         where
         readynessMessage cl c = AnswerClients [sendChan cl] [if isReady c then "READY" else "NOT_READY", nick c]
--- a/gameServer/Utils.hs	Wed Dec 04 12:28:04 2013 +0100
+++ b/gameServer/Utils.hs	Thu Dec 05 00:51:27 2013 +0400
@@ -180,3 +180,6 @@
 
 loc :: B.ByteString -> B.ByteString
 loc = id
+
+maybeNick :: Maybe ClientInfo -> B.ByteString
+maybeNick = fromMaybe "[empty]" . liftM nick