-- RobotProxy.hs -- Tom Moertel -- CVS $Id: RobotProxy.hs,v 1.3 2002/09/06 04:03:51 thor Exp $ -- | The RobotProxy program is a proxy for a robot that monitors -- communications between the robot and the game server. The -- monitored communications are written to standard output in a format -- that can be read later and analyzed. -- TODO -- -- error handling -- usage module Main (main) where import Char import Control.Exception (handle) import Network import System.Environment import System.IO import Board import Commands main :: IO () main = withSocketsDo $ do -- set up I/O buffering hSetBuffering stdout LineBuffering -- check arguments args <- getArgs case args of [localPortS, remoteHost, remotePortS] -> runProxy localPortS remoteHost remotePortS _ -> usage where usage = do cmd <- getProgName hPutStrLn stderr $ "Usage: " ++ cmd ++ " localport remotehost remoteport" runProxy localPortS remoteHost remotePortS = do let localPort = PortNumber $ fromIntegral (read localPortS) let remotePort = PortNumber $ fromIntegral (read remotePortS) -- wait for robot to connect clientSocket <- listenOn localPort (hClient, clientHost, _) <- accept clientSocket hSetBuffering hClient LineBuffering -- connect to server hServer <- connectTo remoteHost remotePort hSetBuffering hServer LineBuffering -- start acting like a proxy proxy hClient hServer proxy :: Handle -> Handle -> IO () proxy hClient hServer = do -- handle "Player" handshake recordLineCtoS id -- read board dimStr <- proxyLineStoC let [_, rows] = map read (words dimStr) boardLines <- sequence (replicate rows proxyLineStoC) let (board,_) = parseBoardLns (dimStr:boardLines) putStrLn (serverLabel ++ show board) -- read initial game configuration recordLineStoC readRobotConfig -- read initial server response recordLineStoC readRCommands -- enter game loop gameLoop -- capture any after-game messages handle (const (return ())) $ epilogue -- ignore errors (EOF, most likely) where gameLoop = do recordLineStoC readPackageInfoList -- svr: pkgs recordLineCtoS id -- clt: cmd nextChar <- hLookAhead hServer if (nextChar /= '#') then return () else do recordLineStoC readRCommands -- svr: result gameLoop epilogue = recordLineStoC id >> epilogue recordLineStoC reader = recordLine serverLabel proxyLineStoC reader recordLineCtoS reader = recordLine clientLabel proxyLineCtoS reader recordLine label fetchLineActn reader = do l <- fetchLineActn putStrLn (label ++ show (reader l)) proxyLineCtoS = proxyLine hClient hServer proxyLineStoC = proxyLine hServer hClient proxyLine src dst = do lRaw <- hGetLine src let l = filter isPrint lRaw -- to support telnet hPutStrLn dst l return l serverLabel = "Server: " clientLabel = "Client: " -- ================================================================= -- -- Copyright (C) 2002 Thomas Moertel. -- -- This program is free software; you can redistribute it and/or -- modify it under the terms of the GNU General Public License -- as published by the Free Software Foundation; either version 2 -- of the License, or (at your option) any later version. -- -- The text of the GNU GPL may be found in the LICENSE file, -- included with this software, or online at the following URL: -- -- http://www.gnu.org/copyleft/gpl.html -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- Except as provided for under the terms of the GNU GPL, all rights -- are reserved worldwide. -- -- =================================================================