initial commit
This commit is contained in:
commit
cd137e4b1a
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# environment variables are saved in here
|
||||||
|
setenv.sh
|
72
accounts/accounts.go
Normal file
72
accounts/accounts.go
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
// Package accounts holds functions that interact with the accounts
|
||||||
|
package accounts
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"regexp"
|
||||||
|
|
||||||
|
"git.stinnesbeck.com/nils/artifacts/api"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Account is a struct that holds info on an account
|
||||||
|
type Account struct {
|
||||||
|
Username string `json:"username"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
Email string `json:"email"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// custom Error codes
|
||||||
|
var (
|
||||||
|
ErrUsernameTooShort = errors.New("username is too short, it needs to be at least 6 chars long")
|
||||||
|
ErrUsernameTooLong = errors.New("username is too long, it needs to be at max 32 chars long")
|
||||||
|
ErrUsernameRegex = errors.New(`username must pass this regex: ^[a-zA-Z0-9_-]+$`)
|
||||||
|
ErrPasswordTooShort = errors.New("password is too short, it needs to be at least 5 chars long")
|
||||||
|
ErrPasswordTooLong = errors.New("password is too long, it needs to be at max 50 chars long")
|
||||||
|
ErrPasswordRegex = errors.New(`password must pass this regex: ^[^\s]+$`)
|
||||||
|
)
|
||||||
|
|
||||||
|
// Create can be used to create an account
|
||||||
|
func Create(username, password, email string) error {
|
||||||
|
// >= 6 characters<= 32 characters
|
||||||
|
userRegex := regexp.MustCompile(`^[a-zA-Z0-9_-]+$`)
|
||||||
|
passRegex := regexp.MustCompile(`^[^\s]+$`)
|
||||||
|
|
||||||
|
// username checks
|
||||||
|
switch {
|
||||||
|
case len(username) < 6:
|
||||||
|
return ErrUsernameTooShort
|
||||||
|
case len(username) > 32:
|
||||||
|
return ErrUsernameTooLong
|
||||||
|
case !userRegex.MatchString(username):
|
||||||
|
return ErrUsernameRegex
|
||||||
|
}
|
||||||
|
|
||||||
|
// password checks
|
||||||
|
switch {
|
||||||
|
case len(password) < 5:
|
||||||
|
return ErrPasswordTooShort
|
||||||
|
case len(password) > 50:
|
||||||
|
return ErrPasswordTooLong
|
||||||
|
case !passRegex.MatchString(password):
|
||||||
|
return ErrPasswordRegex
|
||||||
|
}
|
||||||
|
|
||||||
|
// these are the possible response codes, other than 200 OK
|
||||||
|
responseCodes := map[int]string{
|
||||||
|
456: "Username already used.",
|
||||||
|
457: "Email already used.",
|
||||||
|
}
|
||||||
|
|
||||||
|
newAccount := Account{
|
||||||
|
Username: username,
|
||||||
|
Password: password,
|
||||||
|
Email: email,
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := api.Post[string]("/accounts/create", newAccount, responseCodes)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
175
api/api.go
Normal file
175
api/api.go
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
// Package api holds functions to interact with the artifacts API
|
||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"os"
|
||||||
|
"slices"
|
||||||
|
)
|
||||||
|
|
||||||
|
// custom error codes
|
||||||
|
var (
|
||||||
|
ErrTokenNotProvided = errors.New("make sure to provide a token via the api.SetToken() function, or set it via env variable ARTIFACTS_TOKEN")
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
baseURL = "https://api.artifactsmmo.com"
|
||||||
|
)
|
||||||
|
|
||||||
|
var token string // the token must be provided for the client to work
|
||||||
|
|
||||||
|
type apiResponse struct {
|
||||||
|
Data json.RawMessage `json:"data"`
|
||||||
|
Total int `json:"total"`
|
||||||
|
Page int `json:"page"`
|
||||||
|
Size int `json:"size"`
|
||||||
|
Pages int `json:"pages"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetToken can be used to set the token, which must be provided before calling any other function.
|
||||||
|
// It can be provided using this function or via environment variable 'ARTIFACTS_TOKEN'.
|
||||||
|
func SetToken(t string) {
|
||||||
|
token = t
|
||||||
|
}
|
||||||
|
|
||||||
|
func meta[T any](endpoint string, method string, body any, responseCodes map[int]string) (*T, error) {
|
||||||
|
// make it possible to set a token via env variable
|
||||||
|
if token == "" && os.Getenv("ARTIFACTS_TOKEN") != "" {
|
||||||
|
SetToken(os.Getenv("ARTIFACTS_TOKEN"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for token
|
||||||
|
if token == "" {
|
||||||
|
return nil, ErrTokenNotProvided
|
||||||
|
}
|
||||||
|
|
||||||
|
bodyBytes, err := json.Marshal(body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a new request to retrieve characters
|
||||||
|
request, err := http.NewRequest(method, baseURL+endpoint, bytes.NewReader(bodyBytes))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// add auth header to the request
|
||||||
|
request.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token))
|
||||||
|
request.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
// execute this request
|
||||||
|
response, err := http.DefaultClient.Do(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// check all additional status codes first
|
||||||
|
for code, message := range responseCodes {
|
||||||
|
if response.StatusCode != code {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// exit the function if a statuscode was found and return it's message
|
||||||
|
return nil, fmt.Errorf("%d: %s", code, message)
|
||||||
|
}
|
||||||
|
|
||||||
|
// basic error handling
|
||||||
|
if response.StatusCode != 200 {
|
||||||
|
return nil, fmt.Errorf("%s", response.Status)
|
||||||
|
}
|
||||||
|
|
||||||
|
// read in the body of the response
|
||||||
|
b, err := io.ReadAll(response.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// close the body when we are finished
|
||||||
|
defer response.Body.Close()
|
||||||
|
|
||||||
|
// convert it to a native go type
|
||||||
|
var ar apiResponse
|
||||||
|
if err := json.Unmarshal(b, &ar); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if ar.Page < ar.Pages {
|
||||||
|
// parse endpoint
|
||||||
|
u, err := url.Parse(endpoint)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
urlValues := u.Query()
|
||||||
|
urlValues.Set("page", fmt.Sprintf("%d", ar.Page+1))
|
||||||
|
endpoint = u.Path
|
||||||
|
|
||||||
|
nextPage, err := meta[T](fmt.Sprintf("%s?%s", endpoint, urlValues.Encode()), method, body, responseCodes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
b1, err := ar.Data.MarshalJSON()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
b2, err := json.Marshal(nextPage)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
bCombined := slices.Concat(b1[0:len(b1)-1], []byte(","), b2[1:])
|
||||||
|
|
||||||
|
// copy combined dataset into ar.Data
|
||||||
|
ar.Data.UnmarshalJSON(bCombined)
|
||||||
|
|
||||||
|
// combine both things
|
||||||
|
}
|
||||||
|
|
||||||
|
d, err := ar.Data.MarshalJSON()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// no error occurred
|
||||||
|
var r T
|
||||||
|
if err := json.Unmarshal(d, &r); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &r, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Post is used to call an endpoint using a POST request, responseCodes contains all possible
|
||||||
|
// error codes that the API can respond with other than 200 OK
|
||||||
|
func Post[T any](endpoint string, body any, responseCodes map[int]string) (output T, err error) {
|
||||||
|
// use meta function to get a response
|
||||||
|
response, err := meta[T](endpoint, http.MethodPost, body, responseCodes)
|
||||||
|
if err != nil {
|
||||||
|
return output, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// return the data alongside any error that might have occurred
|
||||||
|
return *response, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get is used to call an endpoint using a GET request, responseCodes contains all possible
|
||||||
|
// error codes that the API can respond with other than 200 OK
|
||||||
|
func Get[T any](endpoint string, responseCodes map[int]string) (output T, err error) {
|
||||||
|
// use meta function to get a response
|
||||||
|
response, err := meta[T](endpoint, http.MethodGet, nil, responseCodes)
|
||||||
|
if err != nil {
|
||||||
|
return output, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// return the data alongside any error that might have occurred
|
||||||
|
return *response, err
|
||||||
|
}
|
61
characters/characters.go
Normal file
61
characters/characters.go
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
// Package characters holds functions that interact with the characters
|
||||||
|
package characters
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"git.stinnesbeck.com/nils/artifacts/api"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetMy retrieves all characters from your account
|
||||||
|
func GetMy() ([]Character, error) {
|
||||||
|
// these are the possible response codes, other than 200 OK
|
||||||
|
responseCodes := map[int]string{
|
||||||
|
404: "Characters not found",
|
||||||
|
}
|
||||||
|
|
||||||
|
// use Get function to retrieve characters
|
||||||
|
return api.Get[[]Character]("/my/characters/", responseCodes)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAll tries to retrieve all characters on the server
|
||||||
|
func GetAll() ([]Character, error) {
|
||||||
|
// these are the possible response codes, other than 200 OK
|
||||||
|
responseCodes := map[int]string{
|
||||||
|
404: "Characters not found",
|
||||||
|
}
|
||||||
|
|
||||||
|
// use Get function to retrieve characters
|
||||||
|
return api.Get[[]Character]("/characters/", responseCodes)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get tries to retrieve a character by name
|
||||||
|
func Get(name string) (Character, error) {
|
||||||
|
// these are the possible response codes, other than 200 OK
|
||||||
|
responseCodes := map[int]string{
|
||||||
|
404: "Character not found",
|
||||||
|
}
|
||||||
|
|
||||||
|
// use Get function to retrieve character
|
||||||
|
return api.Get[Character](fmt.Sprintf("/characters/%s", name), responseCodes)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create will try to create a new character
|
||||||
|
func Create(name string, skin Skin) (Character, error) {
|
||||||
|
if len(name) > 12 {
|
||||||
|
return Character{}, fmt.Errorf("make sure to provide a name that is >=3 and <=12 characters long")
|
||||||
|
}
|
||||||
|
|
||||||
|
// these are the possible response codes, other than 200 OK
|
||||||
|
responseCodes := map[int]string{
|
||||||
|
494: "Name already used",
|
||||||
|
495: "Maximum characters reached on your account",
|
||||||
|
}
|
||||||
|
|
||||||
|
newChar := Character{
|
||||||
|
Name: name,
|
||||||
|
Skin: skin,
|
||||||
|
}
|
||||||
|
|
||||||
|
return api.Post[Character]("/characters/create", newChar, responseCodes)
|
||||||
|
}
|
34
characters/move.go
Normal file
34
characters/move.go
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
package characters
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"git.stinnesbeck.com/nils/artifacts/api"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Move will try to move a character to a map tile located at x,y
|
||||||
|
func Move(name string, x, y int) (CharacterMovement, error) {
|
||||||
|
// these are the possible response codes, other than 200 OK
|
||||||
|
responseCodes := map[int]string{
|
||||||
|
404: "Map not found.",
|
||||||
|
486: "Character is locked. Action is already in progress.",
|
||||||
|
490: "Character already at destination.",
|
||||||
|
498: "Character not found.",
|
||||||
|
499: "Character in cooldown.",
|
||||||
|
}
|
||||||
|
|
||||||
|
var movement = struct {
|
||||||
|
X int `json:"x"`
|
||||||
|
Y int `json:"y"`
|
||||||
|
}{
|
||||||
|
X: x,
|
||||||
|
Y: y,
|
||||||
|
}
|
||||||
|
|
||||||
|
return api.Post[CharacterMovement](fmt.Sprintf("/my/%s/action/move", name), movement, responseCodes)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move will try to move a character to a map tile located at x,y
|
||||||
|
func (c *Character) Move(x, y int) (CharacterMovement, error) {
|
||||||
|
return Move(c.Name, x, y)
|
||||||
|
}
|
13
characters/move_test.go
Normal file
13
characters/move_test.go
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package characters_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"git.stinnesbeck.com/nils/artifacts/characters"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestMove(t *testing.T) {
|
||||||
|
if _, err := characters.Move("Nils", 0, 1); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
153
characters/types.go
Normal file
153
characters/types.go
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
package characters
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
// Character is a struct that holds info on a character
|
||||||
|
type Character struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Skin Skin `json:"skin"`
|
||||||
|
Level int `json:"level"`
|
||||||
|
Xp int `json:"xp"`
|
||||||
|
MaxXp int `json:"max_xp"`
|
||||||
|
TotalXp int `json:"total_xp"`
|
||||||
|
Gold int `json:"gold"`
|
||||||
|
Speed int `json:"speed"`
|
||||||
|
MiningLevel int `json:"mining_level"`
|
||||||
|
MiningXp int `json:"mining_xp"`
|
||||||
|
MiningMaxXp int `json:"mining_max_xp"`
|
||||||
|
WoodcuttingLevel int `json:"woodcutting_level"`
|
||||||
|
WoodcuttingXp int `json:"woodcutting_xp"`
|
||||||
|
WoodcuttingMaxXp int `json:"woodcutting_max_xp"`
|
||||||
|
FishingLevel int `json:"fishing_level"`
|
||||||
|
FishingXp int `json:"fishing_xp"`
|
||||||
|
FishingMaxXp int `json:"fishing_max_xp"`
|
||||||
|
WeaponcraftingLevel int `json:"weaponcrafting_level"`
|
||||||
|
WeaponcraftingXp int `json:"weaponcrafting_xp"`
|
||||||
|
WeaponcraftingMaxXp int `json:"weaponcrafting_max_xp"`
|
||||||
|
GearcraftingLevel int `json:"gearcrafting_level"`
|
||||||
|
GearcraftingXp int `json:"gearcrafting_xp"`
|
||||||
|
GearcraftingMaxXp int `json:"gearcrafting_max_xp"`
|
||||||
|
JewelrycraftingLevel int `json:"jewelrycrafting_level"`
|
||||||
|
JewelrycraftingXp int `json:"jewelrycrafting_xp"`
|
||||||
|
JewelrycraftingMaxXp int `json:"jewelrycrafting_max_xp"`
|
||||||
|
CookingLevel int `json:"cooking_level"`
|
||||||
|
CookingXp int `json:"cooking_xp"`
|
||||||
|
CookingMaxXp int `json:"cooking_max_xp"`
|
||||||
|
Hp int `json:"hp"`
|
||||||
|
Haste int `json:"haste"`
|
||||||
|
CriticalStrike int `json:"critical_strike"`
|
||||||
|
Stamina int `json:"stamina"`
|
||||||
|
AttackFire int `json:"attack_fire"`
|
||||||
|
AttackEarth int `json:"attack_earth"`
|
||||||
|
AttackWater int `json:"attack_water"`
|
||||||
|
AttackAir int `json:"attack_air"`
|
||||||
|
DmgFire int `json:"dmg_fire"`
|
||||||
|
DmgEarth int `json:"dmg_earth"`
|
||||||
|
DmgWater int `json:"dmg_water"`
|
||||||
|
DmgAir int `json:"dmg_air"`
|
||||||
|
ResFire int `json:"res_fire"`
|
||||||
|
ResEarth int `json:"res_earth"`
|
||||||
|
ResWater int `json:"res_water"`
|
||||||
|
ResAir int `json:"res_air"`
|
||||||
|
X int `json:"x"`
|
||||||
|
Y int `json:"y"`
|
||||||
|
Cooldown int `json:"cooldown"`
|
||||||
|
CooldownExpiration time.Time `json:"cooldown_expiration"`
|
||||||
|
WeaponSlot string `json:"weapon_slot"`
|
||||||
|
ShieldSlot string `json:"shield_slot"`
|
||||||
|
HelmetSlot string `json:"helmet_slot"`
|
||||||
|
BodyArmorSlot string `json:"body_armor_slot"`
|
||||||
|
LegArmorSlot string `json:"leg_armor_slot"`
|
||||||
|
BootsSlot string `json:"boots_slot"`
|
||||||
|
Ring1Slot string `json:"ring1_slot"`
|
||||||
|
Ring2Slot string `json:"ring2_slot"`
|
||||||
|
AmuletSlot string `json:"amulet_slot"`
|
||||||
|
Artifact1Slot string `json:"artifact1_slot"`
|
||||||
|
Artifact2Slot string `json:"artifact2_slot"`
|
||||||
|
Artifact3Slot string `json:"artifact3_slot"`
|
||||||
|
Consumable1Slot string `json:"consumable1_slot"`
|
||||||
|
Consumable1SlotQuantity int `json:"consumable1_slot_quantity"`
|
||||||
|
Consumable2Slot string `json:"consumable2_slot"`
|
||||||
|
Consumable2SlotQuantity int `json:"consumable2_slot_quantity"`
|
||||||
|
InventorySlot1 string `json:"inventory_slot1"`
|
||||||
|
InventorySlot1Quantity int `json:"inventory_slot1_quantity"`
|
||||||
|
InventorySlot2 string `json:"inventory_slot2"`
|
||||||
|
InventorySlot2Quantity int `json:"inventory_slot2_quantity"`
|
||||||
|
InventorySlot3 string `json:"inventory_slot3"`
|
||||||
|
InventorySlot3Quantity int `json:"inventory_slot3_quantity"`
|
||||||
|
InventorySlot4 string `json:"inventory_slot4"`
|
||||||
|
InventorySlot4Quantity int `json:"inventory_slot4_quantity"`
|
||||||
|
InventorySlot5 string `json:"inventory_slot5"`
|
||||||
|
InventorySlot5Quantity int `json:"inventory_slot5_quantity"`
|
||||||
|
InventorySlot6 string `json:"inventory_slot6"`
|
||||||
|
InventorySlot6Quantity int `json:"inventory_slot6_quantity"`
|
||||||
|
InventorySlot7 string `json:"inventory_slot7"`
|
||||||
|
InventorySlot7Quantity int `json:"inventory_slot7_quantity"`
|
||||||
|
InventorySlot8 string `json:"inventory_slot8"`
|
||||||
|
InventorySlot8Quantity int `json:"inventory_slot8_quantity"`
|
||||||
|
InventorySlot9 string `json:"inventory_slot9"`
|
||||||
|
InventorySlot9Quantity int `json:"inventory_slot9_quantity"`
|
||||||
|
InventorySlot10 string `json:"inventory_slot10"`
|
||||||
|
InventorySlot10Quantity int `json:"inventory_slot10_quantity"`
|
||||||
|
InventorySlot11 string `json:"inventory_slot11"`
|
||||||
|
InventorySlot11Quantity int `json:"inventory_slot11_quantity"`
|
||||||
|
InventorySlot12 string `json:"inventory_slot12"`
|
||||||
|
InventorySlot12Quantity int `json:"inventory_slot12_quantity"`
|
||||||
|
InventorySlot13 string `json:"inventory_slot13"`
|
||||||
|
InventorySlot13Quantity int `json:"inventory_slot13_quantity"`
|
||||||
|
InventorySlot14 string `json:"inventory_slot14"`
|
||||||
|
InventorySlot14Quantity int `json:"inventory_slot14_quantity"`
|
||||||
|
InventorySlot15 string `json:"inventory_slot15"`
|
||||||
|
InventorySlot15Quantity int `json:"inventory_slot15_quantity"`
|
||||||
|
InventorySlot16 string `json:"inventory_slot16"`
|
||||||
|
InventorySlot16Quantity int `json:"inventory_slot16_quantity"`
|
||||||
|
InventorySlot17 string `json:"inventory_slot17"`
|
||||||
|
InventorySlot17Quantity int `json:"inventory_slot17_quantity"`
|
||||||
|
InventorySlot18 string `json:"inventory_slot18"`
|
||||||
|
InventorySlot18Quantity int `json:"inventory_slot18_quantity"`
|
||||||
|
InventorySlot19 string `json:"inventory_slot19"`
|
||||||
|
InventorySlot19Quantity int `json:"inventory_slot19_quantity"`
|
||||||
|
InventorySlot20 string `json:"inventory_slot20"`
|
||||||
|
InventorySlot20Quantity int `json:"inventory_slot20_quantity"`
|
||||||
|
InventoryMaxItems int `json:"inventory_max_items"`
|
||||||
|
Task string `json:"task"`
|
||||||
|
TaskType string `json:"task_type"`
|
||||||
|
TaskProgress int `json:"task_progress"`
|
||||||
|
TaskTotal int `json:"task_total"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skin is a custom type used for the allowed skins
|
||||||
|
type Skin string
|
||||||
|
|
||||||
|
// allowed skins
|
||||||
|
const (
|
||||||
|
Man1 Skin = "men1"
|
||||||
|
Man2 Skin = "men2"
|
||||||
|
Man3 Skin = "men3"
|
||||||
|
Woman1 Skin = "women1"
|
||||||
|
Woman2 Skin = "women2"
|
||||||
|
Woman3 Skin = "women3"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CharacterMovement is a struct that holds info on the movement of a character
|
||||||
|
type CharacterMovement struct {
|
||||||
|
Cooldown Cooldown
|
||||||
|
Destination Destination
|
||||||
|
Character Character
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cooldown is a struct that holds info on the remaining time for a given action
|
||||||
|
type Cooldown struct {
|
||||||
|
TotalSeconds int `json:"totalSeconds"`
|
||||||
|
RemainingSeconds int `json:"remainingSeconds"`
|
||||||
|
Expiration time.Time `json:"expiration"`
|
||||||
|
Reason string `json:"reason"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Destination is a struct that holds info on a map tile
|
||||||
|
type Destination struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
X int `json:"x"`
|
||||||
|
Y int `json:"y"`
|
||||||
|
Content any `json:"content"`
|
||||||
|
}
|
14
maps/maps.go
Normal file
14
maps/maps.go
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
// Package maps holds functions that interact with the maps
|
||||||
|
package maps
|
||||||
|
|
||||||
|
import "git.stinnesbeck.com/nils/artifacts/api"
|
||||||
|
|
||||||
|
// GetAll will try to retrieve all map tiles
|
||||||
|
func GetAll() ([]Map, error) {
|
||||||
|
// these are the possible response codes, other than 200 OK
|
||||||
|
responseCodes := map[int]string{
|
||||||
|
404: "Maps not found.",
|
||||||
|
}
|
||||||
|
|
||||||
|
return api.Get[[]Map]("/maps/", responseCodes)
|
||||||
|
}
|
16
maps/types.go
Normal file
16
maps/types.go
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
package maps
|
||||||
|
|
||||||
|
// Content is a struct that holds info on the type of a map tile
|
||||||
|
type Content struct {
|
||||||
|
Type string `json:"type"`
|
||||||
|
Code string `json:"code"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map is a struct that holds info on a map tile
|
||||||
|
type Map struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Skin string `json:"skin"`
|
||||||
|
X int `json:"x"`
|
||||||
|
Y int `json:"y"`
|
||||||
|
Content Content `json:"content"`
|
||||||
|
}
|
29
status/status.go
Normal file
29
status/status.go
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// Package status holds functions that interact with the status of the server
|
||||||
|
package status
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.stinnesbeck.com/nils/artifacts/api"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Announcements is used to display messages and when they were created
|
||||||
|
type Announcements struct {
|
||||||
|
Message string `json:"message"`
|
||||||
|
CreatedAt time.Time `json:"created_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServerStatus is a struct that holds info on a server
|
||||||
|
type ServerStatus struct {
|
||||||
|
Status string `json:"status"`
|
||||||
|
Version string `json:"version"`
|
||||||
|
CharactersOnline int `json:"characters_online"`
|
||||||
|
Announcements []Announcements `json:"announcements"`
|
||||||
|
LastWipe string `json:"last_wipe"`
|
||||||
|
NextWipe string `json:"next_wipe"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get tries to retrieve the status of the server
|
||||||
|
func Get() (ServerStatus, error) {
|
||||||
|
return api.Get[ServerStatus]("/", nil)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user