author | unc0rr |
Mon, 10 Nov 2008 15:50:46 +0000 | |
changeset 1491 | 0b1f44751509 |
parent 1484 | c01512115c12 |
child 1492 | 2da1fe033f23 |
permissions | -rw-r--r-- |
849 | 1 |
module Miscutils where |
2 |
||
3 |
import IO |
|
4 |
import Control.Concurrent.STM |
|
894 | 5 |
import Data.Word |
6 |
import Data.Char |
|
901
2f5ce9a584f9
Modify protocol implementation functions interface (convertation not yet finished)
unc0rr
parents:
895
diff
changeset
|
7 |
import Data.List |
2f5ce9a584f9
Modify protocol implementation functions interface (convertation not yet finished)
unc0rr
parents:
895
diff
changeset
|
8 |
import Maybe (fromJust) |
1317 | 9 |
import qualified Data.Map as Map |
1478 | 10 |
import Data.Time |
849 | 11 |
|
851 | 12 |
data ClientInfo = |
1082 | 13 |
ClientInfo |
851 | 14 |
{ |
1082 | 15 |
chan :: TChan [String], |
851 | 16 |
handle :: Handle, |
1478 | 17 |
host :: String, |
18 |
connectTime :: UTCTime, |
|
851 | 19 |
nick :: String, |
894 | 20 |
protocol :: Word16, |
851 | 21 |
room :: String, |
1391 | 22 |
isMaster :: Bool, |
1403 | 23 |
isReady :: Bool, |
1391 | 24 |
forceQuit :: Bool |
851 | 25 |
} |
26 |
||
1082 | 27 |
instance Eq ClientInfo where |
28 |
a1 == a2 = handle a1 == handle a2 |
|
29 |
||
1317 | 30 |
data HedgehogInfo = |
31 |
HedgehogInfo String String |
|
32 |
||
1083 | 33 |
data TeamInfo = |
34 |
TeamInfo |
|
35 |
{ |
|
1329 | 36 |
teamowner :: String, |
1317 | 37 |
teamname :: String, |
1321 | 38 |
teamcolor :: String, |
39 |
teamgrave :: String, |
|
40 |
teamfort :: String, |
|
41 |
difficulty :: Int, |
|
1327 | 42 |
hhnum :: Int, |
1317 | 43 |
hedgehogs :: [HedgehogInfo] |
1083 | 44 |
} |
45 |
||
851 | 46 |
data RoomInfo = |
47 |
RoomInfo |
|
48 |
{ |
|
49 |
name :: String, |
|
1083 | 50 |
password :: String, |
1317 | 51 |
roomProto :: Word16, |
52 |
teams :: [TeamInfo], |
|
1333
b0b0510eb82d
- Fix a bug with chosen map (new clinet gets wrong information)
unc0rr
parents:
1329
diff
changeset
|
53 |
gamemap :: String, |
1350 | 54 |
gameinprogress :: Bool, |
1396 | 55 |
playersIn :: Int, |
1403 | 56 |
readyPlayers :: Int, |
1411 | 57 |
isRestrictedJoins :: Bool, |
58 |
isRestrictedTeams :: Bool, |
|
1317 | 59 |
params :: Map.Map String [String] |
851 | 60 |
} |
1411 | 61 |
createRoom = (RoomInfo "" "" 0 [] "+rnd+" False 1 0 False False Map.empty) |
851 | 62 |
|
1491
0b1f44751509
Make answers creation more abstract, in prepare for a conversion
unc0rr
parents:
1484
diff
changeset
|
63 |
data ServerInfo = |
0b1f44751509
Make answers creation more abstract, in prepare for a conversion
unc0rr
parents:
1484
diff
changeset
|
64 |
ServerInfo |
0b1f44751509
Make answers creation more abstract, in prepare for a conversion
unc0rr
parents:
1484
diff
changeset
|
65 |
{ |
0b1f44751509
Make answers creation more abstract, in prepare for a conversion
unc0rr
parents:
1484
diff
changeset
|
66 |
message :: String |
0b1f44751509
Make answers creation more abstract, in prepare for a conversion
unc0rr
parents:
1484
diff
changeset
|
67 |
} |
0b1f44751509
Make answers creation more abstract, in prepare for a conversion
unc0rr
parents:
1484
diff
changeset
|
68 |
|
1082 | 69 |
type ClientsTransform = [ClientInfo] -> [ClientInfo] |
70 |
type RoomsTransform = [RoomInfo] -> [RoomInfo] |
|
71 |
type HandlesSelector = ClientInfo -> [ClientInfo] -> [RoomInfo] -> [Handle] |
|
1491
0b1f44751509
Make answers creation more abstract, in prepare for a conversion
unc0rr
parents:
1484
diff
changeset
|
72 |
type Answer = (HandlesSelector, [String]) |
0b1f44751509
Make answers creation more abstract, in prepare for a conversion
unc0rr
parents:
1484
diff
changeset
|
73 |
type CmdHandler = ClientInfo -> [ClientInfo] -> [RoomInfo] -> [String] -> (ClientsTransform, RoomsTransform, [Answer]) |
1082 | 74 |
|
901
2f5ce9a584f9
Modify protocol implementation functions interface (convertation not yet finished)
unc0rr
parents:
895
diff
changeset
|
75 |
|
902 | 76 |
roomByName :: String -> [RoomInfo] -> RoomInfo |
77 |
roomByName roomName rooms = fromJust $ find (\room -> roomName == name room) rooms |
|
78 |
||
1082 | 79 |
tselect :: [ClientInfo] -> STM ([String], ClientInfo) |
80 |
tselect = foldl orElse retry . map (\ci -> (flip (,) ci) `fmap` readTChan (chan ci)) |
|
889 | 81 |
|
894 | 82 |
maybeRead :: Read a => String -> Maybe a |
83 |
maybeRead s = case reads s of |
|
84 |
[(x, rest)] | all isSpace rest -> Just x |
|
85 |
_ -> Nothing |
|
901
2f5ce9a584f9
Modify protocol implementation functions interface (convertation not yet finished)
unc0rr
parents:
895
diff
changeset
|
86 |
|
2f5ce9a584f9
Modify protocol implementation functions interface (convertation not yet finished)
unc0rr
parents:
895
diff
changeset
|
87 |
deleteBy2t :: (a -> b -> Bool) -> b -> [a] -> [a] |
2f5ce9a584f9
Modify protocol implementation functions interface (convertation not yet finished)
unc0rr
parents:
895
diff
changeset
|
88 |
deleteBy2t _ _ [] = [] |
2f5ce9a584f9
Modify protocol implementation functions interface (convertation not yet finished)
unc0rr
parents:
895
diff
changeset
|
89 |
deleteBy2t eq x (y:ys) = if y `eq` x then ys else y : deleteBy2t eq x ys |
2f5ce9a584f9
Modify protocol implementation functions interface (convertation not yet finished)
unc0rr
parents:
895
diff
changeset
|
90 |
|
2f5ce9a584f9
Modify protocol implementation functions interface (convertation not yet finished)
unc0rr
parents:
895
diff
changeset
|
91 |
deleteFirstsBy2t :: (a -> b -> Bool) -> [a] -> [b] -> [a] |
2f5ce9a584f9
Modify protocol implementation functions interface (convertation not yet finished)
unc0rr
parents:
895
diff
changeset
|
92 |
deleteFirstsBy2t eq = foldl (flip (deleteBy2t eq)) |
1082 | 93 |
|
1466 | 94 |
clientByHandle :: Handle -> [ClientInfo] -> Maybe ClientInfo |
95 |
clientByHandle chandle clients = find (\c -> handle c == chandle) clients |
|
96 |
||
1082 | 97 |
sameRoom :: HandlesSelector |
98 |
sameRoom client clients rooms = map handle $ filter (\ci -> room ci == room client) clients |
|
99 |
||
1484 | 100 |
noRoomSameProto :: HandlesSelector |
101 |
noRoomSameProto client clients _ = map handle $ filter (null . room) $ filter (\ci -> protocol client == protocol ci) clients |
|
102 |
||
1082 | 103 |
othersInRoom :: HandlesSelector |
104 |
othersInRoom client clients rooms = map handle $ filter (client /=) $ filter (\ci -> room ci == room client) clients |
|
105 |
||
106 |
fromRoom :: String -> HandlesSelector |
|
107 |
fromRoom roomName _ clients _ = map handle $ filter (\ci -> room ci == roomName) clients |
|
108 |
||
1461
87e5a6c3882c
Ping clients every 30 seconds, should help with ghosts on server
unc0rr
parents:
1411
diff
changeset
|
109 |
allClients :: HandlesSelector |
87e5a6c3882c
Ping clients every 30 seconds, should help with ghosts on server
unc0rr
parents:
1411
diff
changeset
|
110 |
allClients _ clients _ = map handle $ clients |
87e5a6c3882c
Ping clients every 30 seconds, should help with ghosts on server
unc0rr
parents:
1411
diff
changeset
|
111 |
|
1082 | 112 |
clientOnly :: HandlesSelector |
113 |
clientOnly client _ _ = [handle client] |
|
114 |
||
115 |
noChangeClients :: ClientsTransform |
|
116 |
noChangeClients a = a |
|
117 |
||
118 |
modifyClient :: ClientInfo -> ClientsTransform |
|
1321 | 119 |
modifyClient _ [] = error "modifyClient: no such client" |
1082 | 120 |
modifyClient client (cl:cls) = |
121 |
if cl == client then |
|
122 |
client : cls |
|
123 |
else |
|
124 |
cl : (modifyClient client cls) |
|
125 |
||
1408 | 126 |
modifyRoomClients :: RoomInfo -> (ClientInfo -> ClientInfo) -> ClientsTransform |
127 |
modifyRoomClients clientsroom clientMod clients = map (\c -> if name clientsroom == room c then clientMod c else c) clients |
|
128 |
||
1082 | 129 |
noChangeRooms :: RoomsTransform |
130 |
noChangeRooms a = a |
|
131 |
||
132 |
addRoom :: RoomInfo -> RoomsTransform |
|
133 |
addRoom room rooms = room:rooms |
|
134 |
||
135 |
removeRoom :: String -> RoomsTransform |
|
136 |
removeRoom roomname rooms = filter (\rm -> roomname /= name rm) rooms |
|
1317 | 137 |
|
1321 | 138 |
modifyRoom :: RoomInfo -> RoomsTransform |
139 |
modifyRoom _ [] = error "changeRoomConfig: no such room" |
|
140 |
modifyRoom room (rm:rms) = |
|
141 |
if name room == name rm then |
|
142 |
room : rms |
|
1317 | 143 |
else |
1402 | 144 |
rm : modifyRoom room rms |
1327 | 145 |
|
146 |
modifyTeam :: RoomInfo -> TeamInfo -> RoomInfo |
|
147 |
modifyTeam room team = room{teams = replaceTeam team $ teams room} |
|
148 |
where |
|
149 |
replaceTeam _ [] = error "modifyTeam: no such team" |
|
150 |
replaceTeam team (t:teams) = |
|
151 |
if teamname team == teamname t then |
|
152 |
team : teams |
|
153 |
else |
|
154 |
t : replaceTeam team teams |