Files
lastz-giftcenter-cli/giftcenter.py
Timmy 5b513c31b1 Add profile/news/info commands for store.last-z.com API
profile reads getuserhome.php (power/level/alliance); news and info hit
public getsite_new.php / getindex.php. Store private endpoints authenticate
with the UID alone as Usertoken — no password needed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 23:28:31 +08:00

206 lines
5.8 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""Last-Z Gift Center CLI"""
import argparse
import os
import sys
import requests
from dotenv import load_dotenv
load_dotenv()
BASE_URL = "https://giftcenter.last-z.com"
STORE_URL = "https://store.last-z.com"
LOGIN_ERRORS = {
10006: "Token 已過期",
10007: "請稍後再試",
10017: "需要充值記錄",
10018: "UID 不存在",
10019: "不支援的幣別",
10020: "操作過於頻繁",
10022: "帳號警告",
10023: "不支援的地區",
10024: "帳號已刪除",
10002001: "系統錯誤",
10002002: "請求逾時",
10002003: "未預期的錯誤",
}
REDEEM_ERRORS = {
"E001": "系統錯誤",
"E002": "系統錯誤",
"E003": "系統錯誤",
"E004": "禮品碼不存在",
"E005": "禮品碼已過期",
"E006": "禮品碼已被使用",
"E007": "兌換次數已達上限",
"E008": "系統錯誤",
"E009": "請稍後再試",
}
def get_uid():
uid = os.getenv("UID")
if not uid:
print("錯誤:請在 .env 設定 UID=your_uid_here", file=sys.stderr)
sys.exit(1)
return uid
def cmd_login(args):
uid = args.uid or get_uid()
try:
resp = requests.get(f"{BASE_URL}/getcodeuser.php", params={"uid": uid}, timeout=10)
resp.raise_for_status()
data = resp.json()
except requests.RequestException as e:
print(f"請求失敗:{e}", file=sys.stderr)
sys.exit(1)
if data.get("code") == 0:
r = data["result"]
print(f"登入成功")
print(f" 名稱 : {r.get('name')}")
print(f" UID : {uid}")
print(f" SID : {r.get('sid')}")
print(f" 國家 : {r.get('country')}")
print(f" 等級 : {r.get('level')}")
else:
code = data.get("code", 10002001)
print(f"登入失敗:{LOGIN_ERRORS.get(code, f'錯誤碼 {code}')}", file=sys.stderr)
sys.exit(1)
def cmd_redeem(args):
uid = args.uid or get_uid()
code = args.code
try:
resp = requests.get(
f"{BASE_URL}/code.php",
headers={"Usertoken": uid},
params={"uid": uid, "code": code},
timeout=10,
)
resp.raise_for_status()
data = resp.json()
except requests.RequestException as e:
print(f"請求失敗:{e}", file=sys.stderr)
sys.exit(1)
error_code = data.get("errorCode")
if error_code == "ok":
print(f"兌換成功!禮品碼 {code} 已套用")
else:
msg = REDEEM_ERRORS.get(error_code, f"未知錯誤碼 {error_code}")
print(f"兌換失敗:{msg}", file=sys.stderr)
sys.exit(1)
def store_post(endpoint):
# store.last-z.com 公開端點,免 token
try:
resp = requests.post(f"{STORE_URL}/{endpoint}", json={}, timeout=10)
resp.raise_for_status()
return resp.json()
except requests.RequestException as e:
print(f"請求失敗:{e}", file=sys.stderr)
sys.exit(1)
def cmd_news(args):
data = store_post("getsite_new.php")
announces = data.get("version_announce", [])
if not announces:
print("目前沒有公告")
return
for a in announces:
print(f"[{a.get('createTime')}] {a.get('title')}")
print(f" 👍 {a.get('like_count', 0)} 👎 {a.get('dislike_count', 0)}")
def cmd_info(args):
data = store_post("getindex.php")
print(f"地區 : {data.get('clientCountry')}")
print(f"APK 下載 : {data.get('apkurl')}")
print(f"Token : {data.get('token')}")
def store_auth(endpoint, uid):
# store.last-z.com 私人端點只認 UID 當 Usertoken無密碼
try:
resp = requests.post(
f"{STORE_URL}/{endpoint}",
headers={"Usertoken": uid},
json={"uid": uid},
timeout=10,
)
return resp.json()
except (requests.RequestException, ValueError) as e:
print(f"請求失敗:{e}", file=sys.stderr)
sys.exit(1)
PROFILE_FIELDS = {
"name": "名稱",
"uid": "UID",
"baseLevel": "總部等級",
"power": "戰力",
"likeCount": "點贊量",
"armyKill": "殺敵數量",
"giftLevel": "送禮等級",
"kingWinNum": "稱王次數",
"allianceName": "聯盟",
"abbr": "聯盟縮寫",
}
def cmd_profile(args):
uid = args.uid or get_uid()
data = store_auth("getuserhome.php", uid)
if data.get("code") != 0:
print(f"讀取失敗:{data.get('message') or data.get('code')}", file=sys.stderr)
sys.exit(1)
info = data.get("info", {})
for key, label in PROFILE_FIELDS.items():
if key in info:
print(f" {label}\t: {info[key]}")
def main():
parser = argparse.ArgumentParser(description="Last-Z Gift Center CLI")
parser.add_argument("--uid", help="指定 UID覆蓋 .env")
sub = parser.add_subparsers(dest="command", required=True)
# login
p_login = sub.add_parser("login", help="登入並查看帳號資訊")
p_login.add_argument("--uid", help="指定 UID覆蓋 .env")
p_login.set_defaults(func=cmd_login)
# redeem
p_redeem = sub.add_parser("redeem", help="兌換禮品碼")
p_redeem.add_argument("code", help="禮品碼")
p_redeem.add_argument("--uid", help="指定 UID覆蓋 .env")
p_redeem.set_defaults(func=cmd_redeem)
# news
p_news = sub.add_parser("news", help="查看遊戲公告")
p_news.set_defaults(func=cmd_news)
# info
p_info = sub.add_parser("info", help="查看地區與最新 APK 下載連結")
p_info.set_defaults(func=cmd_info)
# profile
p_profile = sub.add_parser("profile", help="顯示完整帳號資料(戰力/等級/聯盟)")
p_profile.add_argument("--uid", help="指定 UID覆蓋 .env")
p_profile.set_defaults(func=cmd_profile)
args = parser.parse_args()
args.func(args)
if __name__ == "__main__":
main()