Compare commits

...

2 Commits

4 changed files with 370 additions and 89 deletions

View File

@ -1,7 +1,7 @@
# Maintainer: Zergling_man, from fedora.email # Maintainer: Zergling_man, from fedora.email
pkgname=swat-codegen pkgname=swat-codegen
pkgver=1.0.10 pkgver=1.1.1
pkgrel=1 pkgrel=1
pkgdesc="A simple CLI interface to RCPDv3, the rank code management service for the game SWAT: Aftermath" pkgdesc="A simple CLI interface to RCPDv3, the rank code management service for the game SWAT: Aftermath"
arch=('any') arch=('any')

View File

@ -2,18 +2,21 @@
loc=$(dirname $(readlink -f "$0")) loc=$(dirname $(readlink -f "$0"))
account_server_root_url=https://swataftermath.com:8443
code_server_root_url=https://swataftermath.com:9443/account
# TOKEN MANAGEMENT # TOKEN MANAGEMENT
function migrate function migrate
{ {
curl "https://swataftermath.com:8443/account/$1/activate-migrated" --json '{"currentPassword":"'"$3"'","emailAddress":"'"$2"'","newPassword":"'"$3"'"}' curl "$account_server_root_url/account/$1/activate-migrated" --json '{"currentPassword":"'"$3"'","emailAddress":"'"$2"'","newPassword":"'"$3"'"}'
curl "https://swataftermath.com:8443/account/$1/verify-email" --json '{"verificationCode":"'"$(cat)"'"}' curl "$account_server_root_url/account/$1/verify-email" --json '{"verificationCode":"'"$(cat)"'"}'
login "$1" "$3" login "$1" "$3"
} }
function login function login
{ {
[ -n "$2" ] || { echo "Please provide a username and password, in that order, when calling this"; exit; } [ -n "$2" ] || { echo "Please provide a username and password, in that order, when calling this"; exit; }
curl https://swataftermath.com:8443/login --json '{"username":"'"$1"'","password":"'"$2"'"}' > ~/.config/rcpd.cfg curl $account_server_root_url/login --json '{"username":"'"$1"'","password":"'"$2"'"}' > ~/.config/rcpd.cfg
} }
function get_token function get_token
@ -25,19 +28,19 @@ function get_token
function get function get
{ {
TOKE=`get_token` TOKE=`get_token`
curl -H "Authorization:Bearer $TOKE" https://swataftermath.com:9443/account/$1 curl -H "Authorization:Bearer $TOKE" $code_server_root_url/$1
} }
function post function post
{ {
TOKE=`get_token` TOKE=`get_token`
curl -H "Authorization:Bearer $TOKE" https://swataftermath.com:9443/account/$1 --json "$2" curl -$3H "Authorization:Bearer $TOKE" $code_server_root_url/$1 --json "$2"
} }
function delete_code function delete_code
{ {
TOKE=`get_token` TOKE=`get_token`
curl -H "Authorization:Bearer $TOKE" https://swataftermath.com:9443/account/rank-code/$1 -X DELETE curl -H "Authorization:Bearer $TOKE" $code_server_root_url/rank-code/$1 -X DELETE
} }
# UTILS # UTILS
@ -58,16 +61,19 @@ function lookup
# USER-FACING COMMANDS # USER-FACING COMMANDS
function builds function builds
{ {
filter='.[] | .rankCode+" "+.buildName'
if [ -n "$1" ]; then filter='.[] | select(.buildName=="'"$*"'")'; fi if [ -n "$1" ]; then filter='.[] | select(.buildName=="'"$*"'")'; fi
get saved-builds | jq $filter get saved-builds | jq "$filter"
} }
function save function save
{ {
if [ -n "$2" ]; then name=',"buildName":"'"${*:2}"'"'; fi if [ -n "$2" ]; then name=',"buildName":"'"${*:2}"'"'; fi
res=`post rank-code '{"rankCode":"'$1'"'"$name"'}'` res=`post rank-code '{"rankCode":"'$1'"'"$name"'}' i`
created=`head -n 1 <<< "$res" | cut -d' ' -f2`
res=`tr -d '\r' <<< "$res" | awk -F '\r\n' 'BEGIN { a=1 } a==0 { print } $0=="" { a=0 }'`
jq <<< "$res" jq <<< "$res"
if [ -z "`jq -r '.[0].buildName // ""' <<< "$res"`" ]; then delete_code $1; fi # Don't bother storing any build that doesn't have a name. Assume it's just logging the results of a game. if [ $created = 201 -a -z "$2" ]; then delete_code $1; fi # Don't bother storing any build that doesn't have a name if it didn't already exist. Assume it's just logging the results of a game.
} }
function generate function generate

View File

@ -3,7 +3,7 @@
"info" : { "info" : {
"title" : "SWAT Account Service API", "title" : "SWAT Account Service API",
"description" : "API for the SWAT Account Service that allows creation, management, and authentication of SWAT accounts. A SWAT account can be used to access SWAT services, such as RCPD 3.0 (rcpd-service) and map marker. Accounts in RCPD 2.0 have been migrated to SWAT accounts with the same username and password.", "description" : "API for the SWAT Account Service that allows creation, management, and authentication of SWAT accounts. A SWAT account can be used to access SWAT services, such as RCPD 3.0 (rcpd-service) and map marker. Accounts in RCPD 2.0 have been migrated to SWAT accounts with the same username and password.",
"version" : "0.14.0" "version" : "0.14.1"
}, },
"externalDocs" : { "externalDocs" : {
"url" : "/" "url" : "/"
@ -417,7 +417,7 @@
}, },
"responses" : { "responses" : {
"200" : { "200" : {
"description" : "Successfully logged in.", "description" : "Generated JWT returned. Tokens expire 2 hours after creation.",
"headers" : { }, "headers" : { },
"content" : { "content" : {
"application/json" : { "application/json" : {

View File

@ -3,7 +3,7 @@ info:
title: SWAT Aftermath - RCPD Service title: SWAT Aftermath - RCPD Service
description: "Rank code manager service for storing rank codes, generating rank\ description: "Rank code manager service for storing rank codes, generating rank\
\ codes, earning titles, etc. The back end for RPCD 3.0" \ codes, earning titles, etc. The back end for RPCD 3.0"
version: 0.24.3 version: 0.28.0
servers: servers:
- url: https://swataftermath.com:9443/ - url: https://swataftermath.com:9443/
tags: tags:
@ -13,6 +13,8 @@ tags:
description: Resource for retrieving multiple accounts. description: Resource for retrieving multiple accounts.
- name: Rank Code Resource - name: Rank Code Resource
description: Resource for saving and retrieving rank codes and builds. description: Resource for saving and retrieving rank codes and builds.
- name: Statistics Resource
description: Resource for retrieving various statistics about your account
- name: Unlocks Resource - name: Unlocks Resource
description: Resource for retrieving the maximum rank unlocked for each SWAT build description: Resource for retrieving the maximum rank unlocked for each SWAT build
element. element.
@ -260,6 +262,125 @@ paths:
$ref: "#/components/schemas/ErrorResponse" $ref: "#/components/schemas/ErrorResponse"
security: security:
- SWAT-Token: [] - SWAT-Token: []
/account/join-honor-guard:
post:
tags:
- Account Resource
summary: Make default account join honor guard.
description: "Make the default RCPD account for this user join the honor guard.\
\ This will reset all RCPD unlock progress and delete all saved builds, but\
\ will allow you to earn medals and titles on unique hero combinations (class,\
\ trait, specialization), and earn account-level titles."
operationId: joinHonorGuard
responses:
"500":
description: Something went wrong when processing the request.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"502":
description: A dependent service or database had an error.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"204":
description: Default account successfully joined the honor guard.
"400":
description: Default account is already an honor guard account.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"401":
description: "Authorization header is not present, or token is invalid or\
\ expired."
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"503":
description: The security infrastructure cannot currently handle the request.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"404":
description: The requested resource could not be found.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
security:
- SWAT-Token: []
/account/{username}/join-honor-guard:
post:
tags:
- Account Resource
summary: Make account join honor guard.
description: "Make the specified RCPD account for this user join the honor guard.\
\ This will reset all RCPD unlock progress and delete all saved builds, but\
\ will allow you to earn medals and titles on unique hero combinations (class,\
\ trait, specialization), and earn account-level titles."
operationId: joinHonorGuard_1
parameters:
- name: username
in: path
description: The username of the RCPD account that should join the honor guard.
The username is case sensitive.
required: true
schema:
type: string
example: teller55
responses:
"500":
description: Something went wrong when processing the request.
content:
'*/*':
schema:
$ref: "#/components/schemas/ErrorResponse"
"502":
description: A dependent service or database had an error.
content:
'*/*':
schema:
$ref: "#/components/schemas/ErrorResponse"
"204":
description: Account successfully joined the honor guard.
"400":
description: Account is already an honor guard account.
content:
'*/*':
schema:
$ref: "#/components/schemas/ErrorResponse"
"401":
description: "Authorization header is not present, or token is invalid or\
\ expired."
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"503":
description: The security infrastructure cannot currently handle the request.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"403":
description: You are not allowed to perform the requested action.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"404":
description: The requested resource could not be found.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
security:
- SWAT-Token: []
/account/{username}/set-default: /account/{username}/set-default:
post: post:
tags: tags:
@ -378,7 +499,7 @@ paths:
schema: schema:
type: array type: array
items: items:
$ref: "#/components/schemas/AccountSummaryResponse" $ref: "#/components/schemas/AccountResponse"
"401": "401":
description: "Authorization header is not present, or token is invalid or\ description: "Authorization header is not present, or token is invalid or\
\ expired." \ expired."
@ -429,7 +550,7 @@ paths:
schema: schema:
type: array type: array
items: items:
$ref: "#/components/schemas/AccountSummaryResponse" $ref: "#/components/schemas/AccountResponse"
/accounts/search: /accounts/search:
get: get:
tags: tags:
@ -468,7 +589,7 @@ paths:
schema: schema:
type: array type: array
items: items:
$ref: "#/components/schemas/AccountSummaryResponse" $ref: "#/components/schemas/AccountResponse"
"400": "400":
description: Username to search for was not provided. Includes if the provided description: Username to search for was not provided. Includes if the provided
query param is blank. query param is blank.
@ -642,6 +763,13 @@ paths:
application/json: application/json:
schema: schema:
$ref: "#/components/schemas/HeroBuildResponse" $ref: "#/components/schemas/HeroBuildResponse"
"400":
description: One or more of the requested build parts has not been unlocked
to at least rank 1.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"401": "401":
description: "Authorization header is not present, or token is invalid or\ description: "Authorization header is not present, or token is invalid or\
\ expired." \ expired."
@ -705,6 +833,13 @@ paths:
application/json: application/json:
schema: schema:
$ref: "#/components/schemas/HeroBuildResponse" $ref: "#/components/schemas/HeroBuildResponse"
"400":
description: One or more of the requested build parts has not been unlocked
to at least rank 1.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"401": "401":
description: "Authorization header is not present, or token is invalid or\ description: "Authorization header is not present, or token is invalid or\
\ expired." \ expired."
@ -870,11 +1005,27 @@ paths:
schema: schema:
$ref: "#/components/schemas/ErrorResponse" $ref: "#/components/schemas/ErrorResponse"
"200": "200":
description: "The saved build, plus any other saved builds that have had\ description: "The updated saved build, plus any other saved builds that\
\ medals or titles updated as a result of the new build being saved. If\ \ have had medals or titles updated as a result of the new build being\
\ the build that was saved had earned any medals or titles, then all saved\ \ saved. If the build that was saved had earned any medals or titles,\
\ builds with the same class/trait/specialization combination will be\ \ then all saved builds with the same class/trait/specialization combination\
\ updated and returned. This avoids the scenario of earning a medal/title\ \ will be updated and returned. This avoids the scenario of earning a\
\ medal/title on one build, and then earning the same medal/title on another\
\ build with the same class/trait/specialization combination which shares\
\ the new medal/title."
content:
application/json:
schema:
minItems: 1
type: array
items:
$ref: "#/components/schemas/HeroBuildResponse"
"201":
description: "The newly saved build, plus any other saved builds that have\
\ had medals or titles updated as a result of the new build being saved.\
\ If the build that was saved had earned any medals or titles, then all\
\ saved builds with the same class/trait/specialization combination will\
\ be updated and returned. This avoids the scenario of earning a medal/title\
\ on one build, and then earning the same medal/title on another build\ \ on one build, and then earning the same medal/title on another build\
\ with the same class/trait/specialization combination which shares the\ \ with the same class/trait/specialization combination which shares the\
\ new medal/title." \ new medal/title."
@ -956,11 +1107,27 @@ paths:
schema: schema:
$ref: "#/components/schemas/ErrorResponse" $ref: "#/components/schemas/ErrorResponse"
"200": "200":
description: "The saved build, plus any other saved builds that have had\ description: "The updated saved build, plus any other saved builds that\
\ medals or titles updated as a result of the new build being saved. If\ \ have had medals or titles updated as a result of the new build being\
\ the build that was saved had earned any medals or titles, then all saved\ \ saved. If the build that was saved had earned any medals or titles,\
\ builds with the same class/trait/specialization combination will be\ \ then all saved builds with the same class/trait/specialization combination\
\ updated and returned. This avoids the scenario of earning a medal/title\ \ will be updated and returned. This avoids the scenario of earning a\
\ medal/title on one build, and then earning the same medal/title on another\
\ build with the same class/trait/specialization combination which shares\
\ the new medal/title."
content:
application/json:
schema:
minItems: 1
type: array
items:
$ref: "#/components/schemas/HeroBuildResponse"
"201":
description: "The newly saved build, plus any other saved builds that have\
\ had medals or titles updated as a result of the new build being saved.\
\ If the build that was saved had earned any medals or titles, then all\
\ saved builds with the same class/trait/specialization combination will\
\ be updated and returned. This avoids the scenario of earning a medal/title\
\ on one build, and then earning the same medal/title on another build\ \ on one build, and then earning the same medal/title on another build\
\ with the same class/trait/specialization combination which shares the\ \ with the same class/trait/specialization combination which shares the\
\ new medal/title." \ new medal/title."
@ -1010,6 +1177,117 @@ paths:
$ref: "#/components/schemas/ErrorResponse" $ref: "#/components/schemas/ErrorResponse"
security: security:
- SWAT-Token: [] - SWAT-Token: []
/account/medals-and-titles:
get:
tags:
- Statistics Resource
description: Get the total number of medals and titles you have earned on your
unique combinations for your default RCPD account.
operationId: getDefaultStatistics
responses:
"500":
description: Something went wrong when processing the request.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"502":
description: A dependent service or database had an error.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"200":
description: The total number of medals and titles earned for your default
RCPD account.
content:
application/json:
schema:
$ref: "#/components/schemas/Account Statistics Response"
"401":
description: "Authorization header is not present, or token is invalid or\
\ expired."
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"503":
description: The security infrastructure cannot currently handle the request.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"404":
description: The requested resource could not be found.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
security:
- SWAT-Token: []
/account/{username}/medals-and-titles:
get:
tags:
- Statistics Resource
description: Get the total number of medals and titles you have earned on your
unique combinations for your specified RCPD account.
operationId: getStatistics
parameters:
- name: username
in: path
description: The username of the RCPD account you wish to retrieve the medals
and titles for. The username is case sensitive.
required: true
schema:
type: string
example: teller55
responses:
"500":
description: Something went wrong when processing the request.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"502":
description: A dependent service or database had an error.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"200":
description: The total number of medals and titles earned for your specified
RCPD account.
content:
application/json:
schema:
$ref: "#/components/schemas/Account Statistics Response"
"401":
description: "Authorization header is not present, or token is invalid or\
\ expired."
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"503":
description: The security infrastructure cannot currently handle the request.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"403":
description: You are not allowed to perform the requested action.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"404":
description: The requested resource could not be found.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
security:
- SWAT-Token: []
/account/unlocks: /account/unlocks:
get: get:
tags: tags:
@ -1182,6 +1460,15 @@ paths:
application/json: application/json:
schema: schema:
$ref: "#/components/schemas/ErrorResponse" $ref: "#/components/schemas/ErrorResponse"
/openapi:
get:
tags:
- Open API Resource
description: Default endpoint to redirect to index.html page.
operationId: getIndex
responses:
"303":
description: Redirect to index page.
components: components:
schemas: schemas:
ErrorResponse: ErrorResponse:
@ -1242,7 +1529,8 @@ components:
example: 1 example: 1
points: points:
type: integer type: integer
description: The amount of points this account has earned through titles. description: The amount of points this account has earned through medals
and titles.
format: int64 format: int64
example: 100 example: 100
leaderboardRanking: leaderboardRanking:
@ -1264,16 +1552,16 @@ components:
description: "Whether this account has used a code generator to save generated\ description: "Whether this account has used a code generator to save generated\
\ rank codes, rather than earning codes solely through playing SWAT: Aftermath." \ rank codes, rather than earning codes solely through playing SWAT: Aftermath."
example: false example: false
active:
type: boolean
description: Whether this account has been logged into or done anything
recently.
lastActive: lastActive:
type: integer type: integer
description: "The last time this account was active (logged in to, saved\ description: "The last time this account was active (logged in to, saved\
\ a build, generated a build, etc.) represented as milliseconds from epoch." \ a build, generated a build, etc.) represented as milliseconds from epoch."
format: int64 format: int64
example: 1695474479000 example: 1695474479000
active:
type: boolean
description: Whether this account has been logged into or done anything
recently.
description: A response containing information about an RCPD account. description: A response containing information about an RCPD account.
AccountTitlesResponse: AccountTitlesResponse:
title: Account Titles Response title: Account Titles Response
@ -1524,57 +1812,6 @@ components:
description: "A request to update various things on an account. All parameters\ description: "A request to update various things on an account. All parameters\
\ are optional. To delete a value, provide an empty string. This will delete\ \ are optional. To delete a value, provide an empty string. This will delete\
\ the value in the database." \ the value in the database."
AccountSummaryResponse:
type: object
properties:
username:
type: string
description: The username of this RCPD account.
example: Teller55
icon:
type: integer
description: An integer representing the icon (display picture) for the
account.
format: int32
example: 0
description:
type: string
description: A public message for the account that will be displayed on
the leaderboard and to people viewing the account.
nullable: true
example: Swat season 2 lets go!
squad:
type: string
description: The group/clan this account belongs to.
nullable: true
example: XLR8
rank:
maximum: 11
minimum: 1
type: integer
description: The account rank as an integer.
format: int32
example: 1
corrupt:
type: boolean
description: "Whether this account has used a code generator to save generated\
\ rank codes, rather than earning codes solely through playing SWAT: Aftermath."
example: false
active:
type: boolean
description: Whether this account has been logged into or done anything
recently.
lastActive:
type: integer
description: "The last time this account was active (logged in to, saved\
\ a build, generated a build, etc.) represented as milliseconds from epoch."
format: int64
example: 1695474479000
honorGuard:
type: boolean
description: Whether this account has joined the honor guard.
example: true
description: An RCPD account summary.
HeroBuildResponse: HeroBuildResponse:
title: Hero Build Response title: Hero Build Response
type: object type: object
@ -1751,13 +1988,6 @@ components:
\ and build name." \ and build name."
BuildRequest: BuildRequest:
title: Build Request title: Build Request
required:
- armor
- gun
- specialization
- swatClass
- talent
- trait
type: object type: object
properties: properties:
swatClass: swatClass:
@ -1892,6 +2122,51 @@ components:
description: An optional name for this build. description: An optional name for this build.
example: Solo HO example: Solo HO
description: A rank code and optional build name to save. description: A rank code and optional build name to save.
Account Statistics Response:
type: object
properties:
totalKeys:
type: integer
format: int32
totalMohs:
type: integer
format: int32
totalPccs:
type: integer
format: int32
totalCobs:
type: integer
format: int32
totalLsas:
type: integer
format: int32
totalRem1s:
type: integer
format: int32
totalRem2s:
type: integer
format: int32
totalRem3s:
type: integer
format: int32
totalNightmares:
type: integer
format: int32
totalExtinctions:
type: integer
format: int32
totalMegazillas:
type: integer
format: int32
totalDeathless:
type: integer
format: int32
totalImpressives:
type: integer
format: int32
totalSolos:
type: integer
format: int32
UnlocksResponse: UnlocksResponse:
title: Unlocks Response title: Unlocks Response
type: object type: object