{-| Module: BattlePlace.WebApi.Types Description: Web API types. License: MIT -} {-# LANGUAGE DeriveGeneric, GeneralizedNewtypeDeriving, LambdaCase, OverloadedStrings, StandaloneDeriving, TemplateHaskell, ViewPatterns #-} module BattlePlace.WebApi.Types ( ProjectId(..) , Auth(..) , AuthType(..) , authTypeOf , Client(..) , ClientType(..) , clientTypeOf , DeveloperId(..) , ProjectServerId(..) , ProjectServerToken(..) , ProjectServerName(..) , MatchTeamSize , MatchTag(..) , ServerTag(..) , MatchPlayerInfo(..) , MatchServerInfo(..) , MatchToken(..) , MatchFailureReason(..) , SessionToken(..) , SessionId(..) , ServerSessionToken(..) , ExternalSessionId(..) , MatchSession(..) , MatchServerSession(..) , MatchTeam(..) , MatchPlayer(..) , MatchServer(..) , UserStats(..) , Identified(..) , Base64ByteString(..) , Base64Word64(..) , StrWord64(..) ) where import qualified Data.Aeson as J import Data.Hashable import Data.Proxy import qualified Data.Swagger as SW import qualified Data.Text as T import qualified Data.Vector as V import GHC.Generics(Generic) import Servant.API import BattlePlace.Rating import BattlePlace.Token.Types import BattlePlace.Util import BattlePlace.WebApi.Types.Util -- | Project id. newtype ProjectId = ProjectId Base64Word64 deriving (Eq, Generic, Hashable, J.FromJSON, J.ToJSON, FromHttpApiData) instance SW.ToSchema ProjectId where declareNamedSchema = SW.genericDeclareNamedSchemaNewtype swaggerSchemaOptions SW.declareSchema data Auth = Auth_itchJwtToken { auth_itchJwtToken :: !T.Text } | Auth_itchApiKey { auth_itchApiKey :: !T.Text } | Auth_steamEncryptedTicket { auth_steamEncryptedTicket :: !T.Text } | Auth_testKey { auth_testKey :: !T.Text , auth_testId :: !StrWord64 } deriving Generic instance J.FromJSON Auth where parseJSON = J.genericParseJSON jsonOptions { J.sumEncoding = J.UntaggedValue } instance J.ToJSON Auth where toJSON = J.genericToJSON jsonOptions { J.sumEncoding = J.UntaggedValue } toEncoding = J.genericToEncoding jsonOptions { J.sumEncoding = J.UntaggedValue } instance SW.ToSchema Auth where declareNamedSchema = SW.genericDeclareNamedSchemaUnrestricted swaggerSchemaOptions -- | Auth type (for logging). data AuthType = AuthType_itchJwtToken | AuthType_itchApiKey | AuthType_steamEncryptedTicket | AuthType_testKey deriving Eq authTypeOf :: Auth -> AuthType authTypeOf = \case Auth_itchJwtToken {} -> AuthType_itchJwtToken Auth_itchApiKey {} -> AuthType_itchApiKey Auth_steamEncryptedTicket {} -> AuthType_steamEncryptedTicket Auth_testKey {} -> AuthType_testKey data Client = Client_itch { client_itchUserId :: {-# UNPACK #-} !StrWord64 } | Client_steam { client_steamId :: {-# UNPACK #-} !StrWord64 } | Client_test { client_testId :: {-# UNPACK #-} !StrWord64 } deriving (Eq, Generic) instance Hashable Client instance J.FromJSON Client where parseJSON = J.genericParseJSON $ jsonOptionsWithTag "type" instance J.ToJSON Client where toJSON = J.genericToJSON $ jsonOptionsWithTag "type" toEncoding = J.genericToEncoding $ jsonOptionsWithTag "type" -- | Type of the client. Must correspont to JSON field "type" of 'Client'. data ClientType = ClientType_itch | ClientType_steam | ClientType_test deriving Eq instance Hashable ClientType clientTypeOf :: Client -> ClientType clientTypeOf = \case Client_itch {} -> ClientType_itch Client_steam {} -> ClientType_steam Client_test {} -> ClientType_test -- | Developer id. -- At the moment it's just itch user id, but that may change. newtype DeveloperId = DeveloperId Base64Word64 deriving (J.FromJSON, J.ToJSON, FromHttpApiData) -- | Project's server id. newtype ProjectServerId = ProjectServerId Base64Word64 deriving (Eq, Hashable, J.FromJSON, J.FromJSONKey, J.ToJSON, J.ToJSONKey) -- | Project's secret server token. newtype ProjectServerToken = ProjectServerToken T.Text deriving (Eq, Generic, Hashable, J.FromJSON, J.ToJSON) instance SW.ToSchema ProjectServerToken where declareNamedSchema = SW.genericDeclareNamedSchemaNewtype swaggerSchemaOptions SW.declareSchema -- | Project's server name. newtype ProjectServerName = ProjectServerName T.Text deriving (Eq, Generic, Hashable, J.FromJSON, J.ToJSON) instance SW.ToSchema ProjectServerName where declareNamedSchema = SW.genericDeclareNamedSchemaNewtype swaggerSchemaOptions SW.declareSchema -- | Size of a team in match request. type MatchTeamSize = Int -- | Match tag in match request. newtype MatchTag = MatchTag T.Text deriving (Eq, Generic, Hashable, Semigroup, Monoid, J.FromJSON, J.ToJSON) instance SW.ToSchema MatchTag where declareNamedSchema = SW.genericDeclareNamedSchemaNewtype swaggerSchemaOptions SW.declareSchema -- | Server tag in match request. newtype ServerTag = ServerTag T.Text deriving (Eq, Generic, Hashable, Semigroup, Monoid, J.FromJSON, J.ToJSON) instance SW.ToSchema ServerTag where declareNamedSchema = SW.genericDeclareNamedSchemaNewtype swaggerSchemaOptions SW.declareSchema -- | Opaque player info. newtype MatchPlayerInfo = MatchPlayerInfo J.Value deriving (Generic, J.FromJSON, J.ToJSON) instance SW.ToSchema MatchPlayerInfo where declareNamedSchema = SW.genericDeclareNamedSchemaNewtype swaggerSchemaOptions $ \_ -> SW.declareSchema (Proxy :: Proxy J.Object) -- | Opaque server info. newtype MatchServerInfo = MatchServerInfo J.Value deriving (Generic, J.FromJSON, J.ToJSON) instance SW.ToSchema MatchServerInfo where declareNamedSchema = SW.genericDeclareNamedSchemaNewtype swaggerSchemaOptions $ \_ -> SW.declareSchema (Proxy :: Proxy J.Object) -- | Match token. data MatchToken = MatchToken { } -- | Reason of match failure. data MatchFailureReason -- | Failed to make a match in a specified time. = MatchFailureReason_timedOut -- | Match was made, but no server is available (and use of server is mandatory). | MatchFailureReason_noServer -- | Matching was explicitly cancelled by user. | MatchFailureReason_cancelled -- | Session token. data SessionToken = SessionToken { sessionToken_sessionId :: !SessionId , sessionToken_teamIndex :: {-# UNPACK #-} !Int , sessionToken_mateIndex :: {-# UNPACK #-} !Int } -- | Session id. newtype SessionId = SessionId Base64ByteString deriving (Eq, Generic, Hashable, J.FromJSON, J.ToJSON) instance SW.ToSchema SessionId where declareNamedSchema = SW.genericDeclareNamedSchemaNewtype swaggerSchemaOptions SW.declareSchema -- | Server session token. newtype ServerSessionToken = ServerSessionToken { serverSessionToken_sessionId :: SessionId } -- | External session token for exposure to clients and servers. newtype ExternalSessionId = ExternalSessionId T.Text deriving (Eq, Generic, Hashable, J.FromJSON, J.ToJSON) instance SW.ToSchema ExternalSessionId where declareNamedSchema = SW.genericDeclareNamedSchemaNewtype swaggerSchemaOptions SW.declareSchema -- | Match player. data MatchPlayer = MatchPlayer { matchPlayer_info :: !MatchPlayerInfo , matchPlayer_ourTicket :: !(Maybe Ticket) , matchPlayer_theirTicket :: !(Maybe Ticket) } -- | Match server. data MatchServer = MatchServer { matchServer_info :: !MatchServerInfo , matchServer_ourTicket :: !Ticket , matchServer_theirTicket :: !Ticket } declareStruct [ ''AuthType , ''ClientType , ''MatchToken , ''MatchFailureReason , ''SessionToken , ''ServerSessionToken , ''MatchPlayer , ''MatchServer ] instance Hashable AuthType -- | Match session. data MatchSession = MatchSession { matchSession_externalSessionId :: !ExternalSessionId , matchSession_sessionToken :: !(InternalToken SessionToken) , matchSession_teams :: !(V.Vector MatchTeam) , matchSession_teamIndex :: {-# UNPACK #-} !Int , matchSession_mateIndex :: {-# UNPACK #-} !Int , matchSession_server :: !(Maybe MatchServer) } -- | Match server session. data MatchServerSession = MatchServerSession { matchServerSession_externalSessionId :: !ExternalSessionId , matchServerSession_serverSessionToken :: !(InternalToken ServerSessionToken) , matchServerSession_teams :: !(V.Vector MatchTeam) , matchServerSession_matchTag :: !MatchTag , matchServerSession_serverTag :: !ServerTag } -- | Match team. newtype MatchTeam = MatchTeam (V.Vector MatchPlayer) deriving (Generic, J.FromJSON, J.ToJSON) instance SW.ToSchema MatchTeam where declareNamedSchema = SW.genericDeclareNamedSchemaNewtype swaggerSchemaOptions SW.declareSchema -- | User stats. data UserStats = UserStats { userStats_rank :: {-# UNPACK #-} !Int , userStats_rating :: {-# UNPACK #-} !Rating } -- | Generic data type for id + object. data Identified i a = Identified { identified_id :: !i , identified_info :: !a } deriving Generic instance (J.FromJSON i, J.FromJSON a) => J.FromJSON (Identified i a) where parseJSON = J.genericParseJSON jsonOptions instance (J.ToJSON i, J.ToJSON a) => J.ToJSON (Identified i a) where toJSON = J.genericToJSON jsonOptions toEncoding = J.genericToEncoding jsonOptions instance (SW.ToSchema i, SW.ToSchema a) => SW.ToSchema (Identified i a) declareStruct [ ''MatchSession , ''MatchServerSession , ''UserStats ]