- 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
--- 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