Compare commits

...

90 Commits

Author SHA1 Message Date
Renovate 73189203f3 chore(deps): update dependency eslint-config-prettier to v9.1.0 (#89)
ci/woodpecker/push/test Pipeline was successful Details
Reviewed-on: #89
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2024-05-18 05:55:49 +00:00
Renovate ce584fd292 chore(deps): update dependency typescript to v5.4.5 (#99)
ci/woodpecker/push/test Pipeline failed Details
Reviewed-on: #99
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2024-05-18 05:55:33 +00:00
Renovate a6f4d4616e chore(deps): update node.js to v20.13.1 (#106)
ci/woodpecker/push/test Pipeline failed Details
Reviewed-on: #106
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2024-05-18 05:55:19 +00:00
Renovate 50a42f91f0 chore(deps): update commitlint monorepo to v19.3.0 (#102)
ci/woodpecker/push/test Pipeline failed Details
Reviewed-on: #102
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2024-05-18 05:55:07 +00:00
Renovate 9797bbb9d9 chore(deps): update dependency @types/jquery to v3.5.30 (#104)
ci/woodpecker/push/test Pipeline was successful Details
Reviewed-on: #104
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2024-05-17 03:38:07 +00:00
Renovate c5005680b4 chore(deps): update dependency @types/lodash to v4.17.3 (#66)
ci/woodpecker/push/test Pipeline failed Details
Reviewed-on: #66
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2024-05-17 03:38:00 +00:00
Dawid Wysokiński 99ef0c40de
chore: update README.md
ci/woodpecker/push/test Pipeline was successful Details
ci/woodpecker/tag/docker Pipeline was successful Details
ci/woodpecker/tag/deployment Pipeline was successful Details
2024-04-05 07:41:58 +02:00
Dawid Wysokiński cab4709463
chore(deps): update dependency date-fns to v3
ci/woodpecker/push/test Pipeline was successful Details
2024-04-05 06:38:20 +02:00
Renovate 82b864946b chore(deps): update dependency husky to v9 (#98)
ci/woodpecker/push/test Pipeline was successful Details
Reviewed-on: #98
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2024-04-04 03:50:40 +00:00
Dawid Wysokiński b43139bcbb
chore: caddy - enable file listings
ci/woodpecker/push/test Pipeline was successful Details
2024-04-03 07:59:17 +02:00
Dawid Wysokiński 81274707d3
chore: update README.md
ci/woodpecker/push/test Pipeline was successful Details
2024-04-03 07:55:30 +02:00
Dawid Wysokiński f2ed75e4c8
chore: delete manifest.tmpl
ci/woodpecker/push/test Pipeline was successful Details
ci/woodpecker/tag/docker Pipeline was successful Details
ci/woodpecker/tag/deployment Pipeline was successful Details
2024-04-03 07:44:06 +02:00
Dawid Wysokiński dc5f4a03de
chore: add linux/arm64 to docker buildx config
ci/woodpecker/push/test Pipeline was successful Details
2024-04-03 07:41:07 +02:00
Dawid Wysokiński 8496747ac8
chore: update README.md
ci/woodpecker/push/test Pipeline was successful Details
2024-04-03 07:38:16 +02:00
Dawid Wysokiński a637e66258
chore: rename docs folder -> assets
ci/woodpecker/push/test Pipeline was successful Details
2024-04-03 07:32:24 +02:00
Dawid Wysokiński 0fbea77850
feat: specify timeout for api requests
ci/woodpecker/push/test Pipeline was successful Details
2024-04-03 07:29:27 +02:00
Dawid Wysokiński 0d034710b5
refactor: extended tribe profile - use /api/v2
ci/woodpecker/push/test Pipeline was successful Details
2024-04-03 07:18:14 +02:00
Dawid Wysokiński 998deef3aa
refactor: extended player profile - use /api/v2
ci/woodpecker/push/test Pipeline was successful Details
2024-04-03 06:46:29 +02:00
Renovate a740a589be chore(deps): update dependency @types/jquery to v3.5.29 (#82)
ci/woodpecker/push/test Pipeline was successful Details
Reviewed-on: #82
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2024-04-03 03:52:57 +00:00
Renovate 8bffd2647b chore(deps): update commitlint monorepo to v19 (major) (#96)
ci/woodpecker/push/test Pipeline was successful Details
Reviewed-on: #96
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2024-04-03 03:52:19 +00:00
Dawid Wysokiński af3fffae43
refactor: extended village profile - use /api/v2
ci/woodpecker/push/test Pipeline was successful Details
2024-04-02 08:24:02 +02:00
Dawid Wysokiński a2fb6425a0
refactor: extended map popup - use /api/v2
ci/woodpecker/push/test Pipeline was successful Details
2024-04-02 07:29:59 +02:00
Renovate 93fa246f14 chore(deps): update dependency axios to v1.6.8 (#94)
ci/woodpecker/push/test Pipeline was successful Details
Reviewed-on: #94
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2024-04-02 03:42:08 +00:00
Dawid Wysokiński fc9d1be2fe
chore: update README.md [skip ci] 2024-04-01 09:52:38 +02:00
Dawid Wysokiński aaabe449d5
chore: new domain - twhelp.app
ci/woodpecker/push/test Pipeline was successful Details
2024-04-01 09:48:09 +02:00
Dawid Wysokiński ac571326c3
feat: /api/v2 - generate client
ci/woodpecker/push/test Pipeline was successful Details
2024-04-01 09:45:33 +02:00
Renovate cceeb270c4 chore(deps): update commitlint monorepo to v18.6.1 (#92)
ci/woodpecker/push/test Pipeline was successful Details
Reviewed-on: #92
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2024-04-01 07:22:44 +00:00
Dawid Wysokiński f94fd27432
chore: update ci/cd pipelines
ci/woodpecker/push/test Pipeline was successful Details
2024-04-01 09:21:56 +02:00
Renovate 1ddcbb66ed chore(deps): update dependency prettier to v3.2.5 (#93)
ci/woodpecker/push/test Pipeline was successful Details
Reviewed-on: #93
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2024-04-01 07:17:41 +00:00
Renovate d099601b69 chore(deps): update dependency typescript to v5.4.3 (#88)
ci/woodpecker/push/test Pipeline failed Details
Reviewed-on: #88
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2024-04-01 07:17:31 +00:00
Renovate ff364a93ea chore(deps): update node.js to v20 (#79)
ci/woodpecker/push/test Pipeline was successful Details
Reviewed-on: #79
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2024-04-01 07:14:37 +00:00
Renovate f38e3d6954 chore(deps): update dependency @types/node to v18.19.14 (#81)
ci/woodpecker/push/test Pipeline was successful Details
Reviewed-on: #81
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2024-02-02 06:39:01 +00:00
Renovate 2bfc8b1c84 chore(deps): update dependency axios to v1.6.7 (#91)
ci/woodpecker/push/test Pipeline failed Details
Reviewed-on: #91
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2024-02-02 06:38:48 +00:00
Renovate c2fd244639 chore(deps): update caddy docker tag to v2.7.6 (#90)
ci/woodpecker/push/test Pipeline was successful Details
Reviewed-on: #90
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2024-01-13 08:48:23 +00:00
Renovate e69cf46abe chore(deps): update commitlint monorepo to v18.4.4 (#86)
ci/woodpecker/push/test Pipeline was successful Details
Reviewed-on: #86
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2024-01-13 08:19:14 +00:00
Renovate 56944664ac chore(deps): update commitlint monorepo to v18.4.1 (#85)
ci/woodpecker/push/test Pipeline was successful Details
Reviewed-on: #85
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-11-16 04:20:25 +00:00
Renovate 0427e0dd60 chore(deps): update dependency axios to v1.6.2 (#84)
ci/woodpecker/push/test Pipeline failed Details
Reviewed-on: #84
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-11-16 04:20:13 +00:00
Renovate a6a68cd530 chore(deps): update parcel monorepo to v2.10.3 (#83)
ci/woodpecker/push/test Pipeline failed Details
Reviewed-on: #83
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-11-16 04:20:03 +00:00
Renovate 4bd12132f9 chore(deps): update commitlint monorepo to v18 (major) (#76)
ci/woodpecker/push/test Pipeline was successful Details
Reviewed-on: #76
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-11-14 06:34:44 +00:00
Renovate d66e2de08d chore(deps): update dependency prettier to v3.1.0 (#77)
ci/woodpecker/push/test Pipeline failed Details
Reviewed-on: #77
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-11-14 06:34:32 +00:00
Renovate 00397f0aaf chore(deps): update dependency axios to v1.6.1 (#78)
ci/woodpecker/push/test Pipeline failed Details
Reviewed-on: #78
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-11-14 06:34:25 +00:00
Dawid Wysokiński 483ffa3ef7
chore: bump script versions
ci/woodpecker/push/test Pipeline was successful Details
ci/woodpecker/tag/docker Pipeline was successful Details
ci/woodpecker/tag/deploy Pipeline was successful Details
2023-10-30 09:35:57 +01:00
Dawid Wysokiński 54e5faeb44
chore: update alpine/k8s docker tag to v1.26.9
ci/woodpecker/push/test Pipeline was successful Details
2023-10-30 09:34:38 +01:00
Renovate b7f08832d9 chore(deps): update dependency eslint-config-prettier to v9 (#58)
ci/woodpecker/push/test Pipeline was successful Details
Reviewed-on: #58
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-10-30 08:33:43 +00:00
Renovate cfc26dd822 chore(deps): update dependency @types/jquery to v3.5.25 (#71)
ci/woodpecker/push/test Pipeline failed Details
Reviewed-on: #71
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-10-30 08:33:36 +00:00
Renovate 0cae454104 chore(deps): update dependency @types/node to v18.18.7 (#72)
ci/woodpecker/push/test Pipeline failed Details
Reviewed-on: #72
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-10-30 08:33:24 +00:00
Renovate 58dbb8433d chore(deps): update parcel monorepo to v2.10.1 (#75)
ci/woodpecker/push/test Pipeline failed Details
Reviewed-on: #75
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-10-30 08:33:11 +00:00
Renovate 4adc41cb7e chore(deps): update dependency prettier to v3 (#52)
ci/woodpecker/push/test Pipeline failed Details
Reviewed-on: #52
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-10-30 08:32:56 +00:00
Renovate 0bd3692516 chore(deps): update commitlint monorepo to v17.8.1 (#70)
ci/woodpecker/push/test Pipeline was successful Details
Reviewed-on: #70
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-10-22 05:28:21 +00:00
Renovate fabfcf55e4 chore(deps): update dependency axios to v1.5.1 (#74)
ci/woodpecker/push/test Pipeline failed Details
Reviewed-on: #74
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-10-22 05:28:12 +00:00
Renovate 754ead62a3 chore(deps): update caddy docker tag to v2.7.5 (#73)
ci/woodpecker/push/test Pipeline was successful Details
Reviewed-on: #73
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-10-21 04:48:37 +00:00
Renovate 2f1e6e2bff chore(deps): update dependency @types/jquery to v3.5.21 (#65)
ci/woodpecker/push/test Pipeline was successful Details
Reviewed-on: #65
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-10-07 03:34:56 +00:00
Renovate 156c13e5e1 chore(deps): update dependency @types/node to v18.18.3 (#50)
ci/woodpecker/push/test Pipeline failed Details
Reviewed-on: #50
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-10-07 03:34:38 +00:00
Renovate fe800229a5 chore(deps): update node.js to v18.18 (#68)
ci/woodpecker/push/test Pipeline failed Details
Reviewed-on: #68
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-10-07 03:34:25 +00:00
Dawid Wysokiński 24b5c4d24d
chore: remove unnecessary group [skip ci] 2023-09-09 07:23:05 +02:00
Dawid Wysokiński 41614f5054
chore: bump user scripts versions
ci/woodpecker/push/test Pipeline was successful Details
ci/woodpecker/tag/docker Pipeline was successful Details
ci/woodpecker/tag/deploy Pipeline was successful Details
2023-09-09 07:04:42 +02:00
Dawid Wysokiński 4e54a84ff5 feat: migrate from drone to woodpecker (#67)
ci/woodpecker/push/test Pipeline was successful Details
Reviewed-on: #67
2023-09-09 05:03:30 +00:00
Renovate 900c173702 chore(deps): update dependency axios to v1.5.0 (#64)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #64
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-09-09 04:38:16 +00:00
Renovate 03e151d4e1 chore(deps): update dependency typescript to v5.2.2 (#63)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #63
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-08-25 03:32:36 +00:00
Dawid Wysokiński 26965f9f73
fix: metadata are added more than once to the output
continuous-integration/drone/push Build is passing Details
2023-08-19 07:55:46 +02:00
Renovate 3140f56ae9 chore(deps): update commitlint monorepo to v17.7.1 (#59)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #59
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-08-19 05:46:10 +00:00
Renovate b53acc0499 chore(deps): update caddy docker tag to v2.7.4 (#61)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #61
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-08-18 08:18:53 +00:00
Renovate 5952c4e0fb chore(deps): update caddy docker tag to v2.7.3 (#60)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #60
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-08-15 04:52:50 +00:00
Renovate 7ab3ce1955 chore(deps): update dependency eslint-config-prettier to v8.10.0 (#56)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #56
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-08-05 04:29:25 +00:00
Renovate f868086570 chore(deps): update caddy docker tag to v2.7.2 (#57)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #57
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-08-05 04:29:14 +00:00
Renovate 1987c99761 chore(deps): update typescript-eslint monorepo to v5.62.0 (#51)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #51
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-07-21 03:19:30 +00:00
Renovate 9e21d30c77 chore(deps): update commitlint monorepo to v17.6.7 (#54)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #54
Co-authored-by: Renovate <renovate@dwysokinski.me>
Co-committed-by: Renovate <renovate@dwysokinski.me>
2023-07-20 03:43:48 +00:00
Dawid Wysokiński b05d0413b1
feat: ci/cd - email notifications
continuous-integration/drone/push Build is passing Details
2023-07-01 14:14:58 +02:00
Dawid Wysokiński 3f3e836177
chore: bump script versions
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2023-07-01 09:52:57 +02:00
renovate b3e6edb08e chore(deps): update dependency typescript to v5.1.6 (#49)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #49
Co-authored-by: renovate <renovate@noreply.localhost>
Co-committed-by: renovate <renovate@noreply.localhost>
2023-06-30 03:28:03 +00:00
renovate 59e5933167 chore(deps): update dependency typescript to v5.1.5 (#48)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #48
Co-authored-by: renovate <renovate@noreply.localhost>
Co-committed-by: renovate <renovate@noreply.localhost>
2023-06-29 03:34:22 +00:00
renovate d609f87550 chore(deps): update parcel monorepo to v2.9.3 (#46)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #46
Co-authored-by: renovate <renovate@noreply.localhost>
Co-committed-by: renovate <renovate@noreply.localhost>
2023-06-26 03:32:38 +00:00
renovate 83f142ad97 chore(deps): update commitlint monorepo to v17.6.6 (#45)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #45
Co-authored-by: renovate <renovate@noreply.localhost>
Co-committed-by: renovate <renovate@noreply.localhost>
2023-06-25 14:12:57 +00:00
renovate 7bb73e9dce chore(deps): update typescript-eslint monorepo to v5.60.0 (#44)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #44
Co-authored-by: renovate <renovate@noreply.localhost>
Co-committed-by: renovate <renovate@noreply.localhost>
2023-06-20 03:45:40 +00:00
renovate 4e8422c435 chore(deps): update parcel monorepo to v2.9.2 (#42)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #42
Co-authored-by: renovate <renovate@noreply.localhost>
Co-committed-by: renovate <renovate@noreply.localhost>
2023-06-10 04:03:09 +00:00
Dawid Wysokiński 56fbe86774
chore: update alpine/k8s to v1.26.5
continuous-integration/drone/push Build is passing Details
2023-06-09 06:59:27 +02:00
renovate c26c7ebbc9 chore(deps): update dependency @types/lodash to v4.14.195 (#37)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #37
Co-authored-by: renovate <renovate@noreply.localhost>
Co-committed-by: renovate <renovate@noreply.localhost>
2023-06-08 05:53:15 +00:00
renovate 8dc4faa06f chore(deps): update typescript-eslint monorepo to v5.59.9 (#41)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #41
Co-authored-by: renovate <renovate@noreply.localhost>
Co-committed-by: renovate <renovate@noreply.localhost>
2023-06-06 03:23:11 +00:00
Dawid Wysokiński a968d42e8a
chore: bump typescript to v5.1.3 and remove npm-run-all from devDependencies
continuous-integration/drone/push Build is passing Details
2023-06-02 08:12:06 +02:00
Dawid Wysokiński 0ff002ce1a
chore(deps): update parcel monorepo to v2.9.1
continuous-integration/drone/push Build is passing Details
2023-06-02 08:05:32 +02:00
renovate 24a9b7113f chore(deps): update commitlint monorepo to v17.6.5 (#39)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #39
Co-authored-by: renovate <renovate@noreply.localhost>
Co-committed-by: renovate <renovate@noreply.localhost>
2023-06-02 03:20:49 +00:00
renovate 4a30e57fbf chore(deps): update typescript-eslint monorepo to v5.59.8 (#36)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #36
Co-authored-by: renovate <renovate@noreply.localhost>
Co-committed-by: renovate <renovate@noreply.localhost>
2023-05-30 03:36:03 +00:00
renovate 31f276a981 chore(deps): update typescript-eslint monorepo to v5.59.6 (#35)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #35
Co-authored-by: renovate <renovate@noreply.localhost>
Co-committed-by: renovate <renovate@noreply.localhost>
2023-05-16 04:01:48 +00:00
renovate 773d95e923 chore(deps): update typescript-eslint monorepo to v5.59.5 (#34)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #34
Co-authored-by: renovate <renovate@noreply.localhost>
Co-committed-by: renovate <renovate@noreply.localhost>
2023-05-12 06:14:47 +00:00
renovate 9f33b32632 chore(deps): update dependency typescript to v5.0.4 (#30)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #30
Co-authored-by: renovate <renovate@noreply.localhost>
Co-committed-by: renovate <renovate@noreply.localhost>
2023-05-07 06:11:38 +00:00
renovate da32822563 chore(deps): update typescript-eslint monorepo to v5.59.2 (#32)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #32
Co-authored-by: renovate <renovate@noreply.localhost>
Co-committed-by: renovate <renovate@noreply.localhost>
2023-05-07 06:11:29 +00:00
renovate 11cd008009 chore(deps): update commitlint monorepo to v17.6.3 (#33)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #33
Co-authored-by: renovate <renovate@noreply.localhost>
Co-committed-by: renovate <renovate@noreply.localhost>
2023-05-07 06:11:19 +00:00
renovate c6b51673d6 chore(deps): update dependency date-fns to v2.30.0 (#31)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #31
Co-authored-by: renovate <renovate@noreply.localhost>
Co-committed-by: renovate <renovate@noreply.localhost>
2023-05-07 06:11:10 +00:00
Dawid Wysokiński b03bae4cd9
refactor: replace deprecated endpoints
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2023-05-07 08:03:51 +02:00
Dawid Wysokiński c29f987caa
chore: update alpine/k8s docker tag to v1.26.4 [skip ci] 2023-05-01 06:54:04 +02:00
34 changed files with 1943 additions and 2891 deletions

View File

@ -1,111 +0,0 @@
---
kind: pipeline
type: docker
name: build
platform:
os: linux
arch: amd64
steps:
- name: build
image: node:16-bullseye
commands:
- yarn && yarn build
trigger:
event:
- push
- pull_request
branch:
- master
---
kind: pipeline
type: docker
name: linux-amd64
platform:
os: linux
arch: amd64
steps:
- name: publish
image: plugins/docker
settings:
username:
from_secret: docker_username
password:
from_secret: docker_password
registry: gitea.dwysokinski.me
repo: gitea.dwysokinski.me/twhelp-packages/scripts
auto_tag: true
auto_tag_suffix: linux-amd64
dockerfile: Dockerfile
trigger:
event:
- tag
---
kind: pipeline
type: docker
name: manifest
steps:
- name: manifest
image: plugins/manifest
settings:
auto_tag: "true"
ignore_missing: "true"
spec: manifest.tmpl
username:
from_secret: docker_username
password:
from_secret: docker_password
- name: manifest-latest
image: plugins/manifest
settings:
tags: latest
ignore_missing: "true"
spec: manifest.tmpl
username:
from_secret: docker_username
password:
from_secret: docker_password
trigger:
event:
- tag
depends_on:
- linux-amd64
---
kind: pipeline
type: docker
name: deploy
steps:
- name: deploy-k8s
image: alpine/k8s:1.25.6
environment:
KUBECONFIG:
from_secret: kubeconfig
commands:
- "mkdir ~/.kube && echo \"$KUBECONFIG\" > ~/.kube/twhelp"
- "cd ./k8s/overlays/prod && kustomize edit set image scripts=gitea.dwysokinski.me/twhelp-packages/scripts:${DRONE_TAG##v} && cd ../../.."
- kustomize build ./k8s/overlays/prod | kubectl --kubeconfig ~/.kube/twhelp apply -n twhelp -f -
trigger:
event:
- tag
depends_on:
- manifest
---
kind: signature
hmac: 41f8c71c00cee8f0932228f9fcb449b50b36d93899bbc2decdf1fcced338caae
...

2
.env
View File

@ -1 +1 @@
TWHELP_API_BASE_URL=https://tribalwarshelp.com
TWHELP_API_BASE_URL=https://twhelp.app/api

View File

@ -3,5 +3,6 @@ dist
.parcel-cache
k8s
.prettierrc.js
.terserrc.js
commitlint.config.js
postbuild.js
src/lib/twhelp

View File

@ -1,4 +1 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx --no -- commitlint --edit ${1}

View File

@ -1,3 +0,0 @@
module.exports = {
singleQuote: true,
};

4
.prettierrc.json Normal file
View File

@ -0,0 +1,4 @@
{
"singleQuote": true,
"trailingComma": "es5"
}

View File

@ -0,0 +1,34 @@
when:
event: [tag]
ref: refs/tags/v*
steps:
deploy:
image: alpine/k8s:1.27.11
secrets:
- kubeconfig
commands:
- "mkdir ~/.kube && echo \"$KUBECONFIG\" > ~/.kube/twhelp"
- "cd ./k8s/overlays/prod && kustomize edit set image scripts=gitea.dwysokinski.me/twhelp-packages/scripts:${CI_COMMIT_TAG##v} && cd ../../.."
- kustomize build ./k8s/overlays/prod | kubectl --kubeconfig ~/.kube/twhelp apply -n twhelp -f -
email:
image: deblan/woodpecker-email
settings:
dsn:
from_secret: email_dsn
from:
address:
from_secret: email_from_address
name: Woodpecker
recipients:
- notifications@twhelp.app
recipients_only: true
content:
subject:
"[deployment - {{ pipeline.status }}] {{ repo.full_name }} ({{ commit.tag }})"
when:
status: [success, failure]
depends_on:
- docker

16
.woodpecker/docker.yml Normal file
View File

@ -0,0 +1,16 @@
when:
event: [tag]
ref: refs/tags/v*
steps:
publish:
image: woodpeckerci/plugin-docker-buildx
settings:
platforms: linux/amd64,linux/arm64
repo: gitea.dwysokinski.me/twhelp-packages/scripts
registry: gitea.dwysokinski.me
auto_tag: true
username:
from_secret: docker_username
password:
from_secret: docker_password

15
.woodpecker/test.yml Normal file
View File

@ -0,0 +1,15 @@
when:
- event: [pull_request]
- event: push
branch:
- ${CI_REPO_DEFAULT_BRANCH}
variables:
- &node_image 'node:20'
steps:
test-build:
image: *node_image
pull: true
commands:
- yarn && yarn build

View File

@ -1,6 +1,6 @@
:80 {
root * /var/www
file_server
file_server browse
header -Server
header Cache-Control max-age=3600
header *.js Content-type "text/javascript; charset=UTF-8"

View File

@ -1,4 +1,4 @@
FROM node:16.20-alpine as build-deps
FROM --platform=$BUILDPLATFORM node:20.13-alpine as build-deps
WORKDIR /app
COPY package.json yarn.lock ./
@ -8,7 +8,7 @@ COPY . ./
ENV NODE_ENV=production
RUN yarn build
FROM caddy:2.6.4-alpine
FROM caddy:2.7.6-alpine
COPY --from=build-deps /app/dist /var/www
COPY Caddyfile /etc/caddy/Caddyfile

View File

@ -1,6 +1,31 @@
# Tribal Wars - scripts
<div align="center">
<picture>
<img alt="TWHelp logo" src="assets/white_logo_full.png" width="50%">
</picture>
</div>
This repo contains a variety of scripts for [Tribal Wars](https://www.tribalwars.net/en-dk/).
<br>
<h1 align="center"><a href="https://www.tribalwars.net/en-dk/">Tribal Wars</a> scripts to enhance your gameplay</h1>
<div align="center">
[![License](https://img.shields.io/badge/License-MIT-green)](#license)
[![CI/CD](https://woodpecker.dwysokinski.me/api/badges/10/status.svg)](https://woodpecker.dwysokinski.me/repos/10)
</div>
<p align="center">
<a href="https://twhelp.app/api/v2/swagger/">API</a>
·
<a href="https://gitea.dwysokinski.me/twhelp/scripts">Scripts</a>
·
<a href="https://gitea.dwysokinski.me/twhelp/dcbot">Discord Bot</a>
·
<a href="mailto:contact@twhelp.app">Report Bug</a>
·
<a href="mailto:contact@twhelp.app">Request Feature</a>
</p>
## Scripts
@ -8,70 +33,71 @@ This repo contains a variety of scripts for [Tribal Wars](https://www.tribalwars
This script adds additional info and actions on a player overview.
![img.png](docs/extended-player-profile.png)
![img.png](assets/extended-player-profile.png)
#### Installation
[User script](https://scripts.tribalwarshelp.com/extended-player-profile.user.js)
[User script](https://scripts.twhelp.app/extended-player-profile.user.js)
Quick bar:
```javascript
javascript:
$.getScript('https://scripts.tribalwarshelp.com/extended-player-profile.quickbar.js')
$.getScript('https://scripts.twhelp.app/extended-player-profile.quickbar.js?_='+~~(Date.now()/9e6))
```
### Extended tribe profile
This script adds additional info and actions on a tribe overview.
![img.png](docs/extended-tribe-profile.png)
![img.png](assets/extended-tribe-profile.png)
#### Installation
[User script](https://scripts.tribalwarshelp.com/extended-tribe-profile.user.js)
[User script](https://scripts.twhelp.app/extended-tribe-profile.user.js)
Quick bar:
```javascript
javascript:
$.getScript('https://scripts.tribalwarshelp.com/extended-tribe-profile.quickbar.js')
$.getScript('https://scripts.twhelp.app/extended-tribe-profile.quickbar.js?_='+~~(Date.now()/9e6))
```
### Extended map popup
This script extends the map popup with additional info.
![img.png](docs/extended-map-popup.png)
![img.png](assets/extended-map-popup.png)
#### Installation
[User script](https://scripts.tribalwarshelp.com/extended-map-popup.user.js)
[User script](https://scripts.twhelp.app/extended-map-popup.user.js)
Quick bar:
```javascript
javascript:
$.getScript('https://scripts.tribalwarshelp.com/extended-map-popup.quickbar.js')
$.getScript('https://scripts.twhelp.app/extended-map-popup.quickbar.js?_='+~~(Date.now()/9e6))
```
### Extended village profile
This script adds additional info and actions on a village overview.
![img.png](docs/extended-village-profile.png)
![img.png](assets/extended-village-profile.png)
#### Installation
[User script](https://scripts.tribalwarshelp.com/extended-village-profile.user.js)
[User script](https://scripts.twhelp.app/extended-village-profile.user.js)
Quick bar:
```javascript
javascript:
$.getScript('https://scripts.tribalwarshelp.com/extended-village-profile.quickbar.js')
$.getScript('https://scripts.twhelp.app/extended-village-profile.quickbar.js?_='+~~(Date.now()/9e6))
```
## Contributing
If you would like to contribute to the software, please contact me via [email](mailto:contact@twhelp.app).
## License
Distributed under the MIT License. See ``LICENSE`` for more information.
This project is licensed under the MIT license. See the [LICENSE](LICENSE) file for the full license text.
## Contact
Dawid Wysokiński - [contact@dwysokinski.me](mailto:contact@dwysokinski.me)

View File

Before

Width:  |  Height:  |  Size: 204 KiB

After

Width:  |  Height:  |  Size: 204 KiB

View File

Before

Width:  |  Height:  |  Size: 196 KiB

After

Width:  |  Height:  |  Size: 196 KiB

View File

Before

Width:  |  Height:  |  Size: 452 KiB

After

Width:  |  Height:  |  Size: 452 KiB

View File

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 51 KiB

BIN
assets/white_logo_full.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

View File

@ -18,3 +18,13 @@ spec:
name: scripts-caddy-service
port:
number: 80
- host: scripts.twhelp.app
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: scripts-caddy-service
port:
number: 80

View File

@ -1,13 +0,0 @@
image: gitea.dwysokinski.me/twhelp-packages/scripts:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}latest{{/if}}
{{#if build.tags}}
tags:
{{#each build.tags}}
- {{this}}
{{/each}}
{{/if}}
manifests:
-
image: gitea.dwysokinski.me/twhelp-packages/scripts:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}linux-amd64
platform:
architecture: amd64
os: linux

View File

@ -3,17 +3,10 @@
"version": "0.1.0",
"license": "MIT",
"scripts": {
"prepare": "husky install",
"build-single": "PUBLIC_URL=https://scripts.tribalwarshelp.com parcel build",
"build:extended-player-profile-user": "PREAMBLE=extended-player-profile yarn build-single ./src/extended-player-profile.user.ts",
"build:extended-player-profile-quickbar": "yarn build-single ./src/extended-player-profile.quickbar.ts",
"build:extended-map-popup-user": "PREAMBLE=extended-map-popup yarn build-single ./src/extended-map-popup.user.ts",
"build:extended-map-popup-quickbar": "yarn build-single ./src/extended-map-popup.quickbar.ts",
"build:extended-village-profile-user": "PREAMBLE=extended-village-profile yarn build-single ./src/extended-village-profile.user.ts",
"build:extended-village-profile-quickbar": "yarn build-single ./src/extended-village-profile.quickbar.ts",
"build:extended-tribe-profile-user": "PREAMBLE=extended-tribe-profile yarn build-single ./src/extended-tribe-profile.user.ts",
"build:extended-tribe-profile-quickbar": "yarn build-single ./src/extended-tribe-profile.quickbar.ts",
"build": "npm-run-all build:*",
"prepare": "husky",
"generate-client": "openapi --input src/lib/twhelp/openapi3.json --output src/lib/twhelp/generated --name TWHelpClient --useOptions --client axios",
"build": "rm -rf dist && yarn generate-client && parcel build ./src/*.user.ts ./src/*.quickbar.ts",
"postbuild": "PUBLIC_URL=https://scripts.twhelp.app node postbuild.js",
"lint": "eslint src/**/*.ts"
},
"targets": {
@ -28,30 +21,30 @@
"url": "https://dwysokinski.me/"
},
"browserslist": [
"since 2017-06"
"since 2020-01"
],
"devDependencies": {
"@commitlint/cli": "^17.4.4",
"@commitlint/config-conventional": "^17.4.4",
"@parcel/validator-eslint": "^2.8.3",
"@parcel/validator-typescript": "^2.8.3",
"@commitlint/cli": "^19.0.0",
"@commitlint/config-conventional": "^19.0.0",
"@parcel/validator-eslint": "^2.12.0",
"@parcel/validator-typescript": "^2.12.0",
"@types/jquery": "^3.5.14",
"@types/lodash": "^4.14.191",
"@types/node": "^18.11.17",
"@types/node": "^20.0.0",
"@typescript-eslint/eslint-plugin": "^5.50.0",
"@typescript-eslint/parser": "^5.50.0",
"buffer": "^5.5.0",
"eslint": "^7.32.0",
"eslint-config-prettier": "^8.6.0",
"husky": "^8.0.3",
"npm-run-all": "^4.1.5",
"parcel": "^2.8.3",
"prettier": "^2.8.3",
"eslint-config-prettier": "^9.0.0",
"husky": "^9.0.0",
"openapi-typescript-codegen": "^0.28.0",
"parcel": "^2.12.0",
"prettier": "^3.0.0",
"typescript": "^5.0.0"
},
"dependencies": {
"axios": "^1.2.2",
"date-fns": "^2.29.3",
"date-fns": "^3.0.0",
"lodash": "^4.17.21"
}
}

View File

@ -1,9 +1,15 @@
const preambles = {
const fs = require('fs');
const path = require('path');
const FILE_SUFFIX = '.user.js';
const DIST_DIR = 'dist';
const metadata = {
'extended-player-profile': `// ==UserScript==
// @name Extended player profile
// @version 1.1.2
// @version 1.2.0
// @description Adds additional info and actions on a player overview.
// @author Dawid Wysokiński - Kichiyaki - contact@dwysokinski.me
// @author Dawid Wysokiński - Kichiyaki - contact@twhelp.app
// @match https://*/game.php?*screen=info_player*
// @downloadURL ${process.env.PUBLIC_URL}/extended-player-profile.user.js
// @updateURL ${process.env.PUBLIC_URL}/extended-player-profile.user.js
@ -13,9 +19,9 @@ const preambles = {
// ==/UserScript==`,
'extended-map-popup': `// ==UserScript==
// @name Extended map popup
// @version 1.0.2
// @version 1.1.0
// @description Extends the map popup with additional info.
// @author Dawid Wysokiński - Kichiyaki - contact@dwysokinski.me
// @author Dawid Wysokiński - Kichiyaki - contact@twhelp.app
// @match https://*/game.php?*screen=map*
// @downloadURL ${process.env.PUBLIC_URL}/extended-map-popup.user.js
// @updateURL ${process.env.PUBLIC_URL}/extended-map-popup.user.js
@ -25,9 +31,9 @@ const preambles = {
// ==/UserScript==`,
'extended-village-profile': `// ==UserScript==
// @name Extended village profile
// @version 1.0.1
// @version 1.1.0
// @description Adds additional info and actions on a village overview.
// @author Dawid Wysokiński - Kichiyaki - contact@dwysokinski.me
// @author Dawid Wysokiński - Kichiyaki - contact@twhelp.app
// @match https://*/game.php?*screen=info_village*
// @downloadURL ${process.env.PUBLIC_URL}/extended-village-profile.user.js
// @updateURL ${process.env.PUBLIC_URL}/extended-village-profile.user.js
@ -37,9 +43,9 @@ const preambles = {
// ==/UserScript==`,
'extended-tribe-profile': `// ==UserScript==
// @name Extended tribe profile
// @version 1.0.0
// @version 1.1.0
// @description Adds additional info and actions on a tribe overview.
// @author Dawid Wysokiński - Kichiyaki - contact@dwysokinski.me
// @author Dawid Wysokiński - Kichiyaki - contact@twhelp.app
// @match https://*/game.php?*screen=info_ally*
// @downloadURL ${process.env.PUBLIC_URL}/extended-tribe-profile.user.js
// @updateURL ${process.env.PUBLIC_URL}/extended-tribe-profile.user.js
@ -49,11 +55,12 @@ const preambles = {
// ==/UserScript==`,
};
const preamble = preambles[process.env.PREAMBLE];
module.exports = preamble
? {
output: {
preamble: preamble,
},
}
: {};
Object.entries(metadata).forEach(([name, m]) => {
const p = path.join('.', DIST_DIR, `${name}${FILE_SUFFIX}`);
const data = fs.readFileSync(p);
const fd = fs.openSync(p, 'w+');
const insert = Buffer.from(`${m}\n`);
fs.writeSync(fd, insert, 0, insert.length, 0);
fs.writeSync(fd, data, 0, data.length, insert.length);
fs.closeSync(fd);
});

View File

@ -15,48 +15,54 @@ export type DialogTableColumn<T> = {
accessor: (row: T, index: number, rows: T[]) => string;
};
export type Cursor = {
next?: string;
self?: string;
};
export type LoadDataResult<T> = {
cursor?: Cursor;
data: T[];
total: number;
};
export class DialogTable<T> {
prevPageId: string;
selectId: string;
nextPageId: string;
private readonly prevPageId: string;
private readonly nextPageId: string;
private readonly prevCursors: Cursor[] = [];
constructor(
private readonly id: string,
private readonly columns: DialogTableColumn<T>[],
private readonly limit: number,
private readonly loadData: (
page: number,
cursor: string | undefined,
limit: number
) => Promise<LoadDataResult<T>>
) {
this.prevPageId = `${this.id}_page_prev`;
this.selectId = `${this.id}_page_select`;
this.nextPageId = `${this.id}_page_next`;
}
public async render() {
await this.renderPage(1);
await this.renderPage();
}
private async renderPage(page: number) {
window.Dialog.show(`${this.id}_loading`, `<p>${t('Loading')}...</p>`);
private async renderPage(pageCursor?: string) {
window.Dialog.show(this.id, `<p>${t('Loading')}...</p>`);
try {
const { data, total } = await this.loadData(page, this.limit);
const { data, cursor } = await this.loadData(pageCursor, this.limit);
window.Dialog.show(
this.id,
`
${this.buildPagination(page, total)}
${this.buildPagination(cursor)}
${this.buildTable(data)}
`
);
this.addEventListeners(page);
this.addEventListeners(cursor);
} catch (err) {
console.error(err);
window.Dialog.close();
@ -64,31 +70,17 @@ export class DialogTable<T> {
}
}
private buildPagination(page: number, total: number): string {
const maxPage = Math.ceil(total / this.limit);
const pageOpts = [];
for (let i = 1; i <= (page > maxPage ? page : maxPage); i++) {
pageOpts.push(
`<option${
i === page ? ' disabled selected' : ''
} value="${i}">${i}</option>`
);
}
private buildPagination(cursor?: Cursor): string {
return `
<div style="display: flex; flex-direction: row; align-items: center; justify-content: center; margin-bottom: 10px">
<button title="${t(
'Previous page'
)}" style="margin-right: 5px" class="btn" id="${this.prevPageId}"${
page <= 1 ? ' disabled' : ''
}>&lt;</button>
<select style="margin-right: 5px" id="${this.selectId}">
${pageOpts.join('')}
</select>
this.prevCursors.length === 0 ? ' disabled' : ''
}>&lt;</button>
<button title="${t('Next page')}" class="btn" id="${
this.nextPageId
}"${page >= maxPage ? ' disabled' : ''}>&gt;</button>
this.nextPageId
}"${!cursor?.next ? ' disabled' : ''}>&gt;</button>
</div>
`;
}
@ -116,27 +108,25 @@ export class DialogTable<T> {
`;
}
private addEventListeners(page: number) {
private addEventListeners(cursor?: Cursor) {
document
.querySelector('#' + this.prevPageId)
?.addEventListener('click', () => {
this.renderPage(page - 1);
});
document
.querySelector('#' + this.selectId)
?.addEventListener('change', (e: Event) => {
if (!(e.currentTarget instanceof HTMLSelectElement)) {
const prev = this.prevCursors.pop();
if (!prev) {
return;
}
this.renderPage(parseInt(e.currentTarget.value));
this.renderPage(prev.self);
});
document
.querySelector('#' + this.nextPageId)
?.addEventListener('click', () => {
this.renderPage(page + 1);
if (!cursor) {
return;
}
this.prevCursors.push(cursor);
this.renderPage(cursor.next);
});
}
}

View File

@ -1,13 +1,14 @@
import addSeconds from 'date-fns/addSeconds';
import {
Ennoblement,
ServerConfig,
TWHelpClient,
UnitInfo,
} from './lib/twhelp';
import { addSeconds } from 'date-fns/addSeconds';
import { Cache, InMemoryStorage } from './lib/cache';
import { calcDistance, calcLoyalty } from './lib/tw';
import { createTranslationFunc } from './utils';
import {
TWHelpClient,
Ennoblement,
UnitInfo,
ServerConfig,
AxiosHttpRequestWithTimeout,
} from './lib/twhelp';
declare global {
interface Window {
@ -43,25 +44,41 @@ const t = createTranslationFunc({
class TWHelpConnector {
private static readonly SERVER_CONFIG_CACHE_KEY =
'extended_map_popup_server_config';
private static readonly UNIT_INFO_CACHE_KEY = 'extended_map_popup_unit_info';
'extended_map_popup_server_config_v2';
private static readonly UNIT_INFO_CACHE_KEY =
'extended_map_popup_unit_info_v2';
private static readonly VILLAGE_CACHE_KEY_PREFIX =
'extended_map_popup_village_';
'extended_map_popup_village_v2_';
private readonly localStorageCache = new Cache(localStorage);
private readonly inMemoryCache = new Cache(new InMemoryStorage());
private readonly client: TWHelpClient;
constructor(
private readonly client: TWHelpClient,
readonly baseUrl: string,
private readonly version: string,
private readonly server: string
) {}
) {
this.client = new TWHelpClient(
{
BASE: baseUrl,
},
AxiosHttpRequestWithTimeout
);
}
serverConfig() {
return this.localStorageCache.load(
TWHelpConnector.SERVER_CONFIG_CACHE_KEY,
3600,
() => {
return this.client.serverConfig(this.version, this.server);
async () => {
return (
await this.client.servers.getServerConfig({
serverKey: this.server,
versionCode: this.version,
})
).data;
}
);
}
@ -70,8 +87,13 @@ class TWHelpConnector {
return this.localStorageCache.load(
TWHelpConnector.UNIT_INFO_CACHE_KEY,
3600,
() => {
return this.client.unitInfo(this.version, this.server);
async () => {
return (
await this.client.servers.getUnitInfo({
serverKey: this.server,
versionCode: this.version,
})
).data;
}
);
}
@ -84,15 +106,14 @@ class TWHelpConnector {
}
return this.inMemoryCache.load(key, 86400, async () => {
const ennoblements = await this.client.villageEnnoblements(
this.version,
this.server,
id,
{
limit: 1,
const ennoblements =
await this.client.ennoblements.listVillageEnnoblements({
versionCode: this.version,
serverKey: this.server,
sort: ['createdAt:DESC'],
}
);
villageId: id,
limit: 1,
});
return ennoblements.data.length > 0 ? ennoblements.data[0] : null;
});
}
@ -245,9 +266,9 @@ class Popup {
class ExtendedMapPopup {
connector: TWHelpConnector;
constructor(client: TWHelpClient) {
constructor(baseApiUrl: string) {
this.connector = new TWHelpConnector(
client,
baseApiUrl,
window.game_data.market,
window.game_data.world
);
@ -273,9 +294,7 @@ class ExtendedMapPopup {
return;
}
await new ExtendedMapPopup(
new TWHelpClient(process.env.TWHELP_API_BASE_URL ?? '')
)
await new ExtendedMapPopup(process.env.TWHELP_API_BASE_URL ?? '')
.run()
.catch((err) => {
console.log(err);

View File

@ -1,10 +1,16 @@
// Extended player profile
import { Player, PlayerSnapshot, TWHelpClient } from './lib/twhelp';
import { DialogTable } from './common/dialog-table';
import { InADayClient } from './lib/tw';
import { createTranslationFunc } from './utils';
import { buildURL } from './lib/twstats';
import {
TWHelpClient,
PlayerSnapshot,
Player,
AxiosHttpRequestWithTimeout,
} from './lib/twhelp';
import { DialogTable } from './common/dialog-table';
import { Cache } from './lib/cache';
const t = createTranslationFunc({
pl_PL: {
@ -59,62 +65,98 @@ const t = createTranslationFunc({
});
class TWHelpConnector {
private readonly client: TWHelpClient;
constructor(
private readonly client: TWHelpClient,
readonly baseUrl: string,
private readonly version: string,
private readonly server: string,
private readonly id: number
) {}
) {
this.client = new TWHelpClient(
{
BASE: baseUrl,
},
AxiosHttpRequestWithTimeout
);
}
player() {
return this.client.player(this.version, this.server, this.id);
async player() {
return (
await this.client.players.getPlayer({
versionCode: this.version,
serverKey: this.server,
playerId: this.id,
})
).data;
}
async latestSnapshot() {
const history = await this.playerHistory(1, 1);
return history.data.length > 0 ? history.data[0] : null;
const snapshot = await this.playerSnapshots(undefined, 1);
return snapshot.data.length > 0 ? snapshot.data[0] : null;
}
playerTribeChanges(page: number, limit: number) {
return this.client.playerTribeChanges(this.version, this.server, this.id, {
offset: (page - 1) * limit,
playerTribeChanges(cursor: string | undefined, limit: number) {
return this.client.tribeChanges.listPlayerTribeChanges({
versionCode: this.version,
serverKey: this.server,
playerId: this.id,
limit,
sort: ['createdAt:desc', 'id:asc'],
cursor,
sort: ['createdAt:DESC'],
});
}
playerEnnoblements(page: number, limit: number) {
return this.client.playerEnnoblements(this.version, this.server, this.id, {
offset: (page - 1) * limit,
playerEnnoblements(cursor: string | undefined, limit: number) {
return this.client.ennoblements.listPlayerEnnoblements({
versionCode: this.version,
serverKey: this.server,
playerId: this.id,
limit,
sort: ['createdAt:desc'],
cursor,
sort: ['createdAt:DESC'],
});
}
playerHistory(page: number, limit: number) {
return this.client.playerHistory(this.version, this.server, this.id, {
offset: (page - 1) * limit,
playerSnapshots(cursor: string | undefined, limit: number) {
return this.client.snapshots.listPlayerPlayerSnapshots({
versionCode: this.version,
serverKey: this.server,
playerId: this.id,
limit,
sort: ['date:desc'],
cursor,
sort: ['date:DESC'],
});
}
playerOtherServers(page: number, limit: number) {
return this.client.playerOtherServers(this.version, this.server, this.id, {
offset: (page - 1) * limit,
playerOtherServers(cursor: string | undefined, limit: number) {
return this.client.players.listVersionPlayers({
versionCode: this.version,
limit,
cursor,
id: [this.id],
});
}
}
class InADayConnector {
constructor(
private readonly client: InADayClient,
private readonly name: string
) {}
private static readonly CACHE_KEY_PREFIX =
'extended_player_profile_in_a_day_';
private readonly cache = new Cache(localStorage);
private readonly client = new InADayClient();
constructor(private readonly name: string) {}
player() {
return this.client.player(this.name);
return this.cache.load(
InADayConnector.CACHE_KEY_PREFIX + this.name,
600,
() => {
return this.client.player(this.name);
}
);
}
}
@ -160,20 +202,20 @@ class UI {
<tr>
<td>${t('Best rank')}:</td>
<td>${this.player.bestRank} (${new Date(
this.player.bestRankAt
).toLocaleString()})</td>
this.player.bestRankAt
).toLocaleString()})</td>
</tr>
<tr>
<td>${t('Most points')}:</td>
<td>${this.player.mostPoints.toLocaleString()} (${new Date(
this.player.mostPointsAt
).toLocaleString()})</td>
this.player.mostPointsAt
).toLocaleString()})</td>
</tr>
<tr>
<td>${t('Most villages')}:</td>
<td>${this.player.mostVillages.toLocaleString()} (${new Date(
this.player.mostVillagesAt
).toLocaleString()})</td>
this.player.mostVillagesAt
).toLocaleString()})</td>
</tr>
`
);
@ -204,38 +246,54 @@ class UI {
},
{
header: t('ODA'),
value: this.player.scoreAtt - (this.latestSnapshot?.scoreAtt ?? 0),
value:
this.player.opponentsDefeated.scoreAtt -
(this.latestSnapshot?.opponentsDefeated.scoreAtt ?? 0),
},
{
header: t('ODA - rank'),
value: this.player.rankAtt - (this.latestSnapshot?.rankAtt ?? 0),
value:
this.player.opponentsDefeated.rankAtt -
(this.latestSnapshot?.opponentsDefeated.rankAtt ?? 0),
rank: true,
},
{
header: t('ODD'),
value: this.player.scoreDef - (this.latestSnapshot?.scoreDef ?? 0),
value:
this.player.opponentsDefeated.scoreDef -
(this.latestSnapshot?.opponentsDefeated.scoreDef ?? 0),
},
{
header: t('ODD - rank'),
value: this.player.rankDef - (this.latestSnapshot?.rankDef ?? 0),
value:
this.player.opponentsDefeated.rankDef -
(this.latestSnapshot?.opponentsDefeated.rankDef ?? 0),
rank: true,
},
{
header: t('ODS'),
value: this.player.scoreSup - (this.latestSnapshot?.scoreSup ?? 0),
value:
this.player.opponentsDefeated.scoreSup -
(this.latestSnapshot?.opponentsDefeated.scoreSup ?? 0),
},
{
header: t('ODS - rank'),
value: this.player.rankSup - (this.latestSnapshot?.rankSup ?? 0),
value:
this.player.opponentsDefeated.rankSup -
(this.latestSnapshot?.opponentsDefeated.rankSup ?? 0),
rank: true,
},
{
header: t('OD'),
value: this.player.scoreTotal - (this.latestSnapshot?.scoreTotal ?? 0),
value:
this.player.opponentsDefeated.scoreTotal -
(this.latestSnapshot?.opponentsDefeated.scoreTotal ?? 0),
},
{
header: t('OD - rank'),
value: this.player.rankTotal - (this.latestSnapshot?.rankTotal ?? 0),
value:
this.player.opponentsDefeated.rankTotal -
(this.latestSnapshot?.opponentsDefeated.rankTotal ?? 0),
rank: true,
},
];
@ -364,8 +422,8 @@ class UI {
},
],
30,
(page: number, limit: number) => {
return this.twhelpConnector.playerOtherServers(page, limit);
(cursor: string | undefined, limit: number) => {
return this.twhelpConnector.playerOtherServers(cursor, limit);
}
).render();
}
@ -454,8 +512,8 @@ class UI {
},
],
30,
(page: number, limit: number) => {
return this.twhelpConnector.playerTribeChanges(page, limit);
(cursor: string | undefined, limit: number) => {
return this.twhelpConnector.playerTribeChanges(cursor, limit);
}
).render();
}
@ -473,8 +531,8 @@ class UI {
{
header: t('Tribe'),
accessor: (s) =>
s.tribe
? `<a href="${s.tribe.profileUrl}">${s.tribe.tag}</a>`
s.player.tribe
? `<a href="${s.player.tribe.profileUrl}">${s.player.tribe.tag}</a>`
: '-',
},
{
@ -489,29 +547,29 @@ class UI {
{
header: t('OD'),
accessor: (s) =>
`${s.scoreTotal.toLocaleString()} (<strong>${
s.rankTotal
`${s.opponentsDefeated.scoreTotal.toLocaleString()} (<strong>${
s.opponentsDefeated.rankTotal
}</strong>)`,
},
{
header: t('ODA'),
accessor: (s) =>
`${s.scoreAtt.toLocaleString()} (<strong>${s.rankAtt}</strong>)`,
`${s.opponentsDefeated.scoreAtt.toLocaleString()} (<strong>${s.opponentsDefeated.rankAtt}</strong>)`,
},
{
header: t('ODD'),
accessor: (s) =>
`${s.scoreDef.toLocaleString()} (<strong>${s.rankDef}</strong>)`,
`${s.opponentsDefeated.scoreDef.toLocaleString()} (<strong>${s.opponentsDefeated.rankDef}</strong>)`,
},
{
header: t('ODS'),
accessor: (s) =>
`${s.scoreSup.toLocaleString()} (<strong>${s.rankSup}</strong>)`,
`${s.opponentsDefeated.scoreSup.toLocaleString()} (<strong>${s.opponentsDefeated.rankSup}</strong>)`,
},
],
30,
(page: number, limit: number) => {
return this.twhelpConnector.playerHistory(page, limit);
(cursor: string | undefined, limit: number) => {
return this.twhelpConnector.playerSnapshots(cursor, limit);
}
).render();
}
@ -563,8 +621,8 @@ class UI {
},
],
30,
(page: number, limit: number) => {
return this.twhelpConnector.playerEnnoblements(page, limit);
(cursor: string | undefined, limit: number) => {
return this.twhelpConnector.playerEnnoblements(cursor, limit);
}
).render();
}
@ -574,18 +632,15 @@ class ExtendedPlayerProfile {
private readonly twhelpConnector: TWHelpConnector;
private readonly inADayConnector: InADayConnector;
constructor(twhelpClient: TWHelpClient, inADayClient: InADayClient) {
constructor(apiBaseUrl: string) {
this.twhelpConnector = new TWHelpConnector(
twhelpClient,
apiBaseUrl,
window.game_data.market,
window.game_data.world,
this.getPlayerId()
);
this.inADayConnector = new InADayConnector(
inADayClient,
this.getPlayerName()
);
this.inADayConnector = new InADayConnector(this.getPlayerName());
}
async run() {
@ -627,10 +682,7 @@ class ExtendedPlayerProfile {
return;
}
await new ExtendedPlayerProfile(
new TWHelpClient(process.env.TWHELP_API_BASE_URL ?? ''),
new InADayClient()
)
await new ExtendedPlayerProfile(process.env.TWHELP_API_BASE_URL ?? '')
.run()
.catch((err) => {
console.log(err);

View File

@ -1,7 +1,13 @@
import { Player, Tribe, TribeSnapshot, TWHelpClient } from './lib/twhelp';
import {
AxiosHttpRequestWithTimeout,
Player,
Tribe,
TribeSnapshot,
TWHelpClient,
} from './lib/twhelp';
import { createTranslationFunc } from './utils';
import { DialogTable } from './common/dialog-table';
import { buildURL } from './lib/twstats';
import { DialogTable } from './common/dialog-table';
const t = createTranslationFunc({
pl_PL: {
@ -44,47 +50,75 @@ const t = createTranslationFunc({
});
class TWHelpConnector {
private readonly client: TWHelpClient;
constructor(
private readonly client: TWHelpClient,
baseUrl: string,
private readonly version: string,
private readonly server: string,
private readonly id: number
) {}
) {
this.client = new TWHelpClient(
{
BASE: baseUrl,
},
AxiosHttpRequestWithTimeout
);
}
tribe() {
return this.client.tribe(this.version, this.server, this.id);
async tribe() {
return (
await this.client.tribes.getTribe({
versionCode: this.version,
serverKey: this.server,
tribeId: this.id,
})
).data;
}
tribeMembers() {
return this.client.tribeMembers(this.version, this.server, this.id);
return this.client.tribes.listTribeMembers({
versionCode: this.version,
serverKey: this.server,
tribeId: this.id,
});
}
async latestSnapshot() {
const history = await this.tribeHistory(1, 1);
return history.data.length > 0 ? history.data[0] : null;
const snapshot = await this.tribeSnapshots(undefined, 1);
return snapshot.data.length > 0 ? snapshot.data[0] : null;
}
tribeHistory(page: number, limit: number) {
return this.client.tribeHistory(this.version, this.server, this.id, {
offset: (page - 1) * limit,
tribeSnapshots(cursor: string | undefined, limit: number) {
return this.client.snapshots.listTribeTribeSnapshots({
versionCode: this.version,
serverKey: this.server,
tribeId: this.id,
cursor,
limit,
sort: ['date:desc'],
sort: ['date:DESC'],
});
}
tribeTribeChanges(page: number, limit: number) {
return this.client.tribeTribeChanges(this.version, this.server, this.id, {
offset: (page - 1) * limit,
memberChanges(cursor: string | undefined, limit: number) {
return this.client.tribeChanges.listTribeMemberChanges({
versionCode: this.version,
serverKey: this.server,
tribeId: this.id,
cursor,
limit,
sort: ['createdAt:desc'],
sort: ['createdAt:DESC'],
});
}
tribeEnnoblements(page: number, limit: number) {
return this.client.tribeEnnoblements(this.version, this.server, this.id, {
offset: (page - 1) * limit,
tribeEnnoblements(cursor: string | undefined, limit: number) {
return this.client.ennoblements.listTribeEnnoblements({
versionCode: this.version,
serverKey: this.server,
tribeId: this.id,
cursor,
limit,
sort: ['createdAt:desc'],
sort: ['createdAt:DESC'],
});
}
}
@ -133,20 +167,20 @@ class UI {
<tr>
<td>${t('Best rank')}:</td>
<td>${this.tribe.bestRank} (${new Date(
this.tribe.bestRankAt
).toLocaleString()})</td>
this.tribe.bestRankAt
).toLocaleString()})</td>
</tr>
<tr>
<td>${t('Most points')}:</td>
<td>${this.tribe.mostPoints.toLocaleString()} (${new Date(
this.tribe.mostPointsAt
).toLocaleString()})</td>
this.tribe.mostPointsAt
).toLocaleString()})</td>
</tr>
<tr>
<td>${t('Most villages')}:</td>
<td>${this.tribe.mostVillages.toLocaleString()} (${new Date(
this.tribe.mostVillagesAt
).toLocaleString()})</td>
this.tribe.mostVillagesAt
).toLocaleString()})</td>
</tr>
`
);
@ -185,29 +219,41 @@ class UI {
},
{
header: t('ODA'),
value: this.tribe.scoreAtt - (this.latestSnapshot?.scoreAtt ?? 0),
value:
this.tribe.opponentsDefeated.scoreAtt -
(this.latestSnapshot?.opponentsDefeated.scoreAtt ?? 0),
},
{
header: t('ODA - rank'),
value: this.tribe.rankAtt - (this.latestSnapshot?.rankAtt ?? 0),
value:
this.tribe.opponentsDefeated.rankAtt -
(this.latestSnapshot?.opponentsDefeated.rankAtt ?? 0),
rank: true,
},
{
header: t('ODD'),
value: this.tribe.scoreDef - (this.latestSnapshot?.scoreDef ?? 0),
value:
this.tribe.opponentsDefeated.scoreDef -
(this.latestSnapshot?.opponentsDefeated.scoreDef ?? 0),
},
{
header: t('ODD - rank'),
value: this.tribe.rankDef - (this.latestSnapshot?.rankDef ?? 0),
value:
this.tribe.opponentsDefeated.rankDef -
(this.latestSnapshot?.opponentsDefeated.rankDef ?? 0),
rank: true,
},
{
header: t('OD'),
value: this.tribe.scoreTotal - (this.latestSnapshot?.scoreTotal ?? 0),
value:
this.tribe.opponentsDefeated.scoreTotal -
(this.latestSnapshot?.opponentsDefeated.scoreTotal ?? 0),
},
{
header: t('OD - rank'),
value: this.tribe.rankTotal - (this.latestSnapshot?.rankTotal ?? 0),
value:
this.tribe.opponentsDefeated.rankTotal -
(this.latestSnapshot?.opponentsDefeated.rankTotal ?? 0),
rank: true,
},
];
@ -231,10 +277,10 @@ class UI {
r.value,
r.rank
)}">${
r.customFormat
? r.customFormat(r.value)
: Math.abs(r.value).toLocaleString()
}</td>
r.customFormat
? r.customFormat(r.value)
: Math.abs(r.value).toLocaleString()
}</td>
</tr>
`
)
@ -323,8 +369,8 @@ class UI {
},
],
30,
(page: number, limit: number) => {
return this.twhelpConnector.tribeTribeChanges(page, limit);
(cursor: string | undefined, limit: number) => {
return this.twhelpConnector.memberChanges(cursor, limit);
}
).render();
}
@ -359,24 +405,24 @@ class UI {
{
header: t('OD'),
accessor: (s) =>
`${s.scoreTotal.toLocaleString()} (<strong>${
s.rankTotal
`${s.opponentsDefeated.scoreTotal.toLocaleString()} (<strong>${
s.opponentsDefeated.rankTotal
}</strong>)`,
},
{
header: t('ODA'),
accessor: (s) =>
`${s.scoreAtt.toLocaleString()} (<strong>${s.rankAtt}</strong>)`,
`${s.opponentsDefeated.scoreAtt.toLocaleString()} (<strong>${s.opponentsDefeated.rankAtt}</strong>)`,
},
{
header: t('ODD'),
accessor: (s) =>
`${s.scoreDef.toLocaleString()} (<strong>${s.rankDef}</strong>)`,
`${s.opponentsDefeated.scoreDef.toLocaleString()} (<strong>${s.opponentsDefeated.rankDef}</strong>)`,
},
],
30,
(page: number, limit: number) => {
return this.twhelpConnector.tribeHistory(page, limit);
(cursor: string | undefined, limit: number) => {
return this.twhelpConnector.tribeSnapshots(cursor, limit);
}
).render();
}
@ -428,8 +474,8 @@ class UI {
},
],
30,
(page: number, limit: number) => {
return this.twhelpConnector.tribeEnnoblements(page, limit);
(cursor: string | undefined, limit: number) => {
return this.twhelpConnector.tribeEnnoblements(cursor, limit);
}
).render();
}
@ -477,10 +523,10 @@ class UI {
const member = this.members.find((m) => m.id === id);
[
(member?.rankAtt ?? 0).toString(),
(member?.rankDef ?? 0).toString(),
(member?.rankSup ?? 0).toString(),
(member?.rankTotal ?? 0).toString(),
(member?.opponentsDefeated.rankAtt ?? 0).toString(),
(member?.opponentsDefeated.rankDef ?? 0).toString(),
(member?.opponentsDefeated.rankSup ?? 0).toString(),
(member?.opponentsDefeated.rankTotal ?? 0).toString(),
member?.lastActivityAt
? new Date(member.lastActivityAt).toLocaleString()
: '-',
@ -501,9 +547,9 @@ class UI {
class ExtendedTribeProfile {
private readonly twhelpConnector: TWHelpConnector;
constructor(twhelpClient: TWHelpClient) {
constructor(apiBaseUrl: string) {
this.twhelpConnector = new TWHelpConnector(
twhelpClient,
apiBaseUrl,
window.game_data.market,
window.game_data.world,
this.getTribeId()
@ -543,9 +589,7 @@ class ExtendedTribeProfile {
return;
}
await new ExtendedTribeProfile(
new TWHelpClient(process.env.TWHELP_API_BASE_URL ?? '')
)
await new ExtendedTribeProfile(process.env.TWHELP_API_BASE_URL ?? '')
.run()
.catch((err) => {
console.log(err);

View File

@ -1,8 +1,13 @@
import { Ennoblement, ServerConfig, TWHelpClient } from './lib/twhelp';
import { createTranslationFunc } from './utils';
import { DialogTable } from './common/dialog-table';
import { calcLoyalty } from './lib/tw';
import { Cache } from './lib/cache';
import {
TWHelpClient,
Ennoblement,
ServerConfig,
AxiosHttpRequestWithTimeout,
} from './lib/twhelp';
import { DialogTable } from './common/dialog-table';
const t = createTranslationFunc({
pl_PL: {
@ -22,32 +27,47 @@ const t = createTranslationFunc({
class TWHelpConnector {
private static SERVER_CONFIG_CACHE_KEY =
'extended_village_profile_server_config';
'extended_village_profile_server_config_v2';
private cache = new Cache(localStorage);
private client: TWHelpClient;
constructor(
private readonly client: TWHelpClient,
readonly baseUrl: string,
private readonly version: string,
private readonly server: string,
private readonly id: number
) {}
) {
this.client = new TWHelpClient(
{
BASE: baseUrl,
},
AxiosHttpRequestWithTimeout
);
}
serverConfig() {
return this.cache.load(
TWHelpConnector.SERVER_CONFIG_CACHE_KEY,
3600,
() => {
return this.client.serverConfig(this.version, this.server);
async () => {
return (
await this.client.servers.getServerConfig({
versionCode: this.version,
serverKey: this.server,
})
).data;
}
);
}
async latestEnnoblement() {
const ennoblements = await this.client.villageEnnoblements(
this.version,
this.server,
this.id,
const ennoblements = await this.client.ennoblements.listVillageEnnoblements(
{
versionCode: this.version,
serverKey: this.server,
villageId: this.id,
limit: 1,
sort: ['createdAt:DESC'],
}
@ -55,11 +75,14 @@ class TWHelpConnector {
return ennoblements.data.length > 0 ? ennoblements.data[0] : null;
}
villageEnnoblements(page: number, limit: number) {
return this.client.villageEnnoblements(this.version, this.server, this.id, {
offset: (page - 1) * limit,
limit,
sort: ['createdAt:desc'],
villageEnnoblements(cursor: string | undefined, limit: number) {
return this.client.ennoblements.listVillageEnnoblements({
cursor,
versionCode: this.version,
serverKey: this.server,
villageId: this.id,
limit: limit,
sort: ['createdAt:DESC'],
});
}
}
@ -138,7 +161,7 @@ class UI {
private async showEnnoblements(e: Event) {
e.preventDefault();
await new DialogTable(
await new DialogTable<Ennoblement>(
DialogId.ENNOBLEMENTS,
[
{
@ -182,8 +205,8 @@ class UI {
},
],
30,
(page: number, limit: number) => {
return this.connector.villageEnnoblements(page, limit);
async (cursor, limit) => {
return this.connector.villageEnnoblements(cursor, limit);
}
).render();
}
@ -191,9 +214,9 @@ class UI {
class ExtendedVillageProfile {
connector: TWHelpConnector;
constructor(client: TWHelpClient) {
constructor(apiBaseUrl: string) {
this.connector = new TWHelpConnector(
client,
apiBaseUrl,
window.game_data.market,
window.game_data.world,
this.getVillageId()
@ -226,9 +249,7 @@ class ExtendedVillageProfile {
return;
}
await new ExtendedVillageProfile(
new TWHelpClient(process.env.TWHELP_API_BASE_URL ?? '')
)
await new ExtendedVillageProfile(process.env.TWHELP_API_BASE_URL ?? '')
.run()
.catch((err) => {
console.log(err);

View File

@ -1,5 +1,5 @@
import addSeconds from 'date-fns/addSeconds';
import isAfter from 'date-fns/isAfter';
import { addSeconds } from 'date-fns/addSeconds';
import { isAfter } from 'date-fns/isAfter';
export interface Storage {
getItem(key: string): string | null;

View File

@ -1,4 +1,4 @@
import differenceInMinutes from 'date-fns/differenceInMinutes';
import { differenceInMinutes } from 'date-fns/differenceInMinutes';
import { LOYALTY_AFTER_CONQUER, MAX_LOYALTY } from './constants';
export const calcLoyalty = (

View File

@ -1,424 +0,0 @@
import axios, {
AxiosInstance,
AxiosResponseHeaders,
RawAxiosResponseHeaders,
} from 'axios';
export type ServerMeta = {
key: string;
open: boolean;
};
export type Tribe = {
id: number;
name: string;
tag: string;
numMembers: number;
numVillages: number;
points: number;
allPoints: number;
rank: number;
dominance: number;
rankAtt: number;
scoreAtt: number;
rankDef: number;
scoreDef: number;
rankTotal: number;
scoreTotal: number;
profileUrl: string;
bestRank: number;
bestRankAt: string;
mostPoints: number;
mostPointsAt: string;
mostVillages: number;
mostVillagesAt: string;
createdAt: string;
deletedAt: string | null;
};
export type TribeMeta = {
id: number;
name: string;
tag: string;
profileUrl: string;
};
export type Player = {
id: number;
points: number;
rank: number;
numVillages: number;
scoreAtt: number;
rankAtt: number;
scoreDef: number;
rankDef: number;
scoreSup: number;
rankSup: number;
scoreTotal: number;
rankTotal: number;
bestRank: number;
bestRankAt: string;
mostPoints: number;
mostPointsAt: string;
mostVillages: number;
mostVillagesAt: string;
lastActivityAt: string;
createdAt: string;
tribe: TribeMeta | null;
};
export type PlayerWithServer = Player & {
server: ServerMeta;
};
export type PlayerMeta = {
id: number;
name: string;
profileUrl: string;
tribe: TribeMeta | null;
};
export type VillageMeta = {
id: number;
fullName: string;
profileUrl: string;
x: number;
y: number;
continent: string;
player: PlayerMeta | null;
};
export type TribeChange = {
id: number;
newTribe: TribeMeta | null;
player: PlayerMeta;
createdAt: string;
};
export type Ennoblement = {
id: number;
points: number;
newOwner: PlayerMeta | null;
village: VillageMeta;
createdAt: string;
};
export type TribeSnapshot = {
id: number;
numMembers: number;
numVillages: number;
points: number;
allPoints: number;
rank: number;
dominance: number;
rankAtt: number;
scoreAtt: number;
rankDef: number;
scoreDef: number;
rankTotal: number;
scoreTotal: number;
date: string;
};
export type PlayerSnapshot = {
id: number;
tribe: TribeMeta | null;
points: number;
numVillages: number;
rank: number;
rankAtt: number;
rankDef: number;
rankSup: number;
rankTotal: number;
scoreAtt: number;
scoreDef: number;
scoreSup: number;
scoreTotal: number;
date: string;
};
export type ServerConfig = {
speed: number;
unitSpeed: number;
snob: {
maxDist: number;
};
};
export type Unit = {
speed: number;
};
export type UnitInfo = {
archer: Unit;
axe: Unit;
catapult: Unit;
heavy: Unit;
knight: Unit;
light: Unit;
marcher: Unit;
militia: Unit;
ram: Unit;
snob: Unit;
spear: Unit;
spy: Unit;
sword: Unit;
};
export type ListResult<T> = {
data: T[];
total: number;
};
export type ListTribeChangesQueryParams = {
offset?: number;
limit?: number;
sort?: string[];
};
export type ListEnnoblementsParams = {
offset?: number;
limit?: number;
sort?: string[];
};
export type ListTribeMembers = {
offset?: number;
limit?: number;
sort?: string[];
};
export type ListSnapshotsParams = {
offset?: number;
limit?: number;
sort?: string[];
};
export type ListPlayerOtherServersParams = {
offset?: number;
limit?: number;
};
export class TWHelpClient {
client: AxiosInstance;
constructor(url: string, timeout = 10000) {
this.client = axios.create({
baseURL: url,
timeout,
});
}
public async serverConfig(
version: string,
server: string
): Promise<ServerConfig> {
const resp = await this.client.get(
`/api/v1/versions/${version}/servers/${server}/config`
);
return resp.data.data;
}
public async unitInfo(version: string, server: string): Promise<UnitInfo> {
const resp = await this.client.get(
`/api/v1/versions/${version}/servers/${server}/unit-info`
);
return resp.data.data;
}
public async tribe(
version: string,
server: string,
id: number
): Promise<Tribe> {
const resp = await this.client.get(
`/api/v1/versions/${version}/servers/${server}/tribes/${id}`
);
return resp.data.data;
}
public async tribeHistory(
version: string,
server: string,
id: number,
queryParams?: ListSnapshotsParams
): Promise<ListResult<TribeSnapshot>> {
const queryString = queryParams ? this.buildQueryString(queryParams) : '';
const resp = await this.client.get(
`/api/v1/versions/${version}/servers/${server}/tribes/${id}/history?${queryString}`
);
return {
data: resp.data.data,
total: this.parseTotal(resp.headers),
};
}
public async tribeTribeChanges(
version: string,
server: string,
id: number,
queryParams?: ListTribeChangesQueryParams
): Promise<ListResult<TribeChange>> {
const queryString = queryParams ? this.buildQueryString(queryParams) : '';
const resp = await this.client.get(
`/api/v1/versions/${version}/servers/${server}/tribes/${id}/tribe-changes?${queryString}`
);
return {
data: resp.data.data,
total: this.parseTotal(resp.headers),
};
}
public async tribeEnnoblements(
version: string,
server: string,
id: number,
queryParams?: ListEnnoblementsParams
): Promise<ListResult<Ennoblement>> {
const queryString = queryParams ? this.buildQueryString(queryParams) : '';
const resp = await this.client.get(
`/api/v1/versions/${version}/servers/${server}/tribes/${id}/ennoblements?${queryString}`
);
return {
data: resp.data.data,
total: this.parseTotal(resp.headers),
};
}
public async tribeMembers(
version: string,
server: string,
id: number,
queryParams?: ListTribeMembers
): Promise<ListResult<Player>> {
const queryString = queryParams ? this.buildQueryString(queryParams) : '';
const resp = await this.client.get(
`/api/v1/versions/${version}/servers/${server}/tribes/${id}/members?${queryString}`
);
return {
data: resp.data.data,
total: this.parseTotal(resp.headers),
};
}
public async player(
version: string,
server: string,
id: number
): Promise<Player> {
const resp = await this.client.get(
`/api/v1/versions/${version}/servers/${server}/players/${id}`
);
return resp.data.data;
}
public async playerTribeChanges(
version: string,
server: string,
id: number,
queryParams?: ListTribeChangesQueryParams
): Promise<ListResult<TribeChange>> {
const queryString = queryParams ? this.buildQueryString(queryParams) : '';
const resp = await this.client.get(
`/api/v1/versions/${version}/servers/${server}/players/${id}/tribe-changes?${queryString}`
);
return {
data: resp.data.data,
total: this.parseTotal(resp.headers),
};
}
public async playerEnnoblements(
version: string,
server: string,
id: number,
queryParams?: ListEnnoblementsParams
): Promise<ListResult<Ennoblement>> {
const queryString = queryParams ? this.buildQueryString(queryParams) : '';
const resp = await this.client.get(
`/api/v1/versions/${version}/servers/${server}/players/${id}/ennoblements?${queryString}`
);
return {
data: resp.data.data,
total: this.parseTotal(resp.headers),
};
}
public async playerHistory(
version: string,
server: string,
id: number,
queryParams?: ListSnapshotsParams
): Promise<ListResult<PlayerSnapshot>> {
const queryString = queryParams ? this.buildQueryString(queryParams) : '';
const resp = await this.client.get(
`/api/v1/versions/${version}/servers/${server}/players/${id}/history?${queryString}`
);
return {
data: resp.data.data,
total: this.parseTotal(resp.headers),
};
}
public async playerOtherServers(
version: string,
server: string,
id: number,
queryParams?: ListPlayerOtherServersParams
): Promise<ListResult<PlayerWithServer>> {
const queryString = queryParams ? this.buildQueryString(queryParams) : '';
const resp = await this.client.get(
`/api/v1/versions/${version}/servers/${server}/players/${id}/other-servers?${queryString}`
);
return {
data: resp.data.data,
total: this.parseTotal(resp.headers),
};
}
public async villageEnnoblements(
version: string,
server: string,
id: number,
queryParams?: ListEnnoblementsParams
): Promise<ListResult<Ennoblement>> {
const queryString = queryParams ? this.buildQueryString(queryParams) : '';
const resp = await this.client.get(
`/api/v1/versions/${version}/servers/${server}/villages/${id}/ennoblements?${queryString}`
);
return {
data: resp.data.data,
total: this.parseTotal(resp.headers),
};
}
private buildQueryString(
queryParams: Record<string, string | boolean | number | Date | string[]>
): string {
const params = new URLSearchParams();
for (const [name, val] of Object.entries(queryParams)) {
if (Array.isArray(val)) {
val.forEach((s) => {
params.append(name, s);
});
continue;
}
if (val instanceof Date) {
params.set(name, val.toISOString());
continue;
}
params.set(name, val.toString());
}
return params.toString();
}
private parseTotal(
headers: RawAxiosResponseHeaders | AxiosResponseHeaders
): number {
return parseInt(headers['x-total-count'] ?? '0');
}
}

1
src/lib/twhelp/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
generated

2
src/lib/twhelp/index.ts Normal file
View File

@ -0,0 +1,2 @@
export * from './generated';
export * from './timeout';

File diff suppressed because one or more lines are too long

20
src/lib/twhelp/timeout.ts Normal file
View File

@ -0,0 +1,20 @@
import axios from 'axios';
import { request as __request } from './generated/core/request';
import { CancelablePromise } from './generated/core/CancelablePromise';
import { BaseHttpRequest } from './generated/core/BaseHttpRequest';
import { ApiRequestOptions } from './generated/core/ApiRequestOptions';
import type { OpenAPIConfig } from './generated/core/OpenAPI';
export class AxiosHttpRequestWithTimeout extends BaseHttpRequest {
axiosInstance = axios.create({
timeout: 5000,
});
constructor(config: OpenAPIConfig) {
super(config);
}
public override request<T>(options: ApiRequestOptions): CancelablePromise<T> {
return __request(this.config, options, this.axiosInstance);
}
}

3456
yarn.lock

File diff suppressed because it is too large Load Diff