gameServer/JoinsMonitor.hs
author sheepluva
Tue, 21 Jan 2014 21:16:52 +0100
changeset 10038 0a5e651d494c
parent 10005 800d1bd9021a
child 10090 a471a7bbc339
permissions -rw-r--r--
Fix uGearsHandlersMess.pas changes lost in merge r1c02143bfe9c. This seems to only include the drill rocket fixes ( re0dd66b2e73b and r8db0c56f7e2f ) as well as the initial cake push ( r8786d4ac9e0b )

{-# LANGUAGE BangPatterns #-}

module JoinsMonitor(
    JoinsMonitor
    , newJoinMonitor
    , cleanup
    , joinsSentry
    ) where

import qualified Data.Map as Map
import Data.Time
import Data.IORef
import qualified Data.ByteString as B
import Data.Maybe
import Control.Monad

newtype JoinsMonitor = JoinsMonitor (IORef (Map.Map B.ByteString [UTCTime]))


newJoinMonitor :: IO JoinsMonitor
newJoinMonitor = do
    ioref <- newIORef Map.empty
    return (JoinsMonitor ioref)


cleanup :: JoinsMonitor -> UTCTime -> IO ()
cleanup (JoinsMonitor ref) time = modifyIORef ref f
    where
        f = Map.mapMaybe (\v -> let v' = takeWhile (\t -> diffUTCTime time t < 60*60) v in if null v' then Nothing else Just v')


joinsSentry :: JoinsMonitor -> B.ByteString -> UTCTime -> IO Bool
joinsSentry (JoinsMonitor ref) host time = do
    m <- readIORef ref
    let lastJoins = map (diffUTCTime time) $ Map.findWithDefault [] host m
    let last30sec = length $ takeWhile (< 30) lastJoins
    let last2min = length $ takeWhile (< 120) lastJoins
    let last10min = length $ takeWhile (< 600) lastJoins
    let pass = last30sec < 2 && last2min < 4 && last10min < 6

    when pass $ writeIORef ref $ Map.alter (Just . (:) time . fromMaybe []) host m

    return pass