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 |