gameServer/EngineInteraction.hs
changeset 12118 72f5d670bbee
parent 11860 ad435d95ca4b
equal deleted inserted replaced
12117:2c21bca6cbfa 12118:72f5d670bbee
    42 -------------
    42 -------------
    43 import CoreTypes
    43 import CoreTypes
    44 import Utils
    44 import Utils
    45 
    45 
    46 #if defined(OFFICIAL_SERVER)
    46 #if defined(OFFICIAL_SERVER)
    47 {-
       
    48     this is snippet from http://stackoverflow.com/questions/10043102/how-to-catch-the-decompress-ioerror
       
    49     because standard 'catch' doesn't seem to catch decompression errors for some reason
       
    50 -}
       
    51 import qualified Codec.Compression.Zlib.Internal as ZI
    47 import qualified Codec.Compression.Zlib.Internal as ZI
    52 import qualified Codec.Compression.Zlib as Z
    48 import qualified Codec.Compression.Zlib as Z
    53 
    49 
    54 decompressWithoutExceptions :: BL.ByteString -> Either String BL.ByteString
    50 decompressWithoutExceptions :: BL.ByteString -> BL.ByteString
    55 decompressWithoutExceptions = finalise
    51 decompressWithoutExceptions = BL.fromChunks . ZI.foldDecompressStreamWithInput chunk end err decomp
    56                             . ZI.foldDecompressStream cons nil err
    52     where
    57                             . ZI.decompressWithErrors ZI.zlibFormat ZI.defaultDecompressParams
    53         decomp = ZI.decompressST ZI.zlibFormat ZI.defaultDecompressParams
    58   where err _ msg = Left msg
    54         chunk = (:)
    59         nil = Right []
    55         end _ = []
    60         cons chunk = right (chunk :)
    56         err = const $ [BW.empty]
    61         finalise = right BL.fromChunks
       
    62 {- end snippet  -}
       
    63 #endif
    57 #endif
    64 
    58 
    65 toEngineMsg :: B.ByteString -> B.ByteString
    59 toEngineMsg :: B.ByteString -> B.ByteString
    66 toEngineMsg msg = Base64.encode (fromIntegral (BW.length msg) `BW.cons` msg)
    60 toEngineMsg msg = Base64.encode (fromIntegral (BW.length msg) `BW.cons` msg)
    67 
    61 
   185         by200 :: [a] -> Maybe ([a], [a])
   179         by200 :: [a] -> Maybe ([a], [a])
   186         by200 [] = Nothing
   180         by200 [] = Nothing
   187         by200 m = Just $ L.splitAt 200 m
   181         by200 m = Just $ L.splitAt 200 m
   188 
   182 
   189 unpackDrawnMap :: B.ByteString -> BL.ByteString
   183 unpackDrawnMap :: B.ByteString -> BL.ByteString
   190 unpackDrawnMap = either (const BL.empty) id
   184 unpackDrawnMap = either
   191         . decompressWithoutExceptions
   185         (const BL.empty) 
   192         . BL.pack
   186         (decompressWithoutExceptions . BL.pack . drop 4 . BW.unpack)
   193         . L.drop 4
       
   194         . fromMaybe []
       
   195         . Base64.decode
   187         . Base64.decode
   196         . B.unpack
       
   197 
   188 
   198 compressWithLength :: BL.ByteString -> BL.ByteString
   189 compressWithLength :: BL.ByteString -> BL.ByteString
   199 compressWithLength b = BL.drop 8 . encode . runPut $ do
   190 compressWithLength b = BL.drop 8 . encode . runPut $ do
   200     put $ ((fromIntegral $ BL.length b)::Word32)
   191     put $ ((fromIntegral $ BL.length b)::Word32)
   201     mapM_ putWord8 $ BW.unpack $ BL.toStrict $ Z.compress b
   192     mapM_ putWord8 $ BW.unpack $ BL.toStrict $ Z.compress b
   202 
   193 
   203 packDrawnMap :: BL.ByteString -> B.ByteString
   194 packDrawnMap :: BL.ByteString -> B.ByteString
   204 packDrawnMap = B.pack
   195 packDrawnMap =
   205     . Base64.encode
   196       Base64.encode
   206     . BW.unpack
       
   207     . BL.toStrict
   197     . BL.toStrict
   208     . compressWithLength
   198     . compressWithLength
   209 
   199 
   210 prependGhostPoints :: [(Int16, Int16)] -> B.ByteString -> B.ByteString
   200 prependGhostPoints :: [(Int16, Int16)] -> B.ByteString -> B.ByteString
   211 prependGhostPoints pts dm = packDrawnMap $ (runPut $ forM_ pts $ \(x, y) -> put x >> put y >> putWord8 99) `BL.append` unpackDrawnMap dm
   201 prependGhostPoints pts dm = packDrawnMap $ (runPut $ forM_ pts $ \(x, y) -> put x >> put y >> putWord8 99) `BL.append` unpackDrawnMap dm