gameServer/Votes.hs
author unc0rr
Wed, 19 Mar 2014 11:54:09 +0400
changeset 10204 50e52e511300
parent 10195 d1c23bb73346
child 10212 5fb3bb2de9d2
permissions -rw-r--r--
Fix div by zero error in new generator
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
10058
4ed428389c4e - Implement /callvote
unc0rr
parents: 10049
diff changeset
     1
{-# LANGUAGE OverloadedStrings #-}
10049
ca11d122f54e Oops, forgot this
unc0rr
parents:
diff changeset
     2
module Votes where
ca11d122f54e Oops, forgot this
unc0rr
parents:
diff changeset
     3
ca11d122f54e Oops, forgot this
unc0rr
parents:
diff changeset
     4
import Control.Monad.Reader
ca11d122f54e Oops, forgot this
unc0rr
parents:
diff changeset
     5
import Control.Monad.State
ca11d122f54e Oops, forgot this
unc0rr
parents:
diff changeset
     6
import ServerState
10058
4ed428389c4e - Implement /callvote
unc0rr
parents: 10049
diff changeset
     7
import qualified Data.ByteString.Char8 as B
10081
0af84e5cbd4d Implement 'voted' function
unc0rr
parents: 10058
diff changeset
     8
import qualified Data.List as L
10195
d1c23bb73346 - Room save/load into/from file
unc0rr
parents: 10090
diff changeset
     9
import qualified Data.Map as Map
10058
4ed428389c4e - Implement /callvote
unc0rr
parents: 10049
diff changeset
    10
import Data.Maybe
4ed428389c4e - Implement /callvote
unc0rr
parents: 10049
diff changeset
    11
-------------------
4ed428389c4e - Implement /callvote
unc0rr
parents: 10049
diff changeset
    12
import Utils
4ed428389c4e - Implement /callvote
unc0rr
parents: 10049
diff changeset
    13
import CoreTypes
4ed428389c4e - Implement /callvote
unc0rr
parents: 10049
diff changeset
    14
import HandlerUtils
10049
ca11d122f54e Oops, forgot this
unc0rr
parents:
diff changeset
    15
10081
0af84e5cbd4d Implement 'voted' function
unc0rr
parents: 10058
diff changeset
    16
0af84e5cbd4d Implement 'voted' function
unc0rr
parents: 10058
diff changeset
    17
voted :: Bool -> Reader (ClientIndex, IRnC) [Action]
0af84e5cbd4d Implement 'voted' function
unc0rr
parents: 10058
diff changeset
    18
voted vote = do
0af84e5cbd4d Implement 'voted' function
unc0rr
parents: 10058
diff changeset
    19
    cl <- thisClient
0af84e5cbd4d Implement 'voted' function
unc0rr
parents: 10058
diff changeset
    20
    rm <- thisRoom
0af84e5cbd4d Implement 'voted' function
unc0rr
parents: 10058
diff changeset
    21
    uid <- liftM clUID thisClient
0af84e5cbd4d Implement 'voted' function
unc0rr
parents: 10058
diff changeset
    22
0af84e5cbd4d Implement 'voted' function
unc0rr
parents: 10058
diff changeset
    23
    if isNothing $ voting rm then
0af84e5cbd4d Implement 'voted' function
unc0rr
parents: 10058
diff changeset
    24
        return [AnswerClients [sendChan cl] ["CHAT", "[server]", loc "There's no voting going on"]]
0af84e5cbd4d Implement 'voted' function
unc0rr
parents: 10058
diff changeset
    25
    else if uid `L.notElem` entitledToVote (fromJust $ voting rm) then
0af84e5cbd4d Implement 'voted' function
unc0rr
parents: 10058
diff changeset
    26
        return []
0af84e5cbd4d Implement 'voted' function
unc0rr
parents: 10058
diff changeset
    27
    else if uid `L.elem` map fst (votes . fromJust $ voting rm) then
0af84e5cbd4d Implement 'voted' function
unc0rr
parents: 10058
diff changeset
    28
        return [AnswerClients [sendChan cl] ["CHAT", "[server]", loc "You already have voted"]]
0af84e5cbd4d Implement 'voted' function
unc0rr
parents: 10058
diff changeset
    29
    else
10087
5ba891578621 Implement kick voting
unc0rr
parents: 10081
diff changeset
    30
        actOnVoting . fromJust . liftM (\v -> v{votes = (uid, vote):votes v}) $ voting rm
5ba891578621 Implement kick voting
unc0rr
parents: 10081
diff changeset
    31
    where
5ba891578621 Implement kick voting
unc0rr
parents: 10081
diff changeset
    32
    actOnVoting :: Voting -> Reader (ClientIndex, IRnC) [Action]
5ba891578621 Implement kick voting
unc0rr
parents: 10081
diff changeset
    33
    actOnVoting vt = do
5ba891578621 Implement kick voting
unc0rr
parents: 10081
diff changeset
    34
        let (contra, pro) = L.partition snd $ votes vt
5ba891578621 Implement kick voting
unc0rr
parents: 10081
diff changeset
    35
        let v = (length $ entitledToVote vt) `div` 2 + 1
5ba891578621 Implement kick voting
unc0rr
parents: 10081
diff changeset
    36
5ba891578621 Implement kick voting
unc0rr
parents: 10081
diff changeset
    37
        if length contra >= v then
5ba891578621 Implement kick voting
unc0rr
parents: 10081
diff changeset
    38
            closeVoting
5ba891578621 Implement kick voting
unc0rr
parents: 10081
diff changeset
    39
        else if length pro >= v then do
5ba891578621 Implement kick voting
unc0rr
parents: 10081
diff changeset
    40
            act $ voteType vt
5ba891578621 Implement kick voting
unc0rr
parents: 10081
diff changeset
    41
            closeVoting
5ba891578621 Implement kick voting
unc0rr
parents: 10081
diff changeset
    42
        else
5ba891578621 Implement kick voting
unc0rr
parents: 10081
diff changeset
    43
            return [ModifyRoom $ \r -> r{voting = Just vt}]
5ba891578621 Implement kick voting
unc0rr
parents: 10081
diff changeset
    44
5ba891578621 Implement kick voting
unc0rr
parents: 10081
diff changeset
    45
    closeVoting = do
5ba891578621 Implement kick voting
unc0rr
parents: 10081
diff changeset
    46
        chans <- roomClientsChans
5ba891578621 Implement kick voting
unc0rr
parents: 10081
diff changeset
    47
        return [
5ba891578621 Implement kick voting
unc0rr
parents: 10081
diff changeset
    48
            AnswerClients chans ["CHAT", "[server]", loc "Voting closed"]
5ba891578621 Implement kick voting
unc0rr
parents: 10081
diff changeset
    49
            , ModifyRoom (\r -> r{voting = Nothing})
5ba891578621 Implement kick voting
unc0rr
parents: 10081
diff changeset
    50
            ]
5ba891578621 Implement kick voting
unc0rr
parents: 10081
diff changeset
    51
5ba891578621 Implement kick voting
unc0rr
parents: 10081
diff changeset
    52
    act (VoteKick nickname) = do
5ba891578621 Implement kick voting
unc0rr
parents: 10081
diff changeset
    53
        (thisClientId, rnc) <- ask
5ba891578621 Implement kick voting
unc0rr
parents: 10081
diff changeset
    54
        maybeClientId <- clientByNick nickname
5ba891578621 Implement kick voting
unc0rr
parents: 10081
diff changeset
    55
        rm <- thisRoom
5ba891578621 Implement kick voting
unc0rr
parents: 10081
diff changeset
    56
        let kickId = fromJust maybeClientId
5ba891578621 Implement kick voting
unc0rr
parents: 10081
diff changeset
    57
        let kickCl = rnc `client` kickId
5ba891578621 Implement kick voting
unc0rr
parents: 10081
diff changeset
    58
        let sameRoom = clientRoom rnc thisClientId == clientRoom rnc kickId
5ba891578621 Implement kick voting
unc0rr
parents: 10081
diff changeset
    59
        return
5ba891578621 Implement kick voting
unc0rr
parents: 10081
diff changeset
    60
            [KickRoomClient kickId |
5ba891578621 Implement kick voting
unc0rr
parents: 10081
diff changeset
    61
                isJust maybeClientId
5ba891578621 Implement kick voting
unc0rr
parents: 10081
diff changeset
    62
                && sameRoom
5ba891578621 Implement kick voting
unc0rr
parents: 10081
diff changeset
    63
                && ((isNothing $ gameInfo rm) || teamsInGame kickCl == 0)
5ba891578621 Implement kick voting
unc0rr
parents: 10081
diff changeset
    64
            ]
10195
d1c23bb73346 - Room save/load into/from file
unc0rr
parents: 10090
diff changeset
    65
    act (VoteMap roomSave) = do
d1c23bb73346 - Room save/load into/from file
unc0rr
parents: 10090
diff changeset
    66
        rm <- thisRoom
d1c23bb73346 - Room save/load into/from file
unc0rr
parents: 10090
diff changeset
    67
        let rs = Map.lookup roomSave (roomSaves rm)
d1c23bb73346 - Room save/load into/from file
unc0rr
parents: 10090
diff changeset
    68
        case rs of
d1c23bb73346 - Room save/load into/from file
unc0rr
parents: 10090
diff changeset
    69
             Nothing -> return []
d1c23bb73346 - Room save/load into/from file
unc0rr
parents: 10090
diff changeset
    70
             Just (mp, p) -> return [ModifyRoom $ \r -> r{params = p, mapParams = mp}]
10081
0af84e5cbd4d Implement 'voted' function
unc0rr
parents: 10058
diff changeset
    71
10049
ca11d122f54e Oops, forgot this
unc0rr
parents:
diff changeset
    72
ca11d122f54e Oops, forgot this
unc0rr
parents:
diff changeset
    73
startVote :: VoteType -> Reader (ClientIndex, IRnC) [Action]
10058
4ed428389c4e - Implement /callvote
unc0rr
parents: 10049
diff changeset
    74
startVote vt = do
4ed428389c4e - Implement /callvote
unc0rr
parents: 10049
diff changeset
    75
    (ci, rnc) <- ask
10090
a471a7bbc339 - Start work on flood detector
unc0rr
parents: 10087
diff changeset
    76
    --cl <- thisClient
10058
4ed428389c4e - Implement /callvote
unc0rr
parents: 10049
diff changeset
    77
    rm <- thisRoom
4ed428389c4e - Implement /callvote
unc0rr
parents: 10049
diff changeset
    78
    chans <- roomClientsChans
4ed428389c4e - Implement /callvote
unc0rr
parents: 10049
diff changeset
    79
4ed428389c4e - Implement /callvote
unc0rr
parents: 10049
diff changeset
    80
    let uids = map (clUID . client rnc) . roomClients rnc $ clientRoom rnc ci
4ed428389c4e - Implement /callvote
unc0rr
parents: 10049
diff changeset
    81
4ed428389c4e - Implement /callvote
unc0rr
parents: 10049
diff changeset
    82
    if isJust $ voting rm then
4ed428389c4e - Implement /callvote
unc0rr
parents: 10049
diff changeset
    83
        return []
4ed428389c4e - Implement /callvote
unc0rr
parents: 10049
diff changeset
    84
    else
4ed428389c4e - Implement /callvote
unc0rr
parents: 10049
diff changeset
    85
        liftM ([ModifyRoom (\r -> r{voting = Just (newVoting vt){entitledToVote = uids}})
4ed428389c4e - Implement /callvote
unc0rr
parents: 10049
diff changeset
    86
        , AnswerClients chans ["CHAT", "[server]", B.concat [loc "New voting started", ": ", voteInfo vt]]
10081
0af84e5cbd4d Implement 'voted' function
unc0rr
parents: 10058
diff changeset
    87
        ] ++ ) $ voted True
0af84e5cbd4d Implement 'voted' function
unc0rr
parents: 10058
diff changeset
    88
10049
ca11d122f54e Oops, forgot this
unc0rr
parents:
diff changeset
    89
ca11d122f54e Oops, forgot this
unc0rr
parents:
diff changeset
    90
checkVotes :: StateT ServerState IO ()
ca11d122f54e Oops, forgot this
unc0rr
parents:
diff changeset
    91
checkVotes = undefined
10058
4ed428389c4e - Implement /callvote
unc0rr
parents: 10049
diff changeset
    92
10081
0af84e5cbd4d Implement 'voted' function
unc0rr
parents: 10058
diff changeset
    93
10058
4ed428389c4e - Implement /callvote
unc0rr
parents: 10049
diff changeset
    94
voteInfo :: VoteType -> B.ByteString
4ed428389c4e - Implement /callvote
unc0rr
parents: 10049
diff changeset
    95
voteInfo (VoteKick n) = B.concat [loc "kick", " ", n]
10195
d1c23bb73346 - Room save/load into/from file
unc0rr
parents: 10090
diff changeset
    96
voteInfo (VoteMap n) = B.concat [loc "map", " ", n]