Skip to content

Commit ae9e138

Browse files
exec-astraeaclaude
andcommitted
refactor: correct source attribution, rename Tori to Seria
The hoyo-codes.seria.moe API is seriaati's (seriaati/hoyo-codes), not torikushiii's. The Tori field name and several comments credited the wrong author, and AGENTS.md paired torikushiii's repo URL with seriaati's endpoint. Renames Game.Tori to Seria, fetchTori to fetchSeria, and the "tori" source label to "seria" (visible in partial-failure logs). torikushiii is still credited where correct: api.ennead.cc is their hoyoverse-api, as is OpenGachaCodes. Ennead keeps its name — it is the endpoint host, not an author. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent 7559ad7 commit ae9e138

4 files changed

Lines changed: 28 additions & 25 deletions

File tree

AGENTS.md

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ Codes are pulled from up to three APIs and merged/de-duplicated, so a hiccup on
99
one source doesn't cause a miss. A source is skipped for any game it doesn't
1010
serve (empty slug), and it only errors when *every* attempted source fails:
1111

12-
- [ennead.cc](https://api.ennead.cc/mihoyo)`/<game>/codes` (HoYoverse only)
13-
- [torikushiii/hoyoverse-api](https://github.com/torikushiii/hoyoverse-api)`hoyo-codes.seria.moe` (HoYoverse only)
12+
- [torikushiii/hoyoverse-api](https://github.com/torikushiii/hoyoverse-api)
13+
`api.ennead.cc/mihoyo/<game>/codes` (HoYoverse only)
14+
- [seriaati/hoyo-codes](https://github.com/seriaati/hoyo-codes)
15+
`hoyo-codes.seria.moe` (HoYoverse only)
1416
- **OpenGachaCodes** — self-hosted read-only API (`opengachaBaseUrl` config).
1517
Supplements the HoYo games it also serves and is the **sole** source for
1618
non-HoYo games like Wuthering Waves. Disabled when `opengachaBaseUrl` is unset.
@@ -202,9 +204,10 @@ When adding a config knob: add it to `fileConf`, resolve/validate it in
202204

203205
## Upstream APIs
204206

205-
- **ennead** — `https://api.ennead.cc/mihoyo/<slug>/codes`, slugs `genshin`,
206-
`starrail`, `zenless`, `honkai`. Shape: `{"active":[{"code","rewards":[...]}],"inactive":[...]}`.
207-
- **torikushiii** — `https://hoyo-codes.seria.moe/codes?game=<slug>`, slugs
207+
- **ennead** (torikushiii/hoyoverse-api) — `https://api.ennead.cc/mihoyo/<slug>/codes`,
208+
slugs `genshin`, `starrail`, `zenless`, `honkai`.
209+
Shape: `{"active":[{"code","rewards":[...]}],"inactive":[...]}`.
210+
- **seria** (seriaati/hoyo-codes) — `https://hoyo-codes.seria.moe/codes?game=<slug>`, slugs
208211
`genshin`, `hkrpg`, `nap`, `honkai3rd`. Shape: `{"codes":[{"code","rewards":"A*60;B*5"}]}`
209212
(active only). Rewards get normalized (`A*60;B*5` → `A ×60, B ×5`).
210213
- **OpenGachaCodes** — `<opengachaBaseUrl>/games/<slug>/codes`, slugs `genshin`,
@@ -215,10 +218,10 @@ When adding a config knob: add it to `fileConf`, resolve/validate it in
215218
use ASCII `x`, not `×`; they're joined with `, ` as-is. `fetchOpengacha` lives
216219
in `sources.go`; the base URL is `opengachaBaseUrl` in config.
217220

218-
The internal key differs from the torikushiii slug for Star Rail (`hsr`/`hkrpg`)
221+
The internal key differs from the seria slug for Star Rail (`hsr`/`hkrpg`)
219222
and Zenless (`zzz`/`nap`). Per-source slugs live in `games.go`; a `Game` sets a
220223
slug to `""` for any source that doesn't serve it (e.g. `wuwa` has empty
221-
`Ennead`/`Tori` and is OpenGachaCodes-only), and `fetchCodes` skips empty-slug
224+
`Ennead`/`Seria` and is OpenGachaCodes-only), and `fetchCodes` skips empty-slug
222225
sources. To add another game, add one entry to the `games` map **and** to
223226
`gameOrder`; nothing else needs to change. A game whose only source is
224227
OpenGachaCodes **fails startup** if `opengachaBaseUrl` is unset (it could never

config.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ func loadConfig(path string) (Config, error) {
138138
// misconfiguration is loud rather than a silent no-op every check.
139139
g := games[key]
140140
opengachaUsable := g.Opengacha != "" && cfg.OpengachaBaseURL != ""
141-
if g.Ennead == "" && g.Tori == "" && !opengachaUsable {
141+
if g.Ennead == "" && g.Seria == "" && !opengachaUsable {
142142
problems = append(problems, fmt.Sprintf("games.%s: only OpenGachaCodes serves this game — set opengachaBaseUrl to watch it", key))
143143
}
144144
cfg.Games = append(cfg.Games, key)

games.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ type Game struct {
66
Key string // canonical internal key (GAMES env, state file)
77
Name string // human display name
88
Ennead string // slug for api.ennead.cc/mihoyo/<slug>/codes
9-
Tori string // slug for hoyo-codes.seria.moe/codes?game=<slug>
9+
Seria string // slug for hoyo-codes.seria.moe/codes?game=<slug>
1010
Opengacha string // slug for <opengachaBaseUrl>/games/<slug>/codes ("" = not served there)
1111
// Redeem is a web redemption URL template with {code} substituted,
1212
// or "" when the game only supports in-game redemption.
@@ -23,42 +23,42 @@ var games = map[string]Game{
2323
Key: "genshin",
2424
Name: "Genshin Impact",
2525
Ennead: "genshin",
26-
Tori: "genshin",
26+
Seria: "genshin",
2727
Opengacha: "genshin",
2828
Redeem: "https://genshin.hoyoverse.com/en/gift?code={code}",
2929
},
3030
"hsr": {
3131
Key: "hsr",
3232
Name: "Honkai: Star Rail",
3333
Ennead: "starrail",
34-
Tori: "hkrpg", // torikushiii's slug for Star Rail
34+
Seria: "hkrpg", // seriaati's slug for Star Rail
3535
Opengacha: "starrail", // OpenGachaCodes slug for Star Rail
3636
Redeem: "https://hsr.hoyoverse.com/gift?code={code}",
3737
},
3838
"zzz": {
3939
Key: "zzz",
4040
Name: "Zenless Zone Zero",
4141
Ennead: "zenless",
42-
Tori: "nap", // torikushiii's slug for Zenless Zone Zero
42+
Seria: "nap", // seriaati's slug for Zenless Zone Zero
4343
Opengacha: "zenless", // OpenGachaCodes slug for Zenless Zone Zero
4444
Redeem: "https://zenless.hoyoverse.com/redemption?code={code}",
4545
},
4646
"honkai3rd": {
4747
Key: "honkai3rd",
4848
Name: "Honkai Impact 3rd",
4949
Ennead: "honkai",
50-
Tori: "honkai3rd",
50+
Seria: "honkai3rd",
5151
Opengacha: "", // OpenGachaCodes doesn't serve Honkai Impact 3rd.
5252
Redeem: "", // Honkai Impact 3rd has no public web redemption page.
5353
},
5454
"wuwa": {
5555
Key: "wuwa",
5656
Name: "Wuthering Waves",
57-
// Not a HoYoverse game — the HoYo-only sources (ennead, tori) don't
57+
// Not a HoYoverse game — the HoYo-only sources (ennead, seria) don't
5858
// serve it, so its codes come solely from OpenGachaCodes. A source with
5959
// an empty slug is skipped in fetchCodes.
6060
Ennead: "",
61-
Tori: "",
61+
Seria: "",
6262
Opengacha: "wuwa",
6363
Redeem: "", // Wuthering Waves redeems codes in-game (no public web page).
6464
},
@@ -67,7 +67,7 @@ var games = map[string]Game{
6767
Name: "Arknights: Endfield",
6868
// Not a HoYoverse game — OpenGachaCodes-only, like wuwa.
6969
Ennead: "",
70-
Tori: "",
70+
Seria: "",
7171
Opengacha: "endfield",
7272
Redeem: "", // Arknights: Endfield redeems codes in-game (no public web page).
7373
},

sources.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ func getJSON(url string, out any) error {
4141
return json.NewDecoder(resp.Body).Decode(out)
4242
}
4343

44-
// fetchEnnead pulls active codes from api.ennead.cc.
44+
// fetchEnnead pulls active codes from api.ennead.cc (torikushiii/hoyoverse-api).
4545
func fetchEnnead(g Game) ([]Code, error) {
4646
var resp struct {
4747
Active []struct {
@@ -63,15 +63,15 @@ func fetchEnnead(g Game) ([]Code, error) {
6363
return out, nil
6464
}
6565

66-
// fetchTori pulls active codes from hoyo-codes.seria.moe (torikushiii).
67-
func fetchTori(g Game) ([]Code, error) {
66+
// fetchSeria pulls active codes from hoyo-codes.seria.moe (seriaati).
67+
func fetchSeria(g Game) ([]Code, error) {
6868
var resp struct {
6969
Codes []struct {
7070
Code string `json:"code"`
7171
Rewards string `json:"rewards"` // "Primogem*60;Adventurer's Experience*5"
7272
} `json:"codes"`
7373
}
74-
url := fmt.Sprintf("https://hoyo-codes.seria.moe/codes?game=%s", g.Tori)
74+
url := fmt.Sprintf("https://hoyo-codes.seria.moe/codes?game=%s", g.Seria)
7575
if err := getJSON(url, &resp); err != nil {
7676
return nil, err
7777
}
@@ -80,13 +80,13 @@ func fetchTori(g Game) ([]Code, error) {
8080
if c.Code == "" {
8181
continue
8282
}
83-
out = append(out, Code{Code: c.Code, Rewards: normalizeToriRewards(c.Rewards)})
83+
out = append(out, Code{Code: c.Code, Rewards: normalizeSeriaRewards(c.Rewards)})
8484
}
8585
return out, nil
8686
}
8787

88-
// normalizeToriRewards turns "A*60;B*5" into "A ×60, B ×5".
89-
func normalizeToriRewards(s string) string {
88+
// normalizeSeriaRewards turns "A*60;B*5" into "A ×60, B ×5".
89+
func normalizeSeriaRewards(s string) string {
9090
if s == "" {
9191
return ""
9292
}
@@ -193,8 +193,8 @@ func fetchCodes(g Game, opengachaBase string) ([]Code, error) {
193193
if g.Ennead != "" {
194194
try("ennead", func() ([]Code, error) { return fetchEnnead(g) })
195195
}
196-
if g.Tori != "" {
197-
try("tori", func() ([]Code, error) { return fetchTori(g) })
196+
if g.Seria != "" {
197+
try("seria", func() ([]Code, error) { return fetchSeria(g) })
198198
}
199199
if opengachaBase != "" && g.Opengacha != "" {
200200
try("opengacha", func() ([]Code, error) { return fetchOpengacha(g, opengachaBase) })

0 commit comments

Comments
 (0)