@nekosuneprojects/gaming-infos 2.1.0 โ†’ 2.2.0

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/README.md CHANGED
@@ -1,20 +1,50 @@
1
1
  # ๐ŸŒ @nekosuneprojects/gaming-infos
2
2
 
3
- A simple Node.js module to load **community game data** โ€” Worlds, Groups, Players, and Characters โ€” for multiple games.
4
- Started as VRChat-only (`vrchat-infos`), now built to grow across games. Currently covers **VRChat**,
5
- **Genshin Impact**, **Neverness to Everness (NTE)**, and **Honkai: Star Rail** โ€” with more to come.
3
+ [![npm version](https://img.shields.io/npm/v/@nekosuneprojects/gaming-infos.svg)](https://www.npmjs.com/package/@nekosuneprojects/gaming-infos)
6
4
 
7
- Data is fetched **live from the NekoSuneVR V5 API** first, so the list of games/entries can be updated in real time
8
- without needing a new npm release. If the API can't be reached, it falls back to the JSON bundled in this package.
5
+ A Node.js data package for **game information, VRChat community data, characters, redeem codes, and creator codes**.
6
+
7
+ The package is **API-first**: it reads from the NekoSuneVR V5 API whenever possible, then automatically falls back to bundled JSON when the API is unavailable. The fallback data in this repository is mirrored from APINODE once per day using an atomic add/change/remove synchronization system.
8
+
9
+ Current package version: **2.2.0**
10
+
11
+ ---
12
+
13
+ ## โœจ What it provides
14
+
15
+ - ๐ŸŽฎ Multi-game metadata and character data
16
+ - ๐ŸŒ Live NekoSuneVR V5 API lookups
17
+ - ๐Ÿ’พ Automatic local JSON fallback when the API is unavailable
18
+ - ๐Ÿ”„ Daily APINODE โ†’ repository cache synchronization
19
+ - ๐Ÿงน Add/change/remove mirroring so deleted API entries disappear from the next successful fallback snapshot
20
+ - ๐Ÿ›ก๏ธ Last-good-cache protection if APINODE is down or a sync only partially succeeds
21
+ - ๐Ÿ‘ค VRChat players
22
+ - ๐Ÿ‘ฅ VRChat groups
23
+ - ๐ŸŒ VRChat worlds
24
+ - ๐Ÿง VRChat avatars
25
+ - ๐Ÿง Character/roster datasets for supported games
26
+ - ๐ŸŽ Redeem-code and creator-code helpers
27
+ - ๐Ÿ“Š Game-code directory, counts, aliases, status, and source-cache information
28
+ - ๐Ÿงช Offline smoke tests for cache replacement and failure recovery
9
29
 
10
30
  ---
11
31
 
12
- ## โœจ Features
32
+ ## ๐ŸŽฎ Gaming Infos coverage
13
33
 
14
- - ๐ŸŽฎ Multi-game: every lookup is scoped by `game` (`vrchat`, `genshinimpact`, ...)
15
- - ๐ŸŒ API-first with offline fallback โ€” reads from `data/<game>/...` locally when the API is unavailable
16
- - ๐Ÿง  Easy-to-use async API
17
- - โค๏ธ Designed with each game's Terms of Service / Community Guidelines in mind
34
+ | Game | Slug | Data |
35
+ |---|---|---|
36
+ | VRChat | `vrchat` | players, groups, worlds, avatars |
37
+ | Genshin Impact | `genshinimpact` | characters |
38
+ | Honkai: Star Rail | `honkaistarrail` | characters |
39
+ | Neverness to Everness | `nte` | characters |
40
+ | Wuthering Waves | `wutheringwaves` | Resonators under `characters` |
41
+ | Warframe | `warframe` | Warframes under `characters` |
42
+ | Fortnite | `fortnite` | current/released Battle Royale characters |
43
+ | Zenless Zone Zero | `zenlesszonezero` | Agents under `characters` |
44
+ | Tower of Fantasy | `toweroffantasy` | Simulacra under `characters` |
45
+ | Arknights: Endfield | `arknightsendfield` | Operators under `characters` |
46
+
47
+ The Game Codes system is separate and its supported game list is returned dynamically by the APINODE `/codes` directory endpoint.
18
48
 
19
49
  ---
20
50
 
@@ -24,181 +54,480 @@ without needing a new npm release. If the API can't be reached, it falls back to
24
54
  npm install @nekosuneprojects/gaming-infos
25
55
  ```
26
56
 
27
- ## ๐Ÿ’ก Usage
57
+ Requires **Node.js 18 or newer**.
58
+
59
+ ---
60
+
61
+ # ๐Ÿš€ Quick start
28
62
 
29
63
  ```js
30
64
  const gamingInfos = require('@nekosuneprojects/gaming-infos');
31
65
 
32
- (async () => {
33
- const games = await gamingInfos.Games(); // every supported game's meta info
34
- const game = await gamingInfos.Game('vrchat');
35
- const world = await gamingInfos.Worlds('vrchat', 'theblackcat');
36
- const group = await gamingInfos.Groups('vrchat', 'nekosunecommunity');
37
- const player = await gamingInfos.Players('vrchat', 'nekosunevr');
38
- const allCharacters = await gamingInfos.List('genshinimpact', 'characters'); // every character for a game
66
+ async function main() {
67
+ const games = await gamingInfos.Games();
68
+ const vrchat = await gamingInfos.Game('vrchat');
69
+
70
+ const worlds = await gamingInfos.List('vrchat', 'worlds');
71
+ const avatars = await gamingInfos.List('vrchat', 'avatars');
72
+ const genshinCharacters = await gamingInfos.List('genshinimpact', 'characters');
73
+ const wuwaCharacters = await gamingInfos.List('wutheringwaves', 'characters');
74
+
75
+ console.log({
76
+ gameCount: games.length,
77
+ vrchat,
78
+ worlds: worlds.length,
79
+ avatars: avatars.length,
80
+ genshinCharacters: genshinCharacters.length,
81
+ wuwaCharacters: wuwaCharacters.length
82
+ });
83
+ }
39
84
 
40
- console.log(games, game, world, group, player, allCharacters.length);
41
- })();
85
+ main();
42
86
  ```
43
87
 
44
- This reads (or falls back to reading) data from:
88
+ ---
89
+
90
+ # ๐Ÿง  Gaming Infos API
91
+
92
+ ## `Games()`
93
+
94
+ Returns every game with bundled/API Gaming Infos metadata.
45
95
 
96
+ ```js
97
+ const games = await gamingInfos.Games();
46
98
  ```
47
- data/
48
- โ””โ”€โ”€ <game>/
49
- โ”œโ”€โ”€ meta.json
50
- โ”œโ”€โ”€ worlds/<name>.json
51
- โ”œโ”€โ”€ groups/<name>.json
52
- โ”œโ”€โ”€ players/<name>.json
53
- โ””โ”€โ”€ characters/<name>.json (for character-driven games, e.g. Genshin Impact)
99
+
100
+ Live endpoint:
101
+
102
+ ```http
103
+ GET /v5/games/api/gaming-infos
54
104
  ```
55
105
 
56
- ### API functions
106
+ ## `Game(game)`
57
107
 
58
- | Function | Description |
59
- |---|---|
60
- | `Games()` | Every supported game's meta info, in one array |
61
- | `Game(game)` | Game-level info, e.g. `data/vrchat/meta.json` |
62
- | `Worlds(game, name)` | A world entry |
63
- | `Groups(game, name)` | A group entry |
64
- | `Players(game, name)` | A player entry |
65
- | `Characters(game, name)` | A character entry (games like Genshin Impact) |
66
- | `Get(game, type, name)` | Generic escape hatch for any other entity type a future game needs |
67
- | `List(game, type)` | Every entry of a type for a game, e.g. `List('genshinimpact', 'characters')` |
108
+ Returns game-level metadata.
68
109
 
69
- An entry with no verified working image simply has `"image": ""` โ€” check for a blank string, not a placeholder value, before using it.
110
+ ```js
111
+ const game = await gamingInfos.Game('warframe');
112
+ ```
70
113
 
71
- ### Configuration (env vars)
114
+ ## `List(game, type)`
72
115
 
73
- | Variable | Default | Purpose |
74
- |---|---|---|
75
- | `GAMING_INFOS_API_BASE` | `https://api.nekosunevr.co.uk` | Base URL of the NekoSuneVR V5 API |
76
- | `GAMING_INFOS_API_PATH` | `/v5/games/api/gaming-infos` | Path prefix for the gaming-infos endpoint |
77
- | `GAMING_INFOS_DISABLE_API` | unset | Set to `1`/`true` to force local-only lookups (no network calls) |
78
- | `GAMING_INFOS_TIMEOUT_MS` | `4000` | API request timeout before falling back to local JSON |
116
+ Returns every entity for a game/type.
79
117
 
80
- ## ๐Ÿ“˜ Example JSON Formats
118
+ ```js
119
+ const resonators = await gamingInfos.List('wutheringwaves', 'characters');
120
+ const agents = await gamingInfos.List('zenlesszonezero', 'characters');
121
+ const operators = await gamingInfos.List('arknightsendfield', 'characters');
122
+ const vrchatGroups = await gamingInfos.List('vrchat', 'groups');
123
+ ```
81
124
 
82
- ## ๐ŸŒ Worlds (`data/<game>/worlds/worldname.json`)
125
+ Live endpoint:
83
126
 
84
- ```json
85
- {
86
- "name": "The Black Cat",
87
- "title": "Main Hall",
88
- "creator": "spookyghostboo",
89
- "aliases": "Black Cat",
90
- "image": "https://example.com/images/world.jpg",
91
- "description": "A cozy hangout world for friends.",
92
- "url": "VRCHAT WORLD URL"
93
- }
127
+ ```http
128
+ GET /v5/games/api/gaming-infos/:game/:type
94
129
  ```
95
130
 
96
- ## ๐Ÿ‘ฅ Groups (`data/<game>/groups/groupname.json`)
131
+ ## Single-entity helpers
132
+
133
+ ```js
134
+ await gamingInfos.Worlds('vrchat', 'world-slug');
135
+ await gamingInfos.Groups('vrchat', 'group-slug');
136
+ await gamingInfos.Players('vrchat', 'player-slug');
137
+ await gamingInfos.Avatars('vrchat', 'avatar-slug');
138
+ await gamingInfos.Characters('warframe', 'warframe-slug');
139
+ ```
140
+
141
+ Generic lookup:
142
+
143
+ ```js
144
+ await gamingInfos.Get('vrchat', 'worlds', 'world-slug');
145
+ ```
146
+
147
+ Live endpoint:
148
+
149
+ ```http
150
+ GET /v5/games/api/gaming-infos/:game/:type/:name
151
+ ```
152
+
153
+ The V5 API returns stable `slug` values for list entries. Use those slugs for detail lookups instead of trying to generate filenames from display names yourself.
154
+
155
+ ## `CacheInfo()`
156
+
157
+ Reads information about the last mirrored Gaming Infos fallback snapshot.
158
+
159
+ ```js
160
+ const cache = await gamingInfos.CacheInfo();
161
+ console.log(cache?.syncedAt, cache?.contentHash);
162
+ ```
163
+
164
+ ---
165
+
166
+ # ๐ŸŽ Game Codes API
167
+
168
+ Version 2.2.0 adds API-first redeem-code and creator-code support using the same fallback model.
169
+
170
+ APINODE endpoints:
171
+
172
+ ```http
173
+ GET /v5/games/api/codes
174
+ GET /v5/games/api/codes/status
175
+ GET /v5/games/api/codes/:game
176
+ GET /v5/games/api/codes/:game/:code
177
+ ```
178
+
179
+ `/codes/status` is cache/status data only and does **not** trigger website scraping or a source refresh.
180
+
181
+ ## `Codes()`
182
+
183
+ Returns the Game Codes directory, including supported games, aliases, metadata, counters, source counts, and endpoint information.
184
+
185
+ ```js
186
+ const directory = await gamingInfos.Codes();
187
+
188
+ console.log(directory.games);
189
+ console.log(directory.aliases);
190
+ ```
191
+
192
+ ## `CodesStatus()`
193
+
194
+ Returns the cached source-refresh state.
195
+
196
+ ```js
197
+ const status = await gamingInfos.CodesStatus();
198
+ ```
199
+
200
+ ## `GameCodes(game, options)`
201
+
202
+ Returns code lists using the existing APINODE response shape:
203
+
204
+ ```js
205
+ const fortniteCodes = await gamingInfos.GameCodes('fortnite');
206
+
207
+ console.log(fortniteCodes.Active);
208
+ console.log(fortniteCodes.Expired);
209
+ ```
210
+
211
+ Default shape:
97
212
 
98
213
  ```json
99
214
  {
100
- "name": "NekoSune Community",
101
- "owner": "NekoSuneVR",
102
- "image": "https://example.com/images/group.png",
103
- "description": "A friendly VRChat group for chill vibes and fun events.",
104
- "url": "VRCHAT GROUP URL"
215
+ "Active": [],
216
+ "Expired": []
105
217
  }
106
218
  ```
107
219
 
108
- ## ๐Ÿง Players (`data/<game>/players/playername.json`)
220
+ Include queued/unknown records:
221
+
222
+ ```js
223
+ const allFortniteCodes = await gamingInfos.GameCodes('fortnite', {
224
+ includeUnknown: true
225
+ });
226
+ ```
227
+
228
+ Which can return:
109
229
 
110
230
  ```json
111
231
  {
112
- "name": "NekoSuneVR",
113
- "title": "The Cutie Streamer",
114
- "species": "half human - half catgirl",
115
- "gender": "Male",
116
- "aliases": "ChisdealHDYT, Chisdeal2013, Chisdeal2014, ChisdealHD, progamer-gr, DarkBlackWolfs",
117
- "image": "https://media.discordapp.net/attachments/794229972490387496/794231249652678696/VRChat_1920x1080_2020-09-14_09-22-18.855.png",
118
- "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.",
119
- "url": "https://creator.nekosunevr.co.uk"
232
+ "Active": [],
233
+ "Expired": [],
234
+ "Unknown": []
120
235
  }
121
236
  ```
122
237
 
123
- ## ๐Ÿง Characters (`data/<game>/characters/charactername.json`)
238
+ Filtering is supported:
239
+
240
+ ```js
241
+ const creatorCodes = await gamingInfos.GameCodes('fortnite', {
242
+ category: 'creator-code',
243
+ includeUnknown: true
244
+ });
245
+
246
+ const freeCodes = await gamingInfos.GameCodes('genshin-impact', {
247
+ claimType: 'free'
248
+ });
249
+ ```
250
+
251
+ Timezone can also be passed through to the live API:
252
+
253
+ ```js
254
+ const codes = await gamingInfos.GameCodes('fortnite', {
255
+ timezone: 'Europe/London',
256
+ includeUnknown: true
257
+ });
258
+ ```
259
+
260
+ Cached aliases from the `/codes` directory are resolved during API outages as well, so aliases such as `fn`, `genshin`, `hsr`, or `wuwa` can still map to their canonical cached game dataset.
261
+
262
+ ## `GameCode(game, code, options)`
263
+
264
+ Looks up one specific code.
265
+
266
+ ```js
267
+ const creator = await gamingInfos.GameCode('fortnite', 'NEKOSUNEVR');
268
+ console.log(creator);
269
+ ```
270
+
271
+ Live endpoint:
272
+
273
+ ```http
274
+ GET /v5/games/api/codes/:game/:code
275
+ ```
276
+
277
+ When APINODE is unavailable, the package searches the locally mirrored Active, Expired, and Unknown code buckets.
278
+
279
+ ## `CodeCacheInfo()`
280
+
281
+ Returns the local Game Codes cache manifest.
282
+
283
+ ```js
284
+ const codeCache = await gamingInfos.CodeCacheInfo();
285
+ console.log(codeCache?.syncedAt, codeCache?.stats);
286
+ ```
287
+
288
+ ---
289
+
290
+ # ๐Ÿ“š Function reference
291
+
292
+ | Function | Purpose |
293
+ |---|---|
294
+ | `Games()` | List Gaming Infos games |
295
+ | `Game(game)` | Get game metadata |
296
+ | `List(game, type)` | List every entry for one game/type |
297
+ | `Worlds(game, name)` | Get one world |
298
+ | `Groups(game, name)` | Get one group |
299
+ | `Players(game, name)` | Get one player |
300
+ | `Avatars(game, name)` | Get one avatar |
301
+ | `Characters(game, name)` | Get one character/Warframe/Agent/etc. |
302
+ | `Get(game, type, name)` | Generic entity lookup |
303
+ | `CacheInfo()` | Gaming Infos fallback manifest |
304
+ | `Codes()` | Game Codes directory |
305
+ | `CodesStatus()` | Cached Game Codes source status |
306
+ | `GameCodes(game, options)` | Active/Expired/Unknown code lists |
307
+ | `GameCode(game, code, options)` | One specific redeem/creator code |
308
+ | `CodeCacheInfo()` | Game Codes fallback manifest |
309
+
310
+ ---
311
+
312
+ # ๐Ÿ’พ API-first fallback behavior
313
+
314
+ Normal reads follow this path:
315
+
316
+ ```text
317
+ Application
318
+ โ”‚
319
+ โ–ผ
320
+ NekoSuneVR V5 API
321
+ โ”‚
322
+ โ”œโ”€โ”€ available โ”€โ”€โ–บ return live data
323
+ โ”‚
324
+ โ””โ”€โ”€ unavailable
325
+ โ”‚
326
+ โ–ผ
327
+ bundled data/
328
+ โ”‚
329
+ โ–ผ
330
+ return last-good fallback
331
+ ```
332
+
333
+ The package does not need an API key for the public read endpoints documented above.
334
+
335
+ Set this to force local-only reads:
124
336
 
125
- For character-driven games like Genshin Impact:
337
+ ```bash
338
+ GAMING_INFOS_DISABLE_API=1
339
+ ```
340
+
341
+ ---
342
+
343
+ # ๐Ÿ”„ Daily fallback synchronization
344
+
345
+ The repository automatically runs the cache mirror **once every day at 03:23 UTC** through GitHub Actions.
346
+
347
+ The combined command is:
348
+
349
+ ```bash
350
+ npm run sync:cache
351
+ ```
352
+
353
+ That performs both:
354
+
355
+ ```bash
356
+ npm run sync:gaming-infos-cache
357
+ npm run sync:game-codes-cache
358
+ ```
359
+
360
+ The synchronization process is designed to be authoritative and failure-safe:
361
+
362
+ 1. Download the complete configured API snapshot into a temporary directory.
363
+ 2. Validate all required responses.
364
+ 3. Calculate content hashes and add/change/remove statistics.
365
+ 4. Replace the old fallback only after the new snapshot succeeds completely.
366
+ 5. Keep the previous fallback untouched if the API fails, times out, returns an error, or produces an incomplete snapshot.
367
+ 6. Commit actual fallback changes back to the repository.
368
+
369
+ Successful syncs mirror **additions, modifications, and removals**. If APINODE removes an entry, that entry is removed from the fallback during the next successful mirror.
370
+
371
+ Gaming Infos and Game Codes use independent atomic caches so a failure in one dataset cannot destroy the last-good snapshot of the other.
372
+
373
+ See [CACHE_SYNC.md](CACHE_SYNC.md) for the detailed cache architecture.
374
+
375
+ ---
376
+
377
+ # ๐Ÿงช Cache tests
378
+
379
+ Run all cache safety tests:
380
+
381
+ ```bash
382
+ npm run test:all-cache
383
+ ```
384
+
385
+ Or individually:
386
+
387
+ ```bash
388
+ npm run test:cache-sync
389
+ npm run test:game-code-cache
390
+ ```
391
+
392
+ The tests cover scenarios including:
393
+
394
+ - new entries appearing
395
+ - existing entries changing
396
+ - upstream entries being removed
397
+ - duplicate/invalid data protection
398
+ - partial API failures
399
+ - simulated HTTP 5xx outages
400
+ - preserving the last-good fallback after a failed sync
401
+
402
+ ---
403
+
404
+ # ๐Ÿ“ Fallback data structure
405
+
406
+ ```text
407
+ data/
408
+ โ”œโ”€โ”€ genshinimpact/
409
+ โ”‚ โ”œโ”€โ”€ meta.json
410
+ โ”‚ โ””โ”€โ”€ characters/
411
+ โ”œโ”€โ”€ honkaistarrail/
412
+ โ”œโ”€โ”€ nte/
413
+ โ”œโ”€โ”€ wutheringwaves/
414
+ โ”œโ”€โ”€ warframe/
415
+ โ”œโ”€โ”€ fortnite/
416
+ โ”œโ”€โ”€ zenlesszonezero/
417
+ โ”œโ”€โ”€ toweroffantasy/
418
+ โ”œโ”€โ”€ arknightsendfield/
419
+ โ”œโ”€โ”€ vrchat/
420
+ โ”‚ โ”œโ”€โ”€ meta.json
421
+ โ”‚ โ”œโ”€โ”€ players/
422
+ โ”‚ โ”œโ”€โ”€ groups/
423
+ โ”‚ โ”œโ”€โ”€ worlds/
424
+ โ”‚ โ””โ”€โ”€ avatars/
425
+ โ”œโ”€โ”€ .cache-manifest.json
426
+ โ””โ”€โ”€ game-codes/
427
+ โ”œโ”€โ”€ directory.json
428
+ โ”œโ”€โ”€ status.json
429
+ โ”œโ”€โ”€ .cache-manifest.json
430
+ โ””โ”€โ”€ games/
431
+ โ””โ”€โ”€ <game>.json
432
+ ```
433
+
434
+ An entity with no verified image can use:
126
435
 
127
436
  ```json
128
437
  {
129
- "name": "Amber",
130
- "quote": "Outrider Amber, at the ready!",
131
- "cv": "Iwami Manaka",
132
- "description": "A perky, straightforward girl, who is also the only Outrider of the Knights of Favonius.",
133
- "image": "https://uploadstatic-sea.mihoyo.com/contentweb/20191009/2019100914372396510.png",
134
- "city": "Mondstadt",
135
- "url": "https://genshin.mihoyo.com/en/character/mondstadt?char=1",
136
- "element": "Pyro",
137
- "weapon": "Bow",
138
- "rating": 4
438
+ "image": ""
139
439
  }
140
440
  ```
141
441
 
142
- `element` is a plain string (Pyro/Hydro/Electro/Cryo/Anemo/Geo/Dendro) โ€” icon mapping is left to
143
- whatever app consumes this data. `rating` is the in-game star rarity (1-5) as a number. Fields
144
- like `cv` (voice actor) or `city` only apply to some games โ€” include whatever's relevant, drop what isn't.
442
+ Consumers should treat a blank image string as "no verified image available".
443
+
444
+ ---
445
+
446
+ # โš™๏ธ Environment variables
145
447
 
146
- ## ๐Ÿค Pull Requests (PRs)
448
+ ## Runtime API reads
147
449
 
148
- We welcome contributions, but please follow these important rules carefully โ€” see [CONTRIBUTING.md](CONTRIBUTING.md) for the full guide.
450
+ | Variable | Default | Purpose |
451
+ |---|---|---|
452
+ | `GAMING_INFOS_API_BASE` | `https://api.nekosunevr.co.uk` | NekoSuneVR APINODE base URL |
453
+ | `GAMING_INFOS_API_PATH` | `/v5/games/api/gaming-infos` | Gaming Infos path |
454
+ | `GAME_CODES_API_PATH` | `/v5/games/api/codes` | Game Codes path |
455
+ | `GAMING_INFOS_DISABLE_API` | unset | `1`/`true` forces local-only operation |
456
+ | `GAMING_INFOS_TIMEOUT_MS` | `4000` | Runtime API timeout before fallback |
149
457
 
150
- โœ… Permission & Source Rules
458
+ ## Cache mirror
151
459
 
152
- - Only include data that is publicly available or that you have permission to include.
153
- - If the data is not public (e.g., from private profiles, Discords, or DMs), do not include it.
154
- - If unsure, ask the world/group/player/character owner first.
155
- - Use only public sources (official game pages/wikis, official listings/profiles).
460
+ | Variable | Default | Purpose |
461
+ |---|---|---|
462
+ | `GAMING_INFOS_CACHE_TIMEOUT_MS` | `15000` | Gaming Infos sync request timeout |
463
+ | `GAMING_INFOS_CACHE_RETRIES` | `2` | Gaming Infos retry count |
464
+ | `GAMING_INFOS_CACHE_RETRY_DELAY_MS` | `750` | Gaming Infos retry delay |
465
+ | `GAME_CODES_CACHE_TIMEOUT_MS` | `15000` | Game Codes sync request timeout |
466
+ | `GAME_CODES_CACHE_RETRIES` | `2` | Game Codes retry count |
467
+ | `GAME_CODES_CACHE_RETRY_DELAY_MS` | `750` | Game Codes retry delay |
468
+ | `GAME_CODES_CACHE_GAME_DELAY_MS` | small delay | Delay between per-game code snapshots |
156
469
 
157
- ๐Ÿšซ Respect & Safety
470
+ ---
158
471
 
159
- - No harassment, bullying, or doxxing.
160
- - Any PR containing harassment, defamation, or private information will be rejected and reported.
161
- - Respect each game's Terms of Service and Community Guidelines.
162
- - Do not include private details, logs, or non-public data.
472
+ # ๐Ÿ“ Example character entry
163
473
 
164
- ## ๐Ÿ–ผ๏ธ Image Requirement
474
+ Different games expose different fields. Consumers should use the fields relevant to that game rather than assuming every title has the same schema.
165
475
 
166
- Each entry must include a valid image URL in its JSON:
167
476
  ```json
168
- "image": "https://example.com/images/item.png"
477
+ {
478
+ "name": "Example Character",
479
+ "slug": "examplecharacter",
480
+ "rarity": "5-star",
481
+ "element": "Electro",
482
+ "weapon": "Sword",
483
+ "description": "Public character information.",
484
+ "image": "https://example.com/character.webp",
485
+ "url": "https://example.com/source",
486
+ "source": {
487
+ "provider": "Public source",
488
+ "publicDataOnly": true
489
+ }
490
+ }
169
491
  ```
170
492
 
171
- ## ๐Ÿ“„ Format Consistency
493
+ ---
172
494
 
173
- Follow the exact folder and field structure:
495
+ # ๐Ÿค Contributions
174
496
 
175
- ```
176
- data/
177
- โ””โ”€โ”€ <game>/
178
- โ”œโ”€โ”€ meta.json
179
- โ”œโ”€โ”€ worlds/
180
- โ”œโ”€โ”€ groups/
181
- โ”œโ”€โ”€ players/
182
- โ””โ”€โ”€ characters/
183
- ```
497
+ Contributions are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md).
184
498
 
185
- Each JSON should match the examples above.
499
+ Please follow these rules:
186
500
 
187
- ## ๐Ÿ” Accuracy
501
+ - Only include publicly available data or data you have permission to publish.
502
+ - Do not include private profiles, private Discord messages, DMs, private logs, authentication data, or personal information.
503
+ - Do not add leaks, datamined/unreleased content, hidden APIs, memory-inspection data, or client-extracted private data.
504
+ - Respect each game's Terms of Service and community rules.
505
+ - Keep sources clear and verifiable.
506
+ - Do not submit harassment, defamation, doxxing, or invasive profile information.
188
507
 
189
- Ensure all data is accurate, current, and permissioned.
508
+ ---
509
+
510
+ # โš ๏ธ Package fallback note
511
+
512
+ GitHub repository cache snapshots update automatically, but published npm packages are immutable.
513
+
514
+ An already-installed npm release keeps the fallback JSON bundled with that release until you update the package. While APINODE is online, live API reads still provide current data without requiring a package release.
515
+
516
+ ---
517
+
518
+ # โš ๏ธ Disclaimer
519
+
520
+ This project is not affiliated with or endorsed by VRChat Inc., HoYoverse, Kuro Games, Digital Extremes, Epic Games, Hotta Studio, Hypergryph/GRYPHLINE, or any other game publisher represented by the data.
190
521
 
191
- ## โš ๏ธ Disclaimer
522
+ Game names, logos, characters, and related trademarks belong to their respective owners.
523
+
524
+ ---
192
525
 
193
- This project is not affiliated with or endorsed by VRChat Inc., Genshin Impact/HoYoverse, or any other game covered here.
194
- All names, logos, and related elements are property of their respective owners.
195
- Always follow each game's official Terms of Service and Community Guidelines
196
- (e.g. [VRChat](https://hello.vrchat.com/legal) / [VRChat Community Guidelines](https://hello.vrchat.com/community-guidelines)).
526
+ # ๐Ÿง  Credits
197
527
 
198
- ## ๐Ÿง  Credits
528
+ Maintained by **NekoSune Projects**.
199
529
 
200
- Maintained by NekoSune Projects
201
- ๐Ÿพ Contributions welcome โ€” stay game-friendly!
530
+ Contributions are welcome โ€” keep the data public, accurate, and game-friendly.
202
531
 
203
532
  <!-- GitAds-Verify: 2XHQSF1IKOWF4FH8P2TRI5GRWIJG2TJP -->
204
533
 
@@ -0,0 +1,14 @@
1
+ {
2
+ "name": "Arknights: Endfield",
3
+ "title": "3D real-time strategy action RPG by Hypergryph.",
4
+ "engine": "Unity",
5
+ "Platform": "Windows, PlayStation 5, iOS, Android",
6
+ "Release date": "2026",
7
+ "Genre": "Action RPG, Strategy, Gacha",
8
+ "developers": "Hypergryph",
9
+ "publisher": "GRYPHLINE",
10
+ "aliases": "Endfield, Arknights Endfield",
11
+ "image": "https://endfield.gryphline.com/favicon.ico",
12
+ "description": "Arknights spin-off featuring playable Operators with classes, elements, weapons and factions.",
13
+ "url": "https://endfield.gryphline.com/"
14
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "name": "Fortnite",
3
+ "title": "Epic Games online ecosystem featuring Battle Royale and creator experiences.",
4
+ "engine": "Unreal Engine 5",
5
+ "Platform": "Windows, PlayStation, Xbox, Nintendo Switch, Android, Cloud",
6
+ "Release date": "July 25, 2017",
7
+ "Genre": "Battle Royale, Action, Sandbox",
8
+ "developers": "Epic Games",
9
+ "publisher": "Epic Games",
10
+ "aliases": "Fortnite, FN",
11
+ "image": "https://www.fortnite.com/favicon.ico",
12
+ "description": "Fortnite characters, current Battle Royale NPCs and related public game information.",
13
+ "url": "https://www.fortnite.com/"
14
+ }