feat(fifa17): real player-contract consumable apply, replacing the probe
POST /ut/game/fifa17/item/resource/<rid> {"apply":[{"id":N}]} now performs a
durable atomic contract application instead of falling through to Python.
THE RULE. grant = fcc_contractcards[card][tier(TARGET.rating)], then
min(99, contract + grant). The column is keyed on the TARGET's tier, NOT the
card's own -- all 36 cells of EA's shipped table match the published FIFA 17
matrix, and staging discriminates the two readings outright: a bronze-RARE
card on a rating-89 player granted 3 (the gold column), where the card-level
reading predicts 15.
No client binary reads fcc_contractcards -- a string scan of every .exe/.dll
in the install finds it referenced nowhere, and CardsDLL reads only 14 fcc_
tables (fcc_discardcoins among them, which is why quick-sell prices locally).
Consumable effects are server-authoritative, so EA's shipped table is the only
non-invented source and the client renders whatever we persist and re-serve.
The host computes the grant, Core owns the mutation -- the same split
quick-sell already uses (host prices via discard_value, Core performs
sell_item), and what migration 0027 means by "Core defines NO per-category
formula".
FAILS CLOSED, never 200-and-do-nothing: manager contracts 409 because staff
ratings are unimported so the target tier is unknowable; every other family
409 as unproven; batch 400; unresolvable operand 404. Core's deterministic
refusals pass through with their own status instead of collapsing to 503,
which would tell the client to retry a request that can never succeed.
`contract: 7` stops being a hardcode in shape_item/shape_staff_item and
becomes the fallback for an instance Core tracks no contract for. `fitness: 99`
is the same class of hardcode and is deliberately untouched.
CLEAN CUTOVER: Route::ConsumableApplyProbe, its handler, apply_probe_enabled,
the OPENFUT_FIFA17_APPLY_PROBE gate and both probe scripts are deleted. A
handler no classifier can reach is this repo's recurring defect class, and the
new economy arm preempts the probe. fifa17-migration-rehearse.py also drove
the probe (spelled "apply probe", so an apply-probe grep missed it) and would
have eaten a card off the rehearsal profile; retargeted to a non-mutating
assertion.
Not implemented, on purpose: the stored-manager bonus (real mechanic, rule
appears in no shipped table -- guessing it would corrupt the proven part) and
contract decrement per match (nothing spends contracts yet).
This commit is contained in:
@@ -77,10 +77,15 @@ try:
|
||||
|
||||
print(json.dumps(checks, indent=2, sort_keys=True))
|
||||
|
||||
print("\n=== apply probe MUST be off in the candidate ===")
|
||||
# The consumable apply is Rust-owned and MUTATES, so the rehearsal must not
|
||||
# send one that would succeed: a two-target body is refused (400
|
||||
# apply_batch_unsupported) before anything is resolved or written. That
|
||||
# refusal is only reachable if the candidate host CLAIMS the route -- a 502
|
||||
# means it fell through to the (dead) upstream, i.e. the cutover is missing.
|
||||
print("\n=== the candidate must OWN the consumable apply ===")
|
||||
req = urllib.request.Request(
|
||||
"http://127.0.0.1:%d/ut/game/fifa17/item/resource/5001004" % HOST_PORT,
|
||||
data=b'{"apply":[{"id":100000003}]}',
|
||||
data=b'{"apply":[{"id":100000003},{"id":100000004}]}',
|
||||
headers={"X-OpenFUT-Game": "fifa17", "Content-Type": "application/json"},
|
||||
method="POST")
|
||||
try:
|
||||
@@ -89,8 +94,9 @@ try:
|
||||
except urllib.error.HTTPError as e:
|
||||
st, body = e.code, e.read().decode()
|
||||
print(" status=%s body=%s" % (st, body))
|
||||
print(" probe OFF (must be 502 upstream-unavailable): %s"
|
||||
% (st == 502 and "upstream" in body))
|
||||
print(" apply route Rust-owned, nothing mutated (must be 400 "
|
||||
"apply_batch_unsupported): %s"
|
||||
% (st == 400 and "apply_batch_unsupported" in body))
|
||||
finally:
|
||||
for p in procs:
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user