Externalize autochess game data
check / local-gate (push) Failing after 58s

This commit is contained in:
JWeBot Contributors
2026-10-15 18:37:41 +08:00
parent 5125b827c0
commit 2bb2effc04
38 changed files with 3562 additions and 524 deletions
+4 -4
View File
@@ -4,13 +4,13 @@ build-backend = "setuptools.build_meta"
[project]
name = "jwebot-kernel"
version = "0.6.8a0+1015"
version = "0.6.9a0+1015"
description = "Stable routing and extension authority for JWeBot"
requires-python = ">=3.9"
dependencies = [
"jwebot-config==0.6.8a0+1015",
"jwebot-sdk==0.6.8a0+1015",
"jwebot-official-extensions==0.6.8a0+1015",
"jwebot-config==0.6.9a0+1015",
"jwebot-sdk==0.6.9a0+1015",
"jwebot-official-extensions==0.6.9a0+1015",
"tomli>=2; python_version < '3.11'",
]
@@ -107,4 +107,4 @@ __all__ = [
"verify_installed_release_signature",
]
__version__ = "0.6.8a0+1015"
__version__ = "0.6.9a0+1015"
@@ -3665,6 +3665,98 @@ class Ledger:
"game_counts": dict(account["game_counts"]),
}
def transfer_player_coins(
self,
group: str,
sender: str,
event_id: str,
command: str,
target_label: str,
amount: int,
render: Callable[[dict[str, Any]], str],
) -> str:
"""Move virtual coins between two group-scoped player accounts."""
source = self._player_identity(group, sender)
source_key = str(source["person_key"])
target = self.resolve_person(group, target_label)
target_key = str(target["person_key"])
target_display_name = person_display_label(target["display_name"])
with self.lock:
self.connection.execute("BEGIN IMMEDIATE")
try:
replay = self._player_action_replay(
group, event_id, source_key, command
)
if replay is not None:
self.connection.execute("COMMIT")
return replay
if source_key == target_key:
data: dict[str, Any] = {
"status": "self",
"source_display_name": source["display_name"],
"target_display_name": target_display_name,
"amount": amount,
}
else:
target_exists = self.connection.execute(
"""
SELECT 1 FROM player_accounts
WHERE group_fingerprint = ? AND person_key = ?
LIMIT 1
""",
(group, target_key),
).fetchone() is not None
if not target_exists:
data = {
"status": "target_missing",
"source_display_name": source["display_name"],
"target_display_name": target_display_name,
"amount": amount,
}
else:
source_account = self._load_player_account(
group, source_key
)
if amount > int(source_account["balance"]):
data = {
"status": "insufficient",
"source_display_name": source["display_name"],
"target_display_name": target_display_name,
"amount": amount,
"source_balance": int(source_account["balance"]),
}
else:
target_account = self._load_player_account(
group, target_key
)
source_account["balance"] -= amount
target_account["balance"] += amount
timestamp = utc_now()
self._save_player_account(
group, source_key, source_account, timestamp
)
self._save_player_account(
group, target_key, target_account, timestamp
)
data = {
"status": "transferred",
"source_display_name": source["display_name"],
"target_display_name": target_display_name,
"amount": amount,
"source_balance": int(source_account["balance"]),
"target_balance": int(target_account["balance"]),
}
response = render(data)
timestamp = utc_now()
self._store_player_action(
group, event_id, source_key, command, response, timestamp
)
self.connection.execute("COMMIT")
return response
except BaseException:
self.connection.execute("ROLLBACK")
raise
def apply_player_action(
self, group: str, sender: str, event_id: str, command: str,
action: Callable[[dict[str, Any]], str],