more work on tokens

This commit is contained in:
Eric 2024-07-22 21:50:39 -07:00
parent 9acbc2c94f
commit ee007b15db
No known key found for this signature in database
GPG Key ID: 89C93F0F8D6D5A98
11 changed files with 266 additions and 98 deletions

88
.efrocachemap generated
View File

@ -4062,50 +4062,50 @@
"build/assets/windows/Win32/ucrtbased.dll": "2def5335207d41b21b9823f6805997f1",
"build/assets/windows/Win32/vc_redist.x86.exe": "b08a55e2e77623fe657bea24f223a3ae",
"build/assets/windows/Win32/vcruntime140d.dll": "865b2af4d1e26a1a8073c89acb06e599",
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "de1a31ddd37764c6a31c6c619a0069fe",
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "1a4894c9eb324e6d2a442f72e5651c2c",
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "1999d90958ff312203a290aaff97a24f",
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "9a33cde90e447754e0b669f1e08948b2",
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "c52c4b14e87cada2d2de8060caf64ec3",
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "4894e58ac2fa3cbff0c0542e33afd94e",
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "eee4b5407e69075d925fad94de12c0b8",
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "5d041c76ab815765179308a01b6a0028",
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "8ae3a85f68553255fa47a86e35cd41b0",
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "cd9dac595579b8e19f15eade2cf8155f",
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "1ab4f141dd2541ae40e886b5d448d86f",
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "fb869f599357cb079851542411b2a852",
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "d06777b1f953c4f102d3ddb5b9d79337",
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "ac0582306bab0108da45dc53e0c544a7",
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "f847c697c1d541bbd1207355065fa988",
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "6edc275e5c427a04df8b02b115d2d832",
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "473ef626512034b43a8fa54ad66af1ce",
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "45f6a37d5e21b45542260f86b7c4784b",
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "4d9922c7ba8e15e2059fcef7f87d195a",
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "fd57a5b64d0fc65bd04bbfdd4b63965d",
"build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "fbfd42ab5d27e3ff921fa9cda02b2b45",
"build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "abb5870a4b01cda2c9a958149f759325",
"build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "fbfd42ab5d27e3ff921fa9cda02b2b45",
"build/prefab/lib/linux_arm64_server/release/libballisticaplus.a": "abb5870a4b01cda2c9a958149f759325",
"build/prefab/lib/linux_x86_64_gui/debug/libballisticaplus.a": "1b51a49163d412cdd0b1441e3459e6c4",
"build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "4a39d8397fb76df3bafa366d8085d1cd",
"build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "1b51a49163d412cdd0b1441e3459e6c4",
"build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "4a39d8397fb76df3bafa366d8085d1cd",
"build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "c4ed230b63e7109de342e045733963e5",
"build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "adb7ef762cb92b4c3bbe74a36e8ac6df",
"build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "c4ed230b63e7109de342e045733963e5",
"build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "adb7ef762cb92b4c3bbe74a36e8ac6df",
"build/prefab/lib/mac_x86_64_gui/debug/libballisticaplus.a": "0863bb24d2a42598dd20e7b55beb1c02",
"build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "1805fd5900917411f0e8032bf3c4734c",
"build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "3277c2f61c315e2ca7ed6776ba2363e2",
"build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "1805fd5900917411f0e8032bf3c4734c",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "b639992e280ee3a73b764a3e3e58baec",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "5ebaf4315d286080e5789939edfe43ce",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "be8f76ded92473fbab8b28018097456c",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "dcab88e3c14c6f4c4a03dd8617328eaf",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "bab18c50134744a7206ea1ded2d90ab2",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "c6788ba7cd99fc29a0b6ca8351f412b4",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "e61726c963e53ee7746ffbd7ed35c919",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "841fbbd6b87ac5d50ccdda647d8ff909",
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "9698e65459797b5a87072643f548f4ab",
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "e02eb31d2e4065e0436fc96232248fc5",
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "c79f227c4164afcd09ea70f8828c2f22",
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "6d4f68f726a373fdc179230a72a92324",
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "c285dfc219ba755f5abfbbe09b9aa9b8",
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "dd0b580b172574f14ef51789acfcc8f2",
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "69619ebd570b57f59ab3648aa6d3590a",
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "916f649191e81cc23e35818016e220df",
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "c2c725f438afe35aaade8b007d812e46",
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "6da83421d80c824fe9fe6f13b5f7991e",
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "f621b7c2e34f55dc8af7ca41bc4dc4ed",
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "2aa7d4c4008d6be2fc172a2375d47fed",
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "c51e187921cff4b389a345a0f87f364b",
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "5a74d47d994cbdf24da77462ef66ab55",
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "f25707a21481e3c45e7dbefc46b544f0",
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "9ace2a7c76cc66b8f9eab4d689a6ea49",
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "6e40b5fb42a16bfeeebf71aabeab1007",
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "8505048dfc05e7c02328bfbc359e23b3",
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "a73f6abea43df032adb422ad5be2f486",
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "cba67113f21cca2a51772ca92fc3f113",
"build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "61badc0ac176ef98abeba3ffa7a0c6d6",
"build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "79862c15f8121428281bb328b3d19e08",
"build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "61badc0ac176ef98abeba3ffa7a0c6d6",
"build/prefab/lib/linux_arm64_server/release/libballisticaplus.a": "79862c15f8121428281bb328b3d19e08",
"build/prefab/lib/linux_x86_64_gui/debug/libballisticaplus.a": "b47a86a58800dadefce197ee923c07c7",
"build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "7d5c7f92343fa4c0690995a0335afed8",
"build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "b47a86a58800dadefce197ee923c07c7",
"build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "7d5c7f92343fa4c0690995a0335afed8",
"build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "bb72cb9f98d48a5f572733db4095c449",
"build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "cc8aea2f632599441196a35fd1dc927a",
"build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "bb72cb9f98d48a5f572733db4095c449",
"build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "cc8aea2f632599441196a35fd1dc927a",
"build/prefab/lib/mac_x86_64_gui/debug/libballisticaplus.a": "60b7e716cd73097cd29654a1787dcc5d",
"build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "c1c40ab7f37c200b366dc6d4dbceb2a6",
"build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "f4cf12b15ecca349357f6fa68541b8e5",
"build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "c1c40ab7f37c200b366dc6d4dbceb2a6",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "3d9473e959782490836d1e76f20dc5ad",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "2887132d17a9909f02e6a12110e747a1",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "7fc343bf0a59b0b77496c5a32e53ae4a",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "2d32ced3489090b4331f690ed6e43c22",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "0380d3daa1497385764b2bb190430567",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "a4c2a736cc9f100a1115defa962448a7",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "bfb0fcd3fc53dcfed5022c9880df6033",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "a648e37862105c638c05c2e833470764",
"src/assets/ba_data/python/babase/_mgen/__init__.py": "f885fed7f2ed98ff2ba271f9dbe3391c",
"src/assets/ba_data/python/babase/_mgen/enums.py": "cb299985623bbcc86015cb103a424ae6",
"src/ballistica/base/mgen/pyembed/binding_base.inc": "efa61468cf098f77cc6a234461d8b86d",

View File

@ -1,4 +1,8 @@
### 1.7.36 (build 21919, api 8, 2024-07-21)
### 1.7.36 (build 21928, api 8, 2024-07-22)
- Wired up Tokens, BombSquad's new purchasable currency. The first thing these
can be used for is storage packs on ballistica.net, but this will expand to
other places in the game soon. For a full explanation on why these were added,
see https://ballistica.net/whataretokens
- Wired up initial support for using asset-packages for bundled assets.
- bacloud workspace commands are now a bit smarter; you can now do things like
`bacloud workspace put .` or even just `bacloud workspace put` and it will

View File

@ -52,7 +52,7 @@ if TYPE_CHECKING:
# Build number and version of the ballistica binary we expect to be
# using.
TARGET_BALLISTICA_BUILD = 21919
TARGET_BALLISTICA_BUILD = 21928
TARGET_BALLISTICA_VERSION = '1.7.36'

View File

@ -4,16 +4,15 @@
from __future__ import annotations
import logging
import time
from enum import Enum
from functools import partial
from dataclasses import dataclass
from typing import TYPE_CHECKING, assert_never
import bacommon.cloud
import bauiv1 as bui
from bauiv1lib.connectivity import wait_for_connectivity
if TYPE_CHECKING:
from typing import Any, Callable
@ -58,8 +57,13 @@ class _TxtDef:
class GetTokensWindow(bui.Window):
"""Window for purchasing/acquiring classic tickets."""
def __del__(self) -> None:
print('~GetTokensWindow()')
class State(Enum):
"""What are we doing?"""
LOADING = 'loading'
NOT_SIGNED_IN = 'not_signed_in'
HAVE_GOLD_PASS = 'have_gold_pass'
SHOWING_STORE = 'showing_store'
def __init__(
self,
@ -291,6 +295,12 @@ class GetTokensWindow(bui.Window):
self._restore_previous_call = restore_previous_call
self._textcolor = (0.92, 0.92, 2.0)
self._query_in_flight = False
self._last_query_time = -1.0
self._last_query_response: bacommon.cloud.StoreQueryResponse | None = (
None
)
# If they provided an origin-widget, scale up from that.
scale_origin: tuple[float, float] | None
if origin_widget is not None:
@ -350,7 +360,7 @@ class GetTokensWindow(bui.Window):
bui.containerwidget(edit=self._root_widget, cancel_button=btn)
bui.textwidget(
self._title_text = bui.textwidget(
parent=self._root_widget,
position=(self._width * 0.5, self._height - 47),
size=(0, 0),
@ -366,6 +376,7 @@ class GetTokensWindow(bui.Window):
self._status_text = bui.textwidget(
parent=self._root_widget,
size=(0, 0),
position=(self._width * 0.5, self._height * 0.5),
h_align='center',
v_align='center',
@ -374,40 +385,117 @@ class GetTokensWindow(bui.Window):
text='Loading...',
)
self._core_widgets = [
self._back_button,
self._title_text,
self._status_text,
]
self._token_count_widget: bui.Widget | None = None
self._smooth_update_timer: bui.AppTimer | None = None
self._smooth_token_count: float | None = None
self._token_count: int = 0
self._smooth_increase_speed = 1.0
self._ticking_sound: bui.Sound | None = None
# Get all textures used by our buttons preloading so hopefully
# they'll be in place by the time we show them.
for bdef in self._buttondefs:
for bimg in bdef.imgdefs:
bui.gettexture(bimg.tex)
# Wait for a master-server connection if need be. Otherwise we
# could error if called at the wrong time even with an internet
# connection, which is unintuitive.
wait_for_connectivity(
on_connected=bui.WeakCall(self._on_have_connectivity),
on_cancel=bui.WeakCall(self._back),
self._state = self.State.LOADING
self._update_timer = bui.AppTimer(
0.789, bui.WeakCall(self._update), repeat=True
)
self._update()
def _on_have_connectivity(self) -> None:
plus = bui.app.plus
assert plus is not None
def __del__(self) -> None:
if self._ticking_sound is not None:
self._ticking_sound.stop()
self._ticking_sound = None
# Sanity check; we need to be signed in. (we should not be
# allowed to get here if we aren't, but it could happen for
# fluke-ish reasons.)
if plus.accounts.primary is None:
bui.screenmessage(
bui.Lstr(resource='notSignedInErrorText'), color=(1, 0, 0)
)
bui.getsound('error').play()
self._back()
def _update(self) -> None:
# No-op if our underlying widget is dead or on its way out.
if not self._root_widget or self._root_widget.transitioning_out:
return
with plus.accounts.primary:
plus.cloud.send_message_cb(
bacommon.cloud.StoreQueryMessage(),
on_response=bui.WeakCall(self._on_store_query_response),
plus = bui.app.plus
if plus is None or plus.accounts.primary is None:
self._update_state(self.State.NOT_SIGNED_IN)
return
# Poll for relevant changes to the store or our account.
now = time.monotonic()
if not self._query_in_flight and now - self._last_query_time > 2.0:
self._last_query_time = now
self._query_in_flight = True
with plus.accounts.primary:
plus.cloud.send_message_cb(
bacommon.cloud.StoreQueryMessage(),
on_response=bui.WeakCall(self._on_store_query_response),
)
# Can't do much until we get a store state.
if self._last_query_response is None:
return
# If we've got a gold-pass, just show that. No need to offer any
# other purchases.
if self._last_query_response.gold_pass:
self._update_state(self.State.HAVE_GOLD_PASS)
return
# Ok we seem to be signed in and have store stuff we can show.
# Do that.
self._update_state(self.State.SHOWING_STORE)
def _update_state(self, state: State) -> None:
# We don't do much when state is unchanged.
if state is self._state:
# Update a few things in store mode though, such as token
# count.
if state is self.State.SHOWING_STORE:
self._update_store_state()
return
# Ok, state is changing. Start by resetting to a blank slate.
self._token_count_widget = None
for widget in self._root_widget.get_children():
if widget not in self._core_widgets:
widget.delete()
# Build up new state.
if state is self.State.NOT_SIGNED_IN:
bui.textwidget(
edit=self._status_text,
color=(1, 0, 0),
text=bui.Lstr(resource='notSignedInErrorText'),
)
elif state is self.State.LOADING:
raise RuntimeError('Should never return to loading state.')
elif state is self.State.HAVE_GOLD_PASS:
bui.textwidget(
edit=self._status_text,
color=(0, 1, 0),
text=(
'You have a Gold Pass.\n'
'All token purchases are free.\n'
'Enjoy!'
),
)
elif state is self.State.SHOWING_STORE:
assert self._last_query_response is not None
bui.textwidget(edit=self._status_text, text='')
self._build_store_for_response(self._last_query_response)
else:
# Make sure we handle all cases.
assert_never(state)
self._state = state
def _on_load_error(self) -> None:
bui.textwidget(
@ -418,20 +506,19 @@ class GetTokensWindow(bui.Window):
def _on_store_query_response(
self, response: bacommon.cloud.StoreQueryResponse | Exception
) -> None:
self._query_in_flight = False
if isinstance(response, bacommon.cloud.StoreQueryResponse):
self._last_query_response = response
# Hurry along any effects of this response.
self._update()
def _build_store_for_response(
self, response: bacommon.cloud.StoreQueryResponse
) -> None:
# pylint: disable=too-many-locals
plus = bui.app.plus
# If our message failed, just error and back out.
if isinstance(response, Exception):
logging.info('Store query failed.', exc_info=response)
bui.screenmessage(bui.Lstr(resource='errorText'), color=(1, 0, 0))
bui.getsound('error').play()
self._back()
return
bui.textwidget(edit=self._status_text, text='')
xinset = 40
@ -559,7 +646,7 @@ class GetTokensWindow(bui.Window):
v_align='center',
text='BombSquad\'s shiny new currency.',
)
_tnumtxt = bui.textwidget(
self._token_count_widget = bui.textwidget(
parent=self._root_widget,
position=(self._width - self._x_inset - 120.0, self._height - 48),
color=(2.0, 0.7, 0.0),
@ -568,8 +655,12 @@ class GetTokensWindow(bui.Window):
size=(0, 0),
h_align='left',
v_align='center',
text=str(response.tokens),
text='',
)
self._token_count = response.tokens
self._smooth_token_count = float(self._token_count)
self._smooth_update() # will set the text widget.
_tlabeltxt = bui.textwidget(
parent=self._root_widget,
position=(self._width - self._x_inset - 123.0, self._height - 48),
@ -592,15 +683,83 @@ class GetTokensWindow(bui.Window):
# Looks like purchases will never work here.
errmsg = (
'Sorry, purchases are not available on this build.\n'
'As a fallback, sign in to this account on another'
' platform and make purchases from there.'
'Try signing into your account on another platform'
' and making purchases from there.'
)
bui.screenmessage(errmsg, color=(1, 0.5, 0))
bui.getsound('error').play()
return
print(f'WOULD PURCHASE {itemid}')
assert plus is not None
plus.purchase(itemid)
def _update_store_state(self) -> None:
"""Called to make minor updates to an already shown store."""
assert self._token_count_widget is not None
assert self._last_query_response is not None
self._token_count = self._last_query_response.tokens
# Kick off new smooth update if need be.
assert self._smooth_token_count is not None
if (
self._token_count != int(self._smooth_token_count)
and self._smooth_update_timer is None
):
self._smooth_update_timer = bui.AppTimer(
0.05, bui.WeakCall(self._smooth_update), repeat=True
)
diff = abs(float(self._token_count) - self._smooth_token_count)
self._smooth_increase_speed = (
diff / 100.0
if diff >= 5000
else (
diff / 50.0
if diff >= 1500
else diff / 30.0 if diff >= 500 else diff / 15.0
)
)
def _smooth_update(self) -> None:
# Stop if the count widget disappears.
if not self._token_count_widget:
self._smooth_update_timer = None
return
finished = False
# If we're going down, do it immediately.
assert self._smooth_token_count is not None
if int(self._smooth_token_count) >= self._token_count:
self._smooth_token_count = float(self._token_count)
finished = True
else:
# We're going up; start a sound if need be.
self._smooth_token_count = min(
self._smooth_token_count + 1.0 * self._smooth_increase_speed,
self._token_count,
)
if int(self._smooth_token_count) >= self._token_count:
finished = True
self._smooth_token_count = float(self._token_count)
elif self._ticking_sound is None:
self._ticking_sound = bui.getsound('scoreIncrease')
self._ticking_sound.play()
bui.textwidget(
edit=self._token_count_widget,
text=str(int(self._smooth_token_count)),
)
# If we've reached the target, kill the timer/sound/etc.
if finished:
self._smooth_update_timer = None
if self._ticking_sound is not None:
self._ticking_sound.stop()
self._ticking_sound = None
bui.getsound('cashRegister2').play()
def _back(self) -> None:

View File

@ -41,12 +41,12 @@ void BasePlatformApple::RestorePurchases() {
}
void BasePlatformApple::PurchaseAck(const std::string& purchase,
const std::string& order_id) {
const std::string& order_id, bool valid) {
#if BA_USE_STORE_KIT
BallisticaKit::StoreKitContext::purchaseAck(purchase, order_id);
// AppleUtils::PurchaseAck(purchase, order_id);
#else
BasePlatform::PurchaseAck(purchase, order_id);
BasePlatform::PurchaseAck(purchase, order_id, valid);
#endif
}

View File

@ -13,8 +13,8 @@ class BasePlatformApple : public BasePlatform {
BasePlatformApple();
void DoPurchase(const std::string& item) override;
void RestorePurchases() override;
void PurchaseAck(const std::string& purchase,
const std::string& order_id) override;
void PurchaseAck(const std::string& purchase, const std::string& order_id,
bool valid) override;
void DoOpenURL(const std::string& url) override;
auto OverlayWebBrowserIsSupported() -> bool override;
void DoOverlayWebBrowserOpenURL(const std::string& url) override;

View File

@ -106,7 +106,7 @@ void BasePlatform::RestorePurchases() {
}
void BasePlatform::PurchaseAck(const std::string& purchase,
const std::string& order_id) {
const std::string& order_id, bool valid) {
Log(LogLevel::kError, "PurchaseAck() unimplemented");
}

View File

@ -52,9 +52,9 @@ class BasePlatform {
/// Restore purchases (currently only relevant on Apple platforms).
virtual void RestorePurchases();
/// Purchase was ack'ed by the master-server (so can consume).
/// Purchase was ack'ed by the master-server (so can consume or cancel).
virtual void PurchaseAck(const std::string& purchase,
const std::string& order_id);
const std::string& order_id, bool valid);
#pragma mark ENVIRONMENT -------------------------------------------------------

View File

@ -39,7 +39,7 @@ auto main(int argc, char** argv) -> int {
namespace ballistica {
// These are set automatically via script; don't modify them here.
const int kEngineBuildNumber = 21919;
const int kEngineBuildNumber = 21928;
const char* kEngineVersion = "1.7.36";
const int kEngineApiVersion = 8;

View File

@ -284,5 +284,7 @@ class StoreQueryResponse(Response):
result: Annotated[Result, IOAttrs('r')]
tokens: Annotated[int, IOAttrs('t')]
gold_pass: Annotated[bool, IOAttrs('g')]
available_purchases: Annotated[list[Purchase], IOAttrs('p')]
token_info_url: Annotated[str, IOAttrs('tiu')]

View File

@ -98,7 +98,10 @@ def run_standard_syncs(
# Actual syncs require localconfig entries.
if link_entry not in localconfig:
print(f'No link entry for {src_project}; skipping sync entry.')
print(
f'No link entry for {src_project}'
f' in project {projectroot}; skipping sync entry.'
)
continue
src = Path(localconfig[link_entry], src_subpath)
if verbose: