@nekosuneprojects/gaming-infos 2.2.0 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +77 -3
- package/README.md +62 -495
- package/index.js +3 -223
- package/package.json +53 -46
- package/src/providers/vrchat.js +11 -0
- package/src/providers/warframe.js +7 -0
- package/src/registry.js +23 -0
- package/.github/workflows/npm-publish-github-packages.yml +0 -56
- package/.github/workflows/npm-publish.yml +0 -71
- package/.github/workflows/sync-api-cache.yml +0 -72
- package/CACHE_SYNC.md +0 -172
- package/CONTRIBUTING.md +0 -217
- package/DATA.md +0 -292
- package/data/arknightsendfield/meta.json +0 -14
- package/data/fortnite/meta.json +0 -14
- package/data/game-codes/.gitkeep +0 -0
- package/data/genshinimpact/characters/albedo.json +0 -11
- package/data/genshinimpact/characters/alhaitham.json +0 -12
- package/data/genshinimpact/characters/aloy.json +0 -11
- package/data/genshinimpact/characters/amber.json +0 -12
- package/data/genshinimpact/characters/aratakiitto.json +0 -12
- package/data/genshinimpact/characters/arlecchino.json +0 -12
- package/data/genshinimpact/characters/baizhu.json +0 -12
- package/data/genshinimpact/characters/barbara.json +0 -11
- package/data/genshinimpact/characters/beidou.json +0 -12
- package/data/genshinimpact/characters/bennett.json +0 -11
- package/data/genshinimpact/characters/candace.json +0 -12
- package/data/genshinimpact/characters/charlotte.json +0 -11
- package/data/genshinimpact/characters/chasca.json +0 -11
- package/data/genshinimpact/characters/chevreuse.json +0 -11
- package/data/genshinimpact/characters/chiori.json +0 -11
- package/data/genshinimpact/characters/chongyun.json +0 -12
- package/data/genshinimpact/characters/citlali.json +0 -11
- package/data/genshinimpact/characters/clorinde.json +0 -11
- package/data/genshinimpact/characters/collei.json +0 -12
- package/data/genshinimpact/characters/cyno.json +0 -12
- package/data/genshinimpact/characters/dahlia.json +0 -10
- package/data/genshinimpact/characters/dehya.json +0 -11
- package/data/genshinimpact/characters/diluc.json +0 -11
- package/data/genshinimpact/characters/diona.json +0 -11
- package/data/genshinimpact/characters/dori.json +0 -11
- package/data/genshinimpact/characters/durin.json +0 -11
- package/data/genshinimpact/characters/emilie.json +0 -11
- package/data/genshinimpact/characters/escoffier.json +0 -12
- package/data/genshinimpact/characters/eula.json +0 -11
- package/data/genshinimpact/characters/faruzan.json +0 -12
- package/data/genshinimpact/characters/fischl.json +0 -12
- package/data/genshinimpact/characters/freminet.json +0 -11
- package/data/genshinimpact/characters/furina.json +0 -12
- package/data/genshinimpact/characters/gaming.json +0 -11
- package/data/genshinimpact/characters/ganyu.json +0 -11
- package/data/genshinimpact/characters/gorou.json +0 -12
- package/data/genshinimpact/characters/hutao.json +0 -12
- package/data/genshinimpact/characters/iansan.json +0 -11
- package/data/genshinimpact/characters/ineffa.json +0 -11
- package/data/genshinimpact/characters/jean.json +0 -11
- package/data/genshinimpact/characters/kachina.json +0 -11
- package/data/genshinimpact/characters/kaedeharakazuha.json +0 -12
- package/data/genshinimpact/characters/kaeya.json +0 -11
- package/data/genshinimpact/characters/kamisatoayaka.json +0 -11
- package/data/genshinimpact/characters/kamisatoayato.json +0 -11
- package/data/genshinimpact/characters/kaveh.json +0 -12
- package/data/genshinimpact/characters/keqing.json +0 -11
- package/data/genshinimpact/characters/kinich.json +0 -11
- package/data/genshinimpact/characters/kirara.json +0 -11
- package/data/genshinimpact/characters/klee.json +0 -11
- package/data/genshinimpact/characters/kujousara.json +0 -11
- package/data/genshinimpact/characters/kukishinobu.json +0 -12
- package/data/genshinimpact/characters/lanyan.json +0 -11
- package/data/genshinimpact/characters/layla.json +0 -11
- package/data/genshinimpact/characters/lisa.json +0 -12
- package/data/genshinimpact/characters/lohen.json +0 -11
- package/data/genshinimpact/characters/lynette.json +0 -11
- package/data/genshinimpact/characters/lyney.json +0 -11
- package/data/genshinimpact/characters/mavuika.json +0 -11
- package/data/genshinimpact/characters/mikaschmidt.json +0 -11
- package/data/genshinimpact/characters/mona.json +0 -12
- package/data/genshinimpact/characters/mualani.json +0 -11
- package/data/genshinimpact/characters/nahida.json +0 -12
- package/data/genshinimpact/characters/navia.json +0 -11
- package/data/genshinimpact/characters/neuvillette.json +0 -11
- package/data/genshinimpact/characters/nilou.json +0 -11
- package/data/genshinimpact/characters/ningguang.json +0 -11
- package/data/genshinimpact/characters/noelle.json +0 -12
- package/data/genshinimpact/characters/ororon.json +0 -11
- package/data/genshinimpact/characters/prune.json +0 -10
- package/data/genshinimpact/characters/qiqi.json +0 -12
- package/data/genshinimpact/characters/raidenshogun.json +0 -12
- package/data/genshinimpact/characters/razor.json +0 -11
- package/data/genshinimpact/characters/rosaria.json +0 -12
- package/data/genshinimpact/characters/sangonomiyakokomi.json +0 -12
- package/data/genshinimpact/characters/sayu.json +0 -11
- package/data/genshinimpact/characters/sethos.json +0 -11
- package/data/genshinimpact/characters/shenhe.json +0 -12
- package/data/genshinimpact/characters/shikanoinheizou.json +0 -12
- package/data/genshinimpact/characters/sigewinne.json +0 -11
- package/data/genshinimpact/characters/skirk.json +0 -11
- package/data/genshinimpact/characters/sucrose.json +0 -12
- package/data/genshinimpact/characters/thoma.json +0 -11
- package/data/genshinimpact/characters/tighnari.json +0 -12
- package/data/genshinimpact/characters/varesa.json +0 -11
- package/data/genshinimpact/characters/varka.json +0 -10
- package/data/genshinimpact/characters/venti.json +0 -12
- package/data/genshinimpact/characters/wanderer.json +0 -11
- package/data/genshinimpact/characters/wriothesley.json +0 -12
- package/data/genshinimpact/characters/xiangling.json +0 -12
- package/data/genshinimpact/characters/xianyun.json +0 -11
- package/data/genshinimpact/characters/xiao.json +0 -11
- package/data/genshinimpact/characters/xilonen.json +0 -11
- package/data/genshinimpact/characters/xingqiu.json +0 -12
- package/data/genshinimpact/characters/xinyan.json +0 -12
- package/data/genshinimpact/characters/yaemiko.json +0 -12
- package/data/genshinimpact/characters/yanfei.json +0 -12
- package/data/genshinimpact/characters/yaoyao.json +0 -12
- package/data/genshinimpact/characters/yelan.json +0 -11
- package/data/genshinimpact/characters/yoimiya.json +0 -12
- package/data/genshinimpact/characters/yumemizukimizuki.json +0 -11
- package/data/genshinimpact/characters/yunjin.json +0 -11
- package/data/genshinimpact/characters/zhongli.json +0 -11
- package/data/genshinimpact/characters/zibai.json +0 -11
- package/data/genshinimpact/meta.json +0 -14
- package/data/honkaistarrail/characters/acheron.json +0 -12
- package/data/honkaistarrail/characters/aglaea.json +0 -12
- package/data/honkaistarrail/characters/anaxa.json +0 -12
- package/data/honkaistarrail/characters/argenti.json +0 -12
- package/data/honkaistarrail/characters/arlan.json +0 -12
- package/data/honkaistarrail/characters/ashveil.json +0 -12
- package/data/honkaistarrail/characters/asta.json +0 -12
- package/data/honkaistarrail/characters/aventurine.json +0 -12
- package/data/honkaistarrail/characters/bailu.json +0 -12
- package/data/honkaistarrail/characters/blackswan.json +0 -12
- package/data/honkaistarrail/characters/blade.json +0 -12
- package/data/honkaistarrail/characters/boothill.json +0 -12
- package/data/honkaistarrail/characters/bronya.json +0 -12
- package/data/honkaistarrail/characters/castorice.json +0 -12
- package/data/honkaistarrail/characters/cerydra.json +0 -12
- package/data/honkaistarrail/characters/cipher.json +0 -12
- package/data/honkaistarrail/characters/clara.json +0 -12
- package/data/honkaistarrail/characters/constance.json +0 -12
- package/data/honkaistarrail/characters/cyrene.json +0 -12
- package/data/honkaistarrail/characters/danheng.json +0 -12
- package/data/honkaistarrail/characters/drratio.json +0 -12
- package/data/honkaistarrail/characters/feixiao.json +0 -12
- package/data/honkaistarrail/characters/firefly.json +0 -12
- package/data/honkaistarrail/characters/fuxuan.json +0 -12
- package/data/honkaistarrail/characters/gallagher.json +0 -12
- package/data/honkaistarrail/characters/gepard.json +0 -12
- package/data/honkaistarrail/characters/guinaifen.json +0 -12
- package/data/honkaistarrail/characters/hanya.json +0 -12
- package/data/honkaistarrail/characters/herta.json +0 -12
- package/data/honkaistarrail/characters/himeko.json +0 -13
- package/data/honkaistarrail/characters/hook.json +0 -12
- package/data/honkaistarrail/characters/huohuo.json +0 -12
- package/data/honkaistarrail/characters/hyacine.json +0 -12
- package/data/honkaistarrail/characters/hysilens.json +0 -12
- package/data/honkaistarrail/characters/jade.json +0 -12
- package/data/honkaistarrail/characters/jiaoqiu.json +0 -12
- package/data/honkaistarrail/characters/jingliu.json +0 -12
- package/data/honkaistarrail/characters/jingyuan.json +0 -12
- package/data/honkaistarrail/characters/kafka.json +0 -12
- package/data/honkaistarrail/characters/lingsha.json +0 -12
- package/data/honkaistarrail/characters/lisushang.json +0 -12
- package/data/honkaistarrail/characters/luka.json +0 -12
- package/data/honkaistarrail/characters/luocha.json +0 -12
- package/data/honkaistarrail/characters/lynx.json +0 -12
- package/data/honkaistarrail/characters/march7th.json +0 -12
- package/data/honkaistarrail/characters/misha.json +0 -12
- package/data/honkaistarrail/characters/moze.json +0 -12
- package/data/honkaistarrail/characters/mydei.json +0 -12
- package/data/honkaistarrail/characters/natasha.json +0 -12
- package/data/honkaistarrail/characters/pela.json +0 -12
- package/data/honkaistarrail/characters/phainon.json +0 -12
- package/data/honkaistarrail/characters/qingque.json +0 -12
- package/data/honkaistarrail/characters/rappa.json +0 -12
- package/data/honkaistarrail/characters/robin.json +0 -12
- package/data/honkaistarrail/characters/ruanmei.json +0 -12
- package/data/honkaistarrail/characters/sampo.json +0 -12
- package/data/honkaistarrail/characters/seele.json +0 -12
- package/data/honkaistarrail/characters/serval.json +0 -12
- package/data/honkaistarrail/characters/silverwolf.json +0 -12
- package/data/honkaistarrail/characters/sparkle.json +0 -12
- package/data/honkaistarrail/characters/tingyun.json +0 -12
- package/data/honkaistarrail/characters/topaz.json +0 -12
- package/data/honkaistarrail/characters/tribbie.json +0 -12
- package/data/honkaistarrail/characters/weltyang.json +0 -12
- package/data/honkaistarrail/characters/xueyi.json +0 -12
- package/data/honkaistarrail/characters/yanqing.json +0 -12
- package/data/honkaistarrail/characters/yaoguang.json +0 -12
- package/data/honkaistarrail/characters/yukong.json +0 -12
- package/data/honkaistarrail/characters/yunli.json +0 -12
- package/data/honkaistarrail/meta.json +0 -14
- package/data/nte/characters/adler.json +0 -14
- package/data/nte/characters/aurelia.json +0 -14
- package/data/nte/characters/baicang.json +0 -14
- package/data/nte/characters/chaos.json +0 -14
- package/data/nte/characters/chiz.json +0 -14
- package/data/nte/characters/daffodill.json +0 -14
- package/data/nte/characters/edgar.json +0 -14
- package/data/nte/characters/esperzero.json +0 -14
- package/data/nte/characters/fadia.json +0 -14
- package/data/nte/characters/haniel.json +0 -14
- package/data/nte/characters/hathor.json +0 -14
- package/data/nte/characters/hotori.json +0 -14
- package/data/nte/characters/iroi.json +0 -14
- package/data/nte/characters/jiuyuan.json +0 -14
- package/data/nte/characters/lacrimosa.json +0 -14
- package/data/nte/characters/mint.json +0 -14
- package/data/nte/characters/nanally.json +0 -14
- package/data/nte/characters/sakiri.json +0 -14
- package/data/nte/characters/shinku.json +0 -14
- package/data/nte/characters/skia.json +0 -14
- package/data/nte/meta.json +0 -14
- package/data/toweroffantasy/meta.json +0 -14
- package/data/vrchat/avatars/.gitkeep +0 -0
- package/data/vrchat/groups/clubzodiac.json +0 -7
- package/data/vrchat/groups/dirtydancers.json +0 -7
- package/data/vrchat/groups/drumsynews.json +0 -7
- package/data/vrchat/groups/ebola20.json +0 -7
- package/data/vrchat/groups/internationaldancersassociation.json +0 -7
- package/data/vrchat/groups/kannagang.json +0 -6
- package/data/vrchat/groups/lolisquad.json +0 -7
- package/data/vrchat/groups/nekonightsnightclub.json +0 -7
- package/data/vrchat/groups/nekostudios.json +0 -7
- package/data/vrchat/groups/nekosunecommunity.json +0 -7
- package/data/vrchat/groups/voidclub.json +0 -7
- package/data/vrchat/groups/voltdanceclub.json +0 -7
- package/data/vrchat/groups/vrceventsgroup.json +0 -7
- package/data/vrchat/groups/vrchatcommunitydiscord.json +0 -6
- package/data/vrchat/meta.json +0 -13
- package/data/vrchat/players/alto.json +0 -9
- package/data/vrchat/players/arcadum.json +0 -10
- package/data/vrchat/players/chairhandler.json +0 -9
- package/data/vrchat/players/chipz.json +0 -9
- package/data/vrchat/players/hikarivr.json +0 -10
- package/data/vrchat/players/kimple.json +0 -10
- package/data/vrchat/players/linkzr.json +0 -8
- package/data/vrchat/players/nagzz21.json +0 -9
- package/data/vrchat/players/nebride.json +0 -10
- package/data/vrchat/players/nekosunevr.json +0 -10
- package/data/vrchat/players/pokelawls.json +0 -9
- package/data/vrchat/players/qwonk.json +0 -8
- package/data/vrchat/players/roflgator.json +0 -10
- package/data/vrchat/players/scifri.json +0 -7
- package/data/vrchat/players/sodapoppin.json +0 -9
- package/data/vrchat/players/woops.json +0 -9
- package/data/vrchat/players/zentreya.json +0 -10
- package/data/vrchat/worlds/ascensionacademy.json +0 -7
- package/data/vrchat/worlds/clubvgl.json +0 -8
- package/data/vrchat/worlds/fightfinder.json +0 -8
- package/data/vrchat/worlds/hangouthouse.json +0 -7
- package/data/vrchat/worlds/nekostudioshalloween.json +0 -9
- package/data/vrchat/worlds/nekostudiosnewyear.json +0 -9
- package/data/vrchat/worlds/nekostudiosxmas.json +0 -9
- package/data/vrchat/worlds/nekosunevranimations2023.json +0 -9
- package/data/vrchat/worlds/nekosunevranimations2024.json +0 -9
- package/data/vrchat/worlds/nekosunevranimations2025.json +0 -9
- package/data/vrchat/worlds/rumhamsavatarworld.json +0 -7
- package/data/vrchat/worlds/smewsranch.json +0 -7
- package/data/vrchat/worlds/smewsroom.json +0 -7
- package/data/vrchat/worlds/sunsetbar.json +0 -7
- package/data/vrchat/worlds/theblackcat.json +0 -9
- package/data/vrchat/worlds/thegreatpug.json +0 -8
- package/data/vrchat/worlds/themidnightbar.json +0 -7
- package/data/vrchat/worlds/voidclub.json +0 -7
- package/data/vrchat/worlds/voltdanceclub.json +0 -7
- package/data/vrchat/worlds/vrchathome.json +0 -8
- package/data/vrchat/worlds/whatalegend.json +0 -6
- package/data/warframe/meta.json +0 -14
- package/data/wutheringwaves/meta.json +0 -14
- package/data/zenlesszonezero/meta.json +0 -14
- package/gamecodes.js +0 -178
- package/scripts/cache-sync-smoke.js +0 -92
- package/scripts/game-code-cache-smoke.js +0 -85
- package/scripts/sync-all-cache.js +0 -18
- package/scripts/sync-api-cache.js +0 -319
- package/scripts/sync-game-code-cache.js +0 -244
- package/scripts/sync-gaming-info-cache.js +0 -46
package/CACHE_SYNC.md
DELETED
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
# APINODE fallback-cache mirror
|
|
2
|
-
|
|
3
|
-
`@nekosuneprojects/gaming-infos` is API-first. Normal reads try the NekoSuneVR V5 API before using bundled JSON under `data/`.
|
|
4
|
-
|
|
5
|
-
The repository keeps **two independent last-good fallback snapshots** synchronized automatically:
|
|
6
|
-
|
|
7
|
-
- Gaming Infos: `GET /v5/games/api/gaming-infos`
|
|
8
|
-
- Game Codes: `GET /v5/games/api/codes`
|
|
9
|
-
|
|
10
|
-
## Schedule
|
|
11
|
-
|
|
12
|
-
The GitHub Action runs **once every day at 03:23 UTC** and can also be started manually with `workflow_dispatch`.
|
|
13
|
-
|
|
14
|
-
It also runs when the cache implementation itself changes so a newly deployed cache format can be populated immediately.
|
|
15
|
-
|
|
16
|
-
## Mirrored gaming-infos datasets
|
|
17
|
-
|
|
18
|
-
| Game | API type(s) |
|
|
19
|
-
|---|---|
|
|
20
|
-
| VRChat | `players`, `groups`, `worlds`, `avatars` |
|
|
21
|
-
| Genshin Impact | `characters` |
|
|
22
|
-
| Honkai: Star Rail | `characters` |
|
|
23
|
-
| Neverness to Everness | `characters` |
|
|
24
|
-
| Wuthering Waves | `characters` (Resonators) |
|
|
25
|
-
| Warframe | `characters` (Warframes) |
|
|
26
|
-
| Fortnite | `characters` (current/released Battle Royale characters) |
|
|
27
|
-
| Zenless Zone Zero | `characters` (Agents) |
|
|
28
|
-
| Tower of Fantasy | `characters` (Simulacra) |
|
|
29
|
-
| Arknights: Endfield | `characters` (Operators) |
|
|
30
|
-
|
|
31
|
-
## Mirrored Game Codes endpoints
|
|
32
|
-
|
|
33
|
-
The daily mirror also caches:
|
|
34
|
-
|
|
35
|
-
```text
|
|
36
|
-
GET /v5/games/api/codes
|
|
37
|
-
GET /v5/games/api/codes/status
|
|
38
|
-
GET /v5/games/api/codes/:game?includeUnknown=true
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
`/codes/status` only reads APINODE's cached source state. It does **not** trigger source website refreshes.
|
|
42
|
-
|
|
43
|
-
The per-game request uses `includeUnknown=true`, so the fallback contains all three buckets when available:
|
|
44
|
-
|
|
45
|
-
```json
|
|
46
|
-
{
|
|
47
|
-
"Active": [],
|
|
48
|
-
"Expired": [],
|
|
49
|
-
"Unknown": []
|
|
50
|
-
}
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
The mirror does not call every `/:game/:code` endpoint. `GameCode(game, code)` can search the full cached per-game snapshot during an outage, which keeps the daily request count low.
|
|
54
|
-
|
|
55
|
-
Game-code fallback layout:
|
|
56
|
-
|
|
57
|
-
```text
|
|
58
|
-
data/game-codes/
|
|
59
|
-
├── directory.json
|
|
60
|
-
├── status.json
|
|
61
|
-
├── .cache-manifest.json
|
|
62
|
-
└── games/
|
|
63
|
-
├── fortnite.json
|
|
64
|
-
├── warframe.json
|
|
65
|
-
├── genshin-impact.json
|
|
66
|
-
└── ...
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
## Atomic synchronization / deletion behavior
|
|
70
|
-
|
|
71
|
-
Each cache is authoritative only **after its complete API download succeeds**.
|
|
72
|
-
|
|
73
|
-
For Gaming Infos:
|
|
74
|
-
|
|
75
|
-
1. Temporarily preserve `data/game-codes/` outside the gaming-info snapshot.
|
|
76
|
-
2. Fetch the root gaming-infos endpoint.
|
|
77
|
-
3. Fetch every configured game's meta endpoint.
|
|
78
|
-
4. Fetch every configured type-list endpoint.
|
|
79
|
-
5. Validate every response and entry slug.
|
|
80
|
-
6. Build a completely separate temporary snapshot.
|
|
81
|
-
7. Atomically replace the gaming-info `data/` snapshot.
|
|
82
|
-
8. Restore the previous game-code fallback before the code phase begins.
|
|
83
|
-
|
|
84
|
-
For Game Codes:
|
|
85
|
-
|
|
86
|
-
1. Fetch `/codes` and validate its game directory.
|
|
87
|
-
2. Fetch cache-only `/codes/status`.
|
|
88
|
-
3. Fetch every listed game's full `Active` / `Expired` / `Unknown` snapshot.
|
|
89
|
-
4. Build a separate temporary `data/game-codes/` tree.
|
|
90
|
-
5. Only after every game succeeds, atomically replace the old game-code snapshot.
|
|
91
|
-
|
|
92
|
-
Because successful API snapshots are authoritative, **adds, changes and removals are mirrored**. If APINODE removes an entry/code/game, the corresponding fallback disappears on the next successful daily sync.
|
|
93
|
-
|
|
94
|
-
If APINODE is down, times out, returns 429/5xx, or one required endpoint fails halfway through, that cache is **not replaced**. The previous last-good fallback remains available.
|
|
95
|
-
|
|
96
|
-
## Package API
|
|
97
|
-
|
|
98
|
-
Gaming Infos functions remain available:
|
|
99
|
-
|
|
100
|
-
```js
|
|
101
|
-
const info = require('@nekosuneprojects/gaming-infos');
|
|
102
|
-
|
|
103
|
-
await info.Games();
|
|
104
|
-
await info.List('vrchat', 'avatars');
|
|
105
|
-
await info.Characters('wutheringwaves', 'cartethyia');
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
Game Codes helpers use live APINODE first and the daily fallback second:
|
|
109
|
-
|
|
110
|
-
```js
|
|
111
|
-
await info.Codes(); // GET /v5/games/api/codes
|
|
112
|
-
await info.CodesStatus(); // GET /v5/games/api/codes/status
|
|
113
|
-
await info.GameCodes('fortnite'); // Active + Expired
|
|
114
|
-
await info.GameCodes('fortnite', { includeUnknown: true });
|
|
115
|
-
await info.GameCode('fortnite', 'NEKOSUNEVR');
|
|
116
|
-
await info.CodeCacheInfo();
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
Per-game fallback filtering is supported for `category` and `claimType` as well.
|
|
120
|
-
|
|
121
|
-
## Commands
|
|
122
|
-
|
|
123
|
-
```bash
|
|
124
|
-
# Test both atomic cache systems
|
|
125
|
-
npm run test:all-cache
|
|
126
|
-
|
|
127
|
-
# Mirror both Gaming Infos and Game Codes
|
|
128
|
-
npm run sync:cache
|
|
129
|
-
|
|
130
|
-
# Debug individually
|
|
131
|
-
npm run sync:gaming-infos-cache
|
|
132
|
-
npm run sync:game-codes-cache
|
|
133
|
-
npm run test:cache-sync
|
|
134
|
-
npm run test:game-code-cache
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
Override APINODE while testing:
|
|
138
|
-
|
|
139
|
-
```bash
|
|
140
|
-
GAMING_INFOS_API_BASE=http://localhost:3000 npm run sync:cache
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
Useful variables:
|
|
144
|
-
|
|
145
|
-
| Variable | Default | Purpose |
|
|
146
|
-
|---|---|---|
|
|
147
|
-
| `GAMING_INFOS_API_BASE` | `https://api.nekosunevr.co.uk` | APINODE host used by both caches |
|
|
148
|
-
| `GAMING_INFOS_API_PATH` | `/v5/games/api/gaming-infos` | Gaming Infos path |
|
|
149
|
-
| `GAME_CODES_API_PATH` | `/v5/games/api/codes` | Game Codes path |
|
|
150
|
-
| `GAMING_INFOS_CACHE_TIMEOUT_MS` | `15000` | Gaming Infos per-request timeout |
|
|
151
|
-
| `GAMING_INFOS_CACHE_RETRIES` | `2` | Gaming Infos retry count |
|
|
152
|
-
| `GAME_CODES_CACHE_TIMEOUT_MS` | `15000` | Game Codes per-request timeout |
|
|
153
|
-
| `GAME_CODES_CACHE_RETRIES` | `2` | Game Codes retry count |
|
|
154
|
-
| `GAME_CODES_CACHE_GAME_DELAY_MS` | `150` | Small delay between game-list requests |
|
|
155
|
-
|
|
156
|
-
## Runtime fallback behavior
|
|
157
|
-
|
|
158
|
-
The package does **not** use the cache instead of live data. It remains API-first:
|
|
159
|
-
|
|
160
|
-
```text
|
|
161
|
-
application
|
|
162
|
-
↓
|
|
163
|
-
live APINODE
|
|
164
|
-
├─ success → current API response
|
|
165
|
-
└─ unavailable/error → last-good bundled fallback
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
A successful changed Gaming Infos snapshot records `data/.cache-manifest.json`. Game Codes records its own `data/game-codes/.cache-manifest.json`. Both include source URL, content hash, counts, synchronization time and add/change/remove statistics.
|
|
169
|
-
|
|
170
|
-
The hash comparison ignores manifest timestamps, so an unchanged API dataset does not create a pointless daily commit.
|
|
171
|
-
|
|
172
|
-
Note: npm releases are immutable. Repository fallback files update daily, but an already-installed npm version keeps the bundled snapshot from that package release until upgraded. Live API reads still remain current whenever APINODE is available.
|
package/CONTRIBUTING.md
DELETED
|
@@ -1,217 +0,0 @@
|
|
|
1
|
-
# 🤝 Contributing to @nekosuneprojects/gaming-infos
|
|
2
|
-
|
|
3
|
-
Thank you for your interest in contributing to **@nekosuneprojects/gaming-infos**!
|
|
4
|
-
This project relies on community help to keep game data organized, accurate, and friendly — across every game it covers,
|
|
5
|
-
not just VRChat.
|
|
6
|
-
|
|
7
|
-
Please read this guide carefully **before submitting a Pull Request (PR)**.
|
|
8
|
-
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
## 🦊 Overview
|
|
12
|
-
|
|
13
|
-
This project provides **community game info** — worlds, groups, players, characters, and more — in JSON format, used by
|
|
14
|
-
scripts and tools. Data lives in the `data/` folder, scoped per game:
|
|
15
|
-
|
|
16
|
-
```
|
|
17
|
-
data/
|
|
18
|
-
└── <game>/
|
|
19
|
-
├── meta.json
|
|
20
|
-
├── worlds/
|
|
21
|
-
├── groups/
|
|
22
|
-
├── players/
|
|
23
|
-
└── characters/
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
Each JSON file represents a public piece of info about a world, group, player, or character for that game.
|
|
27
|
-
Not every game uses every folder — e.g. VRChat uses `worlds`/`groups`/`players`, while a character-driven game like
|
|
28
|
-
Genshin Impact mainly uses `characters`. Use the `Get(game, type, name)` function for any entity type a new game
|
|
29
|
-
needs that isn't already listed above.
|
|
30
|
-
|
|
31
|
-
---
|
|
32
|
-
|
|
33
|
-
## ✅ Contribution Rules
|
|
34
|
-
|
|
35
|
-
### 1. Permission & Privacy
|
|
36
|
-
|
|
37
|
-
- Only include **publicly available data** or **data you have explicit permission** to share.
|
|
38
|
-
- If the data comes from **private profiles, Discord servers, or DMs**, **do not submit it**.
|
|
39
|
-
- You must **ask permission** from the world/group/player/character owner if the information is not publicly listed.
|
|
40
|
-
- Do **not** upload personal or sensitive details under any circumstance.
|
|
41
|
-
|
|
42
|
-
### 2. Accepted Public Sources
|
|
43
|
-
|
|
44
|
-
You may use:
|
|
45
|
-
- Official game wikis/fandoms (e.g. [VRChat Legends (Fandom)](https://vrchat-legends.fandom.com), official Genshin Impact wiki, etc.)
|
|
46
|
-
- Official game pages, group listings, or public user profiles.
|
|
47
|
-
- Other verified public sources (must be referenced in the PR description).
|
|
48
|
-
|
|
49
|
-
If the source is not verifiable or permission is unclear, your PR will be closed.
|
|
50
|
-
|
|
51
|
-
---
|
|
52
|
-
|
|
53
|
-
## 🚫 Community & Safety Guidelines
|
|
54
|
-
|
|
55
|
-
All contributions must comply with the relevant game's Terms of Service and Community Guidelines, e.g. for VRChat:
|
|
56
|
-
|
|
57
|
-
- **VRChat's Terms of Service**:
|
|
58
|
-
[https://hello.vrchat.com/legal](https://hello.vrchat.com/legal)
|
|
59
|
-
|
|
60
|
-
- **VRChat's Community Guidelines**:
|
|
61
|
-
[https://hello.vrchat.com/community-guidelines](https://hello.vrchat.com/community-guidelines)
|
|
62
|
-
|
|
63
|
-
### Forbidden Content:
|
|
64
|
-
- Harassment, bullying, or targeted remarks.
|
|
65
|
-
- Doxxing or sharing private user data.
|
|
66
|
-
- Hate speech, NSFW content, or anything that violates a game's ToS or GitHub rules.
|
|
67
|
-
- False, misleading, or defamatory information.
|
|
68
|
-
|
|
69
|
-
Such PRs will be rejected and may result in a report to platform moderators.
|
|
70
|
-
|
|
71
|
-
---
|
|
72
|
-
|
|
73
|
-
## 🖼️ Image Requirement
|
|
74
|
-
|
|
75
|
-
Every JSON file **must include an `image` field** linking to a **safe, representative image** (world thumbnail, group
|
|
76
|
-
logo, avatar/character art).
|
|
77
|
-
|
|
78
|
-
Example:
|
|
79
|
-
```json
|
|
80
|
-
"image": "https://example.com/images/world.png"
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
Images must not contain:
|
|
84
|
-
- Private or copyrighted art without permission.
|
|
85
|
-
- NSFW or offensive visuals.
|
|
86
|
-
|
|
87
|
-
---
|
|
88
|
-
|
|
89
|
-
## 🧩 JSON Format Guidelines
|
|
90
|
-
|
|
91
|
-
Follow these formats exactly when adding files. New games should follow the same shape for whichever entity types
|
|
92
|
-
apply to them.
|
|
93
|
-
|
|
94
|
-
### 🌍 Worlds (`data/<game>/worlds/worldname.json`)
|
|
95
|
-
```json
|
|
96
|
-
{
|
|
97
|
-
"name": "The Black Cat",
|
|
98
|
-
"title": "Main Hall",
|
|
99
|
-
"creator": "spookyghostboo",
|
|
100
|
-
"aliases": "Black Cat",
|
|
101
|
-
"image": "https://example.com/images/world.jpg",
|
|
102
|
-
"description": "A cozy hangout world for friends.",
|
|
103
|
-
"url": "VRCHAT WORLD URL"
|
|
104
|
-
}
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
### 👥 Groups (`data/<game>/groups/groupname.json`)
|
|
108
|
-
```json
|
|
109
|
-
{
|
|
110
|
-
"name": "NekoSune Community",
|
|
111
|
-
"owner": "NekoSuneVR",
|
|
112
|
-
"image": "https://example.com/images/group.png",
|
|
113
|
-
"description": "A friendly VRChat group for chill vibes and fun events.",
|
|
114
|
-
"url": "VRCHAT GROUP URL"
|
|
115
|
-
}
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
### 🧍 Players (`data/<game>/players/playername.json`)
|
|
119
|
-
```json
|
|
120
|
-
{
|
|
121
|
-
"name": "NekoSuneVR",
|
|
122
|
-
"title": "The Cutie Streamer",
|
|
123
|
-
"species": "half human - half catgirl",
|
|
124
|
-
"gender": "Male",
|
|
125
|
-
"aliases": "ChisdealHDYT, Chisdeal2013, Chisdeal2014, ChisdealHD, progamer-gr, DarkBlackWolfs",
|
|
126
|
-
"image": "https://media.discordapp.net/attachments/794229972490387496/794231249652678696/VRChat_1920x1080_2020-09-14_09-22-18.855.png",
|
|
127
|
-
"description": "A long time ago, Wild Player Chisdeal2013 (later known as ChisdealHDYT). He had been hanging out in a place called [The Black Cat](https://vrchat-legends.fandom.com/wiki/The_Black_Cat), [The Great Pug](https://vrchat-legends.fandom.com/wiki/The_Great_Pug) and [Japan Shrine (ITOAR)](https://vrchat-legends.fandom.com/wiki/Japan_Shrine_(ITOAR)). He had been talking about how he wanted to be Popular on [Twitch](https://twitch.tv/chisdealhdyt) and [TikTok](https://www.tiktok.com/@chisdealhd) / [YouTube](https://www.youtube.com/chisdealhd). Then he did started to streaming on Twitch and Upload Videos on TikTok / YouTube. He loves interest Cryptocurrency Money making and has lot support from [ZENZO Community](https://zenzo.io). He building Community with VRChat, Warframe and many more. He want become as VTuber as Twitch and doing a lot of VR Gaming. That dream is coming very soon in stage getting VR Headset and Brand new VR Ready PC.\n\nYou should Support this Cutie Streamer much on your Heart it can go.",
|
|
128
|
-
"url": "https://creator.nekosunevr.co.uk"
|
|
129
|
-
}
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
### 🧝 Characters (`data/<game>/characters/charactername.json`)
|
|
133
|
-
```json
|
|
134
|
-
{
|
|
135
|
-
"name": "Amber",
|
|
136
|
-
"quote": "Outrider Amber, at the ready!",
|
|
137
|
-
"cv": "Iwami Manaka",
|
|
138
|
-
"description": "A perky, straightforward girl, who is also the only Outrider of the Knights of Favonius.",
|
|
139
|
-
"image": "https://uploadstatic-sea.mihoyo.com/contentweb/20191009/2019100914372396510.png",
|
|
140
|
-
"city": "Mondstadt",
|
|
141
|
-
"url": "https://genshin.mihoyo.com/en/character/mondstadt?char=1",
|
|
142
|
-
"element": "Pyro",
|
|
143
|
-
"weapon": "Bow",
|
|
144
|
-
"rating": 4
|
|
145
|
-
}
|
|
146
|
-
```
|
|
147
|
-
`element` stays a plain string (icon mapping is a consumer-side concern, not stored here).
|
|
148
|
-
`rating` is the in-game star rarity (1-5) as a number. Include whatever fields apply to that
|
|
149
|
-
game's characters (`cv`, `city`, etc.) and drop what doesn't.
|
|
150
|
-
|
|
151
|
-
### 🎮 Game meta (`data/<game>/meta.json`)
|
|
152
|
-
```json
|
|
153
|
-
{
|
|
154
|
-
"name": "Genshin Impact",
|
|
155
|
-
"title": "An open-world action RPG developed by HoYoverse.",
|
|
156
|
-
"engine": "Unity",
|
|
157
|
-
"Platform": "PC, PlayStation, iOS, Android",
|
|
158
|
-
"Release date": "September 28, 2020",
|
|
159
|
-
"Genre": "Action RPG, Open World, Gacha",
|
|
160
|
-
"developers": "HoYoverse",
|
|
161
|
-
"aliases": "GI, Genshin",
|
|
162
|
-
"image": "https://example.com/images/genshin-logo.png",
|
|
163
|
-
"description": "Short factual description of the game.",
|
|
164
|
-
"url": "https://en.wikipedia.org/wiki/Genshin_Impact"
|
|
165
|
-
}
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
---
|
|
169
|
-
|
|
170
|
-
## 🪶 How to Submit a Pull Request
|
|
171
|
-
|
|
172
|
-
1. **Fork** this repository.
|
|
173
|
-
2. **Create a new branch** for your changes:
|
|
174
|
-
```bash
|
|
175
|
-
git checkout -b add-new-world
|
|
176
|
-
```
|
|
177
|
-
3. Add or update JSON files under `data/<game>/...`. If adding a **new game**, create `data/<newgame>/meta.json`
|
|
178
|
-
plus whichever entity folders apply (`worlds`, `groups`, `players`, `characters`, or a new type via `Get()`).
|
|
179
|
-
4. Ensure your files are valid JSON and properly formatted.
|
|
180
|
-
5. **Commit and push** your changes:
|
|
181
|
-
```bash
|
|
182
|
-
git commit -m "Add Example World info"
|
|
183
|
-
git push origin add-new-world
|
|
184
|
-
```
|
|
185
|
-
6. **Open a Pull Request** on GitHub with:
|
|
186
|
-
- A clear title (e.g., "Add Genshin Impact character Furina")
|
|
187
|
-
- A short explanation
|
|
188
|
-
- Source links or permissions if applicable
|
|
189
|
-
|
|
190
|
-
---
|
|
191
|
-
|
|
192
|
-
## 🔍 Before Submitting
|
|
193
|
-
|
|
194
|
-
✅ Validate your JSON syntax using:
|
|
195
|
-
```bash
|
|
196
|
-
npm run lint
|
|
197
|
-
```
|
|
198
|
-
(if available) or an online JSON validator.
|
|
199
|
-
|
|
200
|
-
✅ Make sure:
|
|
201
|
-
- You have **permission** to share the content.
|
|
202
|
-
- The **image link** works and is safe.
|
|
203
|
-
- The **file name matches the item name** (lowercase recommended).
|
|
204
|
-
- The file is in the correct `data/<game>/<type>/` folder.
|
|
205
|
-
|
|
206
|
-
---
|
|
207
|
-
|
|
208
|
-
## 🧠 Final Notes
|
|
209
|
-
|
|
210
|
-
- This project is **game-friendly** and follows all relevant ToS and Community Guidelines.
|
|
211
|
-
- The maintainers reserve the right to remove or edit contributions that break policy.
|
|
212
|
-
- All content remains under the [MIT License](LICENSE) unless otherwise noted.
|
|
213
|
-
|
|
214
|
-
---
|
|
215
|
-
|
|
216
|
-
🐾 Maintained by **NekoSune Projects**
|
|
217
|
-
💬 Community contributions are welcome — just keep it kind, safe, and respectful!
|
package/DATA.md
DELETED
|
@@ -1,292 +0,0 @@
|
|
|
1
|
-
# Gaming Infos — Data & API Spec
|
|
2
|
-
|
|
3
|
-
> **Forward this file into `V5_REBUILD_GREEN`.** It's the shared spec between the
|
|
4
|
-
> `@nekosuneprojects/gaming-infos` npm package and the V5 API. The npm package now calls the API
|
|
5
|
-
> first for live data and only falls back to its own bundled JSON if the API is unreachable — so
|
|
6
|
-
> once this is wired up here, the game/character list can be updated in real time by editing JSON
|
|
7
|
-
> in this repo, without ever needing to bump the npm package version.
|
|
8
|
-
|
|
9
|
-
## What this covers
|
|
10
|
-
|
|
11
|
-
Community info about games — worlds, groups, players, characters, and whatever else a future game
|
|
12
|
-
needs — as small JSON files. Today: VRChat. Coming soon: Genshin Impact, and more. Each game only
|
|
13
|
-
uses the entity types that make sense for it (VRChat: worlds/groups/players. A character-driven
|
|
14
|
-
game like Genshin Impact: mostly characters.).
|
|
15
|
-
|
|
16
|
-
This is **not** the same thing as the existing `src/routes/v5/games/*` routes (Destiny2, Fortnite,
|
|
17
|
-
Hypixel, VRChat profile lookup, etc.) — those pull *live player/account stats* from third-party
|
|
18
|
-
game APIs. `gaming-infos` is curated, hand-written community reference data (bios, lore, links),
|
|
19
|
-
served as static JSON.
|
|
20
|
-
|
|
21
|
-
---
|
|
22
|
-
|
|
23
|
-
## 1. Where the JSON lives
|
|
24
|
-
|
|
25
|
-
Create this folder structure under the API project root:
|
|
26
|
-
|
|
27
|
-
```
|
|
28
|
-
V5_REBUILD_GREEN/
|
|
29
|
-
└── data/
|
|
30
|
-
└── gaming-infos/
|
|
31
|
-
└── <game>/
|
|
32
|
-
├── meta.json
|
|
33
|
-
├── worlds/<name>.json
|
|
34
|
-
├── groups/<name>.json
|
|
35
|
-
├── players/<name>.json
|
|
36
|
-
└── characters/<name>.json
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
Rules:
|
|
40
|
-
- `<game>` is lowercase, no spaces, e.g. `vrchat`, `genshinimpact`.
|
|
41
|
-
- `<name>` (the filename, minus `.json`) is lowercase, no spaces, e.g. `theblackcat.json`, `furina.json`.
|
|
42
|
-
- Only create the entity folders a game actually uses — don't create empty `worlds/` for a game with no worlds.
|
|
43
|
-
- `meta.json` holds game-level info (see schema below) and is required for every game.
|
|
44
|
-
|
|
45
|
-
This mirrors the npm package's own `data/<game>/...` layout 1:1, so JSON can be copied between the
|
|
46
|
-
two repos without any transformation.
|
|
47
|
-
|
|
48
|
-
---
|
|
49
|
-
|
|
50
|
-
## 2. JSON schemas
|
|
51
|
-
|
|
52
|
-
### Game meta — `data/gaming-infos/<game>/meta.json`
|
|
53
|
-
```json
|
|
54
|
-
{
|
|
55
|
-
"name": "Genshin Impact",
|
|
56
|
-
"title": "An open-world action RPG developed by HoYoverse.",
|
|
57
|
-
"engine": "Unity",
|
|
58
|
-
"Platform": "PC, PlayStation, iOS, Android",
|
|
59
|
-
"Release date": "September 28, 2020",
|
|
60
|
-
"Genre": "Action RPG, Open World, Gacha",
|
|
61
|
-
"developers": "HoYoverse",
|
|
62
|
-
"aliases": "GI, Genshin",
|
|
63
|
-
"image": "https://example.com/images/genshin-logo.png",
|
|
64
|
-
"description": "Short factual description of the game.",
|
|
65
|
-
"url": "https://en.wikipedia.org/wiki/Genshin_Impact"
|
|
66
|
-
}
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
### World — `data/gaming-infos/<game>/worlds/<name>.json`
|
|
70
|
-
```json
|
|
71
|
-
{
|
|
72
|
-
"name": "The Black Cat",
|
|
73
|
-
"title": "Main Hall",
|
|
74
|
-
"creator": "spookyghostboo",
|
|
75
|
-
"aliases": "Black Cat",
|
|
76
|
-
"image": "https://example.com/images/world.jpg",
|
|
77
|
-
"description": "A cozy hangout world for friends.",
|
|
78
|
-
"url": "VRCHAT WORLD URL"
|
|
79
|
-
}
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
### Group — `data/gaming-infos/<game>/groups/<name>.json`
|
|
83
|
-
```json
|
|
84
|
-
{
|
|
85
|
-
"name": "NekoSune Community",
|
|
86
|
-
"owner": "NekoSuneVR",
|
|
87
|
-
"image": "https://example.com/images/group.png",
|
|
88
|
-
"description": "A friendly VRChat group for chill vibes and fun events.",
|
|
89
|
-
"url": "VRCHAT GROUP URL"
|
|
90
|
-
}
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
### Player — `data/gaming-infos/<game>/players/<name>.json`
|
|
94
|
-
```json
|
|
95
|
-
{
|
|
96
|
-
"name": "NekoSuneVR",
|
|
97
|
-
"title": "The Cutie Streamer",
|
|
98
|
-
"species": "half human - half catgirl",
|
|
99
|
-
"gender": "Male",
|
|
100
|
-
"aliases": "ChisdealHDYT, Chisdeal2013",
|
|
101
|
-
"image": "https://example.com/images/nekosunevr.png",
|
|
102
|
-
"description": "Bio text, markdown links allowed.",
|
|
103
|
-
"url": "https://creator.nekosunevr.co.uk"
|
|
104
|
-
}
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
### Character — `data/gaming-infos/<game>/characters/<name>.json`
|
|
108
|
-
```json
|
|
109
|
-
{
|
|
110
|
-
"name": "Amber",
|
|
111
|
-
"quote": "Outrider Amber, at the ready!",
|
|
112
|
-
"cv": "Iwami Manaka",
|
|
113
|
-
"description": "A perky, straightforward girl, who is also the only Outrider of the Knights of Favonius.",
|
|
114
|
-
"image": "https://uploadstatic-sea.mihoyo.com/contentweb/20191009/2019100914372396510.png",
|
|
115
|
-
"city": "Mondstadt",
|
|
116
|
-
"url": "https://genshin.mihoyo.com/en/character/mondstadt?char=1",
|
|
117
|
-
"element": "Pyro",
|
|
118
|
-
"weapon": "Bow",
|
|
119
|
-
"rating": 4
|
|
120
|
-
}
|
|
121
|
-
```
|
|
122
|
-
- `element` is a plain string (Pyro/Hydro/Electro/Cryo/Anemo/Geo/Dendro) — no icon URL stored here;
|
|
123
|
-
element -> icon mapping is a consumer-side concern.
|
|
124
|
-
- `rating` is the in-game star rarity (1-5) as a number.
|
|
125
|
-
- `cv` (voice actor) and `city` are Genshin-specific; other character-driven games can drop/replace
|
|
126
|
-
them with whatever fields fit (e.g. a fighting game might use `moveset` instead of `city`).
|
|
127
|
-
|
|
128
|
-
Every entity JSON has an `image` field. When you have a verified, safe (non-NSFW, not privately
|
|
129
|
-
owned without permission) working URL, use it. When you don't, leave it as an **empty string**
|
|
130
|
-
(`"image": ""`) — never fill it with a placeholder/TODO string, since that gets treated as real
|
|
131
|
-
data by consumers.
|
|
132
|
-
|
|
133
|
-
If a game needs an entity type not listed above (e.g. `weapons`, `regions`, `guilds`), just add a
|
|
134
|
-
new folder following the same `data/gaming-infos/<game>/<type>/<name>.json` pattern — the npm
|
|
135
|
-
package's `Get(game, type, name)` function reads any type generically.
|
|
136
|
-
|
|
137
|
-
---
|
|
138
|
-
|
|
139
|
-
## 3. Sourcing & safety rules
|
|
140
|
-
|
|
141
|
-
- Only use **publicly available** info, or info you have explicit permission to publish.
|
|
142
|
-
- Never include data from private profiles, private Discords, or DMs.
|
|
143
|
-
- No harassment, doxxing, defamation, or NSFW content.
|
|
144
|
-
- Respect each game's Terms of Service / Community Guidelines (e.g. VRChat's
|
|
145
|
-
[ToS](https://hello.vrchat.com/legal) and [Community Guidelines](https://hello.vrchat.com/community-guidelines)).
|
|
146
|
-
- Prefer official wikis/fandoms and official game pages as sources; note the source in your PR/commit if unclear.
|
|
147
|
-
|
|
148
|
-
---
|
|
149
|
-
|
|
150
|
-
## 4. Wiring up the API route
|
|
151
|
-
|
|
152
|
-
Follow the existing pattern used by every other file in `src/routes/v5/games/*`
|
|
153
|
-
(`checkEndpointEnabled` + `requireApiKeyIfNeeded` middleware, mounted under `/v5/games/api/...`).
|
|
154
|
-
|
|
155
|
-
There are four routes: list all games, list all entries of a type for a game, a single entity, and
|
|
156
|
-
game meta (meta is just the single-entity route with `type` fixed to `meta`).
|
|
157
|
-
|
|
158
|
-
1. Create `src/routes/v5/games/gaminginfos.js`:
|
|
159
|
-
|
|
160
|
-
```js
|
|
161
|
-
const express = require('express');
|
|
162
|
-
const fs = require('fs');
|
|
163
|
-
const path = require('path');
|
|
164
|
-
const { checkEndpointEnabled, requireApiKeyIfNeeded } = require('../../../middleware/apiAccess');
|
|
165
|
-
|
|
166
|
-
const router = express.Router({ strict: false });
|
|
167
|
-
const DATA_DIR = path.join(__dirname, '..', '..', '..', '..', 'data', 'gaming-infos');
|
|
168
|
-
|
|
169
|
-
function readJson(filePath) {
|
|
170
|
-
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
// GET /v5/games/api/gaming-infos — list every game's meta info
|
|
174
|
-
router.get('/', checkEndpointEnabled, requireApiKeyIfNeeded, (req, res) => {
|
|
175
|
-
try {
|
|
176
|
-
const entries = fs.readdirSync(DATA_DIR, { withFileTypes: true }).filter((e) => e.isDirectory());
|
|
177
|
-
const gamesList = entries
|
|
178
|
-
.map((e) => path.join(DATA_DIR, e.name, 'meta.json'))
|
|
179
|
-
.filter((metaPath) => fs.existsSync(metaPath))
|
|
180
|
-
.map(readJson);
|
|
181
|
-
return res.status(200).json({ success: true, data: gamesList });
|
|
182
|
-
} catch (err) {
|
|
183
|
-
return res.status(500).json({ success: false, error: 'Failed to list games.' });
|
|
184
|
-
}
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
// GET /v5/games/api/gaming-infos/:game/:type — list every entry of that type for a game
|
|
188
|
-
router.get('/:game/:type', checkEndpointEnabled, requireApiKeyIfNeeded, (req, res) => {
|
|
189
|
-
const { game, type } = req.params;
|
|
190
|
-
const dir = path.join(DATA_DIR, game.toLowerCase(), type.toLowerCase());
|
|
191
|
-
|
|
192
|
-
if (!dir.startsWith(DATA_DIR) || !fs.existsSync(dir)) {
|
|
193
|
-
return res.status(404).json({ success: false, error: `No ${type} data found for game "${game}"` });
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
try {
|
|
197
|
-
const items = fs.readdirSync(dir).filter((f) => f.endsWith('.json')).map((f) => readJson(path.join(dir, f)));
|
|
198
|
-
return res.status(200).json({ success: true, data: items });
|
|
199
|
-
} catch (err) {
|
|
200
|
-
return res.status(500).json({ success: false, error: 'Failed to list gaming-infos entries.' });
|
|
201
|
-
}
|
|
202
|
-
});
|
|
203
|
-
|
|
204
|
-
// GET /v5/games/api/gaming-infos/:game/:type/:name — a single entity, or game meta when type === "meta"
|
|
205
|
-
router.get('/:game/:type/:name', checkEndpointEnabled, requireApiKeyIfNeeded, (req, res) => {
|
|
206
|
-
const { game, type, name } = req.params;
|
|
207
|
-
const filePath = type.toLowerCase() === 'meta'
|
|
208
|
-
? path.join(DATA_DIR, game.toLowerCase(), 'meta.json')
|
|
209
|
-
: path.join(DATA_DIR, game.toLowerCase(), type.toLowerCase(), `${name.toLowerCase()}.json`);
|
|
210
|
-
|
|
211
|
-
if (!filePath.startsWith(DATA_DIR) || !fs.existsSync(filePath)) {
|
|
212
|
-
return res.status(404).json({ success: false, error: `${type} "${name}" not found for game "${game}"` });
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
try {
|
|
216
|
-
return res.status(200).json({ success: true, data: readJson(filePath) });
|
|
217
|
-
} catch (err) {
|
|
218
|
-
return res.status(500).json({ success: false, error: 'Failed to read gaming-infos data.' });
|
|
219
|
-
}
|
|
220
|
-
});
|
|
221
|
-
|
|
222
|
-
module.exports = router;
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
2. Register it in `src/app.js` next to the other game routes:
|
|
226
|
-
|
|
227
|
-
```js
|
|
228
|
-
const gamingInfosRoutes = require('./routes/v5/games/gaminginfos');
|
|
229
|
-
// ...
|
|
230
|
-
app.use('/v5/games/api/gaming-infos', gamingInfosRoutes);
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
3. Add the endpoint(s) to `DEFAULT_ENDPOINTS` in `src/services/bootstrap.js` so
|
|
234
|
-
`checkEndpointEnabled` accepts them (same convention as every other `games/api/*` entry):
|
|
235
|
-
|
|
236
|
-
```js
|
|
237
|
-
{
|
|
238
|
-
path: '/v5/games/api/gaming-infos',
|
|
239
|
-
method: 'GET',
|
|
240
|
-
isEnabled: true,
|
|
241
|
-
requiresApiKey: false,
|
|
242
|
-
description: 'List every game with gaming-infos data'
|
|
243
|
-
},
|
|
244
|
-
{
|
|
245
|
-
path: '/v5/games/api/gaming-infos/:game/:type',
|
|
246
|
-
method: 'GET',
|
|
247
|
-
isEnabled: true,
|
|
248
|
-
requiresApiKey: false,
|
|
249
|
-
description: 'List every gaming-infos entry of a type for a game'
|
|
250
|
-
},
|
|
251
|
-
{
|
|
252
|
-
path: '/v5/games/api/gaming-infos/:game/:type/:name',
|
|
253
|
-
method: 'GET',
|
|
254
|
-
isEnabled: true,
|
|
255
|
-
requiresApiKey: false,
|
|
256
|
-
description: 'Community gaming-infos single-entity lookup (worlds/groups/players/characters/meta/etc.)'
|
|
257
|
-
},
|
|
258
|
-
```
|
|
259
|
-
|
|
260
|
-
`bootstrapData()` (called on every app startup in `src/app.js`) runs `seedEndpoints()`, which
|
|
261
|
-
`findOrCreate`s each `DEFAULT_ENDPOINTS` row into the `EndpointToggle` table — so these three
|
|
262
|
-
entries go live (and show up on `/docs` automatically, since that page renders straight from
|
|
263
|
-
`EndpointToggle`) the next time the server restarts. No manual DB or docs-page edit needed.
|
|
264
|
-
|
|
265
|
-
The npm package expects responses shaped as `{ success: true, data: {...} }` (or a bare JSON object/array —
|
|
266
|
-
it accepts either) and defaults to `https://api.nekosunevr.co.uk/v5/games/api/gaming-infos` as the
|
|
267
|
-
base URL. If the real public host differs, override it per-consumer via the `GAMING_INFOS_API_BASE`
|
|
268
|
-
env var — nothing here needs to change either way. The npm package's `Games()` calls the root route,
|
|
269
|
-
`List(game, type)` calls the two-segment route, and everything else calls the three-segment route.
|
|
270
|
-
|
|
271
|
-
---
|
|
272
|
-
|
|
273
|
-
## 5. Prompt template — adding/updating a game or entry
|
|
274
|
-
|
|
275
|
-
Copy-paste this (filling in the brackets) when asking an AI assistant to add or refresh gaming-infos
|
|
276
|
-
data in this repo:
|
|
277
|
-
|
|
278
|
-
```
|
|
279
|
-
Add/update gaming-infos data in this repo (data/gaming-infos/), following DATA.md:
|
|
280
|
-
|
|
281
|
-
- Game: <e.g. Genshin Impact>
|
|
282
|
-
- Entity type: <world|group|player|character|other>
|
|
283
|
-
- Name(s): <e.g. Furina, Nahida>
|
|
284
|
-
- Source(s): <official wiki/page URL(s) — public only, no private info>
|
|
285
|
-
|
|
286
|
-
Look up current, accurate public info for each name above, write one JSON file per entry at
|
|
287
|
-
data/gaming-infos/<game>/<type>/<lowercase-name>.json matching the schema in DATA.md section 2
|
|
288
|
-
(include a working, safe image URL), and create/update data/gaming-infos/<game>/meta.json if this
|
|
289
|
-
is a new game. Don't touch the API route code unless it doesn't exist yet for this game group —
|
|
290
|
-
DATA.md section 4 has the route setup if needed. Skip anything that isn't publicly sourced or
|
|
291
|
-
permissioned.
|
|
292
|
-
```
|