-
Notifications
You must be signed in to change notification settings - Fork 8
/
Api.hs
130 lines (93 loc) · 3.52 KB
/
Api.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
{-# LANGUAGE OverloadedStrings, ScopedTypeVariables #-}
module Main where
import Botland.Helpers
import Botland.Types
import Botland.Control
import Botland.Middleware
import Botland.Tick
import Database.MongoDB (runIOE, connect, access, master, host, Pipe, Action)
import Control.Concurrent (forkIO, threadDelay)
import Control.Monad.IO.Class (liftIO)
import Data.Text.Lazy (Text, pack)
import Network.Wai.Middleware.Headers (cors)
import Network.Wai.Middleware.Static (staticRoot)
import Web.Scotty
import System.IO
main :: IO ()
main = do
-- without this you don't see any log output
hSetBuffering stdout LineBuffering
putStrLn "Starting BOTLAND"
pipe <- connectMongo
let db action = liftIO $ access pipe master "botland" action
let auth = runAuth pipe "botland"
-- recurring tasks
forkIO $ cleanup db
forkIO $ runTick gameInfo db
scotty 3026 $ do
middleware $ staticRoot "public"
middleware cors
get "/" $ do
redirect "/viewer/"
get "/viewer" $ do
cache minute
header "Content-Type" "text/html"
file "public/viewer/viewer.html"
get "/docs" $ do
cache minute
header "Content-Type" "text/html"
file "public/docs/docs.html"
get "/version" $ text "Botland 0.3.0"
get "/game/info" $ do
cache minute
json gameInfo
-- returns all the bots, obstacles and whathaveyounots
-- everything except playerId
get "/game/objects" $ do
{- cache second-}
res <- db $ objects
sendAction "" res
-- really, just gives you a session id, but pretend that it matters :)
-- works because it's a secret number, never sent to anyone
post "/players" $ decodeBody $ \p -> do
id <- db $ createPlayer p
sendActionFault "" id
get "/players/:name" $ do
cache minute
n <- param "name"
p <- db $ getPlayerByName n
sendActionMaybe "Could not find player" p
-- spawn them immediately, don't wait for the tick
post "/players/:playerId/minions" $ decodeBody $ \b -> do
pid <- param "playerId"
id <- db $ createBot gameInfo pid b
sendActionFault "Invalid Starting Location" id
get "/minions/:minionId" $ do
cache second
id <- param "minionId"
bot <- db $ botDetails id
sendActionFault "" bot
-- LEADERBOARDS (undocumented, the viewer can just use the normal objects call)
get "/top/killers" $ do
cache second
bots <- db $ topKillers
sendAction "" bots
get "/top/survivors" $ do
cache second
bots <- db $ topSurvivors
sendAction "" bots
-- sets the bot's action
post "/players/:playerId/minions/:minionId/commands" $ auth $ decodeBody $ \c -> do
mid <- param "minionId"
pid <- param "playerId"
res <- db $ setCommand c gameInfo pid mid
sendAction "" res
-- delete all bots associated with the player
delete "/players/:playerId" $ do
pid <- param "playerId"
ok <- db $ cleanupPlayer pid
sendAction "Could not delete player" ok
delete "/players/:playerId/minions/:minionId" $ auth $ do
mid <- param "minionId"
ok <- db $ cleanupBot mid
sendAction "Could not delete minion" ok