Update GaCy-GO

This commit is contained in:
CAtlas0784 committed 2026-10-28 18:54:43 +07:00
1 parent da8a32f60d
commit 0cbe460e49
345 files changed
+98202 -77559

No files matched your search

+153 -4
View File
@@ -6,6 +6,7 @@ import (
pb "gac-hkrpg-go/protocol/proto"
"google.golang.org/protobuf/proto"
"net/http"
"sort"
"strconv"
"strings"
)
@@ -13,7 +14,7 @@ import (
func apiCurrencyWarsCommand(w http.ResponseWriter, command string) {
fail := func(err error) { writeJSON(w, map[string]any{"success": false, "output": err.Error()}) }
parts := strings.Fields(command)
usage := "Usage: /cw status | /cw gold <total> | /cw hp <total>. Changes apply in CW Preparation; adventure inventory is unchanged."
usage := "Usage: /cw status | /cw list role|equip|orb|consumable|forge | /cw gold <total> | /cw hp <total> | /cw exp <gain> | /cw equip|orb|consumable|forge <itemID> [count] | /cw role <roleID> <star> [count]. Changes apply in CW Preparation."
if len(parts) < 2 {
fail(fmt.Errorf("%s", usage))
return
@@ -23,6 +24,79 @@ func apiCurrencyWarsCommand(w http.ResponseWriter, command string) {
fail(err)
return
}
if strings.EqualFold(parts[1], "help") {
writeJSON(w, map[string]any{"success": true, "output": usage})
return
}
if strings.EqualFold(parts[1], "list") {
if len(parts) != 3 {
fail(fmt.Errorf("%s", usage))
return
}
var lines []string
switch strings.ToLower(parts[2]) {
case "role":
for _, v := range catalog.CapturedVariants {
lines = append(lines, fmt.Sprintf("role=%d star=%d avatar=%d rarity=%d", v.Config.ID, v.Star, v.Config.AvatarID, v.Config.Rarity))
}
case "equip":
rows, e := common.LoadCurrencyWarsEquipment(catalog)
if e != nil {
fail(e)
return
}
ids := make([]uint32, 0, len(rows))
for id := range rows {
ids = append(ids, id)
}
sort.Slice(ids, func(i, j int) bool { return ids[i] < ids[j] })
for _, id := range ids {
v := rows[id]
lines = append(lines, fmt.Sprintf("equip=%d type=%d category=%d ability=%s", id, v.EquipType, v.EquipCategory, v.AbilityName))
}
case "orb", "consumable", "forge":
rows, e := common.LoadCurrencyWarsRewards(catalog)
if e != nil {
fail(e)
return
}
ids := []uint32{}
kind := strings.ToLower(parts[2])
switch kind {
case "orb":
for id := range rows.Orbs {
ids = append(ids, id)
}
case "consumable":
for id := range rows.Consumables {
ids = append(ids, id)
}
case "forge":
for id := range rows.Forges {
ids = append(ids, id)
}
}
sort.Slice(ids, func(i, j int) bool { return ids[i] < ids[j] })
for _, id := range ids {
switch kind {
case "orb":
v := rows.Orbs[id]
lines = append(lines, fmt.Sprintf("orb=%d type=%d bonus=%d", id, v.Type, v.Bonus))
case "consumable":
v := rows.Consumables[id]
lines = append(lines, fmt.Sprintf("consumable=%d rule=%d stack=%t", id, v.ConsumableRule, v.IfStack))
case "forge":
v := rows.Forges[id]
lines = append(lines, fmt.Sprintf("forge=%d function=%d choices=%d parameters=%v", id, v.FuncType, v.EquipNum, v.ParamList))
}
}
default:
fail(fmt.Errorf("available catalogs: role, equip, orb, consumable, forge"))
return
}
writeJSON(w, map[string]any{"success": true, "output": strings.Join(lines, "\n")})
return
}
cfg, err := common.LoadRuntimeConfig()
if err != nil {
fail(err)
@@ -62,7 +136,7 @@ func apiCurrencyWarsCommand(w http.ResponseWriter, command string) {
writeJSON(w, map[string]any{"success": true, "output": fmt.Sprintf("CW run=%d revision=%d gold=%d hp=%d/%d level=%d", run.UniqueId, snapshot.Revision, player.Gold, player.GridFightLineupHp, player.PPKKHHNEOHB, player.EHNJDIDABHD)})
return
}
if len(parts) != 3 || (field != "gold" && field != "hp") {
if len(parts) < 3 || len(parts) > 5 || (field != "gold" && field != "hp" && field != "exp" && field != "equip" && field != "role" && field != "orb" && field != "consumable" && field != "forge") {
fail(fmt.Errorf("%s", usage))
return
}
@@ -75,10 +149,85 @@ func apiCurrencyWarsCommand(w http.ResponseWriter, command string) {
fail(fmt.Errorf("HP must be 1..%d", player.PPKKHHNEOHB))
return
}
id, err := common.QueueCurrencyWarsCommand(cfg.PlayerUID, run.UniqueId, field, uint32(value))
quantity, star := uint32(1), uint32(0)
parse := func(text string) (uint32, error) {
v, e := strconv.ParseUint(text, 10, 32)
if e != nil || v == 0 {
return 0, fmt.Errorf("star/count must be a positive uint32")
}
return uint32(v), nil
}
switch field {
case "role":
if len(parts) < 4 {
fail(fmt.Errorf("%s", usage))
return
}
star, err = parse(parts[3])
if err == nil && len(parts) == 5 {
quantity, err = parse(parts[4])
}
if err == nil {
_, err = catalog.CapturedRoleVariant(uint32(value), star)
}
case "orb", "consumable", "forge":
if len(parts) > 4 {
fail(fmt.Errorf("%s", usage))
return
}
if len(parts) == 4 {
quantity, err = parse(parts[3])
}
if err == nil {
var rows *common.CurrencyWarsRewards
rows, err = common.LoadCurrencyWarsRewards(catalog)
if err == nil {
if field == "forge" {
if _, ok := rows.Forges[uint32(value)]; !ok {
err = fmt.Errorf("unknown forge %d", value)
}
} else if field == "orb" {
if _, ok := rows.Orbs[uint32(value)]; !ok {
err = fmt.Errorf("unknown Orb %d", value)
}
} else {
if _, ok := rows.Consumables[uint32(value)]; !ok {
err = fmt.Errorf("unknown consumable %d", value)
}
}
}
}
case "equip":
if len(parts) > 4 {
fail(fmt.Errorf("%s", usage))
return
}
if len(parts) == 4 {
quantity, err = parse(parts[3])
}
if err == nil {
var rows map[uint32]common.CurrencyWarsEquipment
rows, err = common.LoadCurrencyWarsEquipment(catalog)
if err == nil {
if _, ok := rows[uint32(value)]; !ok {
err = fmt.Errorf("equipment %d not captured; use /cw list equip", value)
}
}
}
default:
if len(parts) != 3 {
fail(fmt.Errorf("%s", usage))
return
}
}
if err != nil {
fail(err)
return
}
writeJSON(w, map[string]any{"success": true, "state": "queued", "request_id": id, "output": fmt.Sprintf("Queued CW %s=%d for run %d. Applies at the next heartbeat in Preparation.", field, value, run.UniqueId)})
id, err := common.QueueCurrencyWarsGrant(cfg.PlayerUID, run.UniqueId, field, uint32(value), quantity, star)
if err != nil {
fail(err)
return
}
writeJSON(w, map[string]any{"success": true, "state": "queued", "request_id": id, "output": fmt.Sprintf("Queued CW %s=%d star=%d count=%d for run %d. Applies at the next heartbeat in Preparation; check CW_GM log for the applied result.", field, value, star, quantity, run.UniqueId)})
}