module Octane.Type.RemoteId
( RemoteId(..)
, SteamId(..)
, PlayStationId(..)
, SplitscreenId(..)
, XboxId(..)
) where
import Data.Aeson ((.=))
import Data.Function ((&))
import qualified Control.DeepSeq as DeepSeq
import qualified Data.Aeson as Aeson
import qualified Data.Binary.Bits as BinaryBit
import qualified Data.Binary.Bits.Get as BinaryBit
import qualified Data.Binary.Bits.Put as BinaryBit
import qualified Data.ByteString.Lazy as LazyBytes
import qualified Data.Text as StrictText
import qualified Data.Text.Encoding as Encoding
import qualified GHC.Generics as Generics
import qualified Octane.Type.Text as Text
import qualified Octane.Type.Word64 as Word64
import qualified Octane.Utility.Endian as Endian
import qualified Text.Printf as Printf
data RemoteId
= RemotePlayStationId PlayStationId
| RemoteSplitscreenId SplitscreenId
| RemoteSteamId SteamId
| RemoteXboxId XboxId
deriving (Eq, Generics.Generic, Show)
instance DeepSeq.NFData RemoteId where
instance Aeson.ToJSON RemoteId where
toJSON remoteId = case remoteId of
RemotePlayStationId x -> Aeson.object
[ "Type" .= ("PlayStation" :: Text.Text)
, "Value" .= Aeson.toJSON x
]
RemoteSplitscreenId x -> Aeson.object
[ "Type" .= ("Splitscreen" :: Text.Text)
, "Value" .= Aeson.toJSON x
]
RemoteSteamId x -> Aeson.object
[ "Type" .= ("Steam" :: Text.Text)
, "Value" .= Aeson.toJSON x
]
RemoteXboxId x -> Aeson.object
[ "Type" .= ("Xbox" :: Text.Text)
, "Value" .= Aeson.toJSON x
]
data PlayStationId = PlayStationId
{ playStationName :: Text.Text
, playStationUnknown :: LazyBytes.ByteString
} deriving (Eq, Generics.Generic, Show)
instance BinaryBit.BinaryBit PlayStationId where
getBits _ = do
nameBytes <- BinaryBit.getByteString 16
let name = nameBytes
& Endian.reverseBitsInStrictBytes
& Encoding.decodeLatin1
& StrictText.dropWhileEnd (== '\0')
& Text.Text
unknownBytes <- BinaryBit.getByteString 16
let unknown = unknownBytes
& Endian.reverseBitsInStrictBytes
& LazyBytes.fromStrict
pure (PlayStationId name unknown)
putBits _ playStationId = do
playStationId
& playStationName
& Text.unpack
& StrictText.justifyLeft 16 '\x00'
& StrictText.take 16
& Text.encodeLatin1
& Endian.reverseBitsInStrictBytes
& BinaryBit.putByteString
playStationId
& playStationUnknown
& LazyBytes.toStrict
& Endian.reverseBitsInStrictBytes
& BinaryBit.putByteString
instance DeepSeq.NFData PlayStationId where
instance Aeson.ToJSON PlayStationId where
toJSON playStationId = Aeson.object
[ "Name" .= playStationName playStationId
, "Unknown" .= (playStationId
& playStationUnknown
& LazyBytes.unpack
& concatMap (Printf.printf "%02x")
& ("0x" ++)
& StrictText.pack)
]
newtype SplitscreenId = SplitscreenId
{ unpackSplitscreenId :: Maybe Int
} deriving (Eq, Generics.Generic, Show)
instance BinaryBit.BinaryBit SplitscreenId where
getBits _ = do
bytes <- BinaryBit.getByteString 3
case bytes of
"\x00\x00\x00" -> do
pure (SplitscreenId (Just 0))
_ -> do
fail ("Unexpected SplitscreenId value " ++ show bytes)
putBits _ _splitscreenId = do
BinaryBit.putByteString "\x00\x00\x00"
instance DeepSeq.NFData SplitscreenId where
instance Aeson.ToJSON SplitscreenId where
toJSON splitscreenId = splitscreenId & unpackSplitscreenId & Aeson.toJSON
newtype SteamId = SteamId
{ unpackSteamId :: Word64.Word64
} deriving (Eq, Generics.Generic, Show)
instance BinaryBit.BinaryBit SteamId where
getBits _ = do
steamId <- BinaryBit.getBits 0
pure (SteamId steamId)
putBits _ steamId = steamId & unpackSteamId & BinaryBit.putBits 0
instance DeepSeq.NFData SteamId where
instance Aeson.ToJSON SteamId where
toJSON steamId = steamId & unpackSteamId & Aeson.toJSON
newtype XboxId = XboxId
{ unpackXboxId :: Word64.Word64
} deriving (Eq, Generics.Generic, Show)
instance BinaryBit.BinaryBit XboxId where
getBits _ = do
xboxId <- BinaryBit.getBits 0
pure (XboxId xboxId)
putBits _ xboxId = xboxId & unpackXboxId & BinaryBit.putBits 0
instance DeepSeq.NFData XboxId where
instance Aeson.ToJSON XboxId where
toJSON xboxId = xboxId & unpackXboxId & Aeson.toJSON