Update GaCy-GO
This commit is contained in:
1 parent
da8a32f60d
commit
0cbe460e49
345 files changed
+98202
-77559
No files matched your search
@@ -0,0 +1,94 @@
|
||||
"""Render an explicitly staged, resource-fed native Warp adapter capture.
|
||||
|
||||
This never modifies scripts/, policy or saves. The operator supplies an output
|
||||
path, then stages that file only after the walking scene is stable. The default
|
||||
is one banner. --assets-only checks Exists without creating pools or UI.
|
||||
"""
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parent.parent
|
||||
|
||||
|
||||
def quote(value):
|
||||
separator = ""
|
||||
while "]" + separator + "]" in value:
|
||||
separator += "="
|
||||
return "[" + separator + "[" + value + "]" + separator + "]"
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--output", type=Path, required=True)
|
||||
parser.add_argument("--limit", type=int, default=1)
|
||||
parser.add_argument("--assets-only", action="store_true")
|
||||
args = parser.parse_args()
|
||||
policy = json.loads((ROOT / "resources/GachaSandboxPolicy.json").read_text(encoding="utf-8"))
|
||||
catalog = json.loads((ROOT / "resources/PreviewGameplayCatalog.json").read_text(encoding="utf-8"))
|
||||
mapping = json.loads((ROOT / "resources/GachaBannerMapping.json").read_text(encoding="utf-8"))
|
||||
if mapping["client_assembly_sha256"] != catalog["client_assembly_sha256"]:
|
||||
raise ValueError("Mapping/captured catalog identity mismatch")
|
||||
template_id = policy["native_presentation"]["template_gacha_id"]
|
||||
template = next(row for row in catalog["tables"]["gacha"] if row["GachaID"] == template_id)
|
||||
if template["PrefabPath"] not in policy["verified_banner_prefabs"]:
|
||||
raise ValueError("Template has no installed-asset verification")
|
||||
avatars = {row["AvatarID"]: row for row in json.loads((ROOT / "resources/AvatarConfig.json").read_text(encoding="utf-8"))["avatar_config"]}
|
||||
active = [row for row in mapping["banners"] if row.get("roster_available", True)]
|
||||
roster = json.loads((ROOT / 'freesr-data.json').read_text(encoding='utf-8'))['avatars']
|
||||
active = [row for row in active if str(row['avatar_id']) in roster]
|
||||
four = sorted(row['avatar_id'] for row in active if avatars[row['avatar_id']]['Rarity'] == 'CombatPowerAvatarRarityType4')
|
||||
banners = [row for row in active if avatars[row['avatar_id']]['Rarity'] == 'CombatPowerAvatarRarityType5']
|
||||
if len(four) < 3:
|
||||
raise ValueError('Need three actual imported four-star avatars')
|
||||
if not 1 <= args.limit <= len(banners):
|
||||
raise ValueError("Limit must select at least one existing mapped banner")
|
||||
config_name = "__GAC_GACHA_ASSET_CAPTURE_CONFIG" if args.assets_only else "__GAC_GACHA_PRESENTATION"
|
||||
rules = policy['limited_rules']
|
||||
payload = ["_G." + config_name + "={enabled=true,template_id=" + str(template_id) + ",template_prefab=" + quote(template["PrefabPath"]) + ",rules={five_star_pity="+str(rules['five_star_pity'])+",four_star_pity="+str(rules['four_star_pity'])+"},banners={"]
|
||||
for index, banner in enumerate(banners[:args.limit], 1):
|
||||
row = avatars[banner["avatar_id"]]
|
||||
featured = [four[(index-1+offset) % len(four)] for offset in range(3)]
|
||||
cards = ','.join('{avatar_id=%d,portrait_path=%s}' % (id, quote(avatars[id]['AvatarGachaResultImgPath'])) for id in featured)
|
||||
payload.append("{gacha_id=%d,avatar_id=%d,sort_order=%d,art_path=%s,icon_path=%s,four_stars={%s}}," % (banner["gacha_id"], banner["avatar_id"], index, quote(row["AvatarCutinFrontImgPath"]), quote(row["DefaultAvatarHeadIconPath"]), cards))
|
||||
payload.append("}}")
|
||||
adapter = "" if args.assets_only else (ROOT / "internal/gameserver/gacha_presentation.lua").read_text(encoding="utf-8")
|
||||
digest = hashlib.sha256(("\n".join(payload) + adapter).encode()).hexdigest()
|
||||
payload.append("_G." + config_name + ".digest=" + quote(digest))
|
||||
pity = json.loads((ROOT / 'freesr-data.json').read_text(encoding='utf-8')).get('gacha_limited', {})
|
||||
payload.append('_G.' + config_name + '.pity={since_five_star=%d,since_four_star=%d}' % (pity.get('since_five_star', 0), pity.get('since_four_star', 0)))
|
||||
if args.assets_only:
|
||||
payload.append("""
|
||||
do
|
||||
local data=_G.__GAC_GACHA_ASSET_CAPTURE_CONFIG
|
||||
local s=_G.__GAC_GACHA_ART_ASSETS
|
||||
if not s or s.digest~=data.digest then s={digest=data.digest,index=1};_G.__GAC_GACHA_ART_ASSETS=s end
|
||||
local flags=CS.System.Enum.ToObject(typeof(CS.System.Reflection.BindingFlags),60)
|
||||
local manager=CS.RPG.Client.GlobalVars.s_GamePhaseManager
|
||||
local phase=manager and typeof(CS.RPG.Client.GamePhaseManager):GetField('_CurrentPhase',flags):GetValue(manager)
|
||||
if phase and not typeof(CS.RPG.Client.BattleGamePhase):IsInstanceOfType(phase) then
|
||||
local ok,err=pcall(function()
|
||||
for n=1,8 do
|
||||
local row=data.banners[s.index]
|
||||
if not row then
|
||||
if not s.done then CS.UnityEngine.Debug.Log('[GAC_GACHA_ART_ASSET] END count='..#data.banners);s.done=true end
|
||||
break
|
||||
end
|
||||
s.index=s.index+1
|
||||
local mgr=CS.RPG.Client.GlobalVars.s_AssetMgr
|
||||
CS.UnityEngine.Debug.Log('[GAC_GACHA_ART_ASSET] banner='..row.gacha_id..' avatar='..row.avatar_id..' art='..tostring(mgr:Exists(row.art_path))..' icon='..tostring(mgr:Exists(row.icon_path)))
|
||||
end
|
||||
end)
|
||||
if not ok then s.done=true;s.index=#data.banners+1;CS.UnityEngine.Debug.Log('[GAC_GACHA_ART_ASSET] ERROR '..tostring(err)) end
|
||||
end
|
||||
end
|
||||
""")
|
||||
else:
|
||||
payload.append(adapter)
|
||||
args.output.write_text("\n".join(payload) + "\n", encoding="utf-8")
|
||||
print(f"Rendered {args.limit} mapped banners; assets_only={args.assets_only}; output={args.output}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in new issue
Block a user