gameServer/Actions.hs
author nemo
Sun, 24 Jan 2010 16:46:06 +0000
changeset 2712 8f4527c9137c
parent 2662 12dc696f1c81
child 2867 9be6693c78cb
permissions -rw-r--r--
Minor tweak, try to make long flavour text last longer, move the hurt self messages to unused messages group, so they don't get wiped by crate an instant later.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
     1
module Actions where
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
     2
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
     3
import Control.Concurrent.STM
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
     4
import Control.Concurrent.Chan
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
     5
import Data.IntMap
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
     6
import qualified Data.IntSet as IntSet
1813
cfe1481e0247 Removeteam action
unc0rr
parents: 1811
diff changeset
     7
import qualified Data.Sequence as Seq
1839
5dd4cb7fd7e5 Server now send ASKPASSWORD command to frontend when user has web account
unc0rr
parents: 1834
diff changeset
     8
import System.Log.Logger
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
     9
import Monad
1926
cb46fbdcaa41 Add simple DoS protection mechanism (although better than previous server had)
unc0rr
parents: 1925
diff changeset
    10
import Data.Time
cb46fbdcaa41 Add simple DoS protection mechanism (although better than previous server had)
unc0rr
parents: 1925
diff changeset
    11
import Maybe
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    12
-----------------------------
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    13
import CoreTypes
1813
cfe1481e0247 Removeteam action
unc0rr
parents: 1811
diff changeset
    14
import Utils
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    15
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    16
data Action =
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    17
	AnswerThisClient [String]
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    18
	| AnswerAll [String]
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    19
	| AnswerAllOthers [String]
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    20
	| AnswerThisRoom [String]
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    21
	| AnswerOthersInRoom [String]
2403
6c5d504af2ba - Proper /team command implementation
unc0rr
parents: 2352
diff changeset
    22
	| AnswerSameClan [String]
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    23
	| AnswerLobby [String]
1923
956b6b3529bc Send server message on join
unc0rr
parents: 1921
diff changeset
    24
	| SendServerMessage
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    25
	| RoomAddThisClient Int -- roomID
2126
cb249fa8e3da - Prevent server from producing zombies
unc0rr
parents: 2118
diff changeset
    26
	| RoomRemoveThisClient String
1813
cfe1481e0247 Removeteam action
unc0rr
parents: 1811
diff changeset
    27
	| RemoveTeam String
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    28
	| RemoveRoom
1811
1b9e33623b7e Implement 'roundfinished' cmd on net server
unc0rr
parents: 1804
diff changeset
    29
	| UnreadyRoomClients
1841
fba7210b438b Retrieve client password from web database and ask for it
unc0rr
parents: 1839
diff changeset
    30
	| MoveToLobby
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    31
	| ProtocolError String
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    32
	| Warning String
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    33
	| ByeClient String
1862
7f303aa066da Implement kick from server by administrator
unc0rr
parents: 1847
diff changeset
    34
	| KickClient Int -- clID
1879
bb114339eb4e Implement kick from room
unc0rr
parents: 1866
diff changeset
    35
	| KickRoomClient Int -- clID
1921
2a09f7f786a0 - User from localhost is server admin
unc0rr
parents: 1879
diff changeset
    36
	| BanClient String -- nick
1879
bb114339eb4e Implement kick from room
unc0rr
parents: 1866
diff changeset
    37
	| RemoveClientTeams Int -- clID
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    38
	| ModifyClient (ClientInfo -> ClientInfo)
2403
6c5d504af2ba - Proper /team command implementation
unc0rr
parents: 2352
diff changeset
    39
	| ModifyClient2 Int (ClientInfo -> ClientInfo)
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    40
	| ModifyRoom (RoomInfo -> RoomInfo)
1925
ec923e56c444 Allow admin to set server's motd
unc0rr
parents: 1923
diff changeset
    41
	| ModifyServerInfo (ServerInfo -> ServerInfo)
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    42
	| AddRoom String String
1834
71cb978dc85f Add working check for www account existance
unc0rr
parents: 1827
diff changeset
    43
	| CheckRegistered
2155
d897222d3339 Implement ability for server admin to clear accounts cache
unc0rr
parents: 2126
diff changeset
    44
	| ClearAccountsCache
1839
5dd4cb7fd7e5 Server now send ASKPASSWORD command to frontend when user has web account
unc0rr
parents: 1834
diff changeset
    45
	| ProcessAccountInfo AccountInfo
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    46
	| Dump
1926
cb46fbdcaa41 Add simple DoS protection mechanism (although better than previous server had)
unc0rr
parents: 1925
diff changeset
    47
	| AddClient ClientInfo
1927
e2031906a347 Ping clients every 30 seconds. Disconnection due to ping timeout to be implemented.
unc0rr
parents: 1926
diff changeset
    48
	| PingAll
2172
80d34c0b9dfe Implement sending gameserver stats to webserver
unc0rr
parents: 2155
diff changeset
    49
	| StatsAction
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    50
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    51
type CmdHandler = Int -> Clients -> Rooms -> [String] -> [Action]
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    52
1862
7f303aa066da Implement kick from server by administrator
unc0rr
parents: 1847
diff changeset
    53
replaceID a (b, c, d, e) = (a, c, d, e)
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    54
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    55
processAction :: (Int, ServerInfo, Clients, Rooms) -> Action -> IO (Int, ServerInfo, Clients, Rooms)
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    56
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    57
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    58
processAction (clID, serverInfo, clients, rooms) (AnswerThisClient msg) = do
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    59
	writeChan (sendChan $ clients ! clID) msg
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    60
	return (clID, serverInfo, clients, rooms)
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    61
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    62
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    63
processAction (clID, serverInfo, clients, rooms) (AnswerAll msg) = do
1927
e2031906a347 Ping clients every 30 seconds. Disconnection due to ping timeout to be implemented.
unc0rr
parents: 1926
diff changeset
    64
	mapM_ (\cl -> writeChan (sendChan cl) msg) (elems clients)
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    65
	return (clID, serverInfo, clients, rooms)
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    66
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    67
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    68
processAction (clID, serverInfo, clients, rooms) (AnswerAllOthers msg) = do
2403
6c5d504af2ba - Proper /team command implementation
unc0rr
parents: 2352
diff changeset
    69
	mapM_ (\id' -> writeChan (sendChan $ clients ! id') msg) $
2352
7eaf82cf0890 Fixes suggested by hlint tool
unc0rr
parents: 2346
diff changeset
    70
		Prelude.filter (\id' -> (id' /= clID) && logonPassed (clients ! id')) (keys clients)
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    71
	return (clID, serverInfo, clients, rooms)
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    72
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    73
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    74
processAction (clID, serverInfo, clients, rooms) (AnswerThisRoom msg) = do
2403
6c5d504af2ba - Proper /team command implementation
unc0rr
parents: 2352
diff changeset
    75
	mapM_ (\id' -> writeChan (sendChan $ clients ! id') msg) roomClients
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    76
	return (clID, serverInfo, clients, rooms)
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    77
	where
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    78
		roomClients = IntSet.elems $ playersIDs room
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    79
		room = rooms ! rID
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    80
		rID = roomID client
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    81
		client = clients ! clID
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    82
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    83
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    84
processAction (clID, serverInfo, clients, rooms) (AnswerOthersInRoom msg) = do
2403
6c5d504af2ba - Proper /team command implementation
unc0rr
parents: 2352
diff changeset
    85
	mapM_ (\id' -> writeChan (sendChan $ clients ! id') msg) $ Prelude.filter (/= clID) roomClients
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    86
	return (clID, serverInfo, clients, rooms)
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    87
	where
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    88
		roomClients = IntSet.elems $ playersIDs room
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    89
		room = rooms ! rID
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    90
		rID = roomID client
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    91
		client = clients ! clID
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    92
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    93
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    94
processAction (clID, serverInfo, clients, rooms) (AnswerLobby msg) = do
2403
6c5d504af2ba - Proper /team command implementation
unc0rr
parents: 2352
diff changeset
    95
	mapM_ (\id' -> writeChan (sendChan $ clients ! id') msg) roomClients
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    96
	return (clID, serverInfo, clients, rooms)
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    97
	where
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    98
		roomClients = IntSet.elems $ playersIDs room
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    99
		room = rooms ! 0
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   100
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   101
2403
6c5d504af2ba - Proper /team command implementation
unc0rr
parents: 2352
diff changeset
   102
processAction (clID, serverInfo, clients, rooms) (AnswerSameClan msg) = do
2662
12dc696f1c81 Implement "team" chat between spectators
unc0rr
parents: 2551
diff changeset
   103
	mapM_ (\cl -> writeChan (sendChan cl) msg) sameClanOrSpec
2403
6c5d504af2ba - Proper /team command implementation
unc0rr
parents: 2352
diff changeset
   104
	return (clID, serverInfo, clients, rooms)
6c5d504af2ba - Proper /team command implementation
unc0rr
parents: 2352
diff changeset
   105
	where
6c5d504af2ba - Proper /team command implementation
unc0rr
parents: 2352
diff changeset
   106
		otherRoomClients = Prelude.map ((!) clients) $ IntSet.elems $ clID `IntSet.delete` (playersIDs room)
2662
12dc696f1c81 Implement "team" chat between spectators
unc0rr
parents: 2551
diff changeset
   107
		sameClanOrSpec = if teamsInGame client > 0 then sameClanClients else spectators
12dc696f1c81 Implement "team" chat between spectators
unc0rr
parents: 2551
diff changeset
   108
		spectators = Prelude.filter (\cl -> teamsInGame cl == 0) otherRoomClients
2403
6c5d504af2ba - Proper /team command implementation
unc0rr
parents: 2352
diff changeset
   109
		sameClanClients = Prelude.filter (\cl -> teamsInGame cl > 0 && clientClan cl == thisClan) otherRoomClients
6c5d504af2ba - Proper /team command implementation
unc0rr
parents: 2352
diff changeset
   110
		thisClan = clientClan client
6c5d504af2ba - Proper /team command implementation
unc0rr
parents: 2352
diff changeset
   111
		room = rooms ! rID
6c5d504af2ba - Proper /team command implementation
unc0rr
parents: 2352
diff changeset
   112
		rID = roomID client
6c5d504af2ba - Proper /team command implementation
unc0rr
parents: 2352
diff changeset
   113
		client = clients ! clID
6c5d504af2ba - Proper /team command implementation
unc0rr
parents: 2352
diff changeset
   114
6c5d504af2ba - Proper /team command implementation
unc0rr
parents: 2352
diff changeset
   115
1923
956b6b3529bc Send server message on join
unc0rr
parents: 1921
diff changeset
   116
processAction (clID, serverInfo, clients, rooms) SendServerMessage = do
2352
7eaf82cf0890 Fixes suggested by hlint tool
unc0rr
parents: 2346
diff changeset
   117
	writeChan (sendChan $ clients ! clID) ["SERVER_MESSAGE", message serverInfo]
1923
956b6b3529bc Send server message on join
unc0rr
parents: 1921
diff changeset
   118
	return (clID, serverInfo, clients, rooms)
1953
fd9c8e3c734d Add a special message for old hedgewars versions
unc0rr
parents: 1931
diff changeset
   119
	where
fd9c8e3c734d Add a special message for old hedgewars versions
unc0rr
parents: 1931
diff changeset
   120
		client = clients ! clID
2551
01eb81cd3198 Update server
unc0rr
parents: 2408
diff changeset
   121
		message = if clientProto client < 29 then
1953
fd9c8e3c734d Add a special message for old hedgewars versions
unc0rr
parents: 1931
diff changeset
   122
			serverMessageForOldVersions
fd9c8e3c734d Add a special message for old hedgewars versions
unc0rr
parents: 1931
diff changeset
   123
			else
1994
990f341a2332 Fix message being sent to users of 0.9.10
unc0rr
parents: 1977
diff changeset
   124
			serverMessage
1923
956b6b3529bc Send server message on join
unc0rr
parents: 1921
diff changeset
   125
956b6b3529bc Send server message on join
unc0rr
parents: 1921
diff changeset
   126
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   127
processAction (clID, serverInfo, clients, rooms) (ProtocolError msg) = do
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   128
	writeChan (sendChan $ clients ! clID) ["ERROR", msg]
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   129
	return (clID, serverInfo, clients, rooms)
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   130
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   131
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   132
processAction (clID, serverInfo, clients, rooms) (Warning msg) = do
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   133
	writeChan (sendChan $ clients ! clID) ["WARNING", msg]
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   134
	return (clID, serverInfo, clients, rooms)
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   135
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   136
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   137
processAction (clID, serverInfo, clients, rooms) (ByeClient msg) = do
2352
7eaf82cf0890 Fixes suggested by hlint tool
unc0rr
parents: 2346
diff changeset
   138
	infoM "Clients" (show (clientUID client) ++ " quits: " ++ msg)
1929
7e6cc8da1c58 - Fix bug with kicking players
unc0rr
parents: 1928
diff changeset
   139
	(_, _, newClients, newRooms) <-
1930
e71c24f11483 Fix server crash (properly follow client's state)
unc0rr
parents: 1929
diff changeset
   140
			if roomID client /= 0 then
2337
723f1cbe2ef3 Some preparation for room control delegation support
unc0rr
parents: 2245
diff changeset
   141
				processAction  (clID, serverInfo, clients, rooms) $ RoomRemoveThisClient "quit"
1930
e71c24f11483 Fix server crash (properly follow client's state)
unc0rr
parents: 1929
diff changeset
   142
				else
e71c24f11483 Fix server crash (properly follow client's state)
unc0rr
parents: 1929
diff changeset
   143
					return (clID, serverInfo, clients, rooms)
1929
7e6cc8da1c58 - Fix bug with kicking players
unc0rr
parents: 1928
diff changeset
   144
7e6cc8da1c58 - Fix bug with kicking players
unc0rr
parents: 1928
diff changeset
   145
	mapM_ (processAction (clID, serverInfo, newClients, newRooms)) $ answerOthersQuit ++ answerInformRoom
1926
cb46fbdcaa41 Add simple DoS protection mechanism (although better than previous server had)
unc0rr
parents: 1925
diff changeset
   146
	writeChan (sendChan $ clients ! clID) ["BYE", msg]
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   147
	return (
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   148
			0,
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   149
			serverInfo,
1929
7e6cc8da1c58 - Fix bug with kicking players
unc0rr
parents: 1928
diff changeset
   150
			delete clID newClients,
1823
1938ef375350 Fix ready players accounting
unc0rr
parents: 1813
diff changeset
   151
			adjust (\r -> r{
1938ef375350 Fix ready players accounting
unc0rr
parents: 1813
diff changeset
   152
					playersIDs = IntSet.delete clID (playersIDs r),
1938ef375350 Fix ready players accounting
unc0rr
parents: 1813
diff changeset
   153
					playersIn = (playersIn r) - 1,
1938ef375350 Fix ready players accounting
unc0rr
parents: 1813
diff changeset
   154
					readyPlayers = if isReady client then readyPlayers r - 1 else readyPlayers r
1930
e71c24f11483 Fix server crash (properly follow client's state)
unc0rr
parents: 1929
diff changeset
   155
					}) (roomID $ newClients ! clID) newRooms
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   156
			)
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   157
	where
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   158
		client = clients ! clID
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   159
		clientNick = nick client
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   160
		answerInformRoom =
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   161
			if roomID client /= 0 then
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   162
				if not $ Prelude.null msg then
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   163
					[AnswerThisRoom ["LEFT", clientNick, msg]]
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   164
				else
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   165
					[AnswerThisRoom ["LEFT", clientNick]]
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   166
			else
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   167
				[]
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   168
		answerOthersQuit =
1846
24d0074d4eed Small optimization in net server
unc0rr
parents: 1841
diff changeset
   169
			if logonPassed client then
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   170
				if not $ Prelude.null msg then
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   171
					[AnswerAll ["LOBBY:LEFT", clientNick, msg]]
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   172
				else
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   173
					[AnswerAll ["LOBBY:LEFT", clientNick]]
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   174
			else
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   175
				[]
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   176
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   177
2352
7eaf82cf0890 Fixes suggested by hlint tool
unc0rr
parents: 2346
diff changeset
   178
processAction (clID, serverInfo, clients, rooms) (ModifyClient func) =
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   179
	return (clID, serverInfo, adjust func clID clients, rooms)
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   180
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   181
2403
6c5d504af2ba - Proper /team command implementation
unc0rr
parents: 2352
diff changeset
   182
processAction (clID, serverInfo, clients, rooms) (ModifyClient2 cl2ID func) =
6c5d504af2ba - Proper /team command implementation
unc0rr
parents: 2352
diff changeset
   183
	return (clID, serverInfo, adjust func cl2ID clients, rooms)
6c5d504af2ba - Proper /team command implementation
unc0rr
parents: 2352
diff changeset
   184
6c5d504af2ba - Proper /team command implementation
unc0rr
parents: 2352
diff changeset
   185
2352
7eaf82cf0890 Fixes suggested by hlint tool
unc0rr
parents: 2346
diff changeset
   186
processAction (clID, serverInfo, clients, rooms) (ModifyRoom func) =
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   187
	return (clID, serverInfo, clients, adjust func rID rooms)
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   188
	where
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   189
		rID = roomID $ clients ! clID
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   190
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   191
2352
7eaf82cf0890 Fixes suggested by hlint tool
unc0rr
parents: 2346
diff changeset
   192
processAction (clID, serverInfo, clients, rooms) (ModifyServerInfo func) =
1925
ec923e56c444 Allow admin to set server's motd
unc0rr
parents: 1923
diff changeset
   193
	return (clID, func serverInfo, clients, rooms)
ec923e56c444 Allow admin to set server's motd
unc0rr
parents: 1923
diff changeset
   194
ec923e56c444 Allow admin to set server's motd
unc0rr
parents: 1923
diff changeset
   195
2352
7eaf82cf0890 Fixes suggested by hlint tool
unc0rr
parents: 2346
diff changeset
   196
processAction (clID, serverInfo, clients, rooms) (RoomAddThisClient rID) =
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   197
	processAction (
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   198
		clID,
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   199
		serverInfo,
2245
c011aecc95e5 unc0rr's patch from issue #144 - prevent spectators from ruining the game
nemo
parents: 2172
diff changeset
   200
		adjust (\cl -> cl{roomID = rID, teamsInGame = if rID == 0 then teamsInGame cl else 0}) clID clients,
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   201
		adjust (\r -> r{playersIDs = IntSet.insert clID (playersIDs r), playersIn = (playersIn r) + 1}) rID $
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   202
			adjust (\r -> r{playersIDs = IntSet.delete clID (playersIDs r)}) 0 rooms
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   203
		) joinMsg
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   204
	where
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   205
		client = clients ! clID
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   206
		joinMsg = if rID == 0 then
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   207
				AnswerAllOthers ["LOBBY:JOINED", nick client]
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   208
			else
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   209
				AnswerThisRoom ["JOINED", nick client]
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   210
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   211
2126
cb249fa8e3da - Prevent server from producing zombies
unc0rr
parents: 2118
diff changeset
   212
processAction (clID, serverInfo, clients, rooms) (RoomRemoveThisClient msg) = do
1977
2284d7fefe4f Some polishing
unc0rr
parents: 1972
diff changeset
   213
	(_, _, newClients, newRooms) <-
2337
723f1cbe2ef3 Some preparation for room control delegation support
unc0rr
parents: 2245
diff changeset
   214
		if roomID client /= 0 then
723f1cbe2ef3 Some preparation for room control delegation support
unc0rr
parents: 2245
diff changeset
   215
			if isMaster client then
2341
408edb2f254c Implement room delegation (not tested, only one predefined name to rename room)
unc0rr
parents: 2337
diff changeset
   216
				if (gameinprogress room) && (playersIn room > 1) then
2343
3ab763dc14a3 Send leaving message and remove room admin's teams when he exits
unc0rr
parents: 2341
diff changeset
   217
					(changeMaster >>= (\state -> foldM processAction state
3ab763dc14a3 Send leaving message and remove room admin's teams when he exits
unc0rr
parents: 2341
diff changeset
   218
						[AnswerOthersInRoom ["LEFT", nick client, msg],
2346
f07fd1ac2c48 Warn players in room when admin lefts room
unc0rr
parents: 2345
diff changeset
   219
						AnswerOthersInRoom ["WARNING", "Admin left the room"],
2343
3ab763dc14a3 Send leaving message and remove room admin's teams when he exits
unc0rr
parents: 2341
diff changeset
   220
						RemoveClientTeams clID]))
2337
723f1cbe2ef3 Some preparation for room control delegation support
unc0rr
parents: 2245
diff changeset
   221
				else -- not in game
723f1cbe2ef3 Some preparation for room control delegation support
unc0rr
parents: 2245
diff changeset
   222
					processAction (clID, serverInfo, clients, rooms) RemoveRoom
723f1cbe2ef3 Some preparation for room control delegation support
unc0rr
parents: 2245
diff changeset
   223
			else -- not master
1977
2284d7fefe4f Some polishing
unc0rr
parents: 1972
diff changeset
   224
				foldM
2284d7fefe4f Some polishing
unc0rr
parents: 1972
diff changeset
   225
					processAction
2284d7fefe4f Some polishing
unc0rr
parents: 1972
diff changeset
   226
						(clID, serverInfo, clients, rooms)
2126
cb249fa8e3da - Prevent server from producing zombies
unc0rr
parents: 2118
diff changeset
   227
						[AnswerOthersInRoom ["LEFT", nick client, msg],
1977
2284d7fefe4f Some polishing
unc0rr
parents: 1972
diff changeset
   228
						RemoveClientTeams clID]
2337
723f1cbe2ef3 Some preparation for room control delegation support
unc0rr
parents: 2245
diff changeset
   229
		else -- in lobby
723f1cbe2ef3 Some preparation for room control delegation support
unc0rr
parents: 2245
diff changeset
   230
			return (clID, serverInfo, clients, rooms)
1977
2284d7fefe4f Some polishing
unc0rr
parents: 1972
diff changeset
   231
	
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   232
	return (
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   233
		clID,
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   234
		serverInfo,
2337
723f1cbe2ef3 Some preparation for room control delegation support
unc0rr
parents: 2245
diff changeset
   235
		adjust resetClientFlags clID newClients,
723f1cbe2ef3 Some preparation for room control delegation support
unc0rr
parents: 2245
diff changeset
   236
		adjust removeClientFromRoom rID $ adjust insertClientToRoom 0 newRooms
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   237
		)
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   238
	where
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   239
		rID = roomID client
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   240
		client = clients ! clID
2337
723f1cbe2ef3 Some preparation for room control delegation support
unc0rr
parents: 2245
diff changeset
   241
		room = rooms ! rID
723f1cbe2ef3 Some preparation for room control delegation support
unc0rr
parents: 2245
diff changeset
   242
		resetClientFlags cl = cl{roomID = 0, isMaster = False, isReady = False, teamsInGame = undefined}
723f1cbe2ef3 Some preparation for room control delegation support
unc0rr
parents: 2245
diff changeset
   243
		removeClientFromRoom r = r{
2341
408edb2f254c Implement room delegation (not tested, only one predefined name to rename room)
unc0rr
parents: 2337
diff changeset
   244
				playersIDs = otherPlayersSet,
2337
723f1cbe2ef3 Some preparation for room control delegation support
unc0rr
parents: 2245
diff changeset
   245
				playersIn = (playersIn r) - 1,
723f1cbe2ef3 Some preparation for room control delegation support
unc0rr
parents: 2245
diff changeset
   246
				readyPlayers = if isReady client then (readyPlayers r) - 1 else readyPlayers r
723f1cbe2ef3 Some preparation for room control delegation support
unc0rr
parents: 2245
diff changeset
   247
				}
723f1cbe2ef3 Some preparation for room control delegation support
unc0rr
parents: 2245
diff changeset
   248
		insertClientToRoom r = r{playersIDs = IntSet.insert clID (playersIDs r)}
2341
408edb2f254c Implement room delegation (not tested, only one predefined name to rename room)
unc0rr
parents: 2337
diff changeset
   249
		changeMaster = do
408edb2f254c Implement room delegation (not tested, only one predefined name to rename room)
unc0rr
parents: 2337
diff changeset
   250
			processAction (newMasterId, serverInfo, clients, rooms) $ AnswerThisClient ["ROOM_CONTROL_ACCESS", "1"]
408edb2f254c Implement room delegation (not tested, only one predefined name to rename room)
unc0rr
parents: 2337
diff changeset
   251
			return (
408edb2f254c Implement room delegation (not tested, only one predefined name to rename room)
unc0rr
parents: 2337
diff changeset
   252
				clID,
408edb2f254c Implement room delegation (not tested, only one predefined name to rename room)
unc0rr
parents: 2337
diff changeset
   253
				serverInfo,
408edb2f254c Implement room delegation (not tested, only one predefined name to rename room)
unc0rr
parents: 2337
diff changeset
   254
				adjust (\cl -> cl{isMaster = True}) newMasterId clients,
2408
41ebdb5f1e6e Server provides more info in rooms list
unc0rr
parents: 2403
diff changeset
   255
				adjust (\r -> r{masterID = newMasterId, name = newRoomName}) rID rooms
2341
408edb2f254c Implement room delegation (not tested, only one predefined name to rename room)
unc0rr
parents: 2337
diff changeset
   256
				)
2345
daf1785f2337 - Frontend: reorganize code controlling widgets state, fix problems getting room admin status
unc0rr
parents: 2343
diff changeset
   257
		newRoomName = nick newMasterClient
2341
408edb2f254c Implement room delegation (not tested, only one predefined name to rename room)
unc0rr
parents: 2337
diff changeset
   258
		otherPlayersSet = IntSet.delete clID (playersIDs room)
408edb2f254c Implement room delegation (not tested, only one predefined name to rename room)
unc0rr
parents: 2337
diff changeset
   259
		newMasterId = IntSet.findMin otherPlayersSet
2345
daf1785f2337 - Frontend: reorganize code controlling widgets state, fix problems getting room admin status
unc0rr
parents: 2343
diff changeset
   260
		newMasterClient = clients ! newMasterId
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   261
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   262
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   263
processAction (clID, serverInfo, clients, rooms) (AddRoom roomName roomPassword) = do
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   264
	let newServerInfo = serverInfo {nextRoomID = newID}
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   265
	let room = newRoom{
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   266
			roomUID = newID,
2408
41ebdb5f1e6e Server provides more info in rooms list
unc0rr
parents: 2403
diff changeset
   267
			masterID = clID,
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   268
			name = roomName,
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   269
			password = roomPassword,
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   270
			roomProto = (clientProto client)
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   271
			}
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   272
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   273
	processAction (clID, serverInfo, clients, rooms) $ AnswerLobby ["ROOM", "ADD", roomName]
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   274
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   275
	processAction (
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   276
		clID,
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   277
		newServerInfo,
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   278
		adjust (\cl -> cl{isMaster = True}) clID clients,
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   279
		insert newID room rooms
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   280
		) $ RoomAddThisClient newID
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   281
	where
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   282
		newID = (nextRoomID serverInfo) - 1
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   283
		client = clients ! clID
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   284
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   285
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   286
processAction (clID, serverInfo, clients, rooms) (RemoveRoom) = do
1811
1b9e33623b7e Implement 'roundfinished' cmd on net server
unc0rr
parents: 1804
diff changeset
   287
	processAction (clID, serverInfo, clients, rooms) $ AnswerLobby ["ROOM", "DEL", name room]
1b9e33623b7e Implement 'roundfinished' cmd on net server
unc0rr
parents: 1804
diff changeset
   288
	processAction (clID, serverInfo, clients, rooms) $ AnswerOthersInRoom ["ROOMABANDONED", name room]
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   289
	return (clID,
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   290
		serverInfo,
2245
c011aecc95e5 unc0rr's patch from issue #144 - prevent spectators from ruining the game
nemo
parents: 2172
diff changeset
   291
		Data.IntMap.map (\cl -> if roomID cl == rID then cl{roomID = 0, isMaster = False, isReady = False, teamsInGame = undefined} else cl) clients,
1811
1b9e33623b7e Implement 'roundfinished' cmd on net server
unc0rr
parents: 1804
diff changeset
   292
		delete rID $ adjust (\r -> r{playersIDs = IntSet.union (playersIDs room) (playersIDs r)}) 0 rooms
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   293
		)
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   294
	where
1811
1b9e33623b7e Implement 'roundfinished' cmd on net server
unc0rr
parents: 1804
diff changeset
   295
		room = rooms ! rID
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   296
		rID = roomID client
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   297
		client = clients ! clID
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   298
1813
cfe1481e0247 Removeteam action
unc0rr
parents: 1811
diff changeset
   299
1811
1b9e33623b7e Implement 'roundfinished' cmd on net server
unc0rr
parents: 1804
diff changeset
   300
processAction (clID, serverInfo, clients, rooms) (UnreadyRoomClients) = do
1b9e33623b7e Implement 'roundfinished' cmd on net server
unc0rr
parents: 1804
diff changeset
   301
	processAction (clID, serverInfo, clients, rooms) $ AnswerThisRoom ("NOT_READY" : roomPlayers)
1b9e33623b7e Implement 'roundfinished' cmd on net server
unc0rr
parents: 1804
diff changeset
   302
	return (clID,
1b9e33623b7e Implement 'roundfinished' cmd on net server
unc0rr
parents: 1804
diff changeset
   303
		serverInfo,
1b9e33623b7e Implement 'roundfinished' cmd on net server
unc0rr
parents: 1804
diff changeset
   304
		Data.IntMap.map (\cl -> if roomID cl == rID then cl{isReady = False} else cl) clients,
1827
3bb5e22b7f9a Fix ready players number after a round
unc0rr
parents: 1823
diff changeset
   305
		adjust (\r -> r{readyPlayers = 0}) rID rooms)
1811
1b9e33623b7e Implement 'roundfinished' cmd on net server
unc0rr
parents: 1804
diff changeset
   306
	where
1b9e33623b7e Implement 'roundfinished' cmd on net server
unc0rr
parents: 1804
diff changeset
   307
		room = rooms ! rID
1b9e33623b7e Implement 'roundfinished' cmd on net server
unc0rr
parents: 1804
diff changeset
   308
		rID = roomID client
1b9e33623b7e Implement 'roundfinished' cmd on net server
unc0rr
parents: 1804
diff changeset
   309
		client = clients ! clID
1b9e33623b7e Implement 'roundfinished' cmd on net server
unc0rr
parents: 1804
diff changeset
   310
		roomPlayers = Prelude.map (nick . (clients !)) roomPlayersIDs
1b9e33623b7e Implement 'roundfinished' cmd on net server
unc0rr
parents: 1804
diff changeset
   311
		roomPlayersIDs = IntSet.elems $ playersIDs room
1b9e33623b7e Implement 'roundfinished' cmd on net server
unc0rr
parents: 1804
diff changeset
   312
1b9e33623b7e Implement 'roundfinished' cmd on net server
unc0rr
parents: 1804
diff changeset
   313
1813
cfe1481e0247 Removeteam action
unc0rr
parents: 1811
diff changeset
   314
processAction (clID, serverInfo, clients, rooms) (RemoveTeam teamName) = do
cfe1481e0247 Removeteam action
unc0rr
parents: 1811
diff changeset
   315
	newRooms <-	if not $ gameinprogress room then
cfe1481e0247 Removeteam action
unc0rr
parents: 1811
diff changeset
   316
			do
cfe1481e0247 Removeteam action
unc0rr
parents: 1811
diff changeset
   317
			processAction (clID, serverInfo, clients, rooms) $ AnswerOthersInRoom ["REMOVE_TEAM", teamName]
cfe1481e0247 Removeteam action
unc0rr
parents: 1811
diff changeset
   318
			return $
cfe1481e0247 Removeteam action
unc0rr
parents: 1811
diff changeset
   319
				adjust (\r -> r{teams = Prelude.filter (\t -> teamName /= teamname t) $ teams r}) rID rooms
cfe1481e0247 Removeteam action
unc0rr
parents: 1811
diff changeset
   320
		else
cfe1481e0247 Removeteam action
unc0rr
parents: 1811
diff changeset
   321
			do
1866
36aa0ca6e8af Cut the length of most used net packet
unc0rr
parents: 1862
diff changeset
   322
			processAction (clID, serverInfo, clients, rooms) $ AnswerOthersInRoom ["EM", rmTeamMsg]
1813
cfe1481e0247 Removeteam action
unc0rr
parents: 1811
diff changeset
   323
			return $
cfe1481e0247 Removeteam action
unc0rr
parents: 1811
diff changeset
   324
				adjust (\r -> r{
cfe1481e0247 Removeteam action
unc0rr
parents: 1811
diff changeset
   325
				teams = Prelude.filter (\t -> teamName /= teamname t) $ teams r,
cfe1481e0247 Removeteam action
unc0rr
parents: 1811
diff changeset
   326
				leftTeams = teamName : leftTeams r,
cfe1481e0247 Removeteam action
unc0rr
parents: 1811
diff changeset
   327
				roundMsgs = roundMsgs r Seq.|> rmTeamMsg
cfe1481e0247 Removeteam action
unc0rr
parents: 1811
diff changeset
   328
				}) rID rooms
cfe1481e0247 Removeteam action
unc0rr
parents: 1811
diff changeset
   329
	return (clID, serverInfo, clients, newRooms)
cfe1481e0247 Removeteam action
unc0rr
parents: 1811
diff changeset
   330
	where
cfe1481e0247 Removeteam action
unc0rr
parents: 1811
diff changeset
   331
		room = rooms ! rID
cfe1481e0247 Removeteam action
unc0rr
parents: 1811
diff changeset
   332
		rID = roomID client
cfe1481e0247 Removeteam action
unc0rr
parents: 1811
diff changeset
   333
		client = clients ! clID
cfe1481e0247 Removeteam action
unc0rr
parents: 1811
diff changeset
   334
		rmTeamMsg = toEngineMsg $ 'F' : teamName
cfe1481e0247 Removeteam action
unc0rr
parents: 1811
diff changeset
   335
cfe1481e0247 Removeteam action
unc0rr
parents: 1811
diff changeset
   336
1834
71cb978dc85f Add working check for www account existance
unc0rr
parents: 1827
diff changeset
   337
processAction (clID, serverInfo, clients, rooms) (CheckRegistered) = do
2116
dec7ead2d178 Bring back authentication to official server, now using separate process to perform database interaction
unc0rr
parents: 2104
diff changeset
   338
	writeChan (dbQueries serverInfo) $ CheckAccount (clientUID client) (nick client) (host client)
1834
71cb978dc85f Add working check for www account existance
unc0rr
parents: 1827
diff changeset
   339
	return (clID, serverInfo, clients, rooms)
71cb978dc85f Add working check for www account existance
unc0rr
parents: 1827
diff changeset
   340
	where
71cb978dc85f Add working check for www account existance
unc0rr
parents: 1827
diff changeset
   341
		client = clients ! clID
71cb978dc85f Add working check for www account existance
unc0rr
parents: 1827
diff changeset
   342
1841
fba7210b438b Retrieve client password from web database and ask for it
unc0rr
parents: 1839
diff changeset
   343
2155
d897222d3339 Implement ability for server admin to clear accounts cache
unc0rr
parents: 2126
diff changeset
   344
processAction (clID, serverInfo, clients, rooms) (ClearAccountsCache) = do
2352
7eaf82cf0890 Fixes suggested by hlint tool
unc0rr
parents: 2346
diff changeset
   345
	writeChan (dbQueries serverInfo) ClearCache
2155
d897222d3339 Implement ability for server admin to clear accounts cache
unc0rr
parents: 2126
diff changeset
   346
	return (clID, serverInfo, clients, rooms)
d897222d3339 Implement ability for server admin to clear accounts cache
unc0rr
parents: 2126
diff changeset
   347
	where
d897222d3339 Implement ability for server admin to clear accounts cache
unc0rr
parents: 2126
diff changeset
   348
		client = clients ! clID
d897222d3339 Implement ability for server admin to clear accounts cache
unc0rr
parents: 2126
diff changeset
   349
d897222d3339 Implement ability for server admin to clear accounts cache
unc0rr
parents: 2126
diff changeset
   350
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   351
processAction (clID, serverInfo, clients, rooms) (Dump) = do
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   352
	writeChan (sendChan $ clients ! clID) ["DUMP", show serverInfo, showTree clients, showTree rooms]
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   353
	return (clID, serverInfo, clients, rooms)
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   354
1841
fba7210b438b Retrieve client password from web database and ask for it
unc0rr
parents: 1839
diff changeset
   355
2352
7eaf82cf0890 Fixes suggested by hlint tool
unc0rr
parents: 2346
diff changeset
   356
processAction (clID, serverInfo, clients, rooms) (ProcessAccountInfo info) =
1839
5dd4cb7fd7e5 Server now send ASKPASSWORD command to frontend when user has web account
unc0rr
parents: 1834
diff changeset
   357
	case info of
1847
2178c0fc838c Set admin flag and send admin notification to users with rid equal to 3
unc0rr
parents: 1846
diff changeset
   358
		HasAccount passwd isAdmin -> do
1839
5dd4cb7fd7e5 Server now send ASKPASSWORD command to frontend when user has web account
unc0rr
parents: 1834
diff changeset
   359
			infoM "Clients" $ show clID ++ " has account"
5dd4cb7fd7e5 Server now send ASKPASSWORD command to frontend when user has web account
unc0rr
parents: 1834
diff changeset
   360
			writeChan (sendChan $ clients ! clID) ["ASKPASSWORD"]
1847
2178c0fc838c Set admin flag and send admin notification to users with rid equal to 3
unc0rr
parents: 1846
diff changeset
   361
			return (clID, serverInfo, adjust (\cl -> cl{webPassword = passwd, isAdministrator = isAdmin}) clID clients, rooms)
1839
5dd4cb7fd7e5 Server now send ASKPASSWORD command to frontend when user has web account
unc0rr
parents: 1834
diff changeset
   362
		Guest -> do
5dd4cb7fd7e5 Server now send ASKPASSWORD command to frontend when user has web account
unc0rr
parents: 1834
diff changeset
   363
			infoM "Clients" $ show clID ++ " is guest"
1841
fba7210b438b Retrieve client password from web database and ask for it
unc0rr
parents: 1839
diff changeset
   364
			processAction (clID, serverInfo, adjust (\cl -> cl{logonPassed = True}) clID clients, rooms) MoveToLobby
1921
2a09f7f786a0 - User from localhost is server admin
unc0rr
parents: 1879
diff changeset
   365
		Admin -> do
2a09f7f786a0 - User from localhost is server admin
unc0rr
parents: 1879
diff changeset
   366
			infoM "Clients" $ show clID ++ " is admin"
2a09f7f786a0 - User from localhost is server admin
unc0rr
parents: 1879
diff changeset
   367
			foldM processAction (clID, serverInfo, adjust (\cl -> cl{logonPassed = True, isAdministrator = True}) clID clients, rooms) [MoveToLobby, AnswerThisClient ["ADMIN_ACCESS"]]
1841
fba7210b438b Retrieve client password from web database and ask for it
unc0rr
parents: 1839
diff changeset
   368
fba7210b438b Retrieve client password from web database and ask for it
unc0rr
parents: 1839
diff changeset
   369
2352
7eaf82cf0890 Fixes suggested by hlint tool
unc0rr
parents: 2346
diff changeset
   370
processAction (clID, serverInfo, clients, rooms) (MoveToLobby) =
1841
fba7210b438b Retrieve client password from web database and ask for it
unc0rr
parents: 1839
diff changeset
   371
	foldM processAction (clID, serverInfo, clients, rooms) $
fba7210b438b Retrieve client password from web database and ask for it
unc0rr
parents: 1839
diff changeset
   372
		(RoomAddThisClient 0)
fba7210b438b Retrieve client password from web database and ask for it
unc0rr
parents: 1839
diff changeset
   373
		: answerLobbyNicks
2118
0ebcc98ebc1a Send server message after nicks info (more chance for it to be seen)
unc0rr
parents: 2116
diff changeset
   374
		++ [SendServerMessage]
0ebcc98ebc1a Send server message after nicks info (more chance for it to be seen)
unc0rr
parents: 2116
diff changeset
   375
1841
fba7210b438b Retrieve client password from web database and ask for it
unc0rr
parents: 1839
diff changeset
   376
		-- ++ (answerServerMessage client clients)
fba7210b438b Retrieve client password from web database and ask for it
unc0rr
parents: 1839
diff changeset
   377
	where
1846
24d0074d4eed Small optimization in net server
unc0rr
parents: 1841
diff changeset
   378
		lobbyNicks = Prelude.map nick $ Prelude.filter logonPassed $ elems clients
2352
7eaf82cf0890 Fixes suggested by hlint tool
unc0rr
parents: 2346
diff changeset
   379
		answerLobbyNicks = [AnswerThisClient ("LOBBY:JOINED": lobbyNicks) | not $ Prelude.null lobbyNicks]
1841
fba7210b438b Retrieve client password from web database and ask for it
unc0rr
parents: 1839
diff changeset
   380
fba7210b438b Retrieve client password from web database and ask for it
unc0rr
parents: 1839
diff changeset
   381
2352
7eaf82cf0890 Fixes suggested by hlint tool
unc0rr
parents: 2346
diff changeset
   382
processAction (clID, serverInfo, clients, rooms) (KickClient kickID) =
1879
bb114339eb4e Implement kick from room
unc0rr
parents: 1866
diff changeset
   383
	liftM2 replaceID (return clID) (processAction (kickID, serverInfo, clients, rooms) $ ByeClient "Kicked")
bb114339eb4e Implement kick from room
unc0rr
parents: 1866
diff changeset
   384
1926
cb46fbdcaa41 Add simple DoS protection mechanism (although better than previous server had)
unc0rr
parents: 1925
diff changeset
   385
2352
7eaf82cf0890 Fixes suggested by hlint tool
unc0rr
parents: 2346
diff changeset
   386
processAction (clID, serverInfo, clients, rooms) (BanClient banNick) =
1921
2a09f7f786a0 - User from localhost is server admin
unc0rr
parents: 1879
diff changeset
   387
	return (clID, serverInfo, clients, rooms)
2a09f7f786a0 - User from localhost is server admin
unc0rr
parents: 1879
diff changeset
   388
1879
bb114339eb4e Implement kick from room
unc0rr
parents: 1866
diff changeset
   389
bb114339eb4e Implement kick from room
unc0rr
parents: 1866
diff changeset
   390
processAction (clID, serverInfo, clients, rooms) (KickRoomClient kickID) = do
bb114339eb4e Implement kick from room
unc0rr
parents: 1866
diff changeset
   391
	writeChan (sendChan $ clients ! kickID) ["KICKED"]
2126
cb249fa8e3da - Prevent server from producing zombies
unc0rr
parents: 2118
diff changeset
   392
	liftM2 replaceID (return clID) (processAction (kickID, serverInfo, clients, rooms) $ RoomRemoveThisClient "kicked")
1879
bb114339eb4e Implement kick from room
unc0rr
parents: 1866
diff changeset
   393
bb114339eb4e Implement kick from room
unc0rr
parents: 1866
diff changeset
   394
2352
7eaf82cf0890 Fixes suggested by hlint tool
unc0rr
parents: 2346
diff changeset
   395
processAction (clID, serverInfo, clients, rooms) (RemoveClientTeams teamsClID) =
1879
bb114339eb4e Implement kick from room
unc0rr
parents: 1866
diff changeset
   396
	liftM2 replaceID (return clID) $
2352
7eaf82cf0890 Fixes suggested by hlint tool
unc0rr
parents: 2346
diff changeset
   397
		foldM processAction (teamsClID, serverInfo, clients, rooms) removeTeamsActions
1879
bb114339eb4e Implement kick from room
unc0rr
parents: 1866
diff changeset
   398
	where
bb114339eb4e Implement kick from room
unc0rr
parents: 1866
diff changeset
   399
		client = clients ! teamsClID
bb114339eb4e Implement kick from room
unc0rr
parents: 1866
diff changeset
   400
		room = rooms ! (roomID client)
bb114339eb4e Implement kick from room
unc0rr
parents: 1866
diff changeset
   401
		teamsToRemove = Prelude.filter (\t -> teamowner t == nick client) $ teams room
bb114339eb4e Implement kick from room
unc0rr
parents: 1866
diff changeset
   402
		removeTeamsActions = Prelude.map (RemoveTeam . teamname) teamsToRemove
1926
cb46fbdcaa41 Add simple DoS protection mechanism (although better than previous server had)
unc0rr
parents: 1925
diff changeset
   403
cb46fbdcaa41 Add simple DoS protection mechanism (although better than previous server had)
unc0rr
parents: 1925
diff changeset
   404
cb46fbdcaa41 Add simple DoS protection mechanism (although better than previous server had)
unc0rr
parents: 1925
diff changeset
   405
processAction (clID, serverInfo, clients, rooms) (AddClient client) = do
cb46fbdcaa41 Add simple DoS protection mechanism (although better than previous server had)
unc0rr
parents: 1925
diff changeset
   406
	let updatedClients = insert (clientUID client) client clients
2352
7eaf82cf0890 Fixes suggested by hlint tool
unc0rr
parents: 2346
diff changeset
   407
	infoM "Clients" (show (clientUID client) ++ ": New client. Time: " ++ show (connectTime client))
7eaf82cf0890 Fixes suggested by hlint tool
unc0rr
parents: 2346
diff changeset
   408
	writeChan (sendChan client) ["CONNECTED", "Hedgewars server http://www.hedgewars.org/"]
1926
cb46fbdcaa41 Add simple DoS protection mechanism (although better than previous server had)
unc0rr
parents: 1925
diff changeset
   409
1977
2284d7fefe4f Some polishing
unc0rr
parents: 1972
diff changeset
   410
	let newLogins = takeWhile (\(_ , time) -> (connectTime client) `diffUTCTime` time <= 11) $ lastLogins serverInfo
1926
cb46fbdcaa41 Add simple DoS protection mechanism (although better than previous server had)
unc0rr
parents: 1925
diff changeset
   411
1931
ffe420e9e61a Ooops.. enable back DoS protection
unc0rr
parents: 1930
diff changeset
   412
	if isJust $ host client `Prelude.lookup` newLogins then
ffe420e9e61a Ooops.. enable back DoS protection
unc0rr
parents: 1930
diff changeset
   413
		processAction (clID, serverInfo{lastLogins = newLogins}, updatedClients, rooms) $ ByeClient "Reconnected too fast"
ffe420e9e61a Ooops.. enable back DoS protection
unc0rr
parents: 1930
diff changeset
   414
		else
ffe420e9e61a Ooops.. enable back DoS protection
unc0rr
parents: 1930
diff changeset
   415
		return (clID, serverInfo{lastLogins = (host client, connectTime client) : newLogins}, updatedClients, rooms)
1927
e2031906a347 Ping clients every 30 seconds. Disconnection due to ping timeout to be implemented.
unc0rr
parents: 1926
diff changeset
   416
e2031906a347 Ping clients every 30 seconds. Disconnection due to ping timeout to be implemented.
unc0rr
parents: 1926
diff changeset
   417
e2031906a347 Ping clients every 30 seconds. Disconnection due to ping timeout to be implemented.
unc0rr
parents: 1926
diff changeset
   418
processAction (clID, serverInfo, clients, rooms) PingAll = do
1928
9bf8f4f30d6b - Implement ping timeout
unc0rr
parents: 1927
diff changeset
   419
	(_, _, newClients, newRooms) <- foldM kickTimeouted (clID, serverInfo, clients, rooms) $ elems clients
1927
e2031906a347 Ping clients every 30 seconds. Disconnection due to ping timeout to be implemented.
unc0rr
parents: 1926
diff changeset
   420
	processAction (clID,
e2031906a347 Ping clients every 30 seconds. Disconnection due to ping timeout to be implemented.
unc0rr
parents: 1926
diff changeset
   421
		serverInfo,
1928
9bf8f4f30d6b - Implement ping timeout
unc0rr
parents: 1927
diff changeset
   422
		Data.IntMap.map (\cl -> cl{pingsQueue = pingsQueue cl + 1}) newClients,
9bf8f4f30d6b - Implement ping timeout
unc0rr
parents: 1927
diff changeset
   423
		newRooms) $ AnswerAll ["PING"]
9bf8f4f30d6b - Implement ping timeout
unc0rr
parents: 1927
diff changeset
   424
	where
9bf8f4f30d6b - Implement ping timeout
unc0rr
parents: 1927
diff changeset
   425
		kickTimeouted (clID, serverInfo, clients, rooms) client =
9bf8f4f30d6b - Implement ping timeout
unc0rr
parents: 1927
diff changeset
   426
			if pingsQueue client > 0 then
9bf8f4f30d6b - Implement ping timeout
unc0rr
parents: 1927
diff changeset
   427
				processAction (clientUID client, serverInfo, clients, rooms) $ ByeClient "Ping timeout"
9bf8f4f30d6b - Implement ping timeout
unc0rr
parents: 1927
diff changeset
   428
				else
9bf8f4f30d6b - Implement ping timeout
unc0rr
parents: 1927
diff changeset
   429
				return (clID, serverInfo, clients, rooms)
2172
80d34c0b9dfe Implement sending gameserver stats to webserver
unc0rr
parents: 2155
diff changeset
   430
80d34c0b9dfe Implement sending gameserver stats to webserver
unc0rr
parents: 2155
diff changeset
   431
80d34c0b9dfe Implement sending gameserver stats to webserver
unc0rr
parents: 2155
diff changeset
   432
processAction (clID, serverInfo, clients, rooms) (StatsAction) = do
80d34c0b9dfe Implement sending gameserver stats to webserver
unc0rr
parents: 2155
diff changeset
   433
	writeChan (dbQueries serverInfo) $ SendStats (size clients) (size rooms - 1)
80d34c0b9dfe Implement sending gameserver stats to webserver
unc0rr
parents: 2155
diff changeset
   434
	return (clID, serverInfo, clients, rooms)