asyncapi: 3.0.0
info:
  title: Game Server
  version: 0.0.1
  description: |
    This is the Websocket Specification for the Tower Defence Game. <br>
    Because of the limitations of Async API, we expect that the actual json,
    which is send as payload to always contain a field called `$id` with
    the corresponding `messageId`. <br>
    The `messageId` should be handled case sensitive.
defaultContentType: application/json
servers:
  localhost:
    host: localhost:8080
    protocol: ws
    pathname: /ws
    security:
      - $ref: "#/components/securitySchemes/JwtAuth"

channels:
  connection:
    title: Connection
    description: |
      The Base Channel used for:
      - Authentication
      - Receiving Tokens for other channels
      - Reconnection
    messages:
      RequestConnectionToken:
        description: |
          A Message telling the Server, that
          you want an Connection Token for a
          Specific Channel
        payload:
          type: object
          additionalProperties: false
          properties:
            $id:
              type: string
              format: messageId
            channel:
              $ref: "#/components/schemas/Channel"
          required:
            - $id
            - channel
      ProvidedConnectionToken:
        description: |
          A Message telling the Server, that
          you want an Connection Token for a
          Specific Channel
        payload:
          type: object
          additionalProperties: false
          properties:
            $id:
              type: string
              format: messageId
            channel:
              $ref: "#/components/schemas/Channel"
            token:
              $ref: "#/components/schemas/JWT"
          required:
            - $id
            - channel
            - token

  matchmaking:
    title: Matchmaking
    description:  |
      A Channel used to search for a match and
      to receive one
    messages:
      MatchSetSearchState:
        payload:
          type: object
          additionalProperties: false
          properties:
            $id:
              type: string
              format: messageId
            searching:
              type: boolean
          required:
            - $id
            - searching
      MatchFound:
        payload:
          type: object
          additionalProperties: false
          properties:
            $id:
              type: string
              format: messageId
            matchId:
              type: string
            created:
              description: "Unix Timestamp describing when this Match was found"
              type: integer
              format: int64
            ttl:
              description: "Time in Milliseconds, how long this Match is open for accepting"
              type: integer
              format: int64
          required:
            - $id
            - matchId
            - created
            - ttl
      MatchAccepted:
        payload:
          type: object
          additionalProperties: false
          properties:
            $id:
              type: string
              format: messageId
            matchId:
              type: string
            accepted:
              type: boolean
          required:
            - $id
            - matchId
            - accepted
      MatchAborted:
        payload:
          type: object
          additionalProperties: false
          properties:
            $id:
              type: string
              format: messageId
            matchId:
              type: string
          required:
            - $id
            - matchId
      MatchEstablished:
        payload:
          type: object
          additionalProperties: false
          properties:
            $id:
              type: string
              format: messageId
            matchId:
              type: string
            opponentName:
              type: string
          required:
            - $id
            - matchId
            - opponentName

  time:
    title: Time
    description: |
      A Simple example channel for receiving
      the current Unix time
    messages:
      CurrentUnixTime:
        description: The Current time in Unix Time
        payload:
          type: object
          additionalProperties: false
          properties:
            $id:
              type: string
              format: messageId
            time:
              type: integer
              format: int64
          required:
            - $id
            - time

operations:
  requestConnectionToken:
    title: RequestConnectionToken
    action: send
    channel:
      $ref: "#/channels/connection"
    messages:
      - $ref: "#/channels/connection/messages/RequestConnectionToken"
    reply:
      channel:
        $ref: "#/channels/connection"
      messages:
        - $ref: "#/channels/connection/messages/ProvidedConnectionToken"
  searchMatch:
    title: SearchMatch
    action: send
    channel:
      $ref: "#/channels/matchmaking"
    messages:
      - $ref: "#/channels/matchmaking/messages/MatchSetSearchState"
  setPlayerMatchSearching:
    title: SetPlayerMatchSearching
    action: receive
    channel:
      $ref: "#/channels/matchmaking"
    messages:
      - $ref: "#/channels/matchmaking/messages/MatchSetSearchState"
  foundMatch:
    title: FoundGame
    action: receive
    channel:
      $ref: "#/channels/matchmaking"
    messages:
      - $ref: "#/channels/matchmaking/messages/MatchFound"
    reply:
      channel:
        $ref: "#/channels/matchmaking"
      messages:
        - $ref: "#/channels/matchmaking/messages/MatchAccepted"
  abortedMatch:
    title: AbortedMatch
    action: receive
    channel:
      $ref: "#/channels/matchmaking"
    messages:
      - $ref: "#/channels/matchmaking/messages/MatchAborted"
  establishedMatch:
    title: EstablishedMatch
    action: receive
    channel:
      $ref: "#/channels/matchmaking"
    messages:
      - $ref: "#/channels/matchmaking/messages/MatchEstablished"
  updateTime:
    title: Updates of the current Unix Time
    action: receive
    channel:
      $ref: "#/channels/time"
    messages:
      - $ref: "#/channels/time/messages/CurrentUnixTime"

components:
  securitySchemes:
    JwtAuth:
      name: Authorization
      description: |
        A JWT Token has to be provided in the Handshake Header. <br>
        This Field is expected to be called `Authorization`. <br>
        It is expected to not have a prefix like `bearer`.
      type: httpApiKey
      in: header
  schemas:
    JWT:
      type: string
      format: jwt
    Channel:
      type: string
      enum:
        - connection
        - matchmaking
        - time