diff --git a/.efrocachemap b/.efrocachemap
index 4da45859..cc2ee877 100644
--- a/.efrocachemap
+++ b/.efrocachemap
@@ -4003,50 +4003,50 @@
"assets/src/ba_data/python/ba/_generated/__init__.py": "https://files.ballistica.net/cache/ba1/ee/e8/cad05aa531c7faf7ff7b96db7f6e",
"assets/src/ba_data/python/ba/_generated/enums.py": "https://files.ballistica.net/cache/ba1/1c/77/ac670a5118abdf8a7687af0e159b",
"ballisticacore-windows/Generic/BallisticaCore.ico": "https://files.ballistica.net/cache/ba1/89/c0/e32c7d2a35dc9aef57cc73b0911a",
- "build/prefab/full/linux_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/25/c1/91a48aca063af359c132049b8197",
- "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/43/11/80e9836994ab9583053b25e528d8",
- "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/f9/3b/4709b8451aecdbc048eef15d01eb",
- "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/03/ae/ee60be4a8b4800b90d1e29691518",
- "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/97/4f/cfee84e252f8b0b7571035f5883b",
- "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/68/f6/5b2d8461aba116b7071ebb5dac2b",
- "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/a6/7a/0d72ca4eda2320d6b78feaf6de84",
- "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/19/5b/183980b86e0af44a4dad40c874c1",
- "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/51/44/3f426d8fb643b0b1d2fe3d5197c0",
- "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/b7/5c/16040bb5fc81e53872880a942f93",
- "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/91/c4/ae905a45513e4b274a618320d4b9",
- "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/29/4d/2c46d9c3c20631ce2eb68ad40211",
- "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/13/76/9b2ae697273b918ba1bab69a7157",
- "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/16/c4/4794acfebd1caee39225de24ad69",
- "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/0d/b2/0e379d5edb40f49d3a0b0abb0c05",
- "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/b3/92/e6914cd28f76d2f69d58502a4d8b",
- "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/3a/53/e128b1b67fcc81ebe7b4a46faf8f",
- "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/dd/1f/288de55d2ded8451643d94ba5d24",
- "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/2e/1e/61a605506c87d391fe5b433d1403",
- "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/f2/e0/94772098ebb18f631dbe78ab6130",
- "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/71/7e/cc04f1d847d7d7002a8452eeee19",
- "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/24/00/1bd70964db65d179f2c6779d8982",
- "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/16/88/93dd42830a0175d5830747a713b8",
- "build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/52/61/b324c91bd0b077a9206d294d52fb",
- "build/prefab/lib/linux_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/84/8e/fbebd6c94cdcf46688b9e38ed8d8",
- "build/prefab/lib/linux_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/e9/94/3e87cc52ee7023beb33b8615d86d",
- "build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/e9/2e/466ad54052a7100921e3e748743e",
- "build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/c7/8f/d3e170f94e48ce122c8cab724791",
- "build/prefab/lib/mac_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/f0/f5/6a7983215a5582bed19f561afc4c",
- "build/prefab/lib/mac_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ff/37/32e4499e0c163ea025257fe884e9",
- "build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/db/ce/0da23791696b0c16a157a0401e82",
- "build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a4/1e/b453b7454f4bfd81cbba6d4f0a68",
- "build/prefab/lib/mac_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/d0/14/5ffa8a2415f14d1ea9ffe9cf4125",
- "build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/30/1a/7c959297e7ef46f7e9280b67a861",
- "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/69/e6/e5c6a65e42307a86cf4e3fcac729",
- "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/5c/6d/ee68f9f9c28363dda0c6b6290c6e",
- "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/f5/c1/86511c74fdc0dbffd9bae04b557e",
- "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/1c/4d/4aa5bfbe1c05a3f1d324d9404315",
- "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/2a/78/7380dc896cbead611c7a191b81a6",
- "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/d8/bb/b49f9176ae9c814e1850c018254a",
- "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/3d/7f/8b4147fdb2a3d6353b24fca7335f",
- "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/52/9d/4f8294fda439dca8b9b32c5e3936",
- "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/78/ce/1b5d8ce25f71fa509b626e55d8fb",
- "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/75/af/455bcadaa37686b1593233b855d3",
+ "build/prefab/full/linux_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/e2/50/52926d05dd5a3fb8b2f90992bfbe",
+ "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/20/de/02a2eca2e4ed2faf26fa492a1979",
+ "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/64/52/15d8c99a844ccb00b432621f79c0",
+ "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/d0/c1/0732dd083548534a3772ef774be5",
+ "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/cd/35/d72bcc057bb6149be27855275892",
+ "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/38/84/3523f3bb5b2cbdcd20430f642750",
+ "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/26/53/940c8b5d8e10e18bab19fb595732",
+ "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/2d/9e/c4674a1b86ebb7cf3a01edba4a35",
+ "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/29/85/af192102cd224f6fd59b03968f8f",
+ "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/d6/2b/e2f43aff52b03c89dba843f4902f",
+ "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/2d/cf/83894dab765d9e0ac3bd45009021",
+ "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/0b/35/eabf5e107be59cb1c53bc5529d73",
+ "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/3e/df/13c13021bdee744f619b7cb19eb5",
+ "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/10/71/0128643784c50dffb3d0461ad39a",
+ "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/3a/a5/c2d839a9e5de0e00df85e7a5ba41",
+ "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/23/6c/88b0d662ff4ae786da742b75500d",
+ "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/e2/e1/3adec175b7613134b2529b5c9f60",
+ "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/1e/16/888d82679e59b313fad06af5508d",
+ "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/8e/e7/01e25dc1bf3f535ab004b2824f27",
+ "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/ae/1e/a10c11048ee8892d4c5b28d1d62c",
+ "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/4f/e5/2b9e9726c394480fee642516d042",
+ "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/27/36/37ee9fd11ca48ad446b212968fba",
+ "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/eb/7c/cb523160cdb87dad92655c447228",
+ "build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a5/28/95f617af770d055705d1097cf45c",
+ "build/prefab/lib/linux_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ec/6a/10da9bd0b47d95c44a607221921b",
+ "build/prefab/lib/linux_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/02/6f/6cf36d8f2944f2fb94d081dc82d9",
+ "build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/07/83/a5c1227f34b2ae44f3bc1ceecd67",
+ "build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/82/b1/0b645d636f4ee7d7ff9bacf814ae",
+ "build/prefab/lib/mac_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/0e/a5/912d3b654e189593d1e4b9fdca52",
+ "build/prefab/lib/mac_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/03/3e/4d27eaad6ed3030f49bf8c74ed06",
+ "build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ec/b2/e4ff8cc0c49cb9d9ab0918a6a5da",
+ "build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/dc/75/e7b770d4e45165e5ad06a004c4c1",
+ "build/prefab/lib/mac_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/2a/34/2e586ec4a223391153ed27652073",
+ "build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/76/cd/00a38c08621bd003e5047922703e",
+ "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/7d/8d/cbcdf9162fb8a479d7af7d841fc9",
+ "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/14/92/af8bb09fa5f1b3f0350348785469",
+ "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/9b/81/878fc1259b50ae541c028b585a3a",
+ "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/68/82/026977d4967136bd8f818817ebdf",
+ "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/98/0d/eeb6fff979f314692ac248964689",
+ "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/f3/c1/457d17a1ab26caeb3219efe76f73",
+ "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/25/3c/e4b656076fbdb48309eadd70ba33",
+ "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/b9/22/ea982f6a461388e68d39d07e5c0a",
+ "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/25/38/12fede37e7a02ccdad5f202af22e",
+ "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/72/a1/0cbb94439bc3904b50d230f931a0",
"src/ballistica/generated/python_embedded/binding.inc": "https://files.ballistica.net/cache/ba1/c0/32/b7907e3859a5c5013a3d97b6b523",
"src/ballistica/generated/python_embedded/bootstrap.inc": "https://files.ballistica.net/cache/ba1/2d/4f/f4fe67827f36cd59cd5193333a02",
"src/ballistica/generated/python_embedded/bootstrap_monolithic.inc": "https://files.ballistica.net/cache/ba1/ef/c1/aa5f1aa10af89f5c0b1e616355fd"
diff --git a/.idea/dictionaries/ericf.xml b/.idea/dictionaries/ericf.xml
index f7ed8256..883a8699 100644
--- a/.idea/dictionaries/ericf.xml
+++ b/.idea/dictionaries/ericf.xml
@@ -224,6 +224,7 @@
basnmessagesender
basntoclient
bastd
+ batocloud
batools
batoolsinternal
baworker
@@ -438,6 +439,7 @@
cloudbuild
cloudshell
cloudshellbuild
+ cloudtoba
cloudtool
cloudtoolcmd
clrblu
@@ -984,6 +986,7 @@
fulltest
funcname
funcnames
+ funcp
funcptr
functiontestcase
functools
@@ -1146,6 +1149,7 @@
hgfs
hgignore
highscores
+ hinst
hitpoints
hkscs
hlsl
@@ -1366,6 +1370,7 @@
levelmodule
levelname
levelno
+ levelstr
lfull
lfval
libballisticacore
@@ -1449,6 +1454,7 @@
lockstr
locktype
locs
+ logcallobj
logcat
logincode
loginid
@@ -1476,6 +1482,7 @@
ltex
ltypes
lubyte
+ luid
luuid
lval
lzma
@@ -1595,6 +1602,7 @@
msgfull
msgid
msglen
+ msgnewline
msgnum
msgpriv
msgpub
@@ -2050,6 +2058,7 @@
pvrtcfast
pvval
pwin
+ pwsz
pybee
pybuild
pybuildapple
@@ -2140,6 +2149,7 @@
relpath
remainingchecks
remoteapp
+ rendertarget
rentry
representer
reprlib
@@ -2620,6 +2630,7 @@
threadpool
threadtype
throwiness
+ thumbstick
ticon
timedisplay
timeformat
@@ -2852,6 +2863,7 @@
wiimote
wiimotes
willeval
+ winapi
winbeast
wincfg
wincount
@@ -2894,6 +2906,7 @@
wttxt
wvmpth
xach
+ xbone
xbox
xcarchive
xcassets
@@ -2935,6 +2948,7 @@
xxsubtype
xxtestfuzz
xxxhdpi
+ yaaay
yach
yapf
yapfconfig
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 74176661..4f6a4ccb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,6 @@
-### 1.7.12 (build 20913, api 7, 2022-10-17)
+### 1.7.13 (build 20917, api 7, 2022-11-02)
+
+### 1.7.12 (build 20914, api 7, 2022-10-18)
- Disabled some live-objects warnings as it seems their use of certain gc module functionality might be causing some rare errors/crashes. On further inspection, it turns out that is technically expected. Basically those calls are useful for debugging but can break things. Added a note at the top of efro.debug elaborating on the situation. We can reimplement similar warnings later in a safe manner.
- Removed `ba._general.print_active_refs()` because the newer stuff in efro.debug does the same thing better.
- Bug fixes related to v2 account connections.
diff --git a/assets/src/ba_data/python/ba/_bootstrap.py b/assets/src/ba_data/python/ba/_bootstrap.py
index e764d4eb..7e2c7197 100644
--- a/assets/src/ba_data/python/ba/_bootstrap.py
+++ b/assets/src/ba_data/python/ba/_bootstrap.py
@@ -47,7 +47,7 @@ def bootstrap() -> None:
# Give a soft warning if we're being used with a different binary
# version than we expect.
- expected_build = 20913
+ expected_build = 20917
running_build: int = env['build_number']
if running_build != expected_build:
print(
diff --git a/ballisticacore-cmake/.idea/dictionaries/ericf.xml b/ballisticacore-cmake/.idea/dictionaries/ericf.xml
index d2f7fe75..b0de6664 100644
--- a/ballisticacore-cmake/.idea/dictionaries/ericf.xml
+++ b/ballisticacore-cmake/.idea/dictionaries/ericf.xml
@@ -117,6 +117,7 @@
basnmessagesender
basntoclient
bastd
+ batocloud
batoolsinternal
baworker
bbbb
@@ -243,6 +244,7 @@
clientinfo
clienttobasn
clipcount
+ cloudtoba
cmakelist
cmath
cmds
@@ -516,6 +518,7 @@
ftou
fullpath
funcname
+ funcp
fval
fvals
fvar
@@ -604,6 +607,7 @@
hexval
highp
highquality
+ hinst
hitchy
hmmm
homebrew
@@ -644,6 +648,7 @@
infotxt
inides
initguid
+ initing
inittab
inputdevice
inputter
@@ -722,6 +727,7 @@
leaderboards
lenval
levelno
+ levelstr
lgui
lhalf
libbz
@@ -742,6 +748,7 @@
lockpath
lockstr
locktype
+ logcallobj
logincode
loginid
logmsg
@@ -761,6 +768,7 @@
lsync
ltypes
lubyte
+ luid
luuid
lval
lvec
@@ -832,6 +840,7 @@
msgfull
msgid
msglen
+ msgnewline
msgnum
msgpriv
msgpub
@@ -1077,6 +1086,7 @@
pverraw
pvrtc
pwin
+ pwsz
pybuildapple
pycommand
pyconfig
@@ -1132,6 +1142,7 @@
relfut
reloadmedia
rendererdata
+ rendertarget
renormalize
rentry
rené
@@ -1361,6 +1372,7 @@
threadname
threadpool
threadtype
+ thumbstick
ticon
tiltage
timedisplay
@@ -1498,6 +1510,7 @@
wheeee
wiimote
wiimotes
+ winapi
windowshade
winmm
winsock
@@ -1518,6 +1531,7 @@
wtfslice
wunused
wvmpth
+ xbone
xcframework
xclamped
xcodebuildverbose
@@ -1535,6 +1549,7 @@
xxlimited
xxsubinterpreters
xxtestfuzz
+ yaaay
yclamped
ydiff
ydist
diff --git a/ballisticacore-cmake/.idea/inspectionProfiles/Project_Default.xml b/ballisticacore-cmake/.idea/inspectionProfiles/Project_Default.xml
index bccdbc35..76a90c06 100644
--- a/ballisticacore-cmake/.idea/inspectionProfiles/Project_Default.xml
+++ b/ballisticacore-cmake/.idea/inspectionProfiles/Project_Default.xml
@@ -1,6 +1,7 @@
+
@@ -12,7 +13,9 @@
+
+
@@ -49,6 +52,7 @@
+
diff --git a/src/ballistica/ballistica.cc b/src/ballistica/ballistica.cc
index f38dcc44..029361f7 100644
--- a/src/ballistica/ballistica.cc
+++ b/src/ballistica/ballistica.cc
@@ -32,8 +32,8 @@
namespace ballistica {
// These are set automatically via script; don't modify them here.
-const int kAppBuildNumber = 20913;
-const char* kAppVersion = "1.7.12";
+const int kAppBuildNumber = 20917;
+const char* kAppVersion = "1.7.13";
// Our standalone globals.
// These are separated out for easy access.
diff --git a/tools/batools/metamakefile.py b/tools/batools/metamakefile.py
index 287f08e3..5e605e71 100755
--- a/tools/batools/metamakefile.py
+++ b/tools/batools/metamakefile.py
@@ -178,8 +178,8 @@ def _add_extra_targets_internal(targets: list[Target]) -> None:
# don't get added to git.
_add_init_module_target(targets, moduledir='bametainternal/generated')
for srcname, dstname, gencmd in [
- ('clienttobasn', 'basnmessagesender', 'gen_basn_msg_sender'),
- ('basntoclient', 'basnmessagereceiver', 'gen_basn_msg_receiver'),
+ ('batocloud', 'basnmessagesender', 'gen_basn_msg_sender'),
+ ('cloudtoba', 'basnmessagereceiver', 'gen_basn_msg_receiver'),
]:
targets.append(
Target(
diff --git a/tools/efro/log.py b/tools/efro/log.py
index 3cc9230f..6ee2e896 100644
--- a/tools/efro/log.py
+++ b/tools/efro/log.py
@@ -103,8 +103,9 @@ class LogHandler(logging.Handler):
self,
path: str | Path | None,
echofile: TextIO | None,
- suppress_non_root_debug: bool = False,
- cache_size_limit: int = 0,
+ suppress_non_root_debug: bool,
+ cache_size_limit: int,
+ cache_time_limit: datetime.timedelta | None,
):
super().__init__()
# pylint: disable=consider-using-with
@@ -121,6 +122,7 @@ class LogHandler(logging.Handler):
self._cache_size = 0
assert cache_size_limit >= 0
self._cache_size_limit = cache_size_limit
+ self._cache_time_limit = cache_time_limit
self._cache: list[tuple[int, LogEntry]] = []
self._cache_index_offset = 0
self._cache_lock = Lock()
@@ -150,6 +152,8 @@ class LogHandler(logging.Handler):
asyncio.set_event_loop(self._event_loop)
self._thread_bootstrapped = True
try:
+ if self._cache_time_limit is not None:
+ self._event_loop.create_task(self._time_prune_cache())
self._event_loop.run_forever()
except BaseException:
# If this ever goes down we're in trouble.
@@ -161,6 +165,28 @@ class LogHandler(logging.Handler):
traceback.print_exc()
raise
+ async def _time_prune_cache(self) -> None:
+ assert self._cache_time_limit is not None
+ while bool(True):
+ await asyncio.sleep(61.27)
+ now = utc_now()
+ with self._cache_lock:
+
+ # Quick out: if oldest cache entry is still valid,
+ # don't touch anything.
+ if (
+ self._cache
+ and (now - self._cache[0][1].time) < self._cache_time_limit
+ ):
+ continue
+
+ # Ok; full prune.
+ self._cache = [
+ e
+ for e in self._cache
+ if (now - e[1].time) < self._cache_time_limit
+ ]
+
def get_cached(
self, start_index: int = 0, max_entries: int | None = None
) -> LogArchive:
@@ -424,6 +450,7 @@ def setup_logging(
suppress_non_root_debug: bool = False,
log_stdout_stderr: bool = False,
cache_size_limit: int = 0,
+ cache_time_limit: datetime.timedelta | None = None,
) -> LogHandler:
"""Set up our logging environment.
@@ -456,6 +483,7 @@ def setup_logging(
echofile=sys.stderr,
suppress_non_root_debug=suppress_non_root_debug,
cache_size_limit=cache_size_limit,
+ cache_time_limit=cache_time_limit,
)
# Note: going ahead with force=True here so that we replace any
diff --git a/tools/efro/rpc.py b/tools/efro/rpc.py
index ba5d1d22..c6412bfd 100644
--- a/tools/efro/rpc.py
+++ b/tools/efro/rpc.py
@@ -210,6 +210,8 @@ class RPCEndpoint:
self._did_close_writer = False
self._did_wait_closed_writer = False
self._did_out_packets_buildup_warning = False
+ self._total_bytes_read = 0
+ self._create_time = time.monotonic()
# Need to hold weak-refs to these otherwise it creates dep-loops
# which keeps us alive.
@@ -422,8 +424,8 @@ class RPCEndpoint:
return await asyncio.wait_for(msgobj.wait_task, timeout=timeout)
except asyncio.CancelledError as exc:
# Question: we assume this means the above wait_for() was
- # cancelled; what happens if a task running *us* is cancelled
- # though?
+ # cancelled; how do we distinguish between this and *us* being
+ # cancelled though?
if self.debug_print:
self.debug_print_call(
f'{self._label}: message {message_id} was cancelled.'
@@ -432,23 +434,34 @@ class RPCEndpoint:
self.close()
raise CommunicationError() from exc
- except asyncio.TimeoutError as exc:
- if self.debug_print:
- self.debug_print_call(
- f'{self._label}: message {message_id} timed out.'
- )
+ except Exception as exc:
- # Stop waiting on the response.
- msgobj.wait_task.cancel()
+ # If our timer timed-out or anything else went wrong with
+ # the stream, lump it in as a communication error.
+ if isinstance(
+ exc, asyncio.TimeoutError
+ ) or is_asyncio_streams_communication_error(exc):
- # Remove the record of this message.
- del self._in_flight_messages[message_id]
+ if self.debug_print:
+ self.debug_print_call(
+ f'{self._label}: got {type(exc)} sending message'
+ f' {message_id}; raising CommunicationError.'
+ )
- if close_on_error:
- self.close()
+ # Stop waiting on the response.
+ msgobj.wait_task.cancel()
- # Let the user know something went wrong.
- raise CommunicationError() from exc
+ # Remove the record of this message.
+ del self._in_flight_messages[message_id]
+
+ if close_on_error:
+ self.close()
+
+ # Let the user know something went wrong.
+ raise CommunicationError() from exc
+
+ # Some unexpected error; let it bubble up.
+ raise
def close(self) -> None:
"""I said seagulls; mmmm; stop it now."""
@@ -589,7 +602,7 @@ class RPCEndpoint:
def _tm(self) -> str:
"""Simple readable time value for debugging."""
- tval = time.time() % 100.0
+ tval = time.monotonic() % 100.0
return f'{tval:.2f}'
async def _run_read_task(self) -> None:
@@ -605,6 +618,7 @@ class RPCEndpoint:
# we'll know if/how we can talk to them.
mlen = await self._read_int_32()
message = await self._reader.readexactly(mlen)
+ self._total_bytes_read += mlen
self._peer_info = dataclass_from_json(_PeerInfo, message.decode())
self._last_keepalive_receive_time = time.monotonic()
if self.debug_print:
@@ -652,6 +666,7 @@ class RPCEndpoint:
else:
msglen = await self._read_int_16()
msg = await self._reader.readexactly(msglen)
+ self._total_bytes_read += msglen
if self.debug_print_io:
self.debug_print_call(
f'{self._label}: received message {msgid}'
@@ -687,6 +702,7 @@ class RPCEndpoint:
f' of size {rsplen} at {self._tm()}.'
)
rsp = await self._reader.readexactly(rsplen)
+ self._total_bytes_read += rsplen
msgobj = self._in_flight_messages.get(msgid)
if msgobj is None:
# It's possible for us to get a response to a message
@@ -791,9 +807,12 @@ class RPCEndpoint:
# if something else does.
if not self._is_expected_connection_error(exc):
logging.exception(
- 'Unexpected error in rpc %s %s task.',
+ 'Unexpected error in rpc %s %s task'
+ ' (age=%.1f, total_bytes_read=%d).',
self._label,
tasklabel,
+ time.monotonic() - self._create_time,
+ self._total_bytes_read,
)
else:
if self.debug_print:
@@ -846,13 +865,19 @@ class RPCEndpoint:
)
async def _read_int_8(self) -> int:
- return int.from_bytes(await self._reader.readexactly(1), _BYTE_ORDER)
+ out = int.from_bytes(await self._reader.readexactly(1), _BYTE_ORDER)
+ self._total_bytes_read += 1
+ return out
async def _read_int_16(self) -> int:
- return int.from_bytes(await self._reader.readexactly(2), _BYTE_ORDER)
+ out = int.from_bytes(await self._reader.readexactly(2), _BYTE_ORDER)
+ self._total_bytes_read += 2
+ return out
async def _read_int_32(self) -> int:
- return int.from_bytes(await self._reader.readexactly(4), _BYTE_ORDER)
+ out = int.from_bytes(await self._reader.readexactly(4), _BYTE_ORDER)
+ self._total_bytes_read += 4
+ return out
@classmethod
def _is_expected_connection_error(cls, exc: Exception) -> bool: