gameServer/Actions.hs
author szczur
Sun, 12 Sep 2010 17:38:14 -0400
changeset 3850 df6ecca1894f
parent 3741 73246d25dfe1
child 3947 709fdb89f76c
permissions -rw-r--r--
This change allows computers limited to 512 texture size like szczur's card to run Hedgewars, so long as reduce quality is set to eliminate background textures. It makes Ammo menu and Hats multicolumn, 512 high.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
3500
af8390d807d6 Use sockets instead of handles, use bytestrings instead of strings
unc0rr
parents: 3458
diff changeset
     1
{-# LANGUAGE OverloadedStrings #-}
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
     2
module Actions where
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
     3
3425
ead2ed20dfd4 Start the server refactoring
unc0rr
parents: 3283
diff changeset
     4
import Control.Concurrent
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
     5
import Control.Concurrent.Chan
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
     6
import qualified Data.IntSet as IntSet
3566
772a46ef8288 Properly handle client exit
unc0rr
parents: 3531
diff changeset
     7
import qualified Data.Set as Set
1813
cfe1481e0247 Removeteam action
unc0rr
parents: 1811
diff changeset
     8
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
     9
import System.Log.Logger
3671
a94d1dc4a8d9 - burp's patch cleaning up module dependancies + cabal file
unc0rr
parents: 3658
diff changeset
    10
import Control.Monad
1926
cb46fbdcaa41 Add simple DoS protection mechanism (although better than previous server had)
unc0rr
parents: 1925
diff changeset
    11
import Data.Time
3671
a94d1dc4a8d9 - burp's patch cleaning up module dependancies + cabal file
unc0rr
parents: 3658
diff changeset
    12
import Data.Maybe
3435
4e4f88a7bdf2 Some more steps in refactoring
unc0rr
parents: 3425
diff changeset
    13
import Control.Monad.Reader
3741
73246d25dfe1 Add some more strictness, use unsafeThaw and unsafeFreeze functions which work at O(1)
unc0rr
parents: 3673
diff changeset
    14
import Control.Monad.State.Strict
3502
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
    15
import qualified Data.ByteString.Char8 as B
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    16
-----------------------------
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    17
import CoreTypes
1813
cfe1481e0247 Removeteam action
unc0rr
parents: 1811
diff changeset
    18
import Utils
3425
ead2ed20dfd4 Start the server refactoring
unc0rr
parents: 3283
diff changeset
    19
import ClientIO
3458
11cd56019f00 Make some more protocol commands work
unc0rr
parents: 3452
diff changeset
    20
import ServerState
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    21
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    22
data Action =
3566
772a46ef8288 Properly handle client exit
unc0rr
parents: 3531
diff changeset
    23
    AnswerClients ![ClientChan] ![B.ByteString]
2867
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
    24
    | SendServerMessage
3283
18ee933a5864 Some stuff for game server administration task
unc0rr
parents: 2948
diff changeset
    25
    | SendServerVars
3502
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
    26
    | MoveToRoom RoomIndex
3531
66c403badff6 Reimplement room creating
unC0Rr@gmail.com
parents: 3502
diff changeset
    27
    | MoveToLobby B.ByteString
3502
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
    28
    | RemoveTeam B.ByteString
2867
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
    29
    | RemoveRoom
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
    30
    | UnreadyRoomClients
3502
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
    31
    | JoinLobby
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
    32
    | ProtocolError B.ByteString
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
    33
    | Warning B.ByteString
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
    34
    | ByeClient B.ByteString
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
    35
    | KickClient ClientIndex
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
    36
    | KickRoomClient ClientIndex
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
    37
    | BanClient B.ByteString -- nick
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
    38
    | RemoveClientTeams ClientIndex
2867
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
    39
    | ModifyClient (ClientInfo -> ClientInfo)
3458
11cd56019f00 Make some more protocol commands work
unc0rr
parents: 3452
diff changeset
    40
    | ModifyClient2 ClientIndex (ClientInfo -> ClientInfo)
2867
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
    41
    | ModifyRoom (RoomInfo -> RoomInfo)
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
    42
    | ModifyServerInfo (ServerInfo -> ServerInfo)
3502
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
    43
    | AddRoom B.ByteString B.ByteString
2867
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
    44
    | CheckRegistered
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
    45
    | ClearAccountsCache
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
    46
    | ProcessAccountInfo AccountInfo
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
    47
    | Dump
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
    48
    | AddClient ClientInfo
3566
772a46ef8288 Properly handle client exit
unc0rr
parents: 3531
diff changeset
    49
    | DeleteClient ClientIndex
2867
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
    50
    | PingAll
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
    51
    | StatsAction
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    52
3502
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
    53
type CmdHandler = [B.ByteString] -> Reader (ClientIndex, IRnC) [Action]
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    54
3451
62089ccec75c Uses StateT monad instead of manually maintaining the state
unc0rr
parents: 3436
diff changeset
    55
3458
11cd56019f00 Make some more protocol commands work
unc0rr
parents: 3452
diff changeset
    56
processAction :: Action -> StateT ServerState IO ()
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    57
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    58
3673
45778b16b224 Some comments on the reason of the bug, leave bug not fixed yet
unc0rr
parents: 3671
diff changeset
    59
processAction (AnswerClients chans msg) = do
3741
73246d25dfe1 Add some more strictness, use unsafeThaw and unsafeFreeze functions which work at O(1)
unc0rr
parents: 3673
diff changeset
    60
    liftIO $ map (flip seq ()) chans `seq` map (flip seq ()) msg `seq` mapM_ (flip writeChan msg) chans
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    61
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    62
3501
a3159a410e5c Reimplement more core actions
unc0rr
parents: 3500
diff changeset
    63
processAction SendServerMessage = do
a3159a410e5c Reimplement more core actions
unc0rr
parents: 3500
diff changeset
    64
    chan <- client's sendChan
a3159a410e5c Reimplement more core actions
unc0rr
parents: 3500
diff changeset
    65
    protonum <- client's clientProto
a3159a410e5c Reimplement more core actions
unc0rr
parents: 3500
diff changeset
    66
    si <- liftM serverInfo get
a3159a410e5c Reimplement more core actions
unc0rr
parents: 3500
diff changeset
    67
    let message = if protonum < latestReleaseVersion si then
3283
18ee933a5864 Some stuff for game server administration task
unc0rr
parents: 2948
diff changeset
    68
            serverMessageForOldVersions si
2867
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
    69
            else
3283
18ee933a5864 Some stuff for game server administration task
unc0rr
parents: 2948
diff changeset
    70
            serverMessage si
3673
45778b16b224 Some comments on the reason of the bug, leave bug not fixed yet
unc0rr
parents: 3671
diff changeset
    71
    processAction $ AnswerClients [chan] ["SERVER_MESSAGE", message]
3501
a3159a410e5c Reimplement more core actions
unc0rr
parents: 3500
diff changeset
    72
{-
3283
18ee933a5864 Some stuff for game server administration task
unc0rr
parents: 2948
diff changeset
    73
3425
ead2ed20dfd4 Start the server refactoring
unc0rr
parents: 3283
diff changeset
    74
processAction (clID, serverInfo, rnc) SendServerVars = do
3283
18ee933a5864 Some stuff for game server administration task
unc0rr
parents: 2948
diff changeset
    75
    writeChan (sendChan $ clients ! clID) ("SERVER_VARS" : vars)
3425
ead2ed20dfd4 Start the server refactoring
unc0rr
parents: 3283
diff changeset
    76
    return (clID, serverInfo, rnc)
3283
18ee933a5864 Some stuff for game server administration task
unc0rr
parents: 2948
diff changeset
    77
    where
18ee933a5864 Some stuff for game server administration task
unc0rr
parents: 2948
diff changeset
    78
        client = clients ! clID
18ee933a5864 Some stuff for game server administration task
unc0rr
parents: 2948
diff changeset
    79
        vars = [
3425
ead2ed20dfd4 Start the server refactoring
unc0rr
parents: 3283
diff changeset
    80
            "MOTD_NEW", serverMessage serverInfo,
ead2ed20dfd4 Start the server refactoring
unc0rr
parents: 3283
diff changeset
    81
            "MOTD_OLD", serverMessageForOldVersions serverInfo,
3283
18ee933a5864 Some stuff for game server administration task
unc0rr
parents: 2948
diff changeset
    82
            "LATEST_PROTO", show $ latestReleaseVersion serverInfo
18ee933a5864 Some stuff for game server administration task
unc0rr
parents: 2948
diff changeset
    83
            ]
1923
956b6b3529bc Send server message on join
unc0rr
parents: 1921
diff changeset
    84
956b6b3529bc Send server message on join
unc0rr
parents: 1921
diff changeset
    85
3501
a3159a410e5c Reimplement more core actions
unc0rr
parents: 3500
diff changeset
    86
-}
a3159a410e5c Reimplement more core actions
unc0rr
parents: 3500
diff changeset
    87
a3159a410e5c Reimplement more core actions
unc0rr
parents: 3500
diff changeset
    88
processAction (ProtocolError msg) = do
a3159a410e5c Reimplement more core actions
unc0rr
parents: 3500
diff changeset
    89
    chan <- client's sendChan
3673
45778b16b224 Some comments on the reason of the bug, leave bug not fixed yet
unc0rr
parents: 3671
diff changeset
    90
    processAction $ AnswerClients [chan] ["ERROR", msg]
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    91
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    92
3501
a3159a410e5c Reimplement more core actions
unc0rr
parents: 3500
diff changeset
    93
processAction (Warning msg) = do
a3159a410e5c Reimplement more core actions
unc0rr
parents: 3500
diff changeset
    94
    chan <- client's sendChan
3673
45778b16b224 Some comments on the reason of the bug, leave bug not fixed yet
unc0rr
parents: 3671
diff changeset
    95
    processAction $ AnswerClients [chan] ["WARNING", msg]
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
    96
3451
62089ccec75c Uses StateT monad instead of manually maintaining the state
unc0rr
parents: 3436
diff changeset
    97
processAction (ByeClient msg) = do
62089ccec75c Uses StateT monad instead of manually maintaining the state
unc0rr
parents: 3436
diff changeset
    98
    (Just ci) <- gets clientIndex
62089ccec75c Uses StateT monad instead of manually maintaining the state
unc0rr
parents: 3436
diff changeset
    99
    rnc <- gets roomsClients
62089ccec75c Uses StateT monad instead of manually maintaining the state
unc0rr
parents: 3436
diff changeset
   100
    ri <- clientRoomA
3436
288fcbdb77b6 Make server build again (it's still useless though)
unc0rr
parents: 3435
diff changeset
   101
    when (ri /= lobbyId) $ do
3531
66c403badff6 Reimplement room creating
unC0Rr@gmail.com
parents: 3502
diff changeset
   102
        processAction $ MoveToLobby ("quit: " `B.append` msg)
3436
288fcbdb77b6 Make server build again (it's still useless though)
unc0rr
parents: 3435
diff changeset
   103
        return ()
1929
7e6cc8da1c58 - Fix bug with kicking players
unc0rr
parents: 1928
diff changeset
   104
3501
a3159a410e5c Reimplement more core actions
unc0rr
parents: 3500
diff changeset
   105
    chan <- client's sendChan
3566
772a46ef8288 Properly handle client exit
unc0rr
parents: 3531
diff changeset
   106
    ready <- client's isReady
3458
11cd56019f00 Make some more protocol commands work
unc0rr
parents: 3452
diff changeset
   107
3451
62089ccec75c Uses StateT monad instead of manually maintaining the state
unc0rr
parents: 3436
diff changeset
   108
    liftIO $ do
3500
af8390d807d6 Use sockets instead of handles, use bytestrings instead of strings
unc0rr
parents: 3458
diff changeset
   109
        infoM "Clients" (show ci ++ " quits: " ++ (B.unpack msg))
3451
62089ccec75c Uses StateT monad instead of manually maintaining the state
unc0rr
parents: 3436
diff changeset
   110
62089ccec75c Uses StateT monad instead of manually maintaining the state
unc0rr
parents: 3436
diff changeset
   111
        --mapM_ (processAction (ci, serverInfo, rnc)) $ answerOthersQuit ++ answerInformRoom
62089ccec75c Uses StateT monad instead of manually maintaining the state
unc0rr
parents: 3436
diff changeset
   112
        modifyRoom rnc (\r -> r{
62089ccec75c Uses StateT monad instead of manually maintaining the state
unc0rr
parents: 3436
diff changeset
   113
                        --playersIDs = IntSet.delete ci (playersIDs r)
3566
772a46ef8288 Properly handle client exit
unc0rr
parents: 3531
diff changeset
   114
                        playersIn = (playersIn r) - 1,
772a46ef8288 Properly handle client exit
unc0rr
parents: 3531
diff changeset
   115
                        readyPlayers = if ready then readyPlayers r - 1 else readyPlayers r
3451
62089ccec75c Uses StateT monad instead of manually maintaining the state
unc0rr
parents: 3436
diff changeset
   116
                        }) ri
3566
772a46ef8288 Properly handle client exit
unc0rr
parents: 3531
diff changeset
   117
3673
45778b16b224 Some comments on the reason of the bug, leave bug not fixed yet
unc0rr
parents: 3671
diff changeset
   118
    processAction $ AnswerClients [chan] ["BYE", msg]
3566
772a46ef8288 Properly handle client exit
unc0rr
parents: 3531
diff changeset
   119
    modify (\s -> s{removedClients = ci `Set.insert` removedClients s})
772a46ef8288 Properly handle client exit
unc0rr
parents: 3531
diff changeset
   120
772a46ef8288 Properly handle client exit
unc0rr
parents: 3531
diff changeset
   121
processAction (DeleteClient ci) = do
3671
a94d1dc4a8d9 - burp's patch cleaning up module dependancies + cabal file
unc0rr
parents: 3658
diff changeset
   122
    rnc <- gets roomsClients
a94d1dc4a8d9 - burp's patch cleaning up module dependancies + cabal file
unc0rr
parents: 3658
diff changeset
   123
    liftIO $ removeClient rnc ci
3566
772a46ef8288 Properly handle client exit
unc0rr
parents: 3531
diff changeset
   124
    modify (\s -> s{removedClients = ci `Set.delete` removedClients s})
772a46ef8288 Properly handle client exit
unc0rr
parents: 3531
diff changeset
   125
3436
288fcbdb77b6 Make server build again (it's still useless though)
unc0rr
parents: 3435
diff changeset
   126
{-
2867
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   127
    where
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   128
        client = clients ! clID
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   129
        clientNick = nick client
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   130
        answerInformRoom =
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   131
            if roomID client /= 0 then
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   132
                if not $ Prelude.null msg then
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   133
                    [AnswerThisRoom ["LEFT", clientNick, msg]]
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   134
                else
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   135
                    [AnswerThisRoom ["LEFT", clientNick]]
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   136
            else
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   137
                []
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   138
        answerOthersQuit =
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   139
            if logonPassed client then
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   140
                if not $ Prelude.null msg then
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   141
                    [AnswerAll ["LOBBY:LEFT", clientNick, msg]]
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   142
                else
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   143
                    [AnswerAll ["LOBBY:LEFT", clientNick]]
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   144
            else
3436
288fcbdb77b6 Make server build again (it's still useless though)
unc0rr
parents: 3435
diff changeset
   145
            [] 
288fcbdb77b6 Make server build again (it's still useless though)
unc0rr
parents: 3435
diff changeset
   146
-}
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   147
3458
11cd56019f00 Make some more protocol commands work
unc0rr
parents: 3452
diff changeset
   148
processAction (ModifyClient f) = do
11cd56019f00 Make some more protocol commands work
unc0rr
parents: 3452
diff changeset
   149
    (Just ci) <- gets clientIndex
11cd56019f00 Make some more protocol commands work
unc0rr
parents: 3452
diff changeset
   150
    rnc <- gets roomsClients
11cd56019f00 Make some more protocol commands work
unc0rr
parents: 3452
diff changeset
   151
    liftIO $ modifyClient rnc f ci
11cd56019f00 Make some more protocol commands work
unc0rr
parents: 3452
diff changeset
   152
    return ()
3568
ae89cf0735dc A bunch of reimplemented commands
unc0rr
parents: 3566
diff changeset
   153
ae89cf0735dc A bunch of reimplemented commands
unc0rr
parents: 3566
diff changeset
   154
processAction (ModifyClient2 ci f) = do
ae89cf0735dc A bunch of reimplemented commands
unc0rr
parents: 3566
diff changeset
   155
    rnc <- gets roomsClients
ae89cf0735dc A bunch of reimplemented commands
unc0rr
parents: 3566
diff changeset
   156
    liftIO $ modifyClient rnc f ci
ae89cf0735dc A bunch of reimplemented commands
unc0rr
parents: 3566
diff changeset
   157
    return ()
ae89cf0735dc A bunch of reimplemented commands
unc0rr
parents: 3566
diff changeset
   158
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   159
3458
11cd56019f00 Make some more protocol commands work
unc0rr
parents: 3452
diff changeset
   160
processAction (ModifyRoom f) = do
11cd56019f00 Make some more protocol commands work
unc0rr
parents: 3452
diff changeset
   161
    rnc <- gets roomsClients
11cd56019f00 Make some more protocol commands work
unc0rr
parents: 3452
diff changeset
   162
    ri <- clientRoomA
11cd56019f00 Make some more protocol commands work
unc0rr
parents: 3452
diff changeset
   163
    liftIO $ modifyRoom rnc f ri
11cd56019f00 Make some more protocol commands work
unc0rr
parents: 3452
diff changeset
   164
    return ()
2403
6c5d504af2ba - Proper /team command implementation
unc0rr
parents: 2352
diff changeset
   165
3458
11cd56019f00 Make some more protocol commands work
unc0rr
parents: 3452
diff changeset
   166
{-
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   167
3425
ead2ed20dfd4 Start the server refactoring
unc0rr
parents: 3283
diff changeset
   168
processAction (clID, serverInfo, rnc) (ModifyServerInfo func) =
ead2ed20dfd4 Start the server refactoring
unc0rr
parents: 3283
diff changeset
   169
    return (clID, func serverInfo, rnc)
1925
ec923e56c444 Allow admin to set server's motd
unc0rr
parents: 1923
diff changeset
   170
3502
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
   171
-}
1925
ec923e56c444 Allow admin to set server's motd
unc0rr
parents: 1923
diff changeset
   172
3531
66c403badff6 Reimplement room creating
unC0Rr@gmail.com
parents: 3502
diff changeset
   173
processAction (MoveToRoom ri) = do
3502
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
   174
    (Just ci) <- gets clientIndex
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
   175
    rnc <- gets roomsClients
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
   176
    liftIO $ do
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
   177
        modifyClient rnc (\cl -> cl{teamsInGame = 0}) ci
3531
66c403badff6 Reimplement room creating
unC0Rr@gmail.com
parents: 3502
diff changeset
   178
        modifyRoom rnc (\r -> r{playersIn = (playersIn r) + 1}) ri
66c403badff6 Reimplement room creating
unC0Rr@gmail.com
parents: 3502
diff changeset
   179
66c403badff6 Reimplement room creating
unC0Rr@gmail.com
parents: 3502
diff changeset
   180
    liftIO $ moveClientToRoom rnc ri ci
66c403badff6 Reimplement room creating
unC0Rr@gmail.com
parents: 3502
diff changeset
   181
66c403badff6 Reimplement room creating
unC0Rr@gmail.com
parents: 3502
diff changeset
   182
    chans <- liftM (map sendChan) $ roomClientsS ri
3502
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
   183
    clNick <- client's nick
3645
c0b3f1bb9316 Reimplement REMOVE_TEAM
unc0rr
parents: 3568
diff changeset
   184
3502
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
   185
    processAction $ AnswerClients chans ["JOINED", clNick]
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   186
3531
66c403badff6 Reimplement room creating
unC0Rr@gmail.com
parents: 3502
diff changeset
   187
processAction (MoveToLobby msg) = do
66c403badff6 Reimplement room creating
unC0Rr@gmail.com
parents: 3502
diff changeset
   188
    (Just ci) <- gets clientIndex
66c403badff6 Reimplement room creating
unC0Rr@gmail.com
parents: 3502
diff changeset
   189
    --ri <- clientRoomA
66c403badff6 Reimplement room creating
unC0Rr@gmail.com
parents: 3502
diff changeset
   190
    rnc <- gets roomsClients
66c403badff6 Reimplement room creating
unC0Rr@gmail.com
parents: 3502
diff changeset
   191
66c403badff6 Reimplement room creating
unC0Rr@gmail.com
parents: 3502
diff changeset
   192
    liftIO $ moveClientToLobby rnc ci
66c403badff6 Reimplement room creating
unC0Rr@gmail.com
parents: 3502
diff changeset
   193
3502
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
   194
{-
2867
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   195
    (_, _, newClients, newRooms) <-
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   196
            if isMaster client then
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   197
                if (gameinprogress room) && (playersIn room > 1) then
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   198
                    (changeMaster >>= (\state -> foldM processAction state
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   199
                        [AnswerOthersInRoom ["LEFT", nick client, msg],
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   200
                        AnswerOthersInRoom ["WARNING", "Admin left the room"],
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   201
                        RemoveClientTeams clID]))
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   202
                else -- not in game
3425
ead2ed20dfd4 Start the server refactoring
unc0rr
parents: 3283
diff changeset
   203
                    processAction (clID, serverInfo, rnc) RemoveRoom
2867
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   204
            else -- not master
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   205
                foldM
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   206
                    processAction
3425
ead2ed20dfd4 Start the server refactoring
unc0rr
parents: 3283
diff changeset
   207
                        (clID, serverInfo, rnc)
2867
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   208
                        [AnswerOthersInRoom ["LEFT", nick client, msg],
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   209
                        RemoveClientTeams clID]
3531
66c403badff6 Reimplement room creating
unC0Rr@gmail.com
parents: 3502
diff changeset
   210
3425
ead2ed20dfd4 Start the server refactoring
unc0rr
parents: 3283
diff changeset
   211
2867
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   212
    return (
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   213
        clID,
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   214
        serverInfo,
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   215
        adjust resetClientFlags clID newClients,
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   216
        adjust removeClientFromRoom rID $ adjust insertClientToRoom 0 newRooms
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   217
        )
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   218
    where
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   219
        rID = roomID client
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   220
        client = clients ! clID
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   221
        room = rooms ! rID
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   222
        resetClientFlags cl = cl{roomID = 0, isMaster = False, isReady = False, teamsInGame = undefined}
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   223
        removeClientFromRoom r = r{
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   224
                playersIDs = otherPlayersSet,
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   225
                playersIn = (playersIn r) - 1,
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   226
                readyPlayers = if isReady client then (readyPlayers r) - 1 else readyPlayers r
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   227
                }
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   228
        insertClientToRoom r = r{playersIDs = IntSet.insert clID (playersIDs r)}
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   229
        changeMaster = do
3425
ead2ed20dfd4 Start the server refactoring
unc0rr
parents: 3283
diff changeset
   230
            processAction (newMasterId, serverInfo, rnc) $ AnswerThisClient ["ROOM_CONTROL_ACCESS", "1"]
2867
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   231
            return (
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   232
                clID,
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   233
                serverInfo,
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   234
                adjust (\cl -> cl{isMaster = True}) newMasterId clients,
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   235
                adjust (\r -> r{masterID = newMasterId, name = newRoomName}) rID rooms
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   236
                )
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   237
        newRoomName = nick newMasterClient
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   238
        otherPlayersSet = IntSet.delete clID (playersIDs room)
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   239
        newMasterId = IntSet.findMin otherPlayersSet
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   240
        newMasterClient = clients ! newMasterId
3502
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
   241
-}
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   242
3502
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
   243
processAction (AddRoom roomName roomPassword) = do
3566
772a46ef8288 Properly handle client exit
unc0rr
parents: 3531
diff changeset
   244
    Just clId <- gets clientIndex
772a46ef8288 Properly handle client exit
unc0rr
parents: 3531
diff changeset
   245
    rnc <- gets roomsClients
3502
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
   246
    proto <- liftIO $ client'sM rnc clientProto clId
3645
c0b3f1bb9316 Reimplement REMOVE_TEAM
unc0rr
parents: 3568
diff changeset
   247
2867
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   248
    let room = newRoom{
3502
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
   249
            masterID = clId,
2867
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   250
            name = roomName,
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   251
            password = roomPassword,
3502
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
   252
            roomProto = proto
2867
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   253
            }
3645
c0b3f1bb9316 Reimplement REMOVE_TEAM
unc0rr
parents: 3568
diff changeset
   254
c0b3f1bb9316 Reimplement REMOVE_TEAM
unc0rr
parents: 3568
diff changeset
   255
    rId <- liftIO $ addRoom rnc room
c0b3f1bb9316 Reimplement REMOVE_TEAM
unc0rr
parents: 3568
diff changeset
   256
c0b3f1bb9316 Reimplement REMOVE_TEAM
unc0rr
parents: 3568
diff changeset
   257
    processAction $ MoveToRoom rId
c0b3f1bb9316 Reimplement REMOVE_TEAM
unc0rr
parents: 3568
diff changeset
   258
3502
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
   259
    chans <- liftM (map sendChan) $ roomClientsS lobbyId
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   260
3502
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
   261
    mapM_ processAction [
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
   262
        AnswerClients chans ["ROOM", "ADD", roomName]
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
   263
        , ModifyClient (\cl -> cl{isMaster = True})
3645
c0b3f1bb9316 Reimplement REMOVE_TEAM
unc0rr
parents: 3568
diff changeset
   264
        ]
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   265
3502
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
   266
{-
3425
ead2ed20dfd4 Start the server refactoring
unc0rr
parents: 3283
diff changeset
   267
processAction (clID, serverInfo, rnc) (RemoveRoom) = do
ead2ed20dfd4 Start the server refactoring
unc0rr
parents: 3283
diff changeset
   268
    processAction (clID, serverInfo, rnc) $ AnswerLobby ["ROOM", "DEL", name room]
ead2ed20dfd4 Start the server refactoring
unc0rr
parents: 3283
diff changeset
   269
    processAction (clID, serverInfo, rnc) $ AnswerOthersInRoom ["ROOMABANDONED", name room]
2867
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   270
    return (clID,
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   271
        serverInfo,
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   272
        Data.IntMap.map (\cl -> if roomID cl == rID then cl{roomID = 0, isMaster = False, isReady = False, teamsInGame = undefined} else cl) clients,
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   273
        delete rID $ adjust (\r -> r{playersIDs = IntSet.union (playersIDs room) (playersIDs r)}) 0 rooms
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   274
        )
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   275
    where
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   276
        room = rooms ! rID
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   277
        rID = roomID client
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   278
        client = clients ! clID
1804
4e78ad846fb6 New game server:
unc0rr
parents:
diff changeset
   279
3656
c74a4a407146 Make ROUNDFINISHED work correctly
unc0rr
parents: 3654
diff changeset
   280
-}
c74a4a407146 Make ROUNDFINISHED work correctly
unc0rr
parents: 3654
diff changeset
   281
processAction (UnreadyRoomClients) = do
c74a4a407146 Make ROUNDFINISHED work correctly
unc0rr
parents: 3654
diff changeset
   282
    rnc <- gets roomsClients
c74a4a407146 Make ROUNDFINISHED work correctly
unc0rr
parents: 3654
diff changeset
   283
    ri <- clientRoomA
c74a4a407146 Make ROUNDFINISHED work correctly
unc0rr
parents: 3654
diff changeset
   284
    roomPlayers <- roomClientsS ri
c74a4a407146 Make ROUNDFINISHED work correctly
unc0rr
parents: 3654
diff changeset
   285
    roomClIDs <- liftIO $ roomClientsIndicesM rnc ri
c74a4a407146 Make ROUNDFINISHED work correctly
unc0rr
parents: 3654
diff changeset
   286
    processAction $ AnswerClients (map sendChan roomPlayers) ("NOT_READY" : map nick roomPlayers)
c74a4a407146 Make ROUNDFINISHED work correctly
unc0rr
parents: 3654
diff changeset
   287
    liftIO $ mapM_ (modifyClient rnc (\cl -> cl{isReady = False})) roomClIDs
c74a4a407146 Make ROUNDFINISHED work correctly
unc0rr
parents: 3654
diff changeset
   288
    processAction $ ModifyRoom (\r -> r{readyPlayers = 0})
1813
cfe1481e0247 Removeteam action
unc0rr
parents: 1811
diff changeset
   289
1811
1b9e33623b7e Implement 'roundfinished' cmd on net server
unc0rr
parents: 1804
diff changeset
   290
3645
c0b3f1bb9316 Reimplement REMOVE_TEAM
unc0rr
parents: 3568
diff changeset
   291
processAction (RemoveTeam teamName) = do
c0b3f1bb9316 Reimplement REMOVE_TEAM
unc0rr
parents: 3568
diff changeset
   292
    rnc <- gets roomsClients
c0b3f1bb9316 Reimplement REMOVE_TEAM
unc0rr
parents: 3568
diff changeset
   293
    cl <- client's id
c0b3f1bb9316 Reimplement REMOVE_TEAM
unc0rr
parents: 3568
diff changeset
   294
    ri <- clientRoomA
c0b3f1bb9316 Reimplement REMOVE_TEAM
unc0rr
parents: 3568
diff changeset
   295
    inGame <- liftIO $ room'sM rnc gameinprogress ri
c0b3f1bb9316 Reimplement REMOVE_TEAM
unc0rr
parents: 3568
diff changeset
   296
    chans <- liftM (map sendChan . filter (/= cl)) $ roomClientsS ri
c0b3f1bb9316 Reimplement REMOVE_TEAM
unc0rr
parents: 3568
diff changeset
   297
    if inGame then
c0b3f1bb9316 Reimplement REMOVE_TEAM
unc0rr
parents: 3568
diff changeset
   298
            mapM_ processAction [
c0b3f1bb9316 Reimplement REMOVE_TEAM
unc0rr
parents: 3568
diff changeset
   299
                AnswerClients chans ["REMOVE_TEAM", teamName],
c0b3f1bb9316 Reimplement REMOVE_TEAM
unc0rr
parents: 3568
diff changeset
   300
                ModifyRoom (\r -> r{teams = Prelude.filter (\t -> teamName /= teamname t) $ teams r})
c0b3f1bb9316 Reimplement REMOVE_TEAM
unc0rr
parents: 3568
diff changeset
   301
                ]
2867
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   302
        else
3645
c0b3f1bb9316 Reimplement REMOVE_TEAM
unc0rr
parents: 3568
diff changeset
   303
            mapM_ processAction [
c0b3f1bb9316 Reimplement REMOVE_TEAM
unc0rr
parents: 3568
diff changeset
   304
                AnswerClients chans ["EM", rmTeamMsg],
c0b3f1bb9316 Reimplement REMOVE_TEAM
unc0rr
parents: 3568
diff changeset
   305
                ModifyRoom (\r -> r{
c0b3f1bb9316 Reimplement REMOVE_TEAM
unc0rr
parents: 3568
diff changeset
   306
                    teams = Prelude.filter (\t -> teamName /= teamname t) $ teams r,
c0b3f1bb9316 Reimplement REMOVE_TEAM
unc0rr
parents: 3568
diff changeset
   307
                    leftTeams = teamName : leftTeams r,
c0b3f1bb9316 Reimplement REMOVE_TEAM
unc0rr
parents: 3568
diff changeset
   308
                    roundMsgs = roundMsgs r Seq.|> rmTeamMsg
c0b3f1bb9316 Reimplement REMOVE_TEAM
unc0rr
parents: 3568
diff changeset
   309
                    })
c0b3f1bb9316 Reimplement REMOVE_TEAM
unc0rr
parents: 3568
diff changeset
   310
                ]
2867
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   311
    where
3645
c0b3f1bb9316 Reimplement REMOVE_TEAM
unc0rr
parents: 3568
diff changeset
   312
        rmTeamMsg = toEngineMsg $ (B.singleton 'F') `B.append` teamName
1813
cfe1481e0247 Removeteam action
unc0rr
parents: 1811
diff changeset
   313
3458
11cd56019f00 Make some more protocol commands work
unc0rr
parents: 3452
diff changeset
   314
processAction CheckRegistered = do
11cd56019f00 Make some more protocol commands work
unc0rr
parents: 3452
diff changeset
   315
    (Just ci) <- gets clientIndex
3501
a3159a410e5c Reimplement more core actions
unc0rr
parents: 3500
diff changeset
   316
    n <- client's nick
a3159a410e5c Reimplement more core actions
unc0rr
parents: 3500
diff changeset
   317
    h <- client's host
3458
11cd56019f00 Make some more protocol commands work
unc0rr
parents: 3452
diff changeset
   318
    db <- gets (dbQueries . serverInfo)
11cd56019f00 Make some more protocol commands work
unc0rr
parents: 3452
diff changeset
   319
    liftIO $ writeChan db $ CheckAccount ci n h
11cd56019f00 Make some more protocol commands work
unc0rr
parents: 3452
diff changeset
   320
    return ()
1834
71cb978dc85f Add working check for www account existance
unc0rr
parents: 1827
diff changeset
   321
3458
11cd56019f00 Make some more protocol commands work
unc0rr
parents: 3452
diff changeset
   322
{-
3425
ead2ed20dfd4 Start the server refactoring
unc0rr
parents: 3283
diff changeset
   323
processAction (clID, serverInfo, rnc) (ClearAccountsCache) = do
2867
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   324
    writeChan (dbQueries serverInfo) ClearCache
3425
ead2ed20dfd4 Start the server refactoring
unc0rr
parents: 3283
diff changeset
   325
    return (clID, serverInfo, rnc)
2867
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   326
    where
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   327
        client = clients ! clID
2155
d897222d3339 Implement ability for server admin to clear accounts cache
unc0rr
parents: 2126
diff changeset
   328
d897222d3339 Implement ability for server admin to clear accounts cache
unc0rr
parents: 2126
diff changeset
   329
3425
ead2ed20dfd4 Start the server refactoring
unc0rr
parents: 3283
diff changeset
   330
processAction (clID, serverInfo, rnc) (Dump) = do
2867
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   331
    writeChan (sendChan $ clients ! clID) ["DUMP", show serverInfo, showTree clients, showTree rooms]
3425
ead2ed20dfd4 Start the server refactoring
unc0rr
parents: 3283
diff changeset
   332
    return (clID, serverInfo, rnc)
3501
a3159a410e5c Reimplement more core actions
unc0rr
parents: 3500
diff changeset
   333
-}
1841
fba7210b438b Retrieve client password from web database and ask for it
unc0rr
parents: 1839
diff changeset
   334
3501
a3159a410e5c Reimplement more core actions
unc0rr
parents: 3500
diff changeset
   335
processAction (ProcessAccountInfo info) =
2867
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   336
    case info of
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   337
        HasAccount passwd isAdmin -> do
3501
a3159a410e5c Reimplement more core actions
unc0rr
parents: 3500
diff changeset
   338
            chan <- client's sendChan
3673
45778b16b224 Some comments on the reason of the bug, leave bug not fixed yet
unc0rr
parents: 3671
diff changeset
   339
            processAction $ AnswerClients [chan] ["ASKPASSWORD"]
2867
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   340
        Guest -> do
3502
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
   341
            processAction JoinLobby
2867
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   342
        Admin -> do
3502
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
   343
            mapM processAction [ModifyClient (\cl -> cl{isAdministrator = True}), JoinLobby]
3501
a3159a410e5c Reimplement more core actions
unc0rr
parents: 3500
diff changeset
   344
            chan <- client's sendChan
3673
45778b16b224 Some comments on the reason of the bug, leave bug not fixed yet
unc0rr
parents: 3671
diff changeset
   345
            processAction $ AnswerClients [chan] ["ADMIN_ACCESS"]
1841
fba7210b438b Retrieve client password from web database and ask for it
unc0rr
parents: 1839
diff changeset
   346
3502
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
   347
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
   348
processAction JoinLobby = do
3501
a3159a410e5c Reimplement more core actions
unc0rr
parents: 3500
diff changeset
   349
    chan <- client's sendChan
3502
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
   350
    clientNick <- client's nick
3566
772a46ef8288 Properly handle client exit
unc0rr
parents: 3531
diff changeset
   351
    (lobbyNicks, clientsChans) <- liftM (unzip . Prelude.map (\c -> (nick c, sendChan c)) . Prelude.filter logonPassed) $! allClientsS
3501
a3159a410e5c Reimplement more core actions
unc0rr
parents: 3500
diff changeset
   352
    mapM_ processAction $
3502
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
   353
        (AnswerClients clientsChans ["LOBBY:JOINED", clientNick])
3566
772a46ef8288 Properly handle client exit
unc0rr
parents: 3531
diff changeset
   354
        : [AnswerClients [chan] ("LOBBY:JOINED" : clientNick : lobbyNicks)]
3502
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
   355
        ++ [ModifyClient (\cl -> cl{logonPassed = True}), SendServerMessage]
2118
0ebcc98ebc1a Send server message after nicks info (more chance for it to be seen)
unc0rr
parents: 2116
diff changeset
   356
3501
a3159a410e5c Reimplement more core actions
unc0rr
parents: 3500
diff changeset
   357
{-
3502
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
   358
processAction (clID, serverInfo, rnc) (RoomAddThisClient rID) =
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
   359
    processAction (
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
   360
        clID,
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
   361
        serverInfo,
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
   362
        adjust (\cl -> cl{roomID = rID, teamsInGame = if rID == 0 then teamsInGame cl else 0}) clID clients,
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
   363
        adjust (\r -> r{playersIDs = IntSet.insert clID (playersIDs r), playersIn = (playersIn r) + 1}) rID $
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
   364
            adjust (\r -> r{playersIDs = IntSet.delete clID (playersIDs r)}) 0 rooms
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
   365
        ) joinMsg
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
   366
    where
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
   367
        client = clients ! clID
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
   368
        joinMsg = if rID == 0 then
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
   369
                AnswerAllOthers ["LOBBY:JOINED", nick client]
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
   370
            else
ad38c653b7d9 Some more progress
unc0rr
parents: 3501
diff changeset
   371
                AnswerThisRoom ["JOINED", nick client]
1841
fba7210b438b Retrieve client password from web database and ask for it
unc0rr
parents: 1839
diff changeset
   372
3425
ead2ed20dfd4 Start the server refactoring
unc0rr
parents: 3283
diff changeset
   373
processAction (clID, serverInfo, rnc) (KickClient kickID) =
ead2ed20dfd4 Start the server refactoring
unc0rr
parents: 3283
diff changeset
   374
    liftM2 replaceID (return clID) (processAction (kickID, serverInfo, rnc) $ ByeClient "Kicked")
1879
bb114339eb4e Implement kick from room
unc0rr
parents: 1866
diff changeset
   375
1926
cb46fbdcaa41 Add simple DoS protection mechanism (although better than previous server had)
unc0rr
parents: 1925
diff changeset
   376
3425
ead2ed20dfd4 Start the server refactoring
unc0rr
parents: 3283
diff changeset
   377
processAction (clID, serverInfo, rnc) (BanClient banNick) =
ead2ed20dfd4 Start the server refactoring
unc0rr
parents: 3283
diff changeset
   378
    return (clID, serverInfo, rnc)
1921
2a09f7f786a0 - User from localhost is server admin
unc0rr
parents: 1879
diff changeset
   379
1879
bb114339eb4e Implement kick from room
unc0rr
parents: 1866
diff changeset
   380
3425
ead2ed20dfd4 Start the server refactoring
unc0rr
parents: 3283
diff changeset
   381
processAction (clID, serverInfo, rnc) (KickRoomClient kickID) = do
2867
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   382
    writeChan (sendChan $ clients ! kickID) ["KICKED"]
3425
ead2ed20dfd4 Start the server refactoring
unc0rr
parents: 3283
diff changeset
   383
    liftM2 replaceID (return clID) (processAction (kickID, serverInfo, rnc) $ RoomRemoveThisClient "kicked")
1879
bb114339eb4e Implement kick from room
unc0rr
parents: 1866
diff changeset
   384
bb114339eb4e Implement kick from room
unc0rr
parents: 1866
diff changeset
   385
3425
ead2ed20dfd4 Start the server refactoring
unc0rr
parents: 3283
diff changeset
   386
processAction (clID, serverInfo, rnc) (RemoveClientTeams teamsClID) =
2867
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   387
    liftM2 replaceID (return clID) $
3425
ead2ed20dfd4 Start the server refactoring
unc0rr
parents: 3283
diff changeset
   388
        foldM processAction (teamsClID, serverInfo, rnc) removeTeamsActions
2867
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   389
    where
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   390
        client = clients ! teamsClID
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   391
        room = rooms ! (roomID client)
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   392
        teamsToRemove = Prelude.filter (\t -> teamowner t == nick client) $ teams room
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   393
        removeTeamsActions = Prelude.map (RemoveTeam . teamname) teamsToRemove
3435
4e4f88a7bdf2 Some more steps in refactoring
unc0rr
parents: 3425
diff changeset
   394
-}
1926
cb46fbdcaa41 Add simple DoS protection mechanism (although better than previous server had)
unc0rr
parents: 1925
diff changeset
   395
3451
62089ccec75c Uses StateT monad instead of manually maintaining the state
unc0rr
parents: 3436
diff changeset
   396
processAction (AddClient client) = do
62089ccec75c Uses StateT monad instead of manually maintaining the state
unc0rr
parents: 3436
diff changeset
   397
    rnc <- gets roomsClients
62089ccec75c Uses StateT monad instead of manually maintaining the state
unc0rr
parents: 3436
diff changeset
   398
    si <- gets serverInfo
62089ccec75c Uses StateT monad instead of manually maintaining the state
unc0rr
parents: 3436
diff changeset
   399
    liftIO $ do
62089ccec75c Uses StateT monad instead of manually maintaining the state
unc0rr
parents: 3436
diff changeset
   400
        ci <- addClient rnc client
3500
af8390d807d6 Use sockets instead of handles, use bytestrings instead of strings
unc0rr
parents: 3458
diff changeset
   401
        forkIO $ clientRecvLoop (clientSocket client) (coreChan si) ci
af8390d807d6 Use sockets instead of handles, use bytestrings instead of strings
unc0rr
parents: 3458
diff changeset
   402
        forkIO $ clientSendLoop (clientSocket client) (coreChan si) (sendChan client) ci
3451
62089ccec75c Uses StateT monad instead of manually maintaining the state
unc0rr
parents: 3436
diff changeset
   403
62089ccec75c Uses StateT monad instead of manually maintaining the state
unc0rr
parents: 3436
diff changeset
   404
        infoM "Clients" (show ci ++ ": New client. Time: " ++ show (connectTime client))
3425
ead2ed20dfd4 Start the server refactoring
unc0rr
parents: 3283
diff changeset
   405
3673
45778b16b224 Some comments on the reason of the bug, leave bug not fixed yet
unc0rr
parents: 3671
diff changeset
   406
    processAction $ AnswerClients [sendChan client] ["CONNECTED", "Hedgewars server http://www.hedgewars.org/"]
3451
62089ccec75c Uses StateT monad instead of manually maintaining the state
unc0rr
parents: 3436
diff changeset
   407
{-        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
   408
3451
62089ccec75c Uses StateT monad instead of manually maintaining the state
unc0rr
parents: 3436
diff changeset
   409
        if False && (isJust $ host client `Prelude.lookup` newLogins) then
62089ccec75c Uses StateT monad instead of manually maintaining the state
unc0rr
parents: 3436
diff changeset
   410
            processAction (ci, serverInfo{lastLogins = newLogins}, rnc) $ ByeClient "Reconnected too fast"
62089ccec75c Uses StateT monad instead of manually maintaining the state
unc0rr
parents: 3436
diff changeset
   411
            else
62089ccec75c Uses StateT monad instead of manually maintaining the state
unc0rr
parents: 3436
diff changeset
   412
            return (ci, serverInfo)
62089ccec75c Uses StateT monad instead of manually maintaining the state
unc0rr
parents: 3436
diff changeset
   413
-}
62089ccec75c Uses StateT monad instead of manually maintaining the state
unc0rr
parents: 3436
diff changeset
   414
62089ccec75c Uses StateT monad instead of manually maintaining the state
unc0rr
parents: 3436
diff changeset
   415
1927
e2031906a347 Ping clients every 30 seconds. Disconnection due to ping timeout to be implemented.
unc0rr
parents: 1926
diff changeset
   416
3654
18189fbc7530 Reimplement ping timeout
unc0rr
parents: 3653
diff changeset
   417
processAction PingAll = do
18189fbc7530 Reimplement ping timeout
unc0rr
parents: 3653
diff changeset
   418
    rnc <- gets roomsClients
3658
113cb9345be1 Make server stay alive when some clients get kicked
unc0rr
parents: 3656
diff changeset
   419
    liftIO (allClientsM rnc) >>= mapM_ (kickTimeouted rnc)
3654
18189fbc7530 Reimplement ping timeout
unc0rr
parents: 3653
diff changeset
   420
    cis <- liftIO $ allClientsM rnc
18189fbc7530 Reimplement ping timeout
unc0rr
parents: 3653
diff changeset
   421
    chans <- liftIO $ mapM (client'sM rnc sendChan) cis
18189fbc7530 Reimplement ping timeout
unc0rr
parents: 3653
diff changeset
   422
    liftIO $ mapM_ (modifyClient rnc (\cl -> cl{pingsQueue = pingsQueue cl + 1})) cis
18189fbc7530 Reimplement ping timeout
unc0rr
parents: 3653
diff changeset
   423
    processAction $ AnswerClients chans ["PING"]
2867
9be6693c78cb - Unbreak support for client versions prior to 0.9.13-dev
unc0rr
parents: 2662
diff changeset
   424
    where
3654
18189fbc7530 Reimplement ping timeout
unc0rr
parents: 3653
diff changeset
   425
        kickTimeouted rnc ci = do
18189fbc7530 Reimplement ping timeout
unc0rr
parents: 3653
diff changeset
   426
            pq <- liftIO $ client'sM rnc pingsQueue ci
18189fbc7530 Reimplement ping timeout
unc0rr
parents: 3653
diff changeset
   427
            when (pq > 0) $
18189fbc7530 Reimplement ping timeout
unc0rr
parents: 3653
diff changeset
   428
                withStateT (\as -> as{clientIndex = Just ci}) $
18189fbc7530 Reimplement ping timeout
unc0rr
parents: 3653
diff changeset
   429
                    processAction (ByeClient "Ping timeout")
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
3653
c0d94fedbd86 Reimplement statistics
unc0rr
parents: 3645
diff changeset
   432
processAction (StatsAction) = do
c0d94fedbd86 Reimplement statistics
unc0rr
parents: 3645
diff changeset
   433
    rnc <- gets roomsClients
c0d94fedbd86 Reimplement statistics
unc0rr
parents: 3645
diff changeset
   434
    si <- gets serverInfo
c0d94fedbd86 Reimplement statistics
unc0rr
parents: 3645
diff changeset
   435
    (roomsNum, clientsNum) <- liftIO $ withRoomsAndClients rnc stats
c0d94fedbd86 Reimplement statistics
unc0rr
parents: 3645
diff changeset
   436
    liftIO $ writeChan (dbQueries si) $ SendStats clientsNum (roomsNum - 1)
c0d94fedbd86 Reimplement statistics
unc0rr
parents: 3645
diff changeset
   437
    where
c0d94fedbd86 Reimplement statistics
unc0rr
parents: 3645
diff changeset
   438
          stats irnc = (length $ allRooms irnc, length $ allClients irnc)
3425
ead2ed20dfd4 Start the server refactoring
unc0rr
parents: 3283
diff changeset
   439