{-# LANGUAGE TemplateHaskell #-}
module NetMatching where
import Networking
import Parse
import Control.Category
import Control.FilterCategory
import Control.Monad (guard)
import Data.ADT.Getters
import Data.List (intercalate)
import Data.Map (delete, insert, lookup)
import Data.Monoid (Monoid(..))
import FRP.Peakachu.Program
import Network.Socket (SockAddr)
import Prelude hiding ((.), id, lookup)
data MatchingIn a
= DoMatching [SockAddr] a
| MITimerEvent a
| MIHttp (Maybe String) a
data MatchingOut a
= MatchingResult [SockAddr] a
| MOSetRetryTimer a
| MOHttp String a
deriving Show
$(mkADTGetters ''MatchingOut)
netMatching :: Ord a => Program (MatchingIn a) (MatchingOut a)
netMatching =
mapMaybeC snd . scanlP step (mempty, Nothing)
where
step (state, _) (DoMatching addrs tag) =
(newState, req newState tag)
where
newState = insert tag addrs state
step (state, _) (MIHttp response tag) =
case parseDifferentAddresses state tag response of
Nothing ->
( state
, Just $ MOSetRetryTimer tag
)
Just res ->
( delete tag state
, Just $ MatchingResult res tag
)
step (state, _) (MITimerEvent tag) = (state, req state tag)
req state tag =
fmap
( (`MOHttp` tag)
. ("http://defendtheking.nfshost.com/match.cgi?" ++)
)
. formatAddrs state $ tag
formatAddrs state =
fmap (intercalate "," . map show) . (`lookup` state)
parseDifferentAddresses state tag response = do
text <- response
myAddrText <- formatAddrs state tag
guard $ myAddrText /= text
mapM parseSockAddr . split ',' $ text