From 74c9f675827b3a4dd9489fa14d2c5d28cc43621c Mon Sep 17 00:00:00 2001 From: Eric Date: Tue, 29 Nov 2022 11:50:18 -0800 Subject: [PATCH 01/26] more work on v2 and google play --- .efrocachemap | 138 ++++----- .idea/dictionaries/ericf.xml | 7 + CHANGELOG.md | 9 +- assets/src/ba_data/python/._ba_sources_hash | 2 +- assets/src/ba_data/python/_ba.py | 50 ++-- assets/src/ba_data/python/_bainternal.py | 1 - assets/src/ba_data/python/ba/__init__.py | 6 +- assets/src/ba_data/python/ba/_accountv1.py | 3 + assets/src/ba_data/python/ba/_accountv2.py | 167 ++++++++++- assets/src/ba_data/python/ba/_app.py | 30 +- assets/src/ba_data/python/ba/_apputils.py | 51 +++- assets/src/ba_data/python/ba/_bootstrap.py | 5 +- assets/src/ba_data/python/ba/_cloud.py | 6 + assets/src/ba_data/python/ba/_coopgame.py | 52 +--- assets/src/ba_data/python/ba/_hooks.py | 4 +- assets/src/ba_data/python/ba/_internal.py | 2 - assets/src/ba_data/python/ba/_login.py | 20 +- assets/src/ba_data/python/ba/internal.py | 4 + .../python/bastd/activity/coopscore.py | 271 +++++++----------- .../src/ba_data/python/bastd/game/football.py | 3 - .../ba_data/python/bastd/game/onslaught.py | 3 - .../ba_data/python/bastd/game/runaround.py | 3 - .../ba_data/python/bastd/game/thelaststand.py | 3 - .../python/bastd/ui/account/settings.py | 197 ++++++++----- .../ba_data/python/bastd/ui/configerror.py | 6 +- .../.idea/dictionaries/ericf.xml | 7 + src/ballistica/app/app_flavor.cc | 49 +++- src/ballistica/app/app_flavor.h | 16 +- src/ballistica/ballistica.cc | 2 +- src/ballistica/core/object.cc | 6 +- src/ballistica/core/object.h | 4 +- src/ballistica/core/thread.cc | 45 ++- src/ballistica/core/thread.h | 7 +- src/ballistica/graphics/gl/gl_sys.h | 2 +- src/ballistica/input/input.cc | 44 +++ src/ballistica/input/input.h | 2 +- .../platform/apple/platform_apple.h | 2 - src/ballistica/platform/platform.cc | 12 +- src/ballistica/platform/platform.h | 7 +- .../python/methods/python_methods_app.cc | 38 ++- .../python/methods/python_methods_system.cc | 54 +++- tools/bacommon/login.py | 10 + tools/batools/project.py | 6 +- tools/efro/error.py | 9 + tools/efro/message/_message.py | 14 + tools/efro/message/_sender.py | 59 ++-- tools/efrotools/pcommand.py | 7 + 47 files changed, 925 insertions(+), 520 deletions(-) diff --git a/.efrocachemap b/.efrocachemap index 769e3cdf..4fb93651 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -420,41 +420,41 @@ "assets/build/ba_data/audio/zoeOw.ogg": "https://files.ballistica.net/cache/ba1/60/ad/38269b7f1c7dc20cb9a506cd0681", "assets/build/ba_data/audio/zoePickup01.ogg": "https://files.ballistica.net/cache/ba1/72/85/d6fc4d16b7081d91fba2850b5b10", "assets/build/ba_data/audio/zoeScream01.ogg": "https://files.ballistica.net/cache/ba1/e9/ae/1d674d0c086eaa0bd1c3b1db0505", - "assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/89/ec/d472036fbb09f310891761beb39a", + "assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/b1/c3/2d8b079670d84bde0558f6454f1f", "assets/build/ba_data/data/languages/arabic.json": "https://files.ballistica.net/cache/ba1/b0/05/e530acaba539f040ce61e22561dc", "assets/build/ba_data/data/languages/belarussian.json": "https://files.ballistica.net/cache/ba1/61/03/89070ca765e06da3a419a579f503", - "assets/build/ba_data/data/languages/chinese.json": "https://files.ballistica.net/cache/ba1/1f/7f/af259ba9b41556e5e667ad4c646d", - "assets/build/ba_data/data/languages/chinesetraditional.json": "https://files.ballistica.net/cache/ba1/3c/22/78a56fc40426ab19ad4e76924b78", + "assets/build/ba_data/data/languages/chinese.json": "https://files.ballistica.net/cache/ba1/05/87/d3e03edbc59eb7e7da7ef8b17134", + "assets/build/ba_data/data/languages/chinesetraditional.json": "https://files.ballistica.net/cache/ba1/12/12/b39bec3a244399223b45f084e0b2", "assets/build/ba_data/data/languages/croatian.json": "https://files.ballistica.net/cache/ba1/c9/73/01a1343af814131b1ee96af0b687", - "assets/build/ba_data/data/languages/czech.json": "https://files.ballistica.net/cache/ba1/61/20/01291c2cb72b22f204730c0d7574", + "assets/build/ba_data/data/languages/czech.json": "https://files.ballistica.net/cache/ba1/cb/df/f2d54d3146a159c678a47d3ff01b", "assets/build/ba_data/data/languages/danish.json": "https://files.ballistica.net/cache/ba1/6a/fa/fcf4a804beaff927b0f12c179eaa", "assets/build/ba_data/data/languages/dutch.json": "https://files.ballistica.net/cache/ba1/68/93/da8e9874f41a786edf52ba4ccaad", - "assets/build/ba_data/data/languages/english.json": "https://files.ballistica.net/cache/ba1/a0/1d/5fbc922d01521142c2a347b1b024", - "assets/build/ba_data/data/languages/esperanto.json": "https://files.ballistica.net/cache/ba1/4c/c7/0184b8178869d1a3827a1bfcd5bb", - "assets/build/ba_data/data/languages/filipino.json": "https://files.ballistica.net/cache/ba1/c7/2e/e0520f58206da01b829e02ff4576", - "assets/build/ba_data/data/languages/french.json": "https://files.ballistica.net/cache/ba1/e8/84/6c9f123e9a0d82fc595c8f55ac7c", - "assets/build/ba_data/data/languages/german.json": "https://files.ballistica.net/cache/ba1/8a/09/3e0fa9e44913b53f4dab195d3fae", - "assets/build/ba_data/data/languages/gibberish.json": "https://files.ballistica.net/cache/ba1/5f/51/c15d74d2fe4e88ee1e3db0986500", - "assets/build/ba_data/data/languages/greek.json": "https://files.ballistica.net/cache/ba1/aa/da/dfc8d710af960d7300c7090faeab", - "assets/build/ba_data/data/languages/hindi.json": "https://files.ballistica.net/cache/ba1/09/55/b50104638f60636af2263877bb7f", - "assets/build/ba_data/data/languages/hungarian.json": "https://files.ballistica.net/cache/ba1/d8/f2/aa16bc336bd7660cc86c3264bfc4", - "assets/build/ba_data/data/languages/indonesian.json": "https://files.ballistica.net/cache/ba1/3a/6b/34714586cb4e9f1b12f8ae54cac8", - "assets/build/ba_data/data/languages/italian.json": "https://files.ballistica.net/cache/ba1/12/62/862228b229057877e89fb195d41d", + "assets/build/ba_data/data/languages/english.json": "https://files.ballistica.net/cache/ba1/74/1d/04985b013519340632a0f5eb6d81", + "assets/build/ba_data/data/languages/esperanto.json": "https://files.ballistica.net/cache/ba1/ac/f5/c0922a99e40dfc9f5e026d43b533", + "assets/build/ba_data/data/languages/filipino.json": "https://files.ballistica.net/cache/ba1/86/26/060476f46994c035ae0d52640657", + "assets/build/ba_data/data/languages/french.json": "https://files.ballistica.net/cache/ba1/c7/cf/35a6ebc876c7476b72547a914d07", + "assets/build/ba_data/data/languages/german.json": "https://files.ballistica.net/cache/ba1/06/58/071d6f7bbb5e93a3e074dbd323ae", + "assets/build/ba_data/data/languages/gibberish.json": "https://files.ballistica.net/cache/ba1/a3/f7/b12c68a8c1ecabbf7b8c41452986", + "assets/build/ba_data/data/languages/greek.json": "https://files.ballistica.net/cache/ba1/ae/89/47486b987d14f58b6cf2d665ce4b", + "assets/build/ba_data/data/languages/hindi.json": "https://files.ballistica.net/cache/ba1/9f/df/469e166c6a0d42bca4baae3a6cb6", + "assets/build/ba_data/data/languages/hungarian.json": "https://files.ballistica.net/cache/ba1/b2/81/53c8cd7617d649403e539c3a6171", + "assets/build/ba_data/data/languages/indonesian.json": "https://files.ballistica.net/cache/ba1/26/57/b9443fccbc90602a5ace74935365", + "assets/build/ba_data/data/languages/italian.json": "https://files.ballistica.net/cache/ba1/5f/b2/b9301d67bef699a092a4c04dd522", "assets/build/ba_data/data/languages/korean.json": "https://files.ballistica.net/cache/ba1/7c/38/d4a44c481757d355836f292ede48", - "assets/build/ba_data/data/languages/persian.json": "https://files.ballistica.net/cache/ba1/10/13/1228836444f7557211f0058ef9bd", - "assets/build/ba_data/data/languages/polish.json": "https://files.ballistica.net/cache/ba1/19/e9/59c891b1fb85f3ba9f19283c233d", - "assets/build/ba_data/data/languages/portuguese.json": "https://files.ballistica.net/cache/ba1/61/5b/847c03407d1c3a85866833323676", + "assets/build/ba_data/data/languages/persian.json": "https://files.ballistica.net/cache/ba1/cd/ed/4d6d0778d256ccc0ff2e27b970c6", + "assets/build/ba_data/data/languages/polish.json": "https://files.ballistica.net/cache/ba1/67/93/372c2a2428a830056e9ba22bbf95", + "assets/build/ba_data/data/languages/portuguese.json": "https://files.ballistica.net/cache/ba1/01/6f/516598d76c29b2fa45ff351426dc", "assets/build/ba_data/data/languages/romanian.json": "https://files.ballistica.net/cache/ba1/d7/06/9d70642d0a4d1e3b1c2149d7a17c", - "assets/build/ba_data/data/languages/russian.json": "https://files.ballistica.net/cache/ba1/34/ed/b97350983272e4b23bf140d7a5f4", + "assets/build/ba_data/data/languages/russian.json": "https://files.ballistica.net/cache/ba1/05/fb/a05a110238d0da5f902d06e5daa7", "assets/build/ba_data/data/languages/serbian.json": "https://files.ballistica.net/cache/ba1/4e/91/6f2a9a3ce733908e91377a6ddb9a", - "assets/build/ba_data/data/languages/slovak.json": "https://files.ballistica.net/cache/ba1/f9/4b/d9f01814224066856695452ef57c", - "assets/build/ba_data/data/languages/spanish.json": "https://files.ballistica.net/cache/ba1/ce/be/2f06c3436871fd464ff3a62597d9", + "assets/build/ba_data/data/languages/slovak.json": "https://files.ballistica.net/cache/ba1/20/a9/163d189884edf802636bf291e432", + "assets/build/ba_data/data/languages/spanish.json": "https://files.ballistica.net/cache/ba1/c9/48/63093604be4e04447974b9e6337d", "assets/build/ba_data/data/languages/swedish.json": "https://files.ballistica.net/cache/ba1/91/0a/35c4baf539d5951fc03a794c0e0b", - "assets/build/ba_data/data/languages/tamil.json": "https://files.ballistica.net/cache/ba1/64/22/7bc899ecbec52cf978a1faf1c127", + "assets/build/ba_data/data/languages/tamil.json": "https://files.ballistica.net/cache/ba1/2b/25/aa93983666b88d1c584f06b742b0", "assets/build/ba_data/data/languages/thai.json": "https://files.ballistica.net/cache/ba1/f7/df/7ba5f99c5c2c4c86fc0503fcf0b7", - "assets/build/ba_data/data/languages/turkish.json": "https://files.ballistica.net/cache/ba1/ee/08/1f77c7c320d8d8504a11ee495db3", - "assets/build/ba_data/data/languages/ukrainian.json": "https://files.ballistica.net/cache/ba1/f3/92/fd7ee5fa8a92fcc8fd2219a88a2f", - "assets/build/ba_data/data/languages/venetian.json": "https://files.ballistica.net/cache/ba1/2e/86/10d3e39d35014d039cc9ea886ca7", + "assets/build/ba_data/data/languages/turkish.json": "https://files.ballistica.net/cache/ba1/bb/f5/0eb74375f3c9ea827b73c67f4a25", + "assets/build/ba_data/data/languages/ukrainian.json": "https://files.ballistica.net/cache/ba1/1b/83/844f9e6f4e9e47a2d788d3faa9d2", + "assets/build/ba_data/data/languages/venetian.json": "https://files.ballistica.net/cache/ba1/17/15/973f4101bf2264173bd1c1729426", "assets/build/ba_data/data/languages/vietnamese.json": "https://files.ballistica.net/cache/ba1/1f/ae/abe3f105b3c4b51f6b7942773305", "assets/build/ba_data/data/maps/big_g.json": "https://files.ballistica.net/cache/ba1/47/0a/a617cc85d927b576c4e6fc1091ed", "assets/build/ba_data/data/maps/bridgit.json": "https://files.ballistica.net/cache/ba1/03/4b/57ee9b42854b26f23f81bd8c58ef", @@ -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/bd/82/98ea775b22a1113323a1ddf12b6a", - "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/e1/0d/0a431edcdee394a4e4d5b18608d7", - "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/e8/94/162a944636170ac881d3f3dfd805", - "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/f8/96/fea047474c276064176b65f7e48a", - "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/12/eb/226aba01e295a807614c64c44d40", - "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/23/71/f60c8e90699d887979c4ad26a2e2", - "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/8d/80/05e3d712c67d0fcde0e8605d0be7", - "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/7f/05/498a538fd28fcd1de964c046b8f2", - "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/d1/6e/01e46632d17db0597d1aef3394d1", - "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/aa/12/7992a25feae2b0bf2c8fe2023187", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/99/a9/2b251e46b2e9e4ef143a0308d9f3", - "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/6a/93/faee77acd35111d083998df65aaa", - "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/25/c1/9b6efb09c364beae30a40510bfcf", - "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/18/76/3f8e144f6727ee8f5f5f4b0b6ddc", - "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/3c/e8/02284ba36b4de9ca68cdd7c3e689", - "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/15/cf/c02041bdc6fa5d0042408e591dcf", - "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/62/98/ee64d80a6332d7d9fc57a2605a2d", - "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/54/e6/c4c75d29a7c19c34ba5876c4c350", - "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/69/3c/96b8690702f596182a305b5b4489", - "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/b4/b4/81668b3afad33372276a46545aae", - "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/c3/1a/ae199ada4bf5a649f73fe1663868", - "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a2/4f/2cf4047fdbac4a661ca99d4aedb8", - "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/06/f5/b0fdcf55008fc53e1660f7bc841f", - "build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/2c/af/159cc0021a3751da19f4d6832602", - "build/prefab/lib/linux_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/cc/4d/0586cbf47105ba1224a445cd72f4", - "build/prefab/lib/linux_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/f8/33/ae7f84447a19e465c134355b359e", - "build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/40/eb/004a4ea3094210114fd739cb9fcb", - "build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/45/ed/36918bf061396d6e1f9814afce8c", - "build/prefab/lib/mac_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/8f/28/7c06af16187bf2db92cf99763f4e", - "build/prefab/lib/mac_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/44/69/aeba19cb88e6b57c4ab9325f5877", - "build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/69/4e/b8354e50de6f2afb45b342919868", - "build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/70/65/f35430e7328bc7ac30de3960dfc7", - "build/prefab/lib/mac_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/d8/47/c89b62ea5a71854b303f9e85e5d7", - "build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/f2/19/280f6773b3563e012ad6bfad33dc", - "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/1e/17/e5ef6ce0e41360a43c63ef9c0974", - "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/cd/78/1adf82e5c3e456d2ea2d4290c61c", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/6b/5f/c5dc0b2a2809bc1d3ea57fb985d0", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/56/ee/49a4a2d7940fd239a66c04657c90", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/39/72/fb9b3400c5d128ad156818ede03d", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/22/65/550d27a960822b8846c0c0a440be", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/33/3b/9b38515580edd4616f9955f7e33c", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/fe/1a/80ddcd73df9985ab768e617a6c2b", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/1d/27/0d69901bb721f986fdbfc490100f", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/e9/59/ab5278ceeae3656f91c6d3c68c83", + "build/prefab/full/linux_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/0f/f4/4a4f1087d2bb778d9be504442270", + "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/0e/10/5c509346d44b89ddd12aec7ec7de", + "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/cd/9f/a6f5274ff94f95e902cca445a510", + "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/04/2a/263e10497930fa6159e5352b7370", + "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/59/62/28c8370b93d43d1c13acfbddee57", + "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/d8/4e/ad0d3316f74e82ffde5c7b976fc2", + "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/4a/41/08aa8c9e197e7cc75b6e8d97dc55", + "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/81/6b/e7bc7863fc9c6b6a241d93f7d4e3", + "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/ec/44/094cd342e6a8eb2f1671f680a5e8", + "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/fc/f9/b44862de39500fc85a3b3960a132", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/78/7d/c4f86fc89838006fa2bacf4fa9a8", + "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/d7/40/0d31b629247be2c16ee042ee9165", + "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/1f/39/781ca02803724b5a84a197d3d264", + "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/39/f9/a085edd64d394ce0f4fee7f857e9", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/fe/60/82caae9fc89ce89688ea5013e5c9", + "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/9c/e9/3fb7c6b71287d2b3c3ab5f11f6c3", + "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/c4/df/b58bf2cf14619d257ca145242cdd", + "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/b5/f9/d5ee77a243aee14ad0cd0f5e53e5", + "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/b8/bc/71febcf1ffd431bd80936d313b73", + "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/5d/ff/c36c1a0d0713aca6aa0f640de48b", + "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/2f/98/0f10aa690341351b047d9dc3fe65", + "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/14/aa/d9e350323ed97ca2c87667c569bb", + "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/64/a9/03eb8d0e32bf35b10941eb8ca082", + "build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/52/2a/31fb94be0f4f5e9ded5a100e298d", + "build/prefab/lib/linux_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a0/dc/5479a3f5499236fd0b72cbec5c9b", + "build/prefab/lib/linux_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/41/6b/175b26bc4b4429aac713d4cc3c20", + "build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/e0/5c/5a5c6cbd883cba37f31d991722fe", + "build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/81/bb/51740409b1cf442d8beed60f759c", + "build/prefab/lib/mac_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a2/7d/c630ea8a7975c3502cbd3ee6716f", + "build/prefab/lib/mac_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/44/66/a2d065477f9677a2b869c5ebc0a9", + "build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/8d/5e/335032c7fc26a8026db29b0bb1f0", + "build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/26/94/73a12ae50fe3750547ce218f3857", + "build/prefab/lib/mac_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/9a/77/a3607ad916ab9d0327cdd61800c5", + "build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/9d/ac/b2dd3b8a8b231210f19b0ec30299", + "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a6/cd/4b2cb9cbb7a617e408006f2eba7e", + "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/9e/f7/cadeae6e408cabe57d9e1cf782d6", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/0a/c3/b0d1aa43e3e66de3c213b7fda5f1", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/3f/39/fb44f0b1907cc8a9def711f90488", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/56/d5/e469a881eacc313ac6ca5e48c450", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/81/f9/ffcebd4dc6f76392516644b04978", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/75/e2/2e4066c5bc8e429723169e8d0ca2", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/9c/b9/1702985e444ba529f8adcb933039", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/76/ab/cb3cfe64a3a8b976fc15166a7878", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/81/c4/b3845fc3fabd2bd3d997685e63f7", "src/ballistica/generated/python_embedded/binding.inc": "https://files.ballistica.net/cache/ba1/25/77/8093dfffddaa80cd513ddaa61867", "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 89615536..32534d60 100644 --- a/.idea/dictionaries/ericf.xml +++ b/.idea/dictionaries/ericf.xml @@ -73,6 +73,7 @@ allsettings allteams allwarnings + alogins aman amazonaws aname @@ -374,6 +375,7 @@ certifi cfconfig cfenv + cfgdict cfgdir cfgkey cfgkeys @@ -2513,6 +2515,7 @@ svne svvv swht + swidth swiftc swip swipsound @@ -2549,6 +2552,9 @@ targs tasklabel tbegin + tbfile + tbfiles + tbpath tbtcolor tbtn tbttxt @@ -2860,6 +2866,7 @@ webpages weeeird whatevs + whatisv wheee whos widgetdeathtime diff --git a/CHANGELOG.md b/CHANGELOG.md index 42606cb3..ab19ed4d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,16 @@ -### 1.7.14 (build 20934, api 7, 2022-11-16) +### 1.7.14 (build 20942, api 7, 2022-11-29) - Android Google Play logins now provide V2 accounts with access to all V2 features such as a globally-unique account tag, cloud-console, and workspaces. They should still retain their V1 data as well. - V2 accounts now have a 'Manage Account' button in the app account window which will sign you into a browser with your current account. - Removed Google App Invite functionality which has been deprecated for a while now. Google Play users can still get tickets by sharing the app via codes (same as other platforms). - Updated Android root-detection library to the latest version. Please holler if you are getting new false 'your device is rooted' errors when trying to play tournaments or anything like that. - Removed a few obsolete internal functions: `_ba.is_ouya_build()`, `_ba.android_media_scan_file()`. - Renaming some methods/data to disambiguate 'login' vs 'sign-in', both in the app and on ballistica.net. Those two terms are somewhat ambiguous and interchangeable in English and can either be a verb or a noun. I'd like to keep things clear in Ballistica by always using 'sign-in' for the verb form and 'login' for the noun. For example: 'You can now sign in to your account using your Google Play login'. -- WARNING: There are currently some rough edges with Google Play V2 accounts; for example Google Play achievements and leaderboards UIs are not currently showing up. I will be cleaning all of this up before the official 1.7.14 release. +- Fixed the 'your config is broken' dialog that shows on desktop builds if the game's config file is corrupt and can't be read. It should let you edit the config or replace it with a default. +- `ba.printobjects()` is now `ba.ls_objects()`. It technically logs and doesn't print so the former name was a bit misleading. +- Added `ba.ls_input_devices()` to dump debug info about the current set of input devices. Can be helpful to diagnose mysterious devices joining games unintentionally and things like that. +- Added 'raw' bool arg to `ba.pushcall()`. Passing True for it disables context save/restore and thread checks. +- Added `ba.internal.dump_tracebacks()` which can be used to dump the stack state of all Python threads after some delay. Useful for debugging deadlock; just call right before said deadlock occurs. Results will be logged on the next app launch if they cannot be immediately. +- Fixed a low level event-loop issue that in some cases was preventing the Android version from properly pausing/resuming the app or managing connections while in the background. If you look at the devices section on ballistica.net you should now see your device disappear when you background the app and reappear when you foreground it. Please holler if not. ### 1.7.13 (build 20919, api 7, 2022-11-03) - Android target-sdk has been updated to 33 (Android 13). Please holler if anything seems broken or is behaving differently than before on Android. diff --git a/assets/src/ba_data/python/._ba_sources_hash b/assets/src/ba_data/python/._ba_sources_hash index bb72bb71..3c92f5a5 100644 --- a/assets/src/ba_data/python/._ba_sources_hash +++ b/assets/src/ba_data/python/._ba_sources_hash @@ -1 +1 @@ -136821726394202151644063370854718971574 \ No newline at end of file +199621046220623727886241861967391185247 \ No newline at end of file diff --git a/assets/src/ba_data/python/_ba.py b/assets/src/ba_data/python/_ba.py index 671c8d6d..f4a79295 100644 --- a/assets/src/ba_data/python/_ba.py +++ b/assets/src/ba_data/python/_ba.py @@ -2429,12 +2429,42 @@ def lock_all_input() -> None: return None +def login_adapter_back_end_active_change(login_type: str, active: bool) -> None: + + """(internal)""" + return None + + def login_adapter_get_sign_in_token(login_type: str, attempt_id: int) -> None: """(internal)""" return None +def ls_input_devices() -> None: + + """Print debugging info about game objects. + + Category: **General Utility Functions** + + This call only functions in debug builds of the game. + It prints various info about the current object count, etc. + """ + return None + + +def ls_objects() -> None: + + """Log debugging info about C++ level objects. + + Category: **General Utility Functions** + + This call only functions in debug builds of the game. + It prints various info about the current object count, etc. + """ + return None + + def mac_music_app_get_library_source() -> None: """(internal)""" @@ -2653,32 +2683,17 @@ def printnodes() -> None: return None -def printobjects() -> None: - - """Print debugging info about game objects. - - Category: **General Utility Functions** - - This call only functions in debug builds of the game. - It prints various info about the current object count, etc. - """ - return None - - def pushcall( call: Callable, from_other_thread: bool = False, suppress_other_thread_warning: bool = False, other_thread_use_fg_context: bool = False, + raw: bool = False, ) -> None: - """Pushes a call onto the event loop to be run during the next cycle. - + """Push a call to the logic event-loop. Category: **General Utility Functions** - This can be handy for calls that are disallowed from within other - callbacks, etc. - This call expects to be used in the logic thread, and will automatically save and restore the ba.Context to behave seamlessly. @@ -2687,6 +2702,7 @@ def pushcall( the call will always run in the UI context on the logic thread or whichever context is in the foreground if other_thread_use_fg_context is True. + Passing raw=True will disable thread checks and context sets/restores. """ return None diff --git a/assets/src/ba_data/python/_bainternal.py b/assets/src/ba_data/python/_bainternal.py index d1bf8109..99fd8ee4 100644 --- a/assets/src/ba_data/python/_bainternal.py +++ b/assets/src/ba_data/python/_bainternal.py @@ -252,7 +252,6 @@ def submit_score( name: Any, score: int | None, callback: Callable, - friend_callback: Callable | None, order: str = 'increasing', tournament_id: str | None = None, score_type: str = 'points', diff --git a/assets/src/ba_data/python/ba/__init__.py b/assets/src/ba_data/python/ba/__init__.py index 290d8482..82738c9e 100644 --- a/assets/src/ba_data/python/ba/__init__.py +++ b/assets/src/ba_data/python/ba/__init__.py @@ -43,7 +43,8 @@ from _ba import ( newnode, playsound, printnodes, - printobjects, + ls_objects, + ls_input_devices, pushcall, quit, rowwidget, @@ -316,7 +317,8 @@ __all__ = [ 'print_error', 'print_exception', 'printnodes', - 'printobjects', + 'ls_objects', + 'ls_input_devices', 'pushcall', 'quit', 'rowwidget', diff --git a/assets/src/ba_data/python/ba/_accountv1.py b/assets/src/ba_data/python/ba/_accountv1.py index c2b81164..7f946097 100644 --- a/assets/src/ba_data/python/ba/_accountv1.py +++ b/assets/src/ba_data/python/ba/_accountv1.py @@ -48,6 +48,9 @@ class AccountV1Subsystem: _ba.pushcall(do_auto_sign_in) + def on_app_pause(self) -> None: + """Should be called when app is pausing.""" + def on_app_resume(self) -> None: """Should be called when the app is resumed.""" diff --git a/assets/src/ba_data/python/ba/_accountv2.py b/assets/src/ba_data/python/ba/_accountv2.py index 32870fe0..372f9dad 100644 --- a/assets/src/ba_data/python/ba/_accountv2.py +++ b/assets/src/ba_data/python/ba/_accountv2.py @@ -4,8 +4,11 @@ from __future__ import annotations +import hashlib +import logging from typing import TYPE_CHECKING +from efro.call import tpartial import _ba if TYPE_CHECKING: @@ -15,6 +18,9 @@ if TYPE_CHECKING: from ba._login import LoginAdapter +DEBUG_LOG = False + + class AccountV2Subsystem: """Subsystem for modern account handling in the app. @@ -37,7 +43,8 @@ class AccountV2Subsystem: self.login_adapters: dict[LoginType, LoginAdapter] = {} self._implicit_signed_in_adapter: LoginAdapter | None = None - self._auto_signed_in = False + self._implicit_state_changed = False + self._can_do_auto_sign_in = True if _ba.app.platform == 'android' and _ba.app.subplatform == 'google': from ba._login import LoginAdapterGPGS @@ -127,7 +134,7 @@ class AccountV2Subsystem: def on_implicit_sign_in( self, login_type: LoginType, login_id: str, display_name: str ) -> None: - """An implicit login happened.""" + """An implicit sign-in happened (called by native layer).""" from ba._login import LoginAdapter with _ba.Context('ui'): @@ -138,7 +145,7 @@ class AccountV2Subsystem: ) def on_implicit_sign_out(self, login_type: LoginType) -> None: - """An implicit logout happened.""" + """An implicit sign-out happened (called by native layer).""" with _ba.Context('ui'): self.login_adapters[login_type].set_implicit_login_state(None) @@ -153,6 +160,12 @@ class AccountV2Subsystem: self._initial_login_completed = True _ba.app.on_initial_login_completed() + @staticmethod + def _hashstr(val: str) -> str: + md5 = hashlib.md5() + md5.update(val.encode()) + return md5.hexdigest() + def on_implicit_login_state_changed( self, login_type: LoginType, @@ -160,18 +173,66 @@ class AccountV2Subsystem: ) -> None: """Called when implicit login state changes. - Logins that tend to sign themselves in/out in the background are - considered implicit. We may choose to honor or ignore their states, - allowing the user to opt for other login types even if the default - implicit one can't be explicitly logged out or otherwise controlled. + Login systems that tend to sign themselves in/out in the + background are considered implicit. We may choose to honor or + ignore their states, allowing the user to opt for other login + types even if the default implicit one can't be explicitly + logged out or otherwise controlled. """ assert _ba.in_logic_thread() + cfg = _ba.app.config + cfgkey = 'ImplicitLoginStates' + cfgdict = _ba.app.config.setdefault(cfgkey, {}) + # Store which (if any) adapter is currently implicitly signed in. + # Making the assumption there will only ever be one implicit + # adapter at a time; may need to update this if that changes. + prev_state = cfgdict.get(login_type.value) if state is None: self._implicit_signed_in_adapter = None + new_state = cfgdict[login_type.value] = None else: self._implicit_signed_in_adapter = self.login_adapters[login_type] + new_state = cfgdict[login_type.value] = self._hashstr( + state.login_id + ) + + # Special case: if the user is already signed in but not with + # this implicit login, we may want to let them know that the + # 'Welcome back FOO' they likely just saw is not actually + # accurate. + if bool(False): + if ( + self.primary is not None + and not self.login_adapters[login_type].is_back_end_active() + ): + _ba.timer( + 2.0, + tpartial( + _ba.screenmessage, + 'Warning: Ignoring your' + ' Google Play Games account.\n' + 'If you want to use it,' + ' sign out of your current account.', + (1, 0.5, 0), + ), + ) + + cfg.commit() + + # We want to respond any time the implicit state changes; + # generally this means the user has explicitly signed in/out or + # switched accounts within that back-end. + if prev_state != new_state: + if DEBUG_LOG: + logging.debug( + 'AccountV2: Implicit state changed (%s -> %s);' + ' will update app sign-in state accordingly.', + prev_state, + new_state, + ) + self._implicit_state_changed = True # We may want to auto-sign-in based on this new state. self._update_auto_sign_in() @@ -187,12 +248,58 @@ class AccountV2Subsystem: def _update_auto_sign_in(self) -> None: from ba._internal import get_v1_account_state - # We attempt auto-sign-in only once. - if self._auto_signed_in: + # If implicit state has changed, try to respond. + if self._implicit_state_changed: + if self._implicit_signed_in_adapter is None: + # If implicit back-end is signed out, follow suit + # immediately; no need to wait for network connectivity. + if DEBUG_LOG: + logging.debug( + 'AccountV2: Signing out as result' + ' of implicit state change...', + ) + _ba.app.accounts_v2.set_primary_credentials(None) + self._implicit_state_changed = False + + # Once we've made a move here we don't want to + # do any more automatic ones. + self._can_do_auto_sign_in = False + + else: + # Ok; we've got a new implicit state. If we've got + # connectivity, let's attempt to sign in with it. + # Consider this an 'explicit' sign in because the + # implicit-login state change presumably was triggered + # by some user action (signing in, signing out, or + # switching accounts via the back-end). + # NOTE: should test case where we don't have + # connectivity here. + if _ba.app.cloud.is_connected(): + if DEBUG_LOG: + logging.debug( + 'AccountV2: Signing in as result' + ' of implicit state change...', + ) + self._implicit_signed_in_adapter.sign_in( + self._on_explicit_sign_in_completed + ) + self._implicit_state_changed = False + + # Once we've made a move here we don't want to + # do any more automatic ones. + self._can_do_auto_sign_in = False + + if not self._can_do_auto_sign_in: return # If we're not currently signed in, we have connectivity, and - # we have an available implicit adapter, do an auto-sign-in. + # we have an available implicit login, auto-sign-in with it. + # The implicit-state-change logic above should keep things + # mostly in-sync, but due to connectivity or other issues that + # might not always be the case. We prefer to keep people signed + # in as a rule, even if there are corner cases where this might + # not be what they want (A user signing out and then restarting + # may be auto-signed back in). connected = _ba.app.cloud.is_connected() signed_in_v1 = get_v1_account_state() == 'signed_in' signed_in_v2 = _ba.app.accounts_v2.have_primary_credentials() @@ -202,14 +309,44 @@ class AccountV2Subsystem: and not signed_in_v2 and self._implicit_signed_in_adapter is not None ): - self._auto_signed_in = True # Only attempt this once - self._implicit_signed_in_adapter.sign_in(self._on_sign_in_completed) + if DEBUG_LOG: + logging.debug( + 'AccountV2: Signing in due to on-launch-auto-sign-in...', + ) + self._can_do_auto_sign_in = False # Only ATTEMPT once + self._implicit_signed_in_adapter.sign_in( + self._on_implicit_sign_in_completed + ) - def _on_sign_in_completed( + def _on_explicit_sign_in_completed( self, adapter: LoginAdapter, result: LoginAdapter.SignInResult | Exception, ) -> None: + """A sign-in has completed that the user asked for explicitly.""" + from ba._language import Lstr + + del adapter # Unused. + + # Make some noise on errors. + # (May want to make this more descriptive). + if isinstance(result, Exception): + with _ba.Context('ui'): + _ba.screenmessage( + Lstr(resource='errorText'), + color=(1, 1, 0), + ) + _ba.playsound(_ba.getsound('error')) + return + + _ba.app.accounts_v2.set_primary_credentials(result.credentials) + + def _on_implicit_sign_in_completed( + self, + adapter: LoginAdapter, + result: LoginAdapter.SignInResult | Exception, + ) -> None: + """A sign-in has completed that the user didn't ask for explicitly.""" from ba._internal import get_v1_account_state del adapter # Unused. @@ -219,7 +356,9 @@ class AccountV2Subsystem: return # If we're still connected and still not signed in, - # plug in the credentials we got. + # plug in the credentials we got. We want to be extra cautious + # in case the user has since explicitly signed in since we + # kicked off. connected = _ba.app.cloud.is_connected() signed_in_v1 = get_v1_account_state() == 'signed_in' signed_in_v2 = _ba.app.accounts_v2.have_primary_credentials() diff --git a/assets/src/ba_data/python/ba/_app.py b/assets/src/ba_data/python/ba/_app.py index 46ac8e6f..89a6184f 100644 --- a/assets/src/ba_data/python/ba/_app.py +++ b/assets/src/ba_data/python/ba/_app.py @@ -354,6 +354,7 @@ class App: from bastd import maps as stdmaps from bastd.actor import spazappearance from ba._generated.enums import TimeType + from ba._apputils import log_dumped_tracebacks assert _ba.in_logic_thread() @@ -407,9 +408,9 @@ class App: # overwrite a broken one or whatnot and wipe out data. if not self.config_file_healthy: if self.platform in ('mac', 'linux', 'windows'): - from bastd.ui import configerror + from bastd.ui.configerror import ConfigErrorWindow - configerror.ConfigErrorWindow() + _ba.pushcall(ConfigErrorWindow) return # For now on other systems we just overwrite the bum config. @@ -459,6 +460,9 @@ class App: 'on_app_launch found state %s; expected LAUNCHING.', self.state ) + # If any traceback dumps happened last run, log and clear them. + log_dumped_tracebacks() + self._launch_completed = True self._update_state() @@ -483,8 +487,21 @@ class App: assert _ba.in_logic_thread() if self._app_paused: - self.state = self.State.PAUSED + # Entering paused state: + if self.state is not self.State.PAUSED: + self.state = self.State.PAUSED + self.cloud.on_app_pause() + self.accounts_v1.on_app_pause() + self.plugins.on_app_pause() else: + # Leaving paused state: + if self.state is self.State.PAUSED: + self.fg_state += 1 + self.cloud.on_app_resume() + self.accounts_v1.on_app_resume() + self.music.on_app_resume() + self.plugins.on_app_resume() + if self._initial_login_completed and self._meta_scan_completed: self.state = self.State.RUNNING if not self._called_on_app_running: @@ -498,19 +515,16 @@ class App: def on_app_pause(self) -> None: """Called when the app goes to a suspended state.""" + assert not self._app_paused # Should avoid redundant calls. self._app_paused = True self._update_state() - self.plugins.on_app_pause() def on_app_resume(self) -> None: """Run when the app resumes from a suspended state.""" + assert self._app_paused # Should avoid redundant calls. self._app_paused = False self._update_state() - self.fg_state += 1 - self.accounts_v1.on_app_resume() - self.music.on_app_resume() - self.plugins.on_app_resume() def on_app_shutdown(self) -> None: """(internal)""" diff --git a/assets/src/ba_data/python/ba/_apputils.py b/assets/src/ba_data/python/ba/_apputils.py index 166b4d33..9633b078 100644 --- a/assets/src/ba_data/python/ba/_apputils.py +++ b/assets/src/ba_data/python/ba/_apputils.py @@ -5,12 +5,13 @@ from __future__ import annotations import gc import os +import logging from typing import TYPE_CHECKING import _ba if TYPE_CHECKING: - from typing import Any + from typing import Any, TextIO import ba @@ -260,3 +261,51 @@ def print_corrupt_file_error() -> None: _ba.timer( 2.0, Call(_ba.playsound, _ba.getsound('error')), timetype=TimeType.REAL ) + + +_tbfiles: list[TextIO] = [] + + +def dump_tracebacks(delay: float) -> None: + """Dump a traceback of all Python threads after a delay in seconds. + + Can be used for debugging deadlock situations. Will dump to a preset + file location in the app config dir. Will attempt to log and clear + the results after dumping. It will be done at next launch otherwise, + or can be done explicitly via log_dumped_tracebacks(). + + Do not use this call during regular operation of the app; it is only + intended for debugging as it can leak file descriptors/etc. + """ + # pylint: disable=consider-using-with + import faulthandler + from ba._generated.enums import TimeType + + tbpath = os.path.join(os.path.dirname(_ba.app.config_file_path), '_tbdump') + + # faulthandler needs the raw file descriptor to still be valid when + # it fires, so stuff this into a global var to make sure it doesn't get + # cleaned up. + tbfile = open(tbpath, 'w', encoding='utf-8') + _tbfiles.append(tbfile) + + faulthandler.dump_traceback_later(delay, file=tbfile) + + # Attempt to log shortly after dumping. + with _ba.Context('ui'): + _ba.timer(delay + 1.0, log_dumped_tracebacks, timetype=TimeType.REAL) + + +def log_dumped_tracebacks() -> None: + """If a traceback dump exists, log it and clear it. No-op otherwise.""" + + try: + tbpath = os.path.join( + os.path.dirname(_ba.app.config_file_path), '_tbdump' + ) + if os.path.exists(tbpath): + with open(tbpath, 'r', encoding='utf-8') as infile: + logging.info('Dumped tracebacks:\n%s', infile.read()) + os.unlink(tbpath) + except Exception: + logging.exception('Error logging dumped tracebacks.') diff --git a/assets/src/ba_data/python/ba/_bootstrap.py b/assets/src/ba_data/python/ba/_bootstrap.py index 02f8cbf1..c13e457a 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 = 20934 + expected_build = 20942 running_build: int = env['build_number'] if running_build != expected_build: print( @@ -120,7 +120,8 @@ def bootstrap() -> None: import __main__ # Clear out the standard quit/exit messages since they don't - # work for us. + # work in our embedded situation (should revisit this once we're + # usable from a standard interpreter). del __main__.__builtins__.quit del __main__.__builtins__.exit diff --git a/assets/src/ba_data/python/ba/_cloud.py b/assets/src/ba_data/python/ba/_cloud.py index 19202b55..785e68c7 100644 --- a/assets/src/ba_data/python/ba/_cloud.py +++ b/assets/src/ba_data/python/ba/_cloud.py @@ -33,6 +33,12 @@ class CloudSubsystem: """ return False # Needs to be overridden + def on_app_pause(self) -> None: + """Should be called when the app pauses.""" + + def on_app_resume(self) -> None: + """Should be called when the app resumes.""" + def on_connectivity_changed(self, connected: bool) -> None: """Called when cloud connectivity state changes.""" if DEBUG_LOG: diff --git a/assets/src/ba_data/python/ba/_coopgame.py b/assets/src/ba_data/python/ba/_coopgame.py index 0df8beb2..6fedc3ca 100644 --- a/assets/src/ba_data/python/ba/_coopgame.py +++ b/assets/src/ba_data/python/ba/_coopgame.py @@ -11,7 +11,7 @@ from ba._gameactivity import GameActivity from ba._general import WeakCall if TYPE_CHECKING: - from typing import Any, Sequence + from typing import Sequence from bastd.actor.playerspaz import PlayerSpaz import ba @@ -56,56 +56,6 @@ class CoopGameActivity(GameActivity[PlayerType, TeamType]): # Preload achievement images in case we get some. _ba.timer(2.0, WeakCall(self._preload_achievements)) - def _show_standard_scores_to_beat_ui( - self, scores: list[dict[str, Any]] - ) -> None: - from efro.util import asserttype - from ba._gameutils import timestring, animate - from ba._nodeactor import NodeActor - from ba._generated.enums import TimeFormat - - display_type = self.get_score_type() - if scores is not None: - - # Sort by originating date so that the most recent is first. - scores.sort(reverse=True, key=lambda s: asserttype(s['time'], int)) - - # Now make a display for the most recent challenge. - for score in scores: - if score['type'] == 'score_challenge': - tval = ( - score['player'] - + ': ' - + timestring( - int(score['value']) * 10, - timeformat=TimeFormat.MILLISECONDS, - ).evaluate() - if display_type == 'time' - else str(score['value']) - ) - hattach = 'center' if display_type == 'time' else 'left' - halign = 'center' if display_type == 'time' else 'left' - pos = (20, -70) if display_type == 'time' else (20, -130) - txt = NodeActor( - _ba.newnode( - 'text', - attrs={ - 'v_attach': 'top', - 'h_attach': hattach, - 'h_align': halign, - 'color': (0.7, 0.4, 1, 1), - 'shadow': 0.5, - 'flatness': 1.0, - 'position': pos, - 'scale': 0.6, - 'text': tval, - }, - ) - ).autoretain() - assert txt.node is not None - animate(txt.node, 'scale', {1.0: 0.0, 1.1: 0.7, 1.2: 0.6}) - break - # FIXME: this is now redundant with activityutils.getscoreconfig(); # need to kill this. def get_score_type(self) -> str: diff --git a/assets/src/ba_data/python/ba/_hooks.py b/assets/src/ba_data/python/ba/_hooks.py index 21d453b5..9d020aa6 100644 --- a/assets/src/ba_data/python/ba/_hooks.py +++ b/assets/src/ba_data/python/ba/_hooks.py @@ -461,12 +461,12 @@ def login_adapter_get_sign_in_token_response( ) -> None: """Login adapter do-sign-in completed.""" from bacommon.login import LoginType - from ba._login import LoginAdapterGPGS + from ba._login import LoginAdapterNative login_type = LoginType(login_type_str) attempt_id = int(attempt_id_str) result = None if result_str == '' else result_str with _ba.Context('ui'): adapter = _ba.app.accounts_v2.login_adapters[login_type] - assert isinstance(adapter, LoginAdapterGPGS) + assert isinstance(adapter, LoginAdapterNative) adapter.on_sign_in_complete(attempt_id=attempt_id, result=result) diff --git a/assets/src/ba_data/python/ba/_internal.py b/assets/src/ba_data/python/ba/_internal.py index 4d6ab704..4fb62ba2 100644 --- a/assets/src/ba_data/python/ba/_internal.py +++ b/assets/src/ba_data/python/ba/_internal.py @@ -104,7 +104,6 @@ def submit_score( name: Any, score: int | None, callback: Callable, - friend_callback: Callable | None, order: str = 'increasing', tournament_id: str | None = None, score_type: str = 'points', @@ -125,7 +124,6 @@ def submit_score( name=name, score=score, callback=callback, - friend_callback=friend_callback, order=order, tournament_id=tournament_id, score_type=score_type, diff --git a/assets/src/ba_data/python/ba/_login.py b/assets/src/ba_data/python/ba/_login.py index 2ec91382..6e95216e 100644 --- a/assets/src/ba_data/python/ba/_login.py +++ b/assets/src/ba_data/python/ba/_login.py @@ -102,6 +102,9 @@ class LoginAdapter: # (possibly) push it to the app for handling. self._update_implicit_login_state() + # This might affect whether we consider that back-end as 'active'. + self._update_back_end_active() + def set_active_logins(self, logins: dict[LoginType, str]) -> None: """Keep the adapter informed of actively used logins. @@ -116,7 +119,7 @@ class LoginAdapter: logging.debug( 'LoginAdapter: %s adapter got active logins %s.', self.login_type.name, - logins, + {k: v[:4] + '...' + v[-4:] for k, v in logins.items()}, ) self._active_login_id = logins.get(self.login_type) @@ -229,6 +232,10 @@ class LoginAdapter: # Kick off the process by fetching a sign-in token. self.get_sign_in_token(completion_cb=_got_sign_in_token_result) + def is_back_end_active(self) -> bool: + """Is this adapter's back-end currently active?""" + return self._back_end_active + def get_sign_in_token( self, completion_cb: Callable[[str | None], None] ) -> None: @@ -289,8 +296,8 @@ class LoginAdapter: self._back_end_active = is_active -class LoginAdapterGPGS(LoginAdapter): - """Google Play Game Services adapter.""" +class LoginAdapterNative(LoginAdapter): + """A login adapter that does its work in the native layer.""" def __init__(self) -> None: super().__init__(LoginType.GPGS) @@ -308,6 +315,9 @@ class LoginAdapterGPGS(LoginAdapter): self._sign_in_attempt_num += 1 _ba.login_adapter_get_sign_in_token(self.login_type.value, attempt_id) + def on_back_end_active_change(self, active: bool) -> None: + _ba.login_adapter_back_end_active_change(self.login_type.value, active) + def on_sign_in_complete(self, attempt_id: int, result: str | None) -> None: """Called by the native layer on a completed attempt.""" assert _ba.in_logic_thread() @@ -316,3 +326,7 @@ class LoginAdapterGPGS(LoginAdapter): return callback = self._sign_in_attempts.pop(attempt_id) callback(result) + + +class LoginAdapterGPGS(LoginAdapterNative): + """Google Play Game Services adapter.""" diff --git a/assets/src/ba_data/python/ba/internal.py b/assets/src/ba_data/python/ba/internal.py index e96cb0aa..c688faf1 100644 --- a/assets/src/ba_data/python/ba/internal.py +++ b/assets/src/ba_data/python/ba/internal.py @@ -100,6 +100,8 @@ from ba._apputils import ( is_browser_likely_available, get_remote_app_name, should_submit_debug_info, + dump_tracebacks, + log_dumped_tracebacks, ) from ba._benchmark import ( run_gpu_benchmark, @@ -330,4 +332,6 @@ __all__ = [ 'sign_out_v1', 'sign_in_v1', 'mark_config_dirty', + 'dump_tracebacks', + 'log_dumped_tracebacks', ] diff --git a/assets/src/ba_data/python/bastd/activity/coopscore.py b/assets/src/ba_data/python/bastd/activity/coopscore.py index 5c32fdeb..63864605 100644 --- a/assets/src/ba_data/python/bastd/activity/coopscore.py +++ b/assets/src/ba_data/python/bastd/activity/coopscore.py @@ -116,7 +116,6 @@ class CoopScoreScreen(ba.Activity[ba.Player, ba.Team]): self._newly_complete: bool | None = None self._is_more_levels: bool | None = None self._next_level_name: str | None = None - self._show_friend_scores: bool | None = None self._show_info: dict[str, Any] | None = None self._name_str: str | None = None self._friends_loading_status: ba.Actor | None = None @@ -177,12 +176,6 @@ class CoopScoreScreen(ba.Activity[ba.Player, ba.Team]): .replace(' ', '_') ) - # If game-center/etc scores are available we show our friends' - # scores. Otherwise we show our local high scores. - self._show_friend_scores = ba.internal.game_service_has_leaderboard( - self._game_name_str, self._game_config_str - ) - try: self._old_best_rank = self._campaign.getlevel( self._level_name @@ -366,21 +359,6 @@ class CoopScoreScreen(ba.Activity[ba.Player, ba.Team]): ba.internal.set_ui_input_device(None) # Menu is up for grabs. - if self._show_friend_scores: - ba.buttonwidget( - parent=rootc, - color=(0.45, 0.4, 0.5), - position=(h_offs - 520, v_offs + 480), - size=(300, 60), - label=ba.Lstr(resource='topFriendsText'), - on_activate_call=ba.WeakCall(self._ui_gc), - transition_delay=delay + 0.5, - icon=self._game_service_leaderboards_texture, - icon_color=self._game_service_icon_color, - autoselect=True, - selectable=can_select_extra_buttons, - ) - if self._have_achievements and self._account_has_achievements: ba.buttonwidget( parent=rootc, @@ -773,18 +751,6 @@ class CoopScoreScreen(ba.Activity[ba.Player, ba.Team]): [p.name for p in self._playerinfos] ) - if self._show_friend_scores: - self._friends_loading_status = Text( - ba.Lstr( - value='${A}...', - subs=[('${A}', ba.Lstr(resource='loadingText'))], - ), - position=(-405, 150 + 30), - color=(1, 1, 1, 0.4), - transition=Text.Transition.FADE_IN, - scale=0.7, - transition_delay=2.0, - ) self._score_loading_status = Text( ba.Lstr( value='${A}...', @@ -850,8 +816,6 @@ class CoopScoreScreen(ba.Activity[ba.Player, ba.Team]): # We expect this only in kiosk mode; complain otherwise. if not (ba.app.demo_mode or ba.app.arcade_mode): print('got not-signed-in at score-submit; unexpected') - if self._show_friend_scores: - ba.pushcall(ba.WeakCall(self._got_friend_score_results, None)) ba.pushcall(ba.WeakCall(self._got_score_results, None)) else: assert self._game_name_str is not None @@ -862,9 +826,6 @@ class CoopScoreScreen(ba.Activity[ba.Player, ba.Team]): name_str, self._score, ba.WeakCall(self._got_score_results), - ba.WeakCall(self._got_friend_score_results) - if self._show_friend_scores - else None, order=self._score_order, tournament_id=self.session.tournament_id, score_type=self._score_type, @@ -899,138 +860,118 @@ class CoopScoreScreen(ba.Activity[ba.Player, ba.Team]): assert txt.node txt.node.client_only = True - # If we have no friend scores, display local best scores. - if self._show_friend_scores: + ts_height = 300 + ts_h_offs = -480 + v_offs = 40 + Text( + ba.Lstr(resource='yourBestScoresText') + if self._score_type == 'points' + else ba.Lstr(resource='yourBestTimesText'), + maxwidth=210, + position=(ts_h_offs - 10, ts_height / 2 + 25 + v_offs + 20), + transition=Text.Transition.IN_RIGHT, + v_align=Text.VAlign.CENTER, + scale=1.2, + transition_delay=1.8, + ).autoretain() - # Host has a button, so we need client-only text. - ts_height = 300 - ts_h_offs = -480 - v_offs = 40 - txt = Text( - ba.Lstr(resource='topFriendsText'), - maxwidth=210, - position=(ts_h_offs - 10, ts_height / 2 + 25 + v_offs + 20), - transition=Text.Transition.IN_RIGHT, - v_align=Text.VAlign.CENTER, - scale=1.2, - transition_delay=1.8, - ).autoretain() - assert txt.node - txt.node.client_only = True - else: + display_scores = list(our_high_scores) + display_count = 5 - ts_height = 300 - ts_h_offs = -480 - v_offs = 40 - Text( - ba.Lstr(resource='yourBestScoresText') - if self._score_type == 'points' - else ba.Lstr(resource='yourBestTimesText'), - maxwidth=210, - position=(ts_h_offs - 10, ts_height / 2 + 25 + v_offs + 20), - transition=Text.Transition.IN_RIGHT, - v_align=Text.VAlign.CENTER, - scale=1.2, - transition_delay=1.8, - ).autoretain() + while len(display_scores) < display_count: + display_scores.append((0, None)) - display_scores = list(our_high_scores) - display_count = 5 - - while len(display_scores) < display_count: - display_scores.append((0, None)) - - showed_ours = False - h_offs_extra = 85 if self._score_type == 'points' else 130 - v_offs_extra = 20 - v_offs_names = 0 - scale = 1.0 - p_count = len(self._playerinfos) - h_offs_extra -= 75 - if p_count > 1: - h_offs_extra -= 20 - if p_count == 2: - scale = 0.9 - elif p_count == 3: - scale = 0.65 - elif p_count == 4: - scale = 0.5 - times: list[tuple[float, float]] = [] - for i in range(display_count): - times.insert( - random.randrange(0, len(times) + 1), - (1.9 + i * 0.05, 2.3 + i * 0.05), - ) - for i in range(display_count): - try: - if display_scores[i][1] is None: - name_str = '-' - else: - # noinspection PyUnresolvedReferences - name_str = ', '.join( - [p['name'] for p in display_scores[i][1]['players']] - ) - except Exception: - ba.print_exception( - f'Error calcing name_str for {display_scores}' - ) + showed_ours = False + h_offs_extra = 85 if self._score_type == 'points' else 130 + v_offs_extra = 20 + v_offs_names = 0 + scale = 1.0 + p_count = len(self._playerinfos) + h_offs_extra -= 75 + if p_count > 1: + h_offs_extra -= 20 + if p_count == 2: + scale = 0.9 + elif p_count == 3: + scale = 0.65 + elif p_count == 4: + scale = 0.5 + times: list[tuple[float, float]] = [] + for i in range(display_count): + times.insert( + random.randrange(0, len(times) + 1), + (1.9 + i * 0.05, 2.3 + i * 0.05), + ) + for i in range(display_count): + try: + if display_scores[i][1] is None: name_str = '-' - if display_scores[i] == our_score and not showed_ours: - flash = True - color0 = (0.6, 0.4, 0.1, 1.0) - color1 = (0.6, 0.6, 0.6, 1.0) - tdelay1 = 3.7 - tdelay2 = 3.7 - showed_ours = True else: - flash = False - color0 = (0.6, 0.4, 0.1, 1.0) - color1 = (0.6, 0.6, 0.6, 1.0) - tdelay1 = times[i][0] - tdelay2 = times[i][1] - Text( - str(display_scores[i][0]) - if self._score_type == 'points' - else ba.timestring( - display_scores[i][0] * 10, - timeformat=ba.TimeFormat.MILLISECONDS, - suppress_format_warning=True, - ), - position=( - ts_h_offs + 20 + h_offs_extra, - v_offs_extra - + ts_height / 2 - + -ts_height * (i + 1) / 10 - + v_offs - + 11.0, - ), - h_align=Text.HAlign.RIGHT, - v_align=Text.VAlign.CENTER, - color=color0, - flash=flash, - transition=Text.Transition.IN_RIGHT, - transition_delay=tdelay1, - ).autoretain() + # noinspection PyUnresolvedReferences + name_str = ', '.join( + [p['name'] for p in display_scores[i][1]['players']] + ) + except Exception: + ba.print_exception( + f'Error calcing name_str for {display_scores}' + ) + name_str = '-' + if display_scores[i] == our_score and not showed_ours: + flash = True + color0 = (0.6, 0.4, 0.1, 1.0) + color1 = (0.6, 0.6, 0.6, 1.0) + tdelay1 = 3.7 + tdelay2 = 3.7 + showed_ours = True + else: + flash = False + color0 = (0.6, 0.4, 0.1, 1.0) + color1 = (0.6, 0.6, 0.6, 1.0) + tdelay1 = times[i][0] + tdelay2 = times[i][1] + Text( + str(display_scores[i][0]) + if self._score_type == 'points' + else ba.timestring( + display_scores[i][0] * 10, + timeformat=ba.TimeFormat.MILLISECONDS, + suppress_format_warning=True, + ), + position=( + ts_h_offs + 20 + h_offs_extra, + v_offs_extra + + ts_height / 2 + + -ts_height * (i + 1) / 10 + + v_offs + + 11.0, + ), + h_align=Text.HAlign.RIGHT, + v_align=Text.VAlign.CENTER, + color=color0, + flash=flash, + transition=Text.Transition.IN_RIGHT, + transition_delay=tdelay1, + ).autoretain() - Text( - ba.Lstr(value=name_str), - position=( - ts_h_offs + 35 + h_offs_extra, - v_offs_extra - + ts_height / 2 - + -ts_height * (i + 1) / 10 - + v_offs_names - + v_offs - + 11.0, - ), - maxwidth=80.0 + 100.0 * len(self._playerinfos), - v_align=Text.VAlign.CENTER, - color=color1, - flash=flash, - scale=scale, - transition=Text.Transition.IN_RIGHT, - transition_delay=tdelay2, - ).autoretain() + Text( + ba.Lstr(value=name_str), + position=( + ts_h_offs + 35 + h_offs_extra, + v_offs_extra + + ts_height / 2 + + -ts_height * (i + 1) / 10 + + v_offs_names + + v_offs + + 11.0, + ), + maxwidth=80.0 + 100.0 * len(self._playerinfos), + v_align=Text.VAlign.CENTER, + color=color1, + flash=flash, + scale=scale, + transition=Text.Transition.IN_RIGHT, + transition_delay=tdelay2, + ).autoretain() # Show achievements for this level. ts_height = -150 diff --git a/assets/src/ba_data/python/bastd/game/football.py b/assets/src/ba_data/python/bastd/game/football.py index a88583e4..a8d87771 100644 --- a/assets/src/ba_data/python/bastd/game/football.py +++ b/assets/src/ba_data/python/bastd/game/football.py @@ -616,9 +616,6 @@ class FootballCoopGame(ba.CoopGameActivity[Player, Team]): for bottype in self._bot_types_initial: self._spawn_bot(bottype) - def _on_got_scores_to_beat(self, scores: list[dict[str, Any]]) -> None: - self._show_standard_scores_to_beat_ui(scores) - def _on_bot_spawn(self, spaz: SpazBot) -> None: # We want to move to the left by default. spaz.target_point_default = ba.Vec3(0, 0, 0) diff --git a/assets/src/ba_data/python/bastd/game/onslaught.py b/assets/src/ba_data/python/bastd/game/onslaught.py index 90aa87be..bf275137 100644 --- a/assets/src/ba_data/python/bastd/game/onslaught.py +++ b/assets/src/ba_data/python/bastd/game/onslaught.py @@ -682,9 +682,6 @@ class OnslaughtGame(ba.CoopGameActivity[Player, Team]): self._bots = SpazBotSet() ba.timer(4.0, self._start_updating_waves) - def _on_got_scores_to_beat(self, scores: list[dict[str, Any]]) -> None: - self._show_standard_scores_to_beat_ui(scores) - def _get_dist_grp_totals(self, grps: list[Any]) -> tuple[int, int]: totalpts = 0 totaldudes = 0 diff --git a/assets/src/ba_data/python/bastd/game/runaround.py b/assets/src/ba_data/python/bastd/game/runaround.py index d8f5e4b4..379ae8e3 100644 --- a/assets/src/ba_data/python/bastd/game/runaround.py +++ b/assets/src/ba_data/python/bastd/game/runaround.py @@ -684,9 +684,6 @@ class RunaroundGame(ba.CoopGameActivity[Player, Team]): }, ) - def _on_got_scores_to_beat(self, scores: list[dict[str, Any]]) -> None: - self._show_standard_scores_to_beat_ui(scores) - def _update_waves(self) -> None: # pylint: disable=too-many-branches diff --git a/assets/src/ba_data/python/bastd/game/thelaststand.py b/assets/src/ba_data/python/bastd/game/thelaststand.py index 2040e5c2..62e98c91 100644 --- a/assets/src/ba_data/python/bastd/game/thelaststand.py +++ b/assets/src/ba_data/python/bastd/game/thelaststand.py @@ -326,9 +326,6 @@ class TheLastStandGame(ba.CoopGameActivity[Player, Team]): else: super().handlemessage(msg) - def _on_got_scores_to_beat(self, scores: list[dict[str, Any]]) -> None: - self._show_standard_scores_to_beat_ui(scores) - def end_game(self) -> None: # Tell our bots to celebrate just to rub it in. self._bots.final_celebrate() diff --git a/assets/src/ba_data/python/bastd/ui/account/settings.py b/assets/src/ba_data/python/bastd/ui/account/settings.py index 0f7f59ab..cd65942a 100644 --- a/assets/src/ba_data/python/bastd/ui/account/settings.py +++ b/assets/src/ba_data/python/bastd/ui/account/settings.py @@ -37,6 +37,8 @@ class AccountSettingsWindow(ba.Window): self._close_once_signed_in = close_once_signed_in ba.set_analytics_screen('Account Window') + self._explicitly_signed_out_of_gpgs = False + # If they provided an origin-widget, scale up from that. scale_origin: tuple[float, float] | None if origin_widget is not None: @@ -104,7 +106,7 @@ class AccountSettingsWindow(ba.Window): # Legacy v1 device accounts are currently always available # (though we need to start phasing them out at some point). - self._show_sign_in_buttons.append('Local') + self._show_sign_in_buttons.append('Device') top_extra = 15 if uiscale is ba.UIScale.SMALL else 0 super().__init__( @@ -229,17 +231,22 @@ class AccountSettingsWindow(ba.Window): # pylint: disable=cyclic-import from bastd.ui import confirm + primary_v2_account = ba.app.accounts_v2.primary + v1_state = ba.internal.get_v1_account_state() - account_type = ( + v1_account_type = ( ba.internal.get_v1_account_type() if v1_state == 'signed_in' else 'unknown' ) - is_google = account_type == 'Google Play' - - show_local_signed_in_as = False - local_signed_in_as_space = 50.0 + # We expose GPGS-specific functionality only if it is 'active' + # (meaning the current GPGS player matches one of our account's + # logins). + gpgs_adapter = ba.app.accounts_v2.login_adapters.get(LoginType.GPGS) + is_gpgs = ( + False if gpgs_adapter is None else gpgs_adapter.is_back_end_active() + ) show_signed_in_as = self._signed_in signed_in_as_space = 95.0 @@ -257,23 +264,25 @@ class AccountSettingsWindow(ba.Window): and self._signing_in_adapter is None and 'Google Play' in self._show_sign_in_buttons ) - show_device_sign_in_button = ( - v1_state == 'signed_out' - and self._signing_in_adapter is None - and 'Local' in self._show_sign_in_buttons - ) show_v2_proxy_sign_in_button = ( v1_state == 'signed_out' and self._signing_in_adapter is None and 'V2Proxy' in self._show_sign_in_buttons ) + show_device_sign_in_button = ( + v1_state == 'signed_out' + and self._signing_in_adapter is None + and 'Device' in self._show_sign_in_buttons + ) sign_in_button_space = 70.0 - show_game_service_button = self._signed_in and account_type in [ + show_game_service_button = self._signed_in and v1_account_type in [ 'Game Center' ] game_service_button_space = 60.0 + show_what_is_v2 = self._signed_in and v1_account_type == 'V2' + show_linked_accounts_text = ( self._signed_in and ba.internal.get_v1_account_misc_read_val( @@ -282,7 +291,7 @@ class AccountSettingsWindow(ba.Window): ) linked_accounts_text_space = 60.0 - show_achievements_button = self._signed_in and account_type in ( + show_achievements_button = self._signed_in and v1_account_type in ( 'Google Play', 'Local', 'V2', @@ -294,7 +303,7 @@ class AccountSettingsWindow(ba.Window): ) achievements_text_space = 27.0 - show_leaderboards_button = self._signed_in and is_google + show_leaderboards_button = self._signed_in and is_gpgs leaderboards_button_space = 60.0 show_campaign_progress = self._signed_in @@ -306,7 +315,9 @@ class AccountSettingsWindow(ba.Window): show_reset_progress_button = False reset_progress_button_space = 70.0 - show_manage_v2_account_button = self._signed_in and account_type == 'V2' + show_manage_v2_account_button = ( + self._signed_in and v1_account_type == 'V2' + ) manage_v2_account_button_space = 100.0 show_player_profiles_button = self._signed_in @@ -325,7 +336,7 @@ class AccountSettingsWindow(ba.Window): show_unlink_accounts_button = show_link_accounts_button unlink_accounts_button_space = 90.0 - show_sign_out_button = self._signed_in and account_type in [ + show_sign_out_button = self._signed_in and v1_account_type in [ 'Local', 'Google Play', 'V2', @@ -337,15 +348,13 @@ class AccountSettingsWindow(ba.Window): # to be verified. show_cancel_sign_in_button = self._signing_in_adapter is not None or ( ba.app.accounts_v2.have_primary_credentials() - and ba.app.accounts_v2.primary is None + and primary_v2_account is None ) cancel_sign_in_button_space = 70.0 if self._subcontainer is not None: self._subcontainer.delete() self._sub_height = 60.0 - if show_local_signed_in_as: - self._sub_height += local_signed_in_as_space if show_signed_in_as: self._sub_height += signed_in_as_space if show_signing_in_text: @@ -398,27 +407,8 @@ class AccountSettingsWindow(ba.Window): first_selectable = None v = self._sub_height - 10.0 - if show_local_signed_in_as: - v -= local_signed_in_as_space * 0.6 - ba.textwidget( - parent=self._subcontainer, - position=(self._sub_width * 0.5, v), - size=(0, 0), - text=ba.Lstr( - resource='accountSettingsWindow.deviceSpecificAccountText', - subs=[ - ('${NAME}', ba.internal.get_v1_account_display_string()) - ], - ), - scale=0.7, - color=(0.5, 0.5, 0.6), - maxwidth=self._sub_width * 0.9, - flatness=1.0, - h_align='center', - v_align='center', - ) - v -= local_signed_in_as_space * 0.4 - + self._account_name_what_is_text: ba.Widget | None + self._account_name_what_is_y = 0.0 self._account_name_text: ba.Widget | None if show_signed_in_as: v -= signed_in_as_space * 0.2 @@ -437,7 +427,7 @@ class AccountSettingsWindow(ba.Window): h_align='center', v_align='center', ) - v -= signed_in_as_space * 0.4 + v -= signed_in_as_space * 0.5 self._account_name_text = ba.textwidget( parent=self._subcontainer, position=(self._sub_width * 0.5, v), @@ -449,10 +439,39 @@ class AccountSettingsWindow(ba.Window): h_align='center', v_align='center', ) + + if show_what_is_v2: + self._account_name_what_is_y = v - 23.0 + self._account_name_what_is_text = ba.textwidget( + parent=self._subcontainer, + position=(0.0, self._account_name_what_is_y), + size=(200.0, 60), + text=ba.Lstr( + value='${WHAT} -->', + subs=[('${WHAT}', ba.Lstr(resource='whatIsThisText'))], + ), + scale=0.6, + color=(0.3, 0.7, 0.05), + maxwidth=200.0, + h_align='right', + v_align='center', + autoselect=True, + selectable=True, + on_activate_call=ba.WeakCall(self._on_what_is_v2_press), + click_activate=True, + ) + if first_selectable is None: + first_selectable = self._account_name_what_is_text + else: + self._account_name_what_is_text = None + self._refresh_account_name_text() + v -= signed_in_as_space * 0.4 + else: self._account_name_text = None + self._account_name_what_is_text = None if self._back_button is None: bbtn = ba.internal.get_special_widget('back_button') @@ -709,12 +728,12 @@ class AccountSettingsWindow(ba.Window): if show_game_service_button: button_width = 300 v -= game_service_button_space * 0.85 - account_type = ba.internal.get_v1_account_type() - if account_type == 'Game Center': - account_type_name = ba.Lstr(resource='gameCenterText') + v1_account_type = ba.internal.get_v1_account_type() + if v1_account_type == 'Game Center': + v1_account_type_name = ba.Lstr(resource='gameCenterText') else: raise ValueError( - "unknown account type: '" + str(account_type) + "'" + "unknown account type: '" + str(v1_account_type) + "'" ) self._game_service_button = btn = ba.buttonwidget( parent=self._subcontainer, @@ -724,7 +743,7 @@ class AccountSettingsWindow(ba.Window): autoselect=True, on_activate_call=ba.internal.show_online_score_ui, size=(button_width, 50), - label=account_type_name, + label=v1_account_type_name, ) if first_selectable is None: first_selectable = btn @@ -767,11 +786,15 @@ class AccountSettingsWindow(ba.Window): autoselect=True, icon=ba.gettexture( 'googlePlayAchievementsIcon' - if is_google + if is_gpgs else 'achievementsIcon' ), - icon_color=(0.8, 0.95, 0.7) if is_google else (0.85, 0.8, 0.9), - on_activate_call=self._on_achievements_press, + icon_color=(0.8, 0.95, 0.7) if is_gpgs else (0.85, 0.8, 0.9), + on_activate_call=( + self._on_custom_achievements_press + if is_gpgs + else self._on_achievements_press + ), size=(button_width, 50), label='', ) @@ -1044,33 +1067,25 @@ class AccountSettingsWindow(ba.Window): ) self._needs_refresh = False + def _on_custom_achievements_press(self) -> None: + ba.timer( + 0.15, + ba.Call(ba.internal.show_online_score_ui, 'achievements'), + timetype=ba.TimeType.REAL, + ) + def _on_achievements_press(self) -> None: # pylint: disable=cyclic-import from bastd.ui import achievements - account_state = ba.internal.get_v1_account_state() - account_type = ( - ba.internal.get_v1_account_type() - if account_state == 'signed_in' - else 'unknown' + assert self._achievements_button is not None + achievements.AchievementsWindow( + position=self._achievements_button.get_screen_space_center() ) - # for google play we use the built-in UI; otherwise pop up our own - if account_type == 'Google Play': - ba.timer( - 0.15, - ba.Call(ba.internal.show_online_score_ui, 'achievements'), - timetype=ba.TimeType.REAL, - ) - elif account_type != 'unknown': - assert self._achievements_button is not None - achievements.AchievementsWindow( - position=self._achievements_button.get_screen_space_center() - ) - else: - print( - 'ERROR: unknown account type in on_achievements_press:', - account_type, - ) + + def _on_what_is_v2_press(self) -> None: + bamasteraddr = ba.internal.get_master_server_address(version=2) + ba.open_url(f'{bamasteraddr}/whatisv2') def _on_manage_account_press(self) -> None: ba.screenmessage(ba.Lstr(resource='oneMomentText')) @@ -1195,6 +1210,7 @@ class AccountSettingsWindow(ba.Window): ) def _refresh_account_name_text(self) -> None: + if self._account_name_text is None: return try: @@ -1202,7 +1218,20 @@ class AccountSettingsWindow(ba.Window): except Exception: ba.print_exception() name_str = '??' + ba.textwidget(edit=self._account_name_text, text=name_str) + if self._account_name_what_is_text is not None: + swidth = ba.internal.get_string_width( + name_str, suppress_warning=True + ) + # Eww; number-fudging. Need to recalibrate this if + # account name scaling changes. + x = self._sub_width * 0.5 - swidth * 0.75 - 170 + + ba.textwidget( + edit=self._account_name_what_is_text, + position=(x, self._account_name_what_is_y), + ) def _refresh_achievements(self) -> None: if ( @@ -1263,6 +1292,11 @@ class AccountSettingsWindow(ba.Window): def _sign_out_press(self) -> None: if ba.app.accounts_v2.have_primary_credentials(): + if ( + ba.app.accounts_v2.primary is not None + and LoginType.GPGS in ba.app.accounts_v2.primary.logins + ): + self._explicitly_signed_out_of_gpgs = True ba.app.accounts_v2.set_primary_credentials(None) else: ba.internal.sign_out_v1() @@ -1334,6 +1368,27 @@ class AccountSettingsWindow(ba.Window): # when finished. ba.app.accounts_v2.set_primary_credentials(result.credentials) + # Special case - if the user has explicitly logged out and + # logged in again with GPGS via this button, warn them that + # they need to use the app if they want to switch to a + # different GPGS account. + if ( + self._explicitly_signed_out_of_gpgs + and adapter.login_type is LoginType.GPGS + ): + # Delay this slightly so it hopefully pops up after + # credentials go through and the account name shows up. + ba.timer( + 1.5, + ba.Call( + ba.screenmessage, + ba.Lstr( + resource=self._r + + '.googlePlayGamesAccountSwitchText' + ), + ), + ) + # Speed any UI updates along. self._needs_refresh = True ba.timer(0.1, ba.WeakCall(self._update), timetype=ba.TimeType.REAL) diff --git a/assets/src/ba_data/python/bastd/ui/configerror.py b/assets/src/ba_data/python/bastd/ui/configerror.py index 129e5eaa..3165bfc3 100644 --- a/assets/src/ba_data/python/bastd/ui/configerror.py +++ b/assets/src/ba_data/python/bastd/ui/configerror.py @@ -20,12 +20,12 @@ class ConfigErrorWindow(ba.Window): self._config_file_path = ba.app.config_file_path width = 800 super().__init__( - ba.containerwidget(size=(width, 300), transition='in_right') + ba.containerwidget(size=(width, 400), transition='in_right') ) padding = 20 ba.textwidget( parent=self._root_widget, - position=(padding, 220), + position=(padding, 220 + 60), size=(width - 2 * padding, 100 - 2 * padding), h_align='center', v_align='top', @@ -41,7 +41,7 @@ class ConfigErrorWindow(ba.Window): ) ba.textwidget( parent=self._root_widget, - position=(padding, 198), + position=(padding, 198 + 60), size=(width - 2 * padding, 100 - 2 * padding), h_align='center', v_align='top', diff --git a/ballisticacore-cmake/.idea/dictionaries/ericf.xml b/ballisticacore-cmake/.idea/dictionaries/ericf.xml index 60593a9f..de0fbb15 100644 --- a/ballisticacore-cmake/.idea/dictionaries/ericf.xml +++ b/ballisticacore-cmake/.idea/dictionaries/ericf.xml @@ -48,6 +48,7 @@ allobjs allocs allwarnings + alogins alot alphaimg alphapixels @@ -217,6 +218,7 @@ cend centiseconds certifi + cfgdict cfgdir cfgpath changeme @@ -1334,6 +1336,7 @@ subtypestr successmsg sval + swidth swiftc symbolification syscalls @@ -1345,6 +1348,9 @@ targs tasklabel tbegin + tbfile + tbfiles + tbpath tcls tdels tdiff @@ -1508,6 +1514,7 @@ weeeird welp whaaaaaaa + whatisv wheee wheeee wiimote diff --git a/src/ballistica/app/app_flavor.cc b/src/ballistica/app/app_flavor.cc index d238d854..d6a2b1ed 100644 --- a/src/ballistica/app/app_flavor.cc +++ b/src/ballistica/app/app_flavor.cc @@ -156,7 +156,6 @@ void AppFlavor::UpdatePauseResume() { void AppFlavor::OnPause() { assert(InMainThread()); - // Avoid reading gyro values for a short time to avoid hitches when restored. g_graphics->SetGyroEnabled(false); // IMPORTANT: Any on-pause related stuff that threads need to do must @@ -234,20 +233,59 @@ void AppFlavor::SetProductPrice(const std::string& product, void AppFlavor::PauseApp() { assert(InMainThread()); + millisecs_t start_time{Platform::GetCurrentMilliseconds()}; + + // Apple mentioned 5 seconds to run stuff once backgrounded or + // they bring down the hammer. Let's aim to stay under 2. + millisecs_t max_duration{2000}; + Platform::DebugLog("PauseApp@" + std::to_string(Platform::GetCurrentMilliseconds())); assert(!sys_paused_app_); sys_paused_app_ = true; UpdatePauseResume(); + + // We assume that the OS will completely suspend our process the moment + // we return from this call (though this is not technically true on all + // platforms). So we want to spin and wait for threads to actually + // process the pause message. + size_t running_thread_count{}; + while (std::abs(Platform::GetCurrentMilliseconds() - start_time) + < max_duration) { + // If/when we get to a point with no threads waiting to be paused, + // we're good to go. + auto threads{Thread::GetStillPausingThreads()}; + running_thread_count = threads.size(); + if (running_thread_count == 0) { + Log(LogLevel::kDebug, + "PauseApp() completed in " + + std::to_string(Platform::GetCurrentMilliseconds() - start_time) + + "ms."); + return; + } + } + + // If we made it here, we timed out. Complain. + Log(LogLevel::kError, + std::string("PauseApp() took too long; ") + + std::to_string(running_thread_count) + + " threads not yet paused after " + + std::to_string(Platform::GetCurrentMilliseconds() - start_time) + + " ms."); } void AppFlavor::ResumeApp() { assert(InMainThread()); + millisecs_t start_time{Platform::GetCurrentMilliseconds()}; Platform::DebugLog("ResumeApp@" + std::to_string(Platform::GetCurrentMilliseconds())); assert(sys_paused_app_); sys_paused_app_ = false; UpdatePauseResume(); + Log(LogLevel::kDebug, + "ResumeApp() completed in " + + std::to_string(Platform::GetCurrentMilliseconds() - start_time) + + "ms."); } void AppFlavor::DidFinishRenderingFrame(FrameDef* frame) {} @@ -265,6 +303,7 @@ void AppFlavor::PrimeEventPump() { #pragma mark Push-Calls +// FIXME - move this call to Platform. void AppFlavor::PushShowOnlineScoreUICall(const std::string& show, const std::string& game, const std::string& game_version) { @@ -316,14 +355,6 @@ void AppFlavor::PushOpenURLCall(const std::string& url) { thread()->PushCall([url] { g_platform->OpenURL(url); }); } -void AppFlavor::PushGetFriendScoresCall(const std::string& game, - const std::string& game_version, - void* data) { - thread()->PushCall([game, game_version, data] { - g_platform->GetFriendScores(game, game_version, data); - }); -} - void AppFlavor::PushSubmitScoreCall(const std::string& game, const std::string& game_version, int64_t score) { diff --git a/src/ballistica/app/app_flavor.h b/src/ballistica/app/app_flavor.h index fb1f013a..c0693b48 100644 --- a/src/ballistica/app/app_flavor.h +++ b/src/ballistica/app/app_flavor.h @@ -43,16 +43,17 @@ class AppFlavor { /// Should process any pending OS events, etc. virtual auto RunEvents() -> void; - // These should be called by the window, view-controller, sdl, - // or whatever is driving the app. They must be called from the main thread. - - /// Should be called on mobile when the app is backgrounded. - /// Pauses threads, closes network sockets, etc. + /// Put the app into a paused state. Should be called from the main + /// thread. Pauses work, closes network sockets, etc. + /// Corresponds to being backgrounded on mobile, etc. + /// It is assumed that, as soon as this call returns, all work is + /// finished and all threads can be suspended by the OS without any + /// negative side effects. auto PauseApp() -> void; auto paused() const -> bool { return actually_paused_; } - /// Should be called on mobile when the app is foregrounded. + /// Resume the app; corresponds to returning to foreground on mobile/etc. /// Spins threads back up, re-opens network sockets, etc. auto ResumeApp() -> void; @@ -101,9 +102,6 @@ class AppFlavor { auto PushShowOnlineScoreUICall(const std::string& show, const std::string& game, const std::string& game_version) -> void; - auto PushGetFriendScoresCall(const std::string& game, - const std::string& game_version, void* data) - -> void; auto PushSubmitScoreCall(const std::string& game, const std::string& game_version, int64_t score) -> void; diff --git a/src/ballistica/ballistica.cc b/src/ballistica/ballistica.cc index 6fa5faad..afac0d1b 100644 --- a/src/ballistica/ballistica.cc +++ b/src/ballistica/ballistica.cc @@ -32,7 +32,7 @@ namespace ballistica { // These are set automatically via script; don't modify them here. -const int kAppBuildNumber = 20934; +const int kAppBuildNumber = 20942; const char* kAppVersion = "1.7.14"; // Our standalone globals. diff --git a/src/ballistica/core/object.cc b/src/ballistica/core/object.cc index ee3280ee..6efc0098 100644 --- a/src/ballistica/core/object.cc +++ b/src/ballistica/core/object.cc @@ -11,7 +11,7 @@ namespace ballistica { -void Object::PrintObjects() { +void Object::LsObjects() { #if BA_DEBUG_BUILD std::string s; { @@ -47,7 +47,7 @@ void Object::PrintObjects() { for (auto&& i : obj_map) { sorted.emplace_back(i.second, i.first); } - std::sort(sorted.begin(), sorted.end()); + std::sort(sorted.rbegin(), sorted.rend()); for (auto&& i : sorted) { s += "\n " + std::to_string(i.first) + ": " + i.second; } @@ -56,7 +56,7 @@ void Object::PrintObjects() { } Log(LogLevel::kInfo, s); #else - Log(LogLevel::kInfo, "PrintObjects() only functions in debug builds."); + Log(LogLevel::kInfo, "LsObjects() only functions in debug builds."); #endif // BA_DEBUG_BUILD } diff --git a/src/ballistica/core/object.h b/src/ballistica/core/object.h index 6847e43b..5cb03e1b 100644 --- a/src/ballistica/core/object.h +++ b/src/ballistica/core/object.h @@ -21,8 +21,8 @@ class Object { Object(); virtual ~Object(); - /// Prints a tally of object types and counts (debug build only). - static void PrintObjects(); + /// Logs a tally of ba::Object types and counts (debug build only). + static void LsObjects(); // Object classes can provide descriptive names for themselves; // these are used for debugging and other purposes. diff --git a/src/ballistica/core/thread.cc b/src/ballistica/core/thread.cc index de2b5985..b9032ff3 100644 --- a/src/ballistica/core/thread.cc +++ b/src/ballistica/core/thread.cc @@ -91,7 +91,7 @@ auto Thread::RunAssetsThreadP(void* data) -> void* { return nullptr; } -void Thread::SetPaused(bool paused) { +void Thread::PushSetPaused(bool paused) { // Can be toggled from the main thread only. assert(std::this_thread::get_id() == g_app->main_thread_id); PushThreadMessage(ThreadMessage(paused ? ThreadMessage::Type::kPause @@ -101,13 +101,24 @@ void Thread::SetPaused(bool paused) { void Thread::WaitForNextEvent(bool single_cycle) { // If we're running a single cycle we never stop to wait. if (single_cycle) { + // Need to revisit this if we ever do single-cycle for + // the gil-holding thread so we don't starve other Python threads. + assert(!acquires_python_gil_); return; } - // We also never wait if we have pending runnables. - // (we run all existing runnables in each loop cycle, but one of those - // may have enqueued more). - if (has_pending_runnables()) { + // We also never wait if we have pending runnables; we wan't to run + // things as soon as we can. We chew through all runnables at the end + // of the loop so it might seem like there should never be any here, + // but runnables can add other runnables that won't get processed until + // the next time through. + // BUG FIX: We now skip this if we're paused since we don't run runnables + // in that case. This was preventing us from releasing the GIL while paused + // (and I assume causing us to spin full-speed through the loop; ugh). + // NOTE: It is theoretically possible for a runnable to add another runnable + // each time through the loop which would effectively starve the GIL as + // well; do we need to worry about that case? + if (has_pending_runnables() && !paused_) { return; } @@ -479,9 +490,6 @@ void Thread::PushThreadMessage(const ThreadMessage& t) { // Plop the data on to the list; we're assuming the mutex is locked. thread_messages_.push_back(t); - // Keep our own count; apparently size() on an stl list involves iterating. - // FIXME: Actually I don't think this is the case anymore; should check. - // Debugging: show message count states. if (explicit_bool(false)) { static int one_off = 0; @@ -525,13 +533,29 @@ void Thread::PushThreadMessage(const ThreadMessage& t) { thread_message_cv_.notify_all(); } -void Thread::SetThreadsPaused(bool paused) { +auto Thread::SetThreadsPaused(bool paused) -> void { + assert(std::this_thread::get_id() == g_app->main_thread_id); g_app->threads_paused = paused; for (auto&& i : g_app->pausable_threads) { - i->SetPaused(paused); + i->PushSetPaused(paused); } } +auto Thread::GetStillPausingThreads() -> std::vector { + std::vector threads; + assert(std::this_thread::get_id() == g_app->main_thread_id); + + // Only return results if an actual pause is in effect. + if (g_app->threads_paused) { + for (auto&& i : g_app->pausable_threads) { + if (!i->paused()) { + threads.push_back(i); + } + } + } + return threads; +} + auto Thread::AreThreadsPaused() -> bool { return g_app->threads_paused; } auto Thread::NewTimer(millisecs_t length, bool repeat, @@ -553,6 +577,7 @@ auto Thread::GetCurrentThreadName() -> std::string { } } + // Ask pthread for the thread name if we don't have one. // FIXME - move this to platform. #if BA_OSTYPE_MACOS || BA_OSTYPE_IOS_TVOS || BA_OSTYPE_LINUX std::string name = "unknown (sys-name="; diff --git a/src/ballistica/core/thread.h b/src/ballistica/core/thread.h index d5a63d01..7f16500f 100644 --- a/src/ballistica/core/thread.h +++ b/src/ballistica/core/thread.h @@ -45,7 +45,8 @@ class Thread { void SetAcquiresPythonGIL(); - void SetPaused(bool paused); + void PushSetPaused(bool paused); + auto thread_id() const -> std::thread::id { return thread_id_; } // Needed in rare cases where we jump physical threads. @@ -97,6 +98,10 @@ class Thread { /// the app through a flood of packets. auto CheckPushSafety() -> bool; + static auto GetStillPausingThreads() -> std::vector; + + auto paused() { return paused_; } + private: struct ThreadMessage { enum class Type { kShutdown = 999, kRunnable, kPause, kResume }; diff --git a/src/ballistica/graphics/gl/gl_sys.h b/src/ballistica/graphics/gl/gl_sys.h index 8ffa9ad8..154e0ce7 100644 --- a/src/ballistica/graphics/gl/gl_sys.h +++ b/src/ballistica/graphics/gl/gl_sys.h @@ -61,9 +61,9 @@ #if BA_OSTYPE_MACOS #if BA_XCODE_BUILD #include +#include #include #endif // BA_XCODE_BUILD -#include #endif // BA_OSTYPE_MACOS #endif // BA_OSTYPE_IOS_TVOS || BA_OSTYPE_ANDROID diff --git a/src/ballistica/input/input.cc b/src/ballistica/input/input.cc index bebef567..a6a1b289 100644 --- a/src/ballistica/input/input.cc +++ b/src/ballistica/input/input.cc @@ -1818,4 +1818,48 @@ auto Input::GetKeyName(int keycode) -> std::string { #pragma clang diagnostic pop #endif // BA_SDL2_BUILD || BA_MINSDL_BUILD +auto Input::LsInputDevices() -> void { + BA_PRECONDITION(InLogicThread()); + + std::string out; + + std::string ind{" "}; + int index{0}; + for (auto& device : input_devices_) { + if (index != 0) { + out += "\n"; + } + out += std::to_string(index + 1) + ":\n"; + out += ind + "name: " + device->GetDeviceName() + "\n"; + out += ind + "index: " + std::to_string(device->index()) + "\n"; + out += (ind + "is-controller: " + std::to_string(device->IsController()) + + "\n"); + out += (ind + "is-sdl-controller: " + + std::to_string(device->IsSDLController()) + "\n"); + out += (ind + "is-touch-screen: " + std::to_string(device->IsTouchScreen()) + + "\n"); + out += (ind + "is-remote-control: " + + std::to_string(device->IsRemoteControl()) + "\n"); + out += (ind + "is-test-input: " + std::to_string(device->IsTestInput()) + + "\n"); + out += + (ind + "is-keyboard: " + std::to_string(device->IsKeyboard()) + "\n"); + out += (ind + "is-mfi-controller: " + + std::to_string(device->IsMFiController()) + "\n"); + out += (ind + "is-local: " + std::to_string(device->IsLocal()) + "\n"); + out += (ind + "is-ui-only: " + std::to_string(device->IsUIOnly()) + "\n"); + out += (ind + "is-remote-app: " + std::to_string(device->IsRemoteApp()) + + "\n"); + + out += ind + "attached-to: " + + (device->GetRemotePlayer() != nullptr ? "remote-player" + : device->GetPlayer() != nullptr ? "local-player" + : "nothing"); + + ++index; + } + + Log(LogLevel::kInfo, out); +} + } // namespace ballistica diff --git a/src/ballistica/input/input.h b/src/ballistica/input/input.h index 1ece106a..3c3659c7 100644 --- a/src/ballistica/input/input.h +++ b/src/ballistica/input/input.h @@ -126,6 +126,7 @@ class Input { auto PushTouchEvent(const TouchEvent& touch_event) -> void; auto PushDestroyKeyboardInputDevices() -> void; auto PushCreateKeyboardInputDevices() -> void; + auto LsInputDevices() -> void; /// Roughly how long in milliseconds have all input devices been idle. auto input_idle_time() const { return input_idle_time_; } @@ -170,7 +171,6 @@ class Input { bool have_non_touch_inputs_{}; float cursor_pos_x_{}; float cursor_pos_y_{}; - // millisecs_t last_input_time_{}; millisecs_t last_click_time_{}; millisecs_t double_click_time_{200}; millisecs_t last_mouse_move_time_{}; diff --git a/src/ballistica/platform/apple/platform_apple.h b/src/ballistica/platform/apple/platform_apple.h index 6aa86d56..5c819577 100644 --- a/src/ballistica/platform/apple/platform_apple.h +++ b/src/ballistica/platform/apple/platform_apple.h @@ -37,8 +37,6 @@ class PlatformApple : public Platform { const std::vector& widths, float scale) -> void* override; auto GetTextTextureData(void* tex) -> uint8_t* override; - auto GetFriendScores(const std::string& game, const std::string& game_version, - void* py_callback) -> void override; auto SubmitScore(const std::string& game, const std::string& version, int64_t score) -> void override; auto ReportAchievement(const std::string& achievement) -> void override; diff --git a/src/ballistica/platform/platform.cc b/src/ballistica/platform/platform.cc index 04adb2dc..31abfccb 100644 --- a/src/ballistica/platform/platform.cc +++ b/src/ballistica/platform/platform.cc @@ -196,6 +196,11 @@ auto Platform::LoginAdapterGetSignInToken(const std::string& login_type, }); } +auto Platform::LoginAdapterBackEndActiveChange(const std::string& login_type, + bool active) -> void { + // Default is no-op. +} + auto Platform::GetDeviceV1AccountUUIDPrefix() -> std::string { Log(LogLevel::kError, "GetDeviceV1AccountUUIDPrefix() unimplemented"); return "u"; @@ -862,13 +867,6 @@ auto Platform::ConvertIncomingLeaderboardScore( return score; } -void Platform::GetFriendScores(const std::string& game, - const std::string& game_version, void* data) { - // As a default, just fail gracefully. - Log(LogLevel::kError, "FIXME: GetFriendScores unimplemented"); - g_logic->PushFriendScoreSetCall(FriendScoreSet(false, data)); -} - void Platform::SubmitScore(const std::string& game, const std::string& version, int64_t score) { Log(LogLevel::kError, "FIXME: SubmitScore() unimplemented"); diff --git a/src/ballistica/platform/platform.h b/src/ballistica/platform/platform.h index 8edcade4..27b03ded 100644 --- a/src/ballistica/platform/platform.h +++ b/src/ballistica/platform/platform.h @@ -339,6 +339,10 @@ class Platform { /// Called when a Python LoginAdapter is requesting an explicit sign-in. virtual auto LoginAdapterGetSignInToken(const std::string& login_type, int attempt_id) -> void; + /// Called when a Python LoginAdapter is informing us that a back-end is + /// active/inactive. + virtual auto LoginAdapterBackEndActiveChange(const std::string& login_type, + bool active) -> void; #pragma mark MUSIC PLAYBACK ---------------------------------------------------- @@ -368,9 +372,6 @@ class Platform { virtual auto ConvertIncomingLeaderboardScore( const std::string& leaderboard_id, int score) -> int; - virtual auto GetFriendScores(const std::string& game, - const std::string& game_version, - void* py_callback) -> void; virtual auto SubmitScore(const std::string& game, const std::string& version, int64_t score) -> void; virtual auto ReportAchievement(const std::string& achievement) -> void; diff --git a/src/ballistica/python/methods/python_methods_app.cc b/src/ballistica/python/methods/python_methods_app.cc index d2460ea9..2de0a6dc 100644 --- a/src/ballistica/python/methods/python_methods_app.cc +++ b/src/ballistica/python/methods/python_methods_app.cc @@ -6,6 +6,7 @@ #include "ballistica/app/app_flavor.h" #include "ballistica/assets/component/texture.h" #include "ballistica/core/logging.h" +#include "ballistica/core/thread.h" #include "ballistica/graphics/graphics.h" #include "ballistica/logic/connection/connection_set.h" #include "ballistica/logic/host_activity.h" @@ -308,18 +309,29 @@ auto PyPushCall(PyObject* self, PyObject* args, PyObject* keywds) -> PyObject* { int from_other_thread{}; int suppress_warning{}; int other_thread_use_fg_context{}; - static const char* kwlist[] = {"call", "from_other_thread", + int raw{0}; + static const char* kwlist[] = {"call", + "from_other_thread", "suppress_other_thread_warning", - "other_thread_use_fg_context", nullptr}; - if (!PyArg_ParseTupleAndKeywords(args, keywds, "O|ppp", + "other_thread_use_fg_context", + "raw", + nullptr}; + if (!PyArg_ParseTupleAndKeywords(args, keywds, "O|pppp", const_cast(kwlist), &call_obj, &from_other_thread, &suppress_warning, - &other_thread_use_fg_context)) { + &other_thread_use_fg_context, &raw)) { return nullptr; } - // The from-other-thread case is basically a different call. - if (from_other_thread) { + // 'raw' mode does no thread checking and no context saves/restores. + if (raw) { + Py_INCREF(call_obj); + g_logic->thread()->PushCall([call_obj] { + assert(InLogicThread()); + + PythonRef(call_obj, PythonRef::kSteal).Call(); + }); + } else if (from_other_thread) { // Warn the user not to use this from the logic thread since it doesnt // save/restore context. if (!suppress_warning && InLogicThread()) { @@ -1132,15 +1144,12 @@ auto PythonMethodsApp::GetMethods() -> std::vector { {"pushcall", (PyCFunction)PyPushCall, METH_VARARGS | METH_KEYWORDS, "pushcall(call: Callable, from_other_thread: bool = False,\n" " suppress_other_thread_warning: bool = False,\n" - " other_thread_use_fg_context: bool = False) -> None\n" - "\n" - "Pushes a call onto the event loop to be run during the next cycle.\n" + " other_thread_use_fg_context: bool = False,\n" + " raw: bool = False) -> None\n" "\n" + "Push a call to the logic event-loop.\n" "Category: **General Utility Functions**\n" "\n" - "This can be handy for calls that are disallowed from within other\n" - "callbacks, etc.\n" - "\n" "This call expects to be used in the logic thread, and will " "automatically\n" "save and restore the ba.Context to behave seamlessly.\n" @@ -1149,8 +1158,9 @@ auto PythonMethodsApp::GetMethods() -> std::vector { "however, you can pass 'from_other_thread' as True. In this case\n" "the call will always run in the UI context on the logic thread\n" "or whichever context is in the foreground if\n" - "other_thread_use_fg_context is True."}, - + "other_thread_use_fg_context is True.\n" + "Passing raw=True will disable thread checks and context" + " sets/restores."}, {"getactivity", (PyCFunction)PyGetActivity, METH_VARARGS | METH_KEYWORDS, "getactivity(doraise: bool = True) -> \n" diff --git a/src/ballistica/python/methods/python_methods_system.cc b/src/ballistica/python/methods/python_methods_system.cc index b4a161b0..1d9f879b 100644 --- a/src/ballistica/python/methods/python_methods_system.cc +++ b/src/ballistica/python/methods/python_methods_system.cc @@ -638,6 +638,22 @@ auto PyLoginAdapterGetSignInToken(PyObject* self, PyObject* args, BA_PYTHON_CATCH; } +auto PyLoginAdapterBackEndActiveChange(PyObject* self, PyObject* args, + PyObject* keywds) -> PyObject* { + BA_PYTHON_TRY; + const char* login_type; + int active; + static const char* kwlist[] = {"login_type", "active", nullptr}; + if (!PyArg_ParseTupleAndKeywords(args, keywds, "sp", + const_cast(kwlist), &login_type, + &active)) { + return nullptr; + } + g_platform->LoginAdapterBackEndActiveChange(login_type, active); + Py_RETURN_NONE; + BA_PYTHON_CATCH; +} + auto PySetInternalLanguageKeys(PyObject* self, PyObject* args) -> PyObject* { BA_PYTHON_TRY; PyObject* list_obj; @@ -715,10 +731,18 @@ auto PyAndroidShowWifiSettings(PyObject* self, PyObject* args, PyObject* keywds) BA_PYTHON_CATCH; } -auto PyPrintObjects(PyObject* self, PyObject* args, PyObject* keywds) +auto PyLsObjects(PyObject* self, PyObject* args, PyObject* keywds) -> PyObject* { BA_PYTHON_TRY; - Object::PrintObjects(); + Object::LsObjects(); + Py_RETURN_NONE; + BA_PYTHON_CATCH; +} + +auto PyLsInputDevices(PyObject* self, PyObject* args, PyObject* keywds) + -> PyObject* { + BA_PYTHON_TRY; + g_input->LsInputDevices(); Py_RETURN_NONE; BA_PYTHON_CATCH; } @@ -756,6 +780,7 @@ auto PythonMethodsSystem::GetMethods() -> std::vector { "\n" "If this returns False, UIs should not show 'copy to clipboard'\n" "buttons, etc."}, + {"clipboard_has_text", (PyCFunction)PyClipboardHasText, METH_NOARGS, "clipboard_has_text() -> bool\n" "\n" @@ -765,6 +790,7 @@ auto PythonMethodsSystem::GetMethods() -> std::vector { "\n" "This will return False if no system clipboard is available; no need\n" " to call ba.clipboard_is_supported() separately."}, + {"clipboard_set_text", (PyCFunction)PyClipboardSetText, METH_VARARGS | METH_KEYWORDS, "clipboard_set_text(value: str) -> None\n" @@ -775,6 +801,7 @@ auto PythonMethodsSystem::GetMethods() -> std::vector { "\n" "Ensure that ba.clipboard_is_supported() returns True before adding\n" " buttons/etc. that make use of this functionality."}, + {"clipboard_get_text", (PyCFunction)PyClipboardGetText, METH_NOARGS, "clipboard_get_text() -> str\n" "\n" @@ -784,9 +811,20 @@ auto PythonMethodsSystem::GetMethods() -> std::vector { "\n" "Ensure that ba.clipboard_has_text() returns True before calling\n" " this function."}, - {"printobjects", (PyCFunction)PyPrintObjects, + + {"ls_objects", (PyCFunction)PyLsObjects, METH_VARARGS | METH_KEYWORDS, + "ls_objects() -> None\n" + "\n" + "Log debugging info about C++ level objects.\n" + "\n" + "Category: **General Utility Functions**\n" + "\n" + "This call only functions in debug builds of the game.\n" + "It prints various info about the current object count, etc."}, + + {"ls_input_devices", (PyCFunction)PyLsInputDevices, METH_VARARGS | METH_KEYWORDS, - "printobjects() -> None\n" + "ls_input_devices() -> None\n" "\n" "Print debugging info about game objects.\n" "\n" @@ -859,6 +897,14 @@ auto PythonMethodsSystem::GetMethods() -> std::vector { "\n" "(internal)"}, + {"login_adapter_back_end_active_change", + (PyCFunction)PyLoginAdapterBackEndActiveChange, + METH_VARARGS | METH_KEYWORDS, + "login_adapter_back_end_active_change(login_type: str, active: bool)" + " -> None\n" + "\n" + "(internal)"}, + {"submit_analytics_counts", (PyCFunction)PySubmitAnalyticsCounts, METH_VARARGS | METH_KEYWORDS, "submit_analytics_counts() -> None\n" diff --git a/tools/bacommon/login.py b/tools/bacommon/login.py index 957997da..c8ec0057 100644 --- a/tools/bacommon/login.py +++ b/tools/bacommon/login.py @@ -19,3 +19,13 @@ class LoginType(Enum): # Google Play Game Services GPGS = 'gpgs' + + @property + def displayname(self) -> str: + """Human readable name for this value.""" + cls = type(self) + match self: + case cls.EMAIL: + return 'Email/Password' + case cls.GPGS: + return 'Google Play Games' diff --git a/tools/batools/project.py b/tools/batools/project.py index 48c4d561..f4d82d7f 100755 --- a/tools/batools/project.py +++ b/tools/batools/project.py @@ -729,8 +729,10 @@ class Updater: def _check_misc(self) -> None: # Misc sanity checks. - if not self._public: - # Make sure we're set to prod master server. + + # Make sure we're set to prod master server. + # (but ONLY when checking; still want to be able to run updates). + if not self._public and self._check: with open( 'src/ballistica/internal/master_server_config.h', encoding='utf-8', diff --git a/tools/efro/error.py b/tools/efro/error.py index d3353708..456fc6f9 100644 --- a/tools/efro/error.py +++ b/tools/efro/error.py @@ -80,6 +80,15 @@ class IntegrityError(ValueError): """Data has been tampered with or corrupted in some form.""" +class AuthenticationError(Exception): + """Authentication has failed for some operation. + + This can be raised if server-side-verification does not match + client-supplied credentials, if an invalid password is supplied + for a sign-in attempt, etc. + """ + + def is_urllib_communication_error(exc: BaseException, url: str | None) -> bool: """Is the provided exception from urllib a communication-related error? diff --git a/tools/efro/message/_message.py b/tools/efro/message/_message.py index 9343a396..0697ad53 100644 --- a/tools/efro/message/_message.py +++ b/tools/efro/message/_message.py @@ -43,6 +43,20 @@ class SysResponse: users of the api never see them. """ + def set_local_exception(self, exc: Exception) -> None: + """Attach a local exception to facilitate better logging/handling. + + Be aware that this data does not get serialized and only + exists on the local object. + """ + setattr(self, '_sr_local_exception', exc) + + def get_local_exception(self) -> Exception | None: + """Fetch a local attached exception.""" + value = getattr(self, '_sr_local_exception', None) + assert isinstance(value, Exception | None) + return value + # Some standard response types: diff --git a/tools/efro/message/_sender.py b/tools/efro/message/_sender.py index bd9e94db..ee439e01 100644 --- a/tools/efro/message/_sender.py +++ b/tools/efro/message/_sender.py @@ -6,7 +6,6 @@ Supports static typing for message types and possible return types. from __future__ import annotations -import logging from typing import TYPE_CHECKING from efro.error import CleanError, RemoteError, CommunicationError @@ -158,17 +157,18 @@ class MessageSender: bound_obj, msg_encoded ) except Exception as exc: - # Any error in the raw send call gets recorded as either - # a local or communication error. - return ErrorSysResponse( - error_message=f'Error in MessageSender @send_method' - f' ({type(exc)}): {exc}', + response = ErrorSysResponse( + error_message='Error in MessageSender @send_method.', error_type=( ErrorSysResponse.ErrorType.COMMUNICATION if isinstance(exc, CommunicationError) else ErrorSysResponse.ErrorType.LOCAL ), ) + # Can include the actual exception since we'll be looking at + # this locally; might be helpful. + response.set_local_exception(exc) + return response return self._decode_raw_response(bound_obj, message, response_encoded) async def fetch_raw_response_async( @@ -193,17 +193,18 @@ class MessageSender: bound_obj, msg_encoded ) except Exception as exc: - # Any error in the raw send call gets recorded as either - # a local or communication error. - return ErrorSysResponse( - error_message=f'Error in MessageSender @send_async_method' - f' ({type(exc)}): {exc}', + response = ErrorSysResponse( + error_message='Error in MessageSender @send_async_method.', error_type=( ErrorSysResponse.ErrorType.COMMUNICATION if isinstance(exc, CommunicationError) else ErrorSysResponse.ErrorType.LOCAL ), ) + # Can include the actual exception since we'll be looking at + # this locally; might be helpful. + response.set_local_exception(exc) + return response return self._decode_raw_response(bound_obj, message, response_encoded) def unpack_raw_response( @@ -250,18 +251,14 @@ class MessageSender: self._decode_filter_call( bound_obj, message, response_dict, response ) - except Exception: - # If we got to this point, we successfully communicated - # with the other end so errors represent protocol mismatches - # or other invalid data. For now let's just log it but perhaps - # we'd want to somehow embed it in the ErrorSysResponse to be - # available directly to the user later. - logging.exception('Error decoding raw response') + except Exception as exc: response = ErrorSysResponse( - error_message='Error decoding raw response;' - ' see log for details.', + error_message='Error decoding raw response.', error_type=ErrorSysResponse.ErrorType.LOCAL, ) + # Since we'll be looking at this locally, we can include + # extra info for logging/etc. + response.set_local_exception(exc) return response def _unpack_raw_response( @@ -282,16 +279,24 @@ class MessageSender: # Some error occurred. Raise a local Exception for it. if isinstance(raw_response, ErrorSysResponse): + # Errors that happened locally can attach their exceptions + # here for extra logging goodness. + local_exception = raw_response.get_local_exception() + if ( raw_response.error_type is ErrorSysResponse.ErrorType.COMMUNICATION ): - raise CommunicationError(raw_response.error_message) + raise CommunicationError( + raw_response.error_message + ) from local_exception # If something went wrong on *our* end of the connection, # don't say it was a remote error. if raw_response.error_type is ErrorSysResponse.ErrorType.LOCAL: - raise RuntimeError(raw_response.error_message) + raise RuntimeError( + raw_response.error_message + ) from local_exception # If they want to support clean errors, do those. if ( @@ -299,14 +304,18 @@ class MessageSender: and raw_response.error_type is ErrorSysResponse.ErrorType.REMOTE_CLEAN ): - raise CleanError(raw_response.error_message) + raise CleanError( + raw_response.error_message + ) from local_exception if ( self.protocol.forward_communication_errors and raw_response.error_type is ErrorSysResponse.ErrorType.REMOTE_COMMUNICATION ): - raise CommunicationError(raw_response.error_message) + raise CommunicationError( + raw_response.error_message + ) from local_exception # Everything else gets lumped in as a remote error. raise RemoteError( @@ -316,7 +325,7 @@ class MessageSender: if self._peer_desc_call is None else self._peer_desc_call(bound_obj) ), - ) + ) from local_exception assert isinstance(raw_response, Response) return raw_response diff --git a/tools/efrotools/pcommand.py b/tools/efrotools/pcommand.py index 8a5a66a1..7e8c2ede 100644 --- a/tools/efrotools/pcommand.py +++ b/tools/efrotools/pcommand.py @@ -162,6 +162,13 @@ def _spelling(words: list[str]) -> None: print(f'Modified {num_modded_dictionaries} dictionaries.') +def pur() -> None: + """Run pur using project's Python version.""" + import subprocess + + subprocess.run([sys.executable, '-m', 'pur'] + sys.argv[2:], check=True) + + def spelling_all() -> None: """Add all misspellings from a pycharm run.""" import subprocess From d75c469baa54bf98c4a91b94f69e7d59a360fa6d Mon Sep 17 00:00:00 2001 From: Eric Date: Tue, 29 Nov 2022 12:11:20 -0800 Subject: [PATCH 02/26] better message/logging on sign-in failures --- .efrocachemap | 40 +++++++++++----------- CHANGELOG.md | 2 +- assets/src/ba_data/python/ba/_accountv2.py | 7 ++-- assets/src/ba_data/python/ba/_bootstrap.py | 2 +- src/ballistica/ballistica.cc | 2 +- 5 files changed, 28 insertions(+), 25 deletions(-) diff --git a/.efrocachemap b/.efrocachemap index 4fb93651..3bf0c798 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -4003,26 +4003,26 @@ "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/0f/f4/4a4f1087d2bb778d9be504442270", - "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/0e/10/5c509346d44b89ddd12aec7ec7de", - "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/cd/9f/a6f5274ff94f95e902cca445a510", - "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/04/2a/263e10497930fa6159e5352b7370", - "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/59/62/28c8370b93d43d1c13acfbddee57", - "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/d8/4e/ad0d3316f74e82ffde5c7b976fc2", - "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/4a/41/08aa8c9e197e7cc75b6e8d97dc55", - "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/81/6b/e7bc7863fc9c6b6a241d93f7d4e3", - "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/ec/44/094cd342e6a8eb2f1671f680a5e8", - "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/fc/f9/b44862de39500fc85a3b3960a132", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/78/7d/c4f86fc89838006fa2bacf4fa9a8", - "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/d7/40/0d31b629247be2c16ee042ee9165", - "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/1f/39/781ca02803724b5a84a197d3d264", - "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/39/f9/a085edd64d394ce0f4fee7f857e9", - "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/fe/60/82caae9fc89ce89688ea5013e5c9", - "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/9c/e9/3fb7c6b71287d2b3c3ab5f11f6c3", - "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/c4/df/b58bf2cf14619d257ca145242cdd", - "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/b5/f9/d5ee77a243aee14ad0cd0f5e53e5", - "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/b8/bc/71febcf1ffd431bd80936d313b73", - "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/5d/ff/c36c1a0d0713aca6aa0f640de48b", + "build/prefab/full/linux_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/8d/26/6c0bd3ce52765637e83231d6fde1", + "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/3b/7e/b7ef105fa0357b0d362603f129fc", + "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/bf/6e/2ca7479c1feebbcd15554bebeea0", + "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/78/00/bb8ae54341023805cf0f280b9155", + "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/42/f5/b91d0ec0f98b50673ef913c7bc8e", + "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/30/fa/9ad8555e93ee445f8154c5330b11", + "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/9e/b9/8d1dede802b852454a3124cae881", + "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/8b/29/897ddf43f01868170b3a82cd7b90", + "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/63/ea/a6a99f8bf6de4997d0ee80f5c469", + "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/4e/9c/e7dca964568c7588765616b7c543", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/85/a3/79df52e6a0487a63305259fa0c1a", + "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/e1/86/353b3402cd2fee04136b0e679838", + "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/8c/a7/0e58c80115b868c92d09807ca8cb", + "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/30/0b/a53e1fd065417789f1d6ab4bbf41", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/a1/d0/e93c6de7d8a64b6427a9a9b76d5d", + "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/f2/64/40913c4d98b3614bf459ecbac060", + "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/d3/29/70461e83a0f10150b4dec3829f51", + "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/a8/8b/bdc933ac2015eb3cc259e83c26fa", + "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/17/8f/6b5134c9c89d09866da1c52a8e20", + "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/aa/8e/4e97eb4e5f1c20ca52c2b8b255dc", "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/2f/98/0f10aa690341351b047d9dc3fe65", "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/14/aa/d9e350323ed97ca2c87667c569bb", "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/64/a9/03eb8d0e32bf35b10941eb8ca082", diff --git a/CHANGELOG.md b/CHANGELOG.md index ab19ed4d..fac45410 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -### 1.7.14 (build 20942, api 7, 2022-11-29) +### 1.7.14 (build 20943, api 7, 2022-11-29) - Android Google Play logins now provide V2 accounts with access to all V2 features such as a globally-unique account tag, cloud-console, and workspaces. They should still retain their V1 data as well. - V2 accounts now have a 'Manage Account' button in the app account window which will sign you into a browser with your current account. - Removed Google App Invite functionality which has been deprecated for a while now. Google Play users can still get tickets by sharing the app via codes (same as other platforms). diff --git a/assets/src/ba_data/python/ba/_accountv2.py b/assets/src/ba_data/python/ba/_accountv2.py index 372f9dad..37fff3c6 100644 --- a/assets/src/ba_data/python/ba/_accountv2.py +++ b/assets/src/ba_data/python/ba/_accountv2.py @@ -331,10 +331,13 @@ class AccountV2Subsystem: # Make some noise on errors. # (May want to make this more descriptive). if isinstance(result, Exception): + logging.warning( + 'Error on explicit sign in attempt.', exc_info=result + ) with _ba.Context('ui'): _ba.screenmessage( - Lstr(resource='errorText'), - color=(1, 1, 0), + Lstr(resource='internal.signInErrorText'), + color=(1, 0, 0), ) _ba.playsound(_ba.getsound('error')) return diff --git a/assets/src/ba_data/python/ba/_bootstrap.py b/assets/src/ba_data/python/ba/_bootstrap.py index c13e457a..5aef6f3c 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 = 20942 + expected_build = 20943 running_build: int = env['build_number'] if running_build != expected_build: print( diff --git a/src/ballistica/ballistica.cc b/src/ballistica/ballistica.cc index afac0d1b..d7b1b79c 100644 --- a/src/ballistica/ballistica.cc +++ b/src/ballistica/ballistica.cc @@ -32,7 +32,7 @@ namespace ballistica { // These are set automatically via script; don't modify them here. -const int kAppBuildNumber = 20942; +const int kAppBuildNumber = 20943; const char* kAppVersion = "1.7.14"; // Our standalone globals. From 3b08ca39f63ef4c9a9623f9d135e7b17c3314724 Mon Sep 17 00:00:00 2001 From: Eric Date: Tue, 29 Nov 2022 15:47:07 -0800 Subject: [PATCH 03/26] more work on v2 account-settings ui --- .efrocachemap | 8 +- CHANGELOG.md | 1 + assets/src/ba_data/python/ba/_accountv2.py | 42 ++++++---- .../python/bastd/ui/account/settings.py | 78 ++++++++++++++----- 4 files changed, 90 insertions(+), 39 deletions(-) diff --git a/.efrocachemap b/.efrocachemap index 3bf0c798..4fc2d2b2 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -420,7 +420,7 @@ "assets/build/ba_data/audio/zoeOw.ogg": "https://files.ballistica.net/cache/ba1/60/ad/38269b7f1c7dc20cb9a506cd0681", "assets/build/ba_data/audio/zoePickup01.ogg": "https://files.ballistica.net/cache/ba1/72/85/d6fc4d16b7081d91fba2850b5b10", "assets/build/ba_data/audio/zoeScream01.ogg": "https://files.ballistica.net/cache/ba1/e9/ae/1d674d0c086eaa0bd1c3b1db0505", - "assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/b1/c3/2d8b079670d84bde0558f6454f1f", + "assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/c1/58/545feb14ab42361ee0eacce7a1e7", "assets/build/ba_data/data/languages/arabic.json": "https://files.ballistica.net/cache/ba1/b0/05/e530acaba539f040ce61e22561dc", "assets/build/ba_data/data/languages/belarussian.json": "https://files.ballistica.net/cache/ba1/61/03/89070ca765e06da3a419a579f503", "assets/build/ba_data/data/languages/chinese.json": "https://files.ballistica.net/cache/ba1/05/87/d3e03edbc59eb7e7da7ef8b17134", @@ -429,16 +429,16 @@ "assets/build/ba_data/data/languages/czech.json": "https://files.ballistica.net/cache/ba1/cb/df/f2d54d3146a159c678a47d3ff01b", "assets/build/ba_data/data/languages/danish.json": "https://files.ballistica.net/cache/ba1/6a/fa/fcf4a804beaff927b0f12c179eaa", "assets/build/ba_data/data/languages/dutch.json": "https://files.ballistica.net/cache/ba1/68/93/da8e9874f41a786edf52ba4ccaad", - "assets/build/ba_data/data/languages/english.json": "https://files.ballistica.net/cache/ba1/74/1d/04985b013519340632a0f5eb6d81", + "assets/build/ba_data/data/languages/english.json": "https://files.ballistica.net/cache/ba1/52/2a/3e6272799aba12af878dfd2eea15", "assets/build/ba_data/data/languages/esperanto.json": "https://files.ballistica.net/cache/ba1/ac/f5/c0922a99e40dfc9f5e026d43b533", "assets/build/ba_data/data/languages/filipino.json": "https://files.ballistica.net/cache/ba1/86/26/060476f46994c035ae0d52640657", "assets/build/ba_data/data/languages/french.json": "https://files.ballistica.net/cache/ba1/c7/cf/35a6ebc876c7476b72547a914d07", "assets/build/ba_data/data/languages/german.json": "https://files.ballistica.net/cache/ba1/06/58/071d6f7bbb5e93a3e074dbd323ae", - "assets/build/ba_data/data/languages/gibberish.json": "https://files.ballistica.net/cache/ba1/a3/f7/b12c68a8c1ecabbf7b8c41452986", + "assets/build/ba_data/data/languages/gibberish.json": "https://files.ballistica.net/cache/ba1/e7/f2/9cf56bec9e4312c7b547e42477ea", "assets/build/ba_data/data/languages/greek.json": "https://files.ballistica.net/cache/ba1/ae/89/47486b987d14f58b6cf2d665ce4b", "assets/build/ba_data/data/languages/hindi.json": "https://files.ballistica.net/cache/ba1/9f/df/469e166c6a0d42bca4baae3a6cb6", "assets/build/ba_data/data/languages/hungarian.json": "https://files.ballistica.net/cache/ba1/b2/81/53c8cd7617d649403e539c3a6171", - "assets/build/ba_data/data/languages/indonesian.json": "https://files.ballistica.net/cache/ba1/26/57/b9443fccbc90602a5ace74935365", + "assets/build/ba_data/data/languages/indonesian.json": "https://files.ballistica.net/cache/ba1/ae/64/97ed10eed5f31b33864d90368330", "assets/build/ba_data/data/languages/italian.json": "https://files.ballistica.net/cache/ba1/5f/b2/b9301d67bef699a092a4c04dd522", "assets/build/ba_data/data/languages/korean.json": "https://files.ballistica.net/cache/ba1/7c/38/d4a44c481757d355836f292ede48", "assets/build/ba_data/data/languages/persian.json": "https://files.ballistica.net/cache/ba1/cd/ed/4d6d0778d256ccc0ff2e27b970c6", diff --git a/CHANGELOG.md b/CHANGELOG.md index fac45410..c887bc08 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ - Added 'raw' bool arg to `ba.pushcall()`. Passing True for it disables context save/restore and thread checks. - Added `ba.internal.dump_tracebacks()` which can be used to dump the stack state of all Python threads after some delay. Useful for debugging deadlock; just call right before said deadlock occurs. Results will be logged on the next app launch if they cannot be immediately. - Fixed a low level event-loop issue that in some cases was preventing the Android version from properly pausing/resuming the app or managing connections while in the background. If you look at the devices section on ballistica.net you should now see your device disappear when you background the app and reappear when you foreground it. Please holler if not. +- Device accounts are now marked as deprecated, and signing in with one now brings up an 'upgrade' UI which allows converting it to a V2 account. It is my hope to push the entire client ecosystem to V2 accounts as quickly as possible since trying to support both independent V1 accounts and V2 accounts is a substantial technical burden. ### 1.7.13 (build 20919, api 7, 2022-11-03) - Android target-sdk has been updated to 33 (Android 13). Please holler if anything seems broken or is behaving differently than before on Android. diff --git a/assets/src/ba_data/python/ba/_accountv2.py b/assets/src/ba_data/python/ba/_accountv2.py index 37fff3c6..58d78149 100644 --- a/assets/src/ba_data/python/ba/_accountv2.py +++ b/assets/src/ba_data/python/ba/_accountv2.py @@ -9,12 +9,12 @@ import logging from typing import TYPE_CHECKING from efro.call import tpartial +from bacommon.login import LoginType import _ba if TYPE_CHECKING: from typing import Any - from bacommon.login import LoginType from ba._login import LoginAdapter @@ -30,7 +30,6 @@ class AccountV2Subsystem: """ def __init__(self) -> None: - from bacommon.login import LoginType # Whether or not everything related to an initial login # (or lack thereof) has completed. This includes things like @@ -179,6 +178,8 @@ class AccountV2Subsystem: types even if the default implicit one can't be explicitly logged out or otherwise controlled. """ + from ba._language import Lstr + assert _ba.in_logic_thread() cfg = _ba.app.config @@ -202,19 +203,26 @@ class AccountV2Subsystem: # this implicit login, we may want to let them know that the # 'Welcome back FOO' they likely just saw is not actually # accurate. - if bool(False): - if ( - self.primary is not None - and not self.login_adapters[login_type].is_back_end_active() - ): + if ( + self.primary is not None + and not self.login_adapters[login_type].is_back_end_active() + ): + if login_type is LoginType.GPGS: + service_str = Lstr(resource='googlePlayText') + else: + service_str = None + if service_str is not None: _ba.timer( 2.0, tpartial( _ba.screenmessage, - 'Warning: Ignoring your' - ' Google Play Games account.\n' - 'If you want to use it,' - ' sign out of your current account.', + Lstr( + resource='notUsingAccountText', + subs=[ + ('${ACCOUNT}', state.display_name), + ('${SERVICE}', service_str), + ], + ), (1, 0.5, 0), ), ) @@ -328,11 +336,11 @@ class AccountV2Subsystem: del adapter # Unused. - # Make some noise on errors. - # (May want to make this more descriptive). + # Make some noise on errors since the user knows a sign-in + # attempt is happening in this case. if isinstance(result, Exception): logging.warning( - 'Error on explicit sign in attempt.', exc_info=result + 'Error on explicit accountv2 sign in attempt.', exc_info=result ) with _ba.Context('ui'): _ba.screenmessage( @@ -354,8 +362,12 @@ class AccountV2Subsystem: del adapter # Unused. - # Silently ignore errors. + # Log errors but don't inform the user; they're not aware of this + # attempt and ignorance is bliss. if isinstance(result, Exception): + logging.warning( + 'Error on implicit accountv2 sign in attempt.', exc_info=result + ) return # If we're still connected and still not signed in, diff --git a/assets/src/ba_data/python/bastd/ui/account/settings.py b/assets/src/ba_data/python/bastd/ui/account/settings.py index cd65942a..7053b757 100644 --- a/assets/src/ba_data/python/bastd/ui/account/settings.py +++ b/assets/src/ba_data/python/bastd/ui/account/settings.py @@ -17,6 +17,12 @@ import ba.internal if TYPE_CHECKING: from ba.internal import LoginAdapter +# We only show v1 linking controls when directly signed in with +# V1 accounts. Generally V2 accounts should use the web ui for linking. +# However we have an escape-hatch here if someone needs to access +# V1 linking for the V1 portion of their V2 account. +FORCE_ENABLE_V1_LINKING = False + class AccountSettingsWindow(ba.Window): """Window for account related functionality.""" @@ -275,6 +281,7 @@ class AccountSettingsWindow(ba.Window): and 'Device' in self._show_sign_in_buttons ) sign_in_button_space = 70.0 + deprecated_space = 60 show_game_service_button = self._signed_in and v1_account_type in [ 'Game Center' @@ -283,12 +290,7 @@ class AccountSettingsWindow(ba.Window): show_what_is_v2 = self._signed_in and v1_account_type == 'V2' - show_linked_accounts_text = ( - self._signed_in - and ba.internal.get_v1_account_misc_read_val( - 'allowAccountLinking2', False - ) - ) + show_linked_accounts_text = self._signed_in linked_accounts_text_space = 60.0 show_achievements_button = self._signed_in and v1_account_type in ( @@ -325,17 +327,17 @@ class AccountSettingsWindow(ba.Window): 70.0 if show_manage_v2_account_button else 100.0 ) - show_link_accounts_button = ( - self._signed_in - and ba.internal.get_v1_account_misc_read_val( - 'allowAccountLinking2', False - ) + show_link_accounts_button = self._signed_in and ( + primary_v2_account is None or FORCE_ENABLE_V1_LINKING ) link_accounts_button_space = 70.0 show_unlink_accounts_button = show_link_accounts_button unlink_accounts_button_space = 90.0 + show_v2_link_info = self._signed_in and not show_link_accounts_button + v2_link_info_space = 70.0 + show_sign_out_button = self._signed_in and v1_account_type in [ 'Local', 'Google Play', @@ -361,10 +363,10 @@ class AccountSettingsWindow(ba.Window): self._sub_height += signing_in_text_space if show_google_play_sign_in_button: self._sub_height += sign_in_button_space - if show_device_sign_in_button: - self._sub_height += sign_in_button_space if show_v2_proxy_sign_in_button: self._sub_height += sign_in_button_space + if show_device_sign_in_button: + self._sub_height += sign_in_button_space + deprecated_space if show_game_service_button: self._sub_height += game_service_button_space if show_linked_accounts_text: @@ -391,6 +393,8 @@ class AccountSettingsWindow(ba.Window): self._sub_height += link_accounts_button_space if show_unlink_accounts_button: self._sub_height += unlink_accounts_button_space + if show_v2_link_info: + self._sub_height += v2_link_info_space if show_sign_out_button: self._sub_height += sign_out_button_space if show_cancel_sign_in_button: @@ -625,7 +629,7 @@ class AccountSettingsWindow(ba.Window): if show_device_sign_in_button: button_width = 350 - v -= sign_in_button_space + v -= sign_in_button_space + deprecated_space self._sign_in_device_button = btn = ba.buttonwidget( parent=self._subcontainer, position=((self._sub_width - button_width) * 0.5, v - 20), @@ -634,6 +638,18 @@ class AccountSettingsWindow(ba.Window): label='', on_activate_call=lambda: self._sign_in_press('Local'), ) + ba.textwidget( + parent=self._subcontainer, + h_align='center', + v_align='center', + size=(0, 0), + position=(self._sub_width * 0.5, v + 60), + text=ba.Lstr(resource='deprecatedText'), + scale=0.8, + maxwidth=300, + color=(0.6, 0.55, 0.45), + ) + ba.textwidget( parent=self._subcontainer, draw_controller=btn, @@ -926,6 +942,7 @@ class AccountSettingsWindow(ba.Window): scale=0.9, color=(0.75, 0.7, 0.8), maxwidth=self._sub_width * 0.95, + text=ba.Lstr(resource=self._r + '.linkedAccountsText'), h_align='center', v_align='center', ) @@ -934,6 +951,8 @@ class AccountSettingsWindow(ba.Window): else: self._linked_accounts_text = None + # Show link/unlink buttons only for V1 accounts. + if show_link_accounts_button: v -= link_accounts_button_space self._link_accounts_button = btn = ba.buttonwidget( @@ -1013,6 +1032,21 @@ class AccountSettingsWindow(ba.Window): else: self._unlink_accounts_button = None + if show_v2_link_info: + v -= v2_link_info_space + ba.textwidget( + parent=self._subcontainer, + h_align='center', + v_align='center', + size=(0, 0), + position=(self._sub_width * 0.5, v + v2_link_info_space - 20), + text=ba.Lstr(resource='v2AccountLinkingInfoText'), + flatness=1.0, + scale=0.8, + maxwidth=450, + color=(0.5, 0.45, 0.55), + ) + if show_sign_out_button: v -= sign_out_button_space self._sign_out_button = btn = ba.buttonwidget( @@ -1144,6 +1178,14 @@ class AccountSettingsWindow(ba.Window): if self._linked_accounts_text is None: return + # Disable this by default when signed in to a V2 account + # (since this shows V1 links which we should no longer care about). + if ( + ba.app.accounts_v2.primary is not None + and not FORCE_ENABLE_V1_LINKING + ): + return + # if this is not present, we haven't had contact from the server so # let's not proceed.. if ba.internal.get_public_login_id() is None: @@ -1153,13 +1195,9 @@ class AccountSettingsWindow(ba.Window): accounts = ba.internal.get_v1_account_misc_read_val_2( 'linkedAccounts', [] ) - # our_account = _bs.get_v1_account_display_string() - # accounts = [a for a in accounts if a != our_account] - # accounts_str = u', '.join(accounts) if accounts else - # ba.Lstr(translate=('settingNames', 'None')) # UPDATE - we now just print the number here; not the actual - # accounts - # (they can see that in the unlink section if they're curious) + # accounts (they can see that in the unlink section if they're + # curious) accounts_str = str(max(0, len(accounts) - 1)) ba.textwidget( edit=self._linked_accounts_text, From 60b1d0306a23df69c050d8b63ebdd8da907c29d0 Mon Sep 17 00:00:00 2001 From: Eric Date: Tue, 29 Nov 2022 16:38:32 -0800 Subject: [PATCH 04/26] tidying --- .efrocachemap | 72 +++++++++---------- CHANGELOG.md | 2 +- assets/src/ba_data/python/._ba_sources_hash | 2 +- assets/src/ba_data/python/ba/_bootstrap.py | 2 +- ballisticacore-cmake/CMakeLists.txt | 1 - .../Generic/BallisticaCoreGeneric.vcxproj | 1 - .../BallisticaCoreGeneric.vcxproj.filters | 3 - .../Headless/BallisticaCoreHeadless.vcxproj | 1 - .../BallisticaCoreHeadless.vcxproj.filters | 3 - src/ballistica/ballistica.cc | 2 +- src/ballistica/core/types.h | 1 - src/ballistica/logic/friend_score_set.h | 30 -------- src/ballistica/logic/logic.cc | 6 -- src/ballistica/logic/logic.h | 1 - src/ballistica/platform/platform.cc | 1 - src/ballistica/python/python.cc | 35 --------- src/ballistica/python/python.h | 1 - tools/efro/rpc.py | 3 +- 18 files changed, 42 insertions(+), 125 deletions(-) delete mode 100644 src/ballistica/logic/friend_score_set.h diff --git a/.efrocachemap b/.efrocachemap index 4fc2d2b2..8f0e8722 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/8d/26/6c0bd3ce52765637e83231d6fde1", - "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/3b/7e/b7ef105fa0357b0d362603f129fc", - "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/bf/6e/2ca7479c1feebbcd15554bebeea0", - "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/78/00/bb8ae54341023805cf0f280b9155", - "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/42/f5/b91d0ec0f98b50673ef913c7bc8e", - "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/30/fa/9ad8555e93ee445f8154c5330b11", - "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/9e/b9/8d1dede802b852454a3124cae881", - "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/8b/29/897ddf43f01868170b3a82cd7b90", - "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/63/ea/a6a99f8bf6de4997d0ee80f5c469", - "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/4e/9c/e7dca964568c7588765616b7c543", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/85/a3/79df52e6a0487a63305259fa0c1a", - "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/e1/86/353b3402cd2fee04136b0e679838", - "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/8c/a7/0e58c80115b868c92d09807ca8cb", - "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/30/0b/a53e1fd065417789f1d6ab4bbf41", - "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/a1/d0/e93c6de7d8a64b6427a9a9b76d5d", - "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/f2/64/40913c4d98b3614bf459ecbac060", - "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/d3/29/70461e83a0f10150b4dec3829f51", - "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/a8/8b/bdc933ac2015eb3cc259e83c26fa", - "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/17/8f/6b5134c9c89d09866da1c52a8e20", - "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/aa/8e/4e97eb4e5f1c20ca52c2b8b255dc", - "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/2f/98/0f10aa690341351b047d9dc3fe65", + "build/prefab/full/linux_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/08/44/a5f87c9250077aaa171cea27db18", + "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/c6/e1/938043bce1342a4166964c55931f", + "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/29/dd/0468d50927fc6b2e407328f91956", + "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/49/f4/cc2b8ad8725827b569272148f6b7", + "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/26/12/e5cb20be2bab9833b1f1d848d9fb", + "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/f1/bd/c86f032265760dc16606f3778a2d", + "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/58/f6/9864b4ab5bbad1f1610d03028f1b", + "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/fb/a3/d547e96bd36ce3d3d4b8af9b782d", + "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/af/74/f32e207555fe7a4c24c798aa295d", + "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/cb/d4/b160011cc796371010241a38b859", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/2d/05/bd94b7d8854b18bf603823d08589", + "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/16/f8/80de6f8f602cac3a65cff1362011", + "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/30/34/4e940a7f4b569deb69a65e275334", + "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/fb/95/e848148af57de2607e4961612a29", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/9a/4d/5fe0983397557b61673124ec7237", + "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/2b/aa/6c86d675fbd55004e7a494a5d194", + "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/87/1b/f28c7759ca1664903bcb58f47c48", + "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/31/c0/21f4c6d231bd31d38c0015c5949a", + "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/93/60/22f3159334837527f5349657be51", + "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/df/2f/a371987b1d72aecf0197de973f8d", + "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/c1/71/ff78dcc2d1079c1befb3909f88b6", "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/14/aa/d9e350323ed97ca2c87667c569bb", - "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/64/a9/03eb8d0e32bf35b10941eb8ca082", + "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/c1/cc/f5ed9c6f03949851eaa5d2cd7aeb", "build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/52/2a/31fb94be0f4f5e9ded5a100e298d", - "build/prefab/lib/linux_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a0/dc/5479a3f5499236fd0b72cbec5c9b", + "build/prefab/lib/linux_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ee/9f/7287e695504ed86e890d5472935e", "build/prefab/lib/linux_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/41/6b/175b26bc4b4429aac713d4cc3c20", - "build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/e0/5c/5a5c6cbd883cba37f31d991722fe", + "build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/2e/7b/a1cd21de67736957e7b2f7550b6f", "build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/81/bb/51740409b1cf442d8beed60f759c", - "build/prefab/lib/mac_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a2/7d/c630ea8a7975c3502cbd3ee6716f", + "build/prefab/lib/mac_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/55/87/933974be0293a51749aa38afb90c", "build/prefab/lib/mac_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/44/66/a2d065477f9677a2b869c5ebc0a9", - "build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/8d/5e/335032c7fc26a8026db29b0bb1f0", + "build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a8/f7/4bbfc5478309ad97d056ba16f8d0", "build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/26/94/73a12ae50fe3750547ce218f3857", - "build/prefab/lib/mac_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/9a/77/a3607ad916ab9d0327cdd61800c5", + "build/prefab/lib/mac_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/b1/ff/d2d2fc01c67baac72281783d38d6", "build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/9d/ac/b2dd3b8a8b231210f19b0ec30299", - "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a6/cd/4b2cb9cbb7a617e408006f2eba7e", + "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/3e/37/1926c5062ca3589cf1d7c49bebff", "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/9e/f7/cadeae6e408cabe57d9e1cf782d6", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/0a/c3/b0d1aa43e3e66de3c213b7fda5f1", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/3f/39/fb44f0b1907cc8a9def711f90488", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/56/d5/e469a881eacc313ac6ca5e48c450", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/81/f9/ffcebd4dc6f76392516644b04978", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/75/e2/2e4066c5bc8e429723169e8d0ca2", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/9c/b9/1702985e444ba529f8adcb933039", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/76/ab/cb3cfe64a3a8b976fc15166a7878", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/81/c4/b3845fc3fabd2bd3d997685e63f7", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/92/71/0e497882534506d4636784f83e41", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/65/87/f08f5ba3e4e91cc1bba8eb135c08", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/9d/80/5b8bbe6321375a34b2e42a07c603", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/77/2a/84887c5ed3a5b427a3cbd928e5f0", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/15/8b/8b1a60b721c13d693f8beec3c707", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/08/65/feb0f30e3f4bcdfa0576cededab1", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/b9/21/6a24928df840f9881a91469b07cc", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/e0/36/952c3f268d5d2ddb8b1acf83436e", "src/ballistica/generated/python_embedded/binding.inc": "https://files.ballistica.net/cache/ba1/25/77/8093dfffddaa80cd513ddaa61867", "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/CHANGELOG.md b/CHANGELOG.md index c887bc08..48347e44 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -### 1.7.14 (build 20943, api 7, 2022-11-29) +### 1.7.14 (build 20944, api 7, 2022-11-29) - Android Google Play logins now provide V2 accounts with access to all V2 features such as a globally-unique account tag, cloud-console, and workspaces. They should still retain their V1 data as well. - V2 accounts now have a 'Manage Account' button in the app account window which will sign you into a browser with your current account. - Removed Google App Invite functionality which has been deprecated for a while now. Google Play users can still get tickets by sharing the app via codes (same as other platforms). diff --git a/assets/src/ba_data/python/._ba_sources_hash b/assets/src/ba_data/python/._ba_sources_hash index 3c92f5a5..121cc8c6 100644 --- a/assets/src/ba_data/python/._ba_sources_hash +++ b/assets/src/ba_data/python/._ba_sources_hash @@ -1 +1 @@ -199621046220623727886241861967391185247 \ No newline at end of file +313825873705357186590048512620581045590 \ No newline at end of file diff --git a/assets/src/ba_data/python/ba/_bootstrap.py b/assets/src/ba_data/python/ba/_bootstrap.py index 5aef6f3c..f877b79c 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 = 20943 + expected_build = 20944 running_build: int = env['build_number'] if running_build != expected_build: print( diff --git a/ballisticacore-cmake/CMakeLists.txt b/ballisticacore-cmake/CMakeLists.txt index 77deaf38..4b79cb15 100644 --- a/ballisticacore-cmake/CMakeLists.txt +++ b/ballisticacore-cmake/CMakeLists.txt @@ -464,7 +464,6 @@ add_executable(ballisticacore ${BA_SRC_ROOT}/ballistica/logic/connection/connection_to_host.h ${BA_SRC_ROOT}/ballistica/logic/connection/connection_to_host_udp.cc ${BA_SRC_ROOT}/ballistica/logic/connection/connection_to_host_udp.h - ${BA_SRC_ROOT}/ballistica/logic/friend_score_set.h ${BA_SRC_ROOT}/ballistica/logic/host_activity.cc ${BA_SRC_ROOT}/ballistica/logic/host_activity.h ${BA_SRC_ROOT}/ballistica/logic/logic.cc diff --git a/ballisticacore-windows/Generic/BallisticaCoreGeneric.vcxproj b/ballisticacore-windows/Generic/BallisticaCoreGeneric.vcxproj index 8f4b7c5a..18e36464 100644 --- a/ballisticacore-windows/Generic/BallisticaCoreGeneric.vcxproj +++ b/ballisticacore-windows/Generic/BallisticaCoreGeneric.vcxproj @@ -455,7 +455,6 @@ - diff --git a/ballisticacore-windows/Generic/BallisticaCoreGeneric.vcxproj.filters b/ballisticacore-windows/Generic/BallisticaCoreGeneric.vcxproj.filters index 4430ba75..75bed1a1 100644 --- a/ballisticacore-windows/Generic/BallisticaCoreGeneric.vcxproj.filters +++ b/ballisticacore-windows/Generic/BallisticaCoreGeneric.vcxproj.filters @@ -799,9 +799,6 @@ ballistica\logic\connection - - ballistica\logic - ballistica\logic diff --git a/ballisticacore-windows/Headless/BallisticaCoreHeadless.vcxproj b/ballisticacore-windows/Headless/BallisticaCoreHeadless.vcxproj index f1654fcf..78353bdb 100644 --- a/ballisticacore-windows/Headless/BallisticaCoreHeadless.vcxproj +++ b/ballisticacore-windows/Headless/BallisticaCoreHeadless.vcxproj @@ -450,7 +450,6 @@ - diff --git a/ballisticacore-windows/Headless/BallisticaCoreHeadless.vcxproj.filters b/ballisticacore-windows/Headless/BallisticaCoreHeadless.vcxproj.filters index 4430ba75..75bed1a1 100644 --- a/ballisticacore-windows/Headless/BallisticaCoreHeadless.vcxproj.filters +++ b/ballisticacore-windows/Headless/BallisticaCoreHeadless.vcxproj.filters @@ -799,9 +799,6 @@ ballistica\logic\connection - - ballistica\logic - ballistica\logic diff --git a/src/ballistica/ballistica.cc b/src/ballistica/ballistica.cc index d7b1b79c..d524e081 100644 --- a/src/ballistica/ballistica.cc +++ b/src/ballistica/ballistica.cc @@ -32,7 +32,7 @@ namespace ballistica { // These are set automatically via script; don't modify them here. -const int kAppBuildNumber = 20943; +const int kAppBuildNumber = 20944; const char* kAppVersion = "1.7.14"; // Our standalone globals. diff --git a/src/ballistica/core/types.h b/src/ballistica/core/types.h index 663d0ad9..956d63f8 100644 --- a/src/ballistica/core/types.h +++ b/src/ballistica/core/types.h @@ -80,7 +80,6 @@ class Data; class DataData; class Dynamics; class FrameDef; -struct FriendScoreSet; class GLContext; class GlobalsNode; class Graphics; diff --git a/src/ballistica/logic/friend_score_set.h b/src/ballistica/logic/friend_score_set.h deleted file mode 100644 index e90dd619..00000000 --- a/src/ballistica/logic/friend_score_set.h +++ /dev/null @@ -1,30 +0,0 @@ -// Released under the MIT License. See LICENSE for details. - -#ifndef BALLISTICA_LOGIC_FRIEND_SCORE_SET_H_ -#define BALLISTICA_LOGIC_FRIEND_SCORE_SET_H_ - -#include -#include -#include - -namespace ballistica { - -// Used by game-center/etc when reporting friend scores to the game. -struct FriendScoreSet { - FriendScoreSet(bool success, void* user_data) - : success(success), user_data(user_data) {} - struct Entry { - Entry(int score, std::string name, bool is_me) - : score(score), name(std::move(name)), is_me(is_me) {} - int score; - std::string name; - bool is_me; - }; - std::list entries; - bool success; - void* user_data; -}; - -} // namespace ballistica - -#endif // BALLISTICA_LOGIC_FRIEND_SCORE_SET_H_ diff --git a/src/ballistica/logic/logic.cc b/src/ballistica/logic/logic.cc index 7e43bc65..8ac784af 100644 --- a/src/ballistica/logic/logic.cc +++ b/src/ballistica/logic/logic.cc @@ -19,7 +19,6 @@ #include "ballistica/logic/connection/connection_set.h" #include "ballistica/logic/connection/connection_to_client_udp.h" #include "ballistica/logic/connection/connection_to_host_udp.h" -#include "ballistica/logic/friend_score_set.h" #include "ballistica/logic/host_activity.h" #include "ballistica/logic/player.h" #include "ballistica/logic/session/client_session.h" @@ -1138,11 +1137,6 @@ void Logic::PushPlaySoundCall(SystemSoundID sound) { [sound] { g_audio->PlaySound(g_assets->GetSound(sound)); }); } -void Logic::PushFriendScoreSetCall(const FriendScoreSet& score_set) { - thread()->PushCall( - [score_set] { g_python->HandleFriendScoresCB(score_set); }); -} - void Logic::PushConfirmQuitCall() { thread()->PushCall([this] { assert(InLogicThread()); diff --git a/src/ballistica/logic/logic.h b/src/ballistica/logic/logic.h index 5a5c0bfa..1baa65d0 100644 --- a/src/ballistica/logic/logic.h +++ b/src/ballistica/logic/logic.h @@ -88,7 +88,6 @@ class Logic { auto PushConfirmQuitCall() -> void; auto PushStringEditSetCall(const std::string& value) -> void; auto PushStringEditCancelCall() -> void; - auto PushFriendScoreSetCall(const FriendScoreSet& score_set) -> void; auto PushShowURLCall(const std::string& url) -> void; auto PushOnAppResumeCall() -> void; auto PushFrameDefRequest() -> void; diff --git a/src/ballistica/platform/platform.cc b/src/ballistica/platform/platform.cc index 31abfccb..0bdb8a89 100644 --- a/src/ballistica/platform/platform.cc +++ b/src/ballistica/platform/platform.cc @@ -28,7 +28,6 @@ #include "ballistica/graphics/mesh/sprite_mesh.h" #include "ballistica/graphics/vr_graphics.h" #include "ballistica/input/input.h" -#include "ballistica/logic/friend_score_set.h" #include "ballistica/logic/logic.h" #include "ballistica/networking/networking_sys.h" #include "ballistica/platform/sdl/sdl_app.h" diff --git a/src/ballistica/python/python.cc b/src/ballistica/python/python.cc index 4ca762fe..4d2c57cc 100644 --- a/src/ballistica/python/python.cc +++ b/src/ballistica/python/python.cc @@ -14,7 +14,6 @@ #include "ballistica/input/device/joystick.h" #include "ballistica/input/device/keyboard_input.h" #include "ballistica/internal/app_internal.h" -#include "ballistica/logic/friend_score_set.h" #include "ballistica/logic/host_activity.h" #include "ballistica/logic/player.h" #include "ballistica/logic/v1_account.h" @@ -2144,40 +2143,6 @@ void Python::CaptureKeyboardInput(PyObject* obj) { } void Python::ReleaseKeyboardInput() { keyboard_call_.Release(); } -void Python::HandleFriendScoresCB(const FriendScoreSet& score_set) { - // This is the initial strong-ref to this pointer - // so it will be cleaned up properly. - Object::Ref cb( - static_cast(score_set.user_data)); - - // We pass None on error. - if (!score_set.success) { - PythonRef args(Py_BuildValue("(O)", Py_None), PythonRef::kSteal); - cb->Run(args); - } else { - // Otherwise convert it to a python list and pass that. - PyObject* py_list = PyList_New(0); - std::string icon_str; -#if BA_USE_GOOGLE_PLAY_GAME_SERVICES - icon_str = g_logic->CharStr(SpecialChar::kGooglePlayGamesLogo); -#elif BA_USE_GAME_CIRCLE - icon_str = g_logic->CharStr(SpecialChar::kGameCircleLogo); -#elif BA_USE_GAME_CENTER - icon_str = g_logic->CharStr(SpecialChar::kGameCenterLogo); -#endif - for (auto&& i : score_set.entries) { - PyObject* obj = - Py_BuildValue("[isi]", i.score, (icon_str + i.name).c_str(), - static_cast(i.is_me)); - PyList_Append(py_list, obj); - Py_DECREF(obj); - } - PythonRef args(Py_BuildValue("(O)", py_list), PythonRef::kSteal); - Py_DECREF(py_list); - cb->Run(args); - } -} - auto Python::HandleKeyPressEvent(const SDL_Keysym& keysym) -> bool { assert(InLogicThread()); if (!keyboard_call_.exists()) { diff --git a/src/ballistica/python/python.h b/src/ballistica/python/python.h index 284e589f..35df1fe0 100644 --- a/src/ballistica/python/python.h +++ b/src/ballistica/python/python.h @@ -114,7 +114,6 @@ class Python { auto ReleaseGamePadInput() -> void; auto CaptureKeyboardInput(PyObject* obj) -> void; auto ReleaseKeyboardInput() -> void; - auto HandleFriendScoresCB(const FriendScoreSet& ss) -> void; auto IssueCallInLogicThreadWarning(PyObject* call) -> void; /// Borrowed from python's source code: used in overriding of objects' dir() diff --git a/tools/efro/rpc.py b/tools/efro/rpc.py index c6412bfd..4fe7e639 100644 --- a/tools/efro/rpc.py +++ b/tools/efro/rpc.py @@ -628,7 +628,8 @@ class RPCEndpoint: # Now just sit and handle stuff as it comes in. while True: - assert not self._closing + if self._closing: + return # Read message type. mtype = _PacketType(await self._read_int_8()) From 0cad87ae1d36a92784c09bd122b1fa3d6730d21c Mon Sep 17 00:00:00 2001 From: Eric Date: Thu, 1 Dec 2022 14:40:46 -0800 Subject: [PATCH 05/26] minor bug fixes and polishing --- .efrocachemap | 108 ++++++++--------- CHANGELOG.md | 3 +- assets/.asset_manifest_public.json | 2 + assets/Makefile | 2 + assets/src/ba_data/python/ba/_accountv2.py | 30 +++-- assets/src/ba_data/python/ba/_bootstrap.py | 2 +- assets/src/ba_data/python/ba/_login.py | 12 +- .../python/bastd/ui/account/settings.py | 9 +- .../src/ba_data/python/bastd/ui/v2upgrade.py | 111 ++++++++++++++++++ src/ballistica/ballistica.cc | 2 +- src/ballistica/core/thread.cc | 37 ++++-- src/ballistica/core/thread.h | 3 +- 12 files changed, 236 insertions(+), 85 deletions(-) create mode 100644 assets/src/ba_data/python/bastd/ui/v2upgrade.py diff --git a/.efrocachemap b/.efrocachemap index 8f0e8722..a7a574be 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -420,39 +420,39 @@ "assets/build/ba_data/audio/zoeOw.ogg": "https://files.ballistica.net/cache/ba1/60/ad/38269b7f1c7dc20cb9a506cd0681", "assets/build/ba_data/audio/zoePickup01.ogg": "https://files.ballistica.net/cache/ba1/72/85/d6fc4d16b7081d91fba2850b5b10", "assets/build/ba_data/audio/zoeScream01.ogg": "https://files.ballistica.net/cache/ba1/e9/ae/1d674d0c086eaa0bd1c3b1db0505", - "assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/c1/58/545feb14ab42361ee0eacce7a1e7", + "assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/46/74/5bd691984b02c1fe036445eb5361", "assets/build/ba_data/data/languages/arabic.json": "https://files.ballistica.net/cache/ba1/b0/05/e530acaba539f040ce61e22561dc", "assets/build/ba_data/data/languages/belarussian.json": "https://files.ballistica.net/cache/ba1/61/03/89070ca765e06da3a419a579f503", - "assets/build/ba_data/data/languages/chinese.json": "https://files.ballistica.net/cache/ba1/05/87/d3e03edbc59eb7e7da7ef8b17134", - "assets/build/ba_data/data/languages/chinesetraditional.json": "https://files.ballistica.net/cache/ba1/12/12/b39bec3a244399223b45f084e0b2", + "assets/build/ba_data/data/languages/chinese.json": "https://files.ballistica.net/cache/ba1/d3/84/5e7df03070af059070ad1bd93cee", + "assets/build/ba_data/data/languages/chinesetraditional.json": "https://files.ballistica.net/cache/ba1/c2/a4/993d5f0f30d0670d7053466929b6", "assets/build/ba_data/data/languages/croatian.json": "https://files.ballistica.net/cache/ba1/c9/73/01a1343af814131b1ee96af0b687", "assets/build/ba_data/data/languages/czech.json": "https://files.ballistica.net/cache/ba1/cb/df/f2d54d3146a159c678a47d3ff01b", "assets/build/ba_data/data/languages/danish.json": "https://files.ballistica.net/cache/ba1/6a/fa/fcf4a804beaff927b0f12c179eaa", "assets/build/ba_data/data/languages/dutch.json": "https://files.ballistica.net/cache/ba1/68/93/da8e9874f41a786edf52ba4ccaad", - "assets/build/ba_data/data/languages/english.json": "https://files.ballistica.net/cache/ba1/52/2a/3e6272799aba12af878dfd2eea15", + "assets/build/ba_data/data/languages/english.json": "https://files.ballistica.net/cache/ba1/91/8c/67fb1ca2b8f256f133950b41ba2c", "assets/build/ba_data/data/languages/esperanto.json": "https://files.ballistica.net/cache/ba1/ac/f5/c0922a99e40dfc9f5e026d43b533", "assets/build/ba_data/data/languages/filipino.json": "https://files.ballistica.net/cache/ba1/86/26/060476f46994c035ae0d52640657", "assets/build/ba_data/data/languages/french.json": "https://files.ballistica.net/cache/ba1/c7/cf/35a6ebc876c7476b72547a914d07", "assets/build/ba_data/data/languages/german.json": "https://files.ballistica.net/cache/ba1/06/58/071d6f7bbb5e93a3e074dbd323ae", - "assets/build/ba_data/data/languages/gibberish.json": "https://files.ballistica.net/cache/ba1/e7/f2/9cf56bec9e4312c7b547e42477ea", + "assets/build/ba_data/data/languages/gibberish.json": "https://files.ballistica.net/cache/ba1/45/e1/32cc8660b71d3d6b5fe1faff694d", "assets/build/ba_data/data/languages/greek.json": "https://files.ballistica.net/cache/ba1/ae/89/47486b987d14f58b6cf2d665ce4b", "assets/build/ba_data/data/languages/hindi.json": "https://files.ballistica.net/cache/ba1/9f/df/469e166c6a0d42bca4baae3a6cb6", "assets/build/ba_data/data/languages/hungarian.json": "https://files.ballistica.net/cache/ba1/b2/81/53c8cd7617d649403e539c3a6171", - "assets/build/ba_data/data/languages/indonesian.json": "https://files.ballistica.net/cache/ba1/ae/64/97ed10eed5f31b33864d90368330", + "assets/build/ba_data/data/languages/indonesian.json": "https://files.ballistica.net/cache/ba1/18/36/799b6271fe8cb0e73b2eabb7f400", "assets/build/ba_data/data/languages/italian.json": "https://files.ballistica.net/cache/ba1/5f/b2/b9301d67bef699a092a4c04dd522", "assets/build/ba_data/data/languages/korean.json": "https://files.ballistica.net/cache/ba1/7c/38/d4a44c481757d355836f292ede48", "assets/build/ba_data/data/languages/persian.json": "https://files.ballistica.net/cache/ba1/cd/ed/4d6d0778d256ccc0ff2e27b970c6", "assets/build/ba_data/data/languages/polish.json": "https://files.ballistica.net/cache/ba1/67/93/372c2a2428a830056e9ba22bbf95", - "assets/build/ba_data/data/languages/portuguese.json": "https://files.ballistica.net/cache/ba1/01/6f/516598d76c29b2fa45ff351426dc", + "assets/build/ba_data/data/languages/portuguese.json": "https://files.ballistica.net/cache/ba1/c5/d4/f933bd3d80ded2b6ac2ea1af6eb2", "assets/build/ba_data/data/languages/romanian.json": "https://files.ballistica.net/cache/ba1/d7/06/9d70642d0a4d1e3b1c2149d7a17c", - "assets/build/ba_data/data/languages/russian.json": "https://files.ballistica.net/cache/ba1/05/fb/a05a110238d0da5f902d06e5daa7", + "assets/build/ba_data/data/languages/russian.json": "https://files.ballistica.net/cache/ba1/6e/c3/df824198c6fe2da6ace053d30641", "assets/build/ba_data/data/languages/serbian.json": "https://files.ballistica.net/cache/ba1/4e/91/6f2a9a3ce733908e91377a6ddb9a", "assets/build/ba_data/data/languages/slovak.json": "https://files.ballistica.net/cache/ba1/20/a9/163d189884edf802636bf291e432", - "assets/build/ba_data/data/languages/spanish.json": "https://files.ballistica.net/cache/ba1/c9/48/63093604be4e04447974b9e6337d", + "assets/build/ba_data/data/languages/spanish.json": "https://files.ballistica.net/cache/ba1/6d/b7/dfc80f923378a408010cf4ee627a", "assets/build/ba_data/data/languages/swedish.json": "https://files.ballistica.net/cache/ba1/91/0a/35c4baf539d5951fc03a794c0e0b", "assets/build/ba_data/data/languages/tamil.json": "https://files.ballistica.net/cache/ba1/2b/25/aa93983666b88d1c584f06b742b0", "assets/build/ba_data/data/languages/thai.json": "https://files.ballistica.net/cache/ba1/f7/df/7ba5f99c5c2c4c86fc0503fcf0b7", - "assets/build/ba_data/data/languages/turkish.json": "https://files.ballistica.net/cache/ba1/bb/f5/0eb74375f3c9ea827b73c67f4a25", + "assets/build/ba_data/data/languages/turkish.json": "https://files.ballistica.net/cache/ba1/b5/e8/606f6d3dc1f4bffc96128abaef03", "assets/build/ba_data/data/languages/ukrainian.json": "https://files.ballistica.net/cache/ba1/1b/83/844f9e6f4e9e47a2d788d3faa9d2", "assets/build/ba_data/data/languages/venetian.json": "https://files.ballistica.net/cache/ba1/17/15/973f4101bf2264173bd1c1729426", "assets/build/ba_data/data/languages/vietnamese.json": "https://files.ballistica.net/cache/ba1/1f/ae/abe3f105b3c4b51f6b7942773305", @@ -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/08/44/a5f87c9250077aaa171cea27db18", - "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/c6/e1/938043bce1342a4166964c55931f", - "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/29/dd/0468d50927fc6b2e407328f91956", - "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/49/f4/cc2b8ad8725827b569272148f6b7", - "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/26/12/e5cb20be2bab9833b1f1d848d9fb", - "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/f1/bd/c86f032265760dc16606f3778a2d", - "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/58/f6/9864b4ab5bbad1f1610d03028f1b", - "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/fb/a3/d547e96bd36ce3d3d4b8af9b782d", - "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/af/74/f32e207555fe7a4c24c798aa295d", - "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/cb/d4/b160011cc796371010241a38b859", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/2d/05/bd94b7d8854b18bf603823d08589", - "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/16/f8/80de6f8f602cac3a65cff1362011", - "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/30/34/4e940a7f4b569deb69a65e275334", - "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/fb/95/e848148af57de2607e4961612a29", - "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/9a/4d/5fe0983397557b61673124ec7237", - "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/2b/aa/6c86d675fbd55004e7a494a5d194", - "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/87/1b/f28c7759ca1664903bcb58f47c48", - "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/31/c0/21f4c6d231bd31d38c0015c5949a", - "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/93/60/22f3159334837527f5349657be51", - "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/df/2f/a371987b1d72aecf0197de973f8d", - "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/c1/71/ff78dcc2d1079c1befb3909f88b6", - "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/14/aa/d9e350323ed97ca2c87667c569bb", - "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/c1/cc/f5ed9c6f03949851eaa5d2cd7aeb", - "build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/52/2a/31fb94be0f4f5e9ded5a100e298d", - "build/prefab/lib/linux_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ee/9f/7287e695504ed86e890d5472935e", - "build/prefab/lib/linux_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/41/6b/175b26bc4b4429aac713d4cc3c20", - "build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/2e/7b/a1cd21de67736957e7b2f7550b6f", - "build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/81/bb/51740409b1cf442d8beed60f759c", - "build/prefab/lib/mac_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/55/87/933974be0293a51749aa38afb90c", - "build/prefab/lib/mac_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/44/66/a2d065477f9677a2b869c5ebc0a9", - "build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a8/f7/4bbfc5478309ad97d056ba16f8d0", - "build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/26/94/73a12ae50fe3750547ce218f3857", - "build/prefab/lib/mac_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/b1/ff/d2d2fc01c67baac72281783d38d6", - "build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/9d/ac/b2dd3b8a8b231210f19b0ec30299", - "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/3e/37/1926c5062ca3589cf1d7c49bebff", - "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/9e/f7/cadeae6e408cabe57d9e1cf782d6", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/92/71/0e497882534506d4636784f83e41", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/65/87/f08f5ba3e4e91cc1bba8eb135c08", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/9d/80/5b8bbe6321375a34b2e42a07c603", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/77/2a/84887c5ed3a5b427a3cbd928e5f0", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/15/8b/8b1a60b721c13d693f8beec3c707", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/08/65/feb0f30e3f4bcdfa0576cededab1", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/b9/21/6a24928df840f9881a91469b07cc", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/e0/36/952c3f268d5d2ddb8b1acf83436e", + "build/prefab/full/linux_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/cf/52/f613c9b0d400e6a3cc46d1b10243", + "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/a2/a1/9bfcb44eed26b64ee45c10e71ebf", + "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/e4/6a/b6828e87838c864910769e10b082", + "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/15/1b/4b88f866b595f9aee3589fe61f22", + "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/b3/bd/61195ab2b707b27ced0b88aab751", + "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/3f/5f/15a89a2c8aabd42d6fd990dcef61", + "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/e1/a7/5c1fbf021cca742d3835b1b9ded8", + "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/1f/0d/b7ce6c28626235b46ed2f3b90d40", + "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/4d/67/34b91ed9e0236b4a5d5bfd72dfa9", + "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/bf/4a/e071a870261746f96a76f6dbb3c6", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/00/78/253923b1d2bd27fac67351eb06cd", + "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/ba/8d/f11ab9ad9ebf7512c5b7d8b35a6f", + "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/38/bf/edf22880968b719327db7d8dd998", + "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/09/bf/758bd310a00cb749657149580e81", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/9c/95/5b9f366fff40806b7ee2062f7050", + "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/24/a7/35eb9753ebaa9e41bc87e8f27dc3", + "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/ab/c6/1b1576f9d2f767815f7519353bd4", + "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/5a/d4/d2896f57e07ee1cbb43877c174cd", + "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/30/e9/d0dbf1bf4886264f9fc51b54e419", + "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/dc/62/a75c243384728a69acfb273e91f7", + "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/1b/bc/4d8cc7c9807c8b7a02d67de95dba", + "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/10/e6/ccd40f2a83735c5da9193333cbf1", + "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/eb/3e/91f24852fb1766c9cf273e0952a6", + "build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/6f/64/c1cb80d0f007af1e7a7386281fc2", + "build/prefab/lib/linux_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/12/e5/ed36f54413a114c8d0762c2f57b1", + "build/prefab/lib/linux_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/2c/8c/1597a2fe945c36e76c375fa5e412", + "build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ce/28/61941473817cd934b21cc8447f4d", + "build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/18/e3/01ee52c5bb52687324ecd3bb3f78", + "build/prefab/lib/mac_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/3d/85/62176cf03dd0be0e11ec6ed56230", + "build/prefab/lib/mac_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/cf/62/7587a846e73295a7e12c66d0e19c", + "build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ff/43/3ff93b30de352362dde3a173db18", + "build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/5e/15/0279dbe76b979d494d69c03b0527", + "build/prefab/lib/mac_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/20/e6/7f97b816171100873578dfebc237", + "build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/da/75/32d072333f57926ed2b649b01543", + "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/17/c2/e334283a230cfe50e5d4da8c02d4", + "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/c4/41/6a346833e2193a05b339d596f3dc", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/62/4a/87bc0017df139dbbc0195be774f5", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/fd/44/5db285cf7fd3301cd46f944dab6d", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/2f/09/dedf1229e5fa5ab73cea4b8b575b", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/c8/3e/7f3ce434876f2992a4043f398073", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/ed/a7/2088ab8e7e0ceb2ea768370bb464", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/03/51/0d6c5b45b326d2d7d069f8b371fc", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/77/fe/4f0d3a4ac3f71e4b214c5c5e4cc9", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/42/ef/e9b23bd9661675f6a9ec2bd7745d", "src/ballistica/generated/python_embedded/binding.inc": "https://files.ballistica.net/cache/ba1/25/77/8093dfffddaa80cd513ddaa61867", "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/CHANGELOG.md b/CHANGELOG.md index 48347e44..23388791 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -### 1.7.14 (build 20944, api 7, 2022-11-29) +### 1.7.14 (build 20956, api 7, 2022-12-01) - Android Google Play logins now provide V2 accounts with access to all V2 features such as a globally-unique account tag, cloud-console, and workspaces. They should still retain their V1 data as well. - V2 accounts now have a 'Manage Account' button in the app account window which will sign you into a browser with your current account. - Removed Google App Invite functionality which has been deprecated for a while now. Google Play users can still get tickets by sharing the app via codes (same as other platforms). @@ -12,6 +12,7 @@ - Added `ba.internal.dump_tracebacks()` which can be used to dump the stack state of all Python threads after some delay. Useful for debugging deadlock; just call right before said deadlock occurs. Results will be logged on the next app launch if they cannot be immediately. - Fixed a low level event-loop issue that in some cases was preventing the Android version from properly pausing/resuming the app or managing connections while in the background. If you look at the devices section on ballistica.net you should now see your device disappear when you background the app and reappear when you foreground it. Please holler if not. - Device accounts are now marked as deprecated, and signing in with one now brings up an 'upgrade' UI which allows converting it to a V2 account. It is my hope to push the entire client ecosystem to V2 accounts as quickly as possible since trying to support both independent V1 accounts and V2 accounts is a substantial technical burden. +- Fixed an issue where Log calls made within `Thread::PushThreadMessage()` could result in deadlock. ### 1.7.13 (build 20919, api 7, 2022-11-03) - Android target-sdk has been updated to 33 (Android 13). Please holler if anything seems broken or is behaving differently than before on Android. diff --git a/assets/.asset_manifest_public.json b/assets/.asset_manifest_public.json index d6172785..895eda83 100644 --- a/assets/.asset_manifest_public.json +++ b/assets/.asset_manifest_public.json @@ -356,6 +356,7 @@ "ba_data/python/bastd/ui/__pycache__/tournamentscores.cpython-310.opt-1.pyc", "ba_data/python/bastd/ui/__pycache__/trophies.cpython-310.opt-1.pyc", "ba_data/python/bastd/ui/__pycache__/url.cpython-310.opt-1.pyc", + "ba_data/python/bastd/ui/__pycache__/v2upgrade.cpython-310.opt-1.pyc", "ba_data/python/bastd/ui/__pycache__/watch.cpython-310.opt-1.pyc", "ba_data/python/bastd/ui/account/__init__.py", "ba_data/python/bastd/ui/account/__pycache__/__init__.cpython-310.opt-1.pyc", @@ -514,6 +515,7 @@ "ba_data/python/bastd/ui/tournamentscores.py", "ba_data/python/bastd/ui/trophies.py", "ba_data/python/bastd/ui/url.py", + "ba_data/python/bastd/ui/v2upgrade.py", "ba_data/python/bastd/ui/watch.py", "ba_data/python/efro/__init__.py", "ba_data/python/efro/__pycache__/__init__.cpython-310.opt-1.pyc", diff --git a/assets/Makefile b/assets/Makefile index 63833361..e764adfc 100644 --- a/assets/Makefile +++ b/assets/Makefile @@ -381,6 +381,7 @@ SCRIPT_TARGETS_PY_PUBLIC = \ build/ba_data/python/bastd/ui/tournamentscores.py \ build/ba_data/python/bastd/ui/trophies.py \ build/ba_data/python/bastd/ui/url.py \ + build/ba_data/python/bastd/ui/v2upgrade.py \ build/ba_data/python/bastd/ui/watch.py \ build/server/ballisticacore_server.py @@ -633,6 +634,7 @@ SCRIPT_TARGETS_PYC_PUBLIC = \ build/ba_data/python/bastd/ui/__pycache__/tournamentscores.cpython-310.opt-1.pyc \ build/ba_data/python/bastd/ui/__pycache__/trophies.cpython-310.opt-1.pyc \ build/ba_data/python/bastd/ui/__pycache__/url.cpython-310.opt-1.pyc \ + build/ba_data/python/bastd/ui/__pycache__/v2upgrade.cpython-310.opt-1.pyc \ build/ba_data/python/bastd/ui/__pycache__/watch.cpython-310.opt-1.pyc \ build/server/__pycache__/ballisticacore_server.cpython-310.opt-1.pyc diff --git a/assets/src/ba_data/python/ba/_accountv2.py b/assets/src/ba_data/python/ba/_accountv2.py index 58d78149..f5fee480 100644 --- a/assets/src/ba_data/python/ba/_accountv2.py +++ b/assets/src/ba_data/python/ba/_accountv2.py @@ -9,6 +9,7 @@ import logging from typing import TYPE_CHECKING from efro.call import tpartial +from efro.error import CommunicationError from bacommon.login import LoginType import _ba @@ -336,18 +337,27 @@ class AccountV2Subsystem: del adapter # Unused. - # Make some noise on errors since the user knows a sign-in - # attempt is happening in this case. + # Make some noise on errors since the user knows + # a sign-in attempt is happening in this case. if isinstance(result, Exception): - logging.warning( - 'Error on explicit accountv2 sign in attempt.', exc_info=result - ) + # We expect the occasional communication errors; + # Log a full exception for anything else though. + if not isinstance(result, CommunicationError): + logging.warning( + 'Error on explicit accountv2 sign in attempt.', + exc_info=result, + ) with _ba.Context('ui'): _ba.screenmessage( Lstr(resource='internal.signInErrorText'), color=(1, 0, 0), ) _ba.playsound(_ba.getsound('error')) + + # Also I suppose we should sign them out in this case since + # it could be misleading to be still signed in with the old + # account. + _ba.app.accounts_v2.set_primary_credentials(None) return _ba.app.accounts_v2.set_primary_credentials(result.credentials) @@ -365,9 +375,13 @@ class AccountV2Subsystem: # Log errors but don't inform the user; they're not aware of this # attempt and ignorance is bliss. if isinstance(result, Exception): - logging.warning( - 'Error on implicit accountv2 sign in attempt.', exc_info=result - ) + # We expect the occasional communication errors; + # Log a full exception for anything else though. + if not isinstance(result, CommunicationError): + logging.warning( + 'Error on implicit accountv2 sign in attempt.', + exc_info=result, + ) return # If we're still connected and still not signed in, diff --git a/assets/src/ba_data/python/ba/_bootstrap.py b/assets/src/ba_data/python/ba/_bootstrap.py index f877b79c..9d058ae7 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 = 20944 + expected_build = 20956 running_build: int = env['build_number'] if running_build != expected_build: print( diff --git a/assets/src/ba_data/python/ba/_login.py b/assets/src/ba_data/python/ba/_login.py index 6e95216e..0ca4098e 100644 --- a/assets/src/ba_data/python/ba/_login.py +++ b/assets/src/ba_data/python/ba/_login.py @@ -174,7 +174,7 @@ class LoginAdapter: Call( result_cb, self, - RuntimeError('fetch-sign-in-token failed'), + RuntimeError('fetch-sign-in-token failed.'), ) ) return @@ -192,7 +192,6 @@ class LoginAdapter: def _got_sign_in_response( response: bacommon.cloud.SignInResponse | Exception, ) -> None: - # from ba._language import Lstr if isinstance(response, Exception): if DEBUG_LOG: @@ -202,10 +201,6 @@ class LoginAdapter: self.login_type.name, response, ) - # _ba.screenmessage( - # Lstr(resource='errorText'), color=(1, 0, 0) - # ) - # _ba.playsound(_ba.getsound('error')) _ba.pushcall(Call(result_cb, self, response)) else: if DEBUG_LOG: @@ -216,7 +211,10 @@ class LoginAdapter: ) if response.credentials is None: result2: LoginAdapter.SignInResult | Exception = ( - RuntimeError('No credentials returned.') + RuntimeError( + 'No credentials returned after' + ' submitting sign-in-token.' + ) ) else: result2 = self.SignInResult( diff --git a/assets/src/ba_data/python/bastd/ui/account/settings.py b/assets/src/ba_data/python/bastd/ui/account/settings.py index 7053b757..04d17a36 100644 --- a/assets/src/ba_data/python/bastd/ui/account/settings.py +++ b/assets/src/ba_data/python/bastd/ui/account/settings.py @@ -1118,8 +1118,7 @@ class AccountSettingsWindow(ba.Window): ) def _on_what_is_v2_press(self) -> None: - bamasteraddr = ba.internal.get_master_server_address(version=2) - ba.open_url(f'{bamasteraddr}/whatisv2') + show_what_is_v2_page() def _on_manage_account_press(self) -> None: ba.screenmessage(ba.Lstr(resource='oneMomentText')) @@ -1495,3 +1494,9 @@ class AccountSettingsWindow(ba.Window): ba.containerwidget(edit=self._root_widget, selected_child=sel) except Exception: ba.print_exception(f'Error restoring state for {self}.') + + +def show_what_is_v2_page() -> None: + """Show the webpage describing V2 accounts.""" + bamasteraddr = ba.internal.get_master_server_address(version=2) + ba.open_url(f'{bamasteraddr}/whatisv2') diff --git a/assets/src/ba_data/python/bastd/ui/v2upgrade.py b/assets/src/ba_data/python/bastd/ui/v2upgrade.py new file mode 100644 index 00000000..ed61e170 --- /dev/null +++ b/assets/src/ba_data/python/bastd/ui/v2upgrade.py @@ -0,0 +1,111 @@ +# Released under the MIT License. See LICENSE for details. +# +"""UI for upgrading V1 accounts to V2.""" + +from __future__ import annotations + +import ba +import ba.internal + + +class V2UpgradeWindow(ba.Window): + """A window presenting a URL to the user visually.""" + + def __init__(self, login_name: str, code: str): + from bastd.ui.account.settings import show_what_is_v2_page + + app = ba.app + uiscale = app.ui.uiscale + + self._code = code + + self._width = 700 + self._height = 270 + super().__init__( + root_widget=ba.containerwidget( + size=(self._width, self._height + 40), + transition='in_right', + scale=( + 1.25 + if uiscale is ba.UIScale.SMALL + else 1.25 + if uiscale is ba.UIScale.MEDIUM + else 1.25 + ), + ) + ) + ba.playsound(ba.getsound('error')) + + ba.textwidget( + parent=self._root_widget, + position=(self._width * 0.5, self._height - 46), + size=(0, 0), + color=ba.app.ui.title_color, + h_align='center', + v_align='center', + text=ba.Lstr( + resource='deviceAccountUpgradeText', + subs=[('${NAME}', login_name)], + ), + maxwidth=self._width * 0.95, + ) + ba.textwidget( + parent=self._root_widget, + position=(self._width * 0.5, 125), + size=(0, 0), + scale=0.8, + color=(0.7, 0.8, 0.7), + h_align='center', + v_align='center', + text=( + ba.charstr(ba.SpecialChar.LOCAL_ACCOUNT) + + login_name + + ' ----> ' + + ba.charstr(ba.SpecialChar.V2_LOGO) + + login_name + ), + maxwidth=self._width * 0.95, + ) + button_width = 200 + + cancel_button = ba.buttonwidget( + parent=self._root_widget, + position=(20, 25), + size=(button_width, 65), + autoselect=True, + label=ba.Lstr(resource='notNowText'), + on_activate_call=self._done, + ) + + _what_is_this_button = ba.buttonwidget( + parent=self._root_widget, + position=(self._width * 0.5 - button_width * 0.5, 25), + size=(button_width, 65), + autoselect=True, + label=ba.Lstr(resource='whatIsThisText'), + color=(0.55, 0.5, 0.6), + textcolor=(0.75, 0.7, 0.8), + on_activate_call=show_what_is_v2_page, + ) + + bamasteraddr = ba.internal.get_master_server_address(version=2) + upgrade_button = ba.buttonwidget( + parent=self._root_widget, + position=(self._width - button_width - 20, 25), + size=(button_width, 65), + autoselect=True, + label=ba.Lstr(resource='upgradeText'), + on_activate_call=ba.Call( + ba.open_url, + f'{bamasteraddr}/v2uda/{self._code}', + ), + ) + + ba.containerwidget( + edit=self._root_widget, + selected_child=upgrade_button, + cancel_button=cancel_button, + ) + + def _done(self) -> None: + ba.containerwidget(edit=self._root_widget, transition='out_left') diff --git a/src/ballistica/ballistica.cc b/src/ballistica/ballistica.cc index d524e081..7e901c60 100644 --- a/src/ballistica/ballistica.cc +++ b/src/ballistica/ballistica.cc @@ -32,7 +32,7 @@ namespace ballistica { // These are set automatically via script; don't modify them here. -const int kAppBuildNumber = 20944; +const int kAppBuildNumber = 20956; const char* kAppVersion = "1.7.14"; // Our standalone globals. diff --git a/src/ballistica/core/thread.cc b/src/ballistica/core/thread.cc index b9032ff3..c1fae4a8 100644 --- a/src/ballistica/core/thread.cc +++ b/src/ballistica/core/thread.cc @@ -433,15 +433,17 @@ Thread::~Thread() = default; #pragma clang diagnostic push #pragma ide diagnostic ignored "ConstantConditionsOC" -void Thread::LogThreadMessageTally() { +void Thread::LogThreadMessageTally( + std::vector>* log_entries) { // Prevent recursion. if (!writing_tally_) { writing_tally_ = true; std::unordered_map tally; - Log(LogLevel::kError, "Thread message tally (" + log_entries->emplace_back(std::make_pair( + LogLevel::kError, "Thread message tally (" + std::to_string(thread_messages_.size()) - + " in list):"); + + " in list):")); for (auto&& m : thread_messages_) { std::string s; switch (m.type) { @@ -475,8 +477,9 @@ void Thread::LogThreadMessageTally() { } int entry = 1; for (auto&& i : tally) { - Log(LogLevel::kError, " #" + std::to_string(entry++) + " (" - + std::to_string(i.second) + "x): " + i.first); + log_entries->emplace_back(std::make_pair( + LogLevel::kError, " #" + std::to_string(entry++) + " (" + + std::to_string(i.second) + "x): " + i.first)); } writing_tally_ = false; } @@ -484,6 +487,12 @@ void Thread::LogThreadMessageTally() { #pragma clang diagnostic pop void Thread::PushThreadMessage(const ThreadMessage& t) { + // We don't want to make log calls while holding this mutex; + // log calls acquire the GIL and if the GIL-holder (generally + // the logic thread) is trying to send a thread message to the + // thread doing the logging we would get deadlock. + // So tally up any logs and send them after. + std::vector> log_entries; { std::unique_lock lock(thread_message_mutex_); @@ -506,8 +515,9 @@ void Thread::PushThreadMessage(const ThreadMessage& t) { // Show count periodically. if ((std::this_thread::get_id() == g_app->main_thread_id) && foo > 100) { foo = 0; - Log(LogLevel::kInfo, - "MSG COUNT " + std::to_string(thread_messages_.size())); + log_entries.emplace_back(std::make_pair( + LogLevel::kInfo, + "MSG COUNT " + std::to_string(thread_messages_.size()))); } } @@ -515,9 +525,11 @@ void Thread::PushThreadMessage(const ThreadMessage& t) { static bool sent_error = false; if (!sent_error) { sent_error = true; - Log(LogLevel::kError, - "ThreadMessage list > 1000 in thread: " + GetCurrentThreadName()); - LogThreadMessageTally(); + log_entries.emplace_back(std::make_pair( + LogLevel::kError, + "ThreadMessage list > 1000 in thread: " + GetCurrentThreadName())); + + LogThreadMessageTally(&log_entries); } } @@ -531,6 +543,11 @@ void Thread::PushThreadMessage(const ThreadMessage& t) { // available. } thread_message_cv_.notify_all(); + + // Now log anything we accumulated safely outside of the locked section. + for (auto&& log_entry : log_entries) { + Log(log_entry.first, log_entry.second); + } } auto Thread::SetThreadsPaused(bool paused) -> void { diff --git a/src/ballistica/core/thread.h b/src/ballistica/core/thread.h index 7f16500f..a0c5c594 100644 --- a/src/ballistica/core/thread.h +++ b/src/ballistica/core/thread.h @@ -118,7 +118,8 @@ class Thread { auto SetInternalThreadName(const std::string& name) -> void; auto WaitForNextEvent(bool single_cycle) -> void; auto LoopUpkeep(bool once) -> void; - auto LogThreadMessageTally() -> void; + auto LogThreadMessageTally( + std::vector>* log_entries) -> void; auto PushLocalRunnable(Runnable* runnable, bool* completion_flag) -> void; auto PushCrossThreadRunnable(Runnable* runnable, bool* completion_flag) -> void; From 4248540d887340de25e47539fdf567525ae8918e Mon Sep 17 00:00:00 2001 From: Eric Date: Sat, 3 Dec 2022 11:41:33 -0800 Subject: [PATCH 06/26] v1.7.14 --- .efrocachemap | 40 +++++++++++----------- CHANGELOG.md | 2 +- assets/src/ba_data/python/ba/_bootstrap.py | 2 +- src/ballistica/ballistica.cc | 2 +- 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/.efrocachemap b/.efrocachemap index a7a574be..d097dcd6 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -4003,26 +4003,26 @@ "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/cf/52/f613c9b0d400e6a3cc46d1b10243", - "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/a2/a1/9bfcb44eed26b64ee45c10e71ebf", - "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/e4/6a/b6828e87838c864910769e10b082", - "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/15/1b/4b88f866b595f9aee3589fe61f22", - "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/b3/bd/61195ab2b707b27ced0b88aab751", - "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/3f/5f/15a89a2c8aabd42d6fd990dcef61", - "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/e1/a7/5c1fbf021cca742d3835b1b9ded8", - "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/1f/0d/b7ce6c28626235b46ed2f3b90d40", - "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/4d/67/34b91ed9e0236b4a5d5bfd72dfa9", - "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/bf/4a/e071a870261746f96a76f6dbb3c6", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/00/78/253923b1d2bd27fac67351eb06cd", - "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/ba/8d/f11ab9ad9ebf7512c5b7d8b35a6f", - "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/38/bf/edf22880968b719327db7d8dd998", - "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/09/bf/758bd310a00cb749657149580e81", - "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/9c/95/5b9f366fff40806b7ee2062f7050", - "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/24/a7/35eb9753ebaa9e41bc87e8f27dc3", - "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/ab/c6/1b1576f9d2f767815f7519353bd4", - "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/5a/d4/d2896f57e07ee1cbb43877c174cd", - "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/30/e9/d0dbf1bf4886264f9fc51b54e419", - "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/dc/62/a75c243384728a69acfb273e91f7", + "build/prefab/full/linux_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/df/a3/64ac7606c1bf9ce707dfd3114127", + "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/1f/70/a2d9b6e09c866dbc5f75974da183", + "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/e8/50/64bb044aef2d3d37da810602fe80", + "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/66/54/40159901988438140f6c879772da", + "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/91/65/6a36636f69dfdd76e0ffeb0e0f3a", + "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/8f/52/d5f181b1f444c44dbc9bf7a428dd", + "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/cb/db/d8e1d84660fb800de940d7283ac5", + "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/29/6e/d6238719cabbc11c7f20abc52966", + "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/55/6c/5aea38aadb0683b9baa1fd50e0c6", + "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/0b/2a/5059145781aa5b2747ba1b4c6e26", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/47/ff/7782c66aa8ecdef670e49afe9b3a", + "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/48/69/8d3c26a624375f5c7bc2dcbbf144", + "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/ff/a6/aa0afad6ea5a949908822b72716c", + "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/82/4f/d534d96e93f5d4d70ebf9f7d9c77", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/c1/e2/96e411b353287280f3315e7ac63d", + "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/1e/86/9580019dee2099862d0ecabc5aef", + "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/4a/c1/dbf6444578f666b5a8af954ac11c", + "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/fe/6e/1123e3b3d9359307c3eea6c071f3", + "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/02/43/6e56c1d135896956bc0ad874b398", + "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/e9/4f/da92e04a7a7a2cc2839b0d76d7a8", "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/1b/bc/4d8cc7c9807c8b7a02d67de95dba", "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/10/e6/ccd40f2a83735c5da9193333cbf1", "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/eb/3e/91f24852fb1766c9cf273e0952a6", diff --git a/CHANGELOG.md b/CHANGELOG.md index 23388791..0ca7b0c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -### 1.7.14 (build 20956, api 7, 2022-12-01) +### 1.7.14 (build 20957, api 7, 2022-12-03) - Android Google Play logins now provide V2 accounts with access to all V2 features such as a globally-unique account tag, cloud-console, and workspaces. They should still retain their V1 data as well. - V2 accounts now have a 'Manage Account' button in the app account window which will sign you into a browser with your current account. - Removed Google App Invite functionality which has been deprecated for a while now. Google Play users can still get tickets by sharing the app via codes (same as other platforms). diff --git a/assets/src/ba_data/python/ba/_bootstrap.py b/assets/src/ba_data/python/ba/_bootstrap.py index 9d058ae7..96c26654 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 = 20956 + expected_build = 20957 running_build: int = env['build_number'] if running_build != expected_build: print( diff --git a/src/ballistica/ballistica.cc b/src/ballistica/ballistica.cc index 7e901c60..7594d335 100644 --- a/src/ballistica/ballistica.cc +++ b/src/ballistica/ballistica.cc @@ -32,7 +32,7 @@ namespace ballistica { // These are set automatically via script; don't modify them here. -const int kAppBuildNumber = 20956; +const int kAppBuildNumber = 20957; const char* kAppVersion = "1.7.14"; // Our standalone globals. From 1e8ad4361dd1b367c2777357115234cf49057b49 Mon Sep 17 00:00:00 2001 From: Eric Date: Sun, 4 Dec 2022 12:07:14 -0800 Subject: [PATCH 07/26] version bump --- .efrocachemap | 106 ++++++++++----------- CHANGELOG.md | 4 +- assets/src/ba_data/python/ba/_bootstrap.py | 2 +- src/ballistica/ballistica.cc | 4 +- tools/efro/dataclassio/_base.py | 13 ++- tools/efrotools/ios.py | 1 + 6 files changed, 72 insertions(+), 58 deletions(-) diff --git a/.efrocachemap b/.efrocachemap index d097dcd6..efcf1ed1 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -420,7 +420,7 @@ "assets/build/ba_data/audio/zoeOw.ogg": "https://files.ballistica.net/cache/ba1/60/ad/38269b7f1c7dc20cb9a506cd0681", "assets/build/ba_data/audio/zoePickup01.ogg": "https://files.ballistica.net/cache/ba1/72/85/d6fc4d16b7081d91fba2850b5b10", "assets/build/ba_data/audio/zoeScream01.ogg": "https://files.ballistica.net/cache/ba1/e9/ae/1d674d0c086eaa0bd1c3b1db0505", - "assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/46/74/5bd691984b02c1fe036445eb5361", + "assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/65/39/48faf0cc1c930728f3bf2a25e52b", "assets/build/ba_data/data/languages/arabic.json": "https://files.ballistica.net/cache/ba1/b0/05/e530acaba539f040ce61e22561dc", "assets/build/ba_data/data/languages/belarussian.json": "https://files.ballistica.net/cache/ba1/61/03/89070ca765e06da3a419a579f503", "assets/build/ba_data/data/languages/chinese.json": "https://files.ballistica.net/cache/ba1/d3/84/5e7df03070af059070ad1bd93cee", @@ -435,26 +435,26 @@ "assets/build/ba_data/data/languages/french.json": "https://files.ballistica.net/cache/ba1/c7/cf/35a6ebc876c7476b72547a914d07", "assets/build/ba_data/data/languages/german.json": "https://files.ballistica.net/cache/ba1/06/58/071d6f7bbb5e93a3e074dbd323ae", "assets/build/ba_data/data/languages/gibberish.json": "https://files.ballistica.net/cache/ba1/45/e1/32cc8660b71d3d6b5fe1faff694d", - "assets/build/ba_data/data/languages/greek.json": "https://files.ballistica.net/cache/ba1/ae/89/47486b987d14f58b6cf2d665ce4b", + "assets/build/ba_data/data/languages/greek.json": "https://files.ballistica.net/cache/ba1/8a/82/392f2a4e0e6e5a5e367f19e49538", "assets/build/ba_data/data/languages/hindi.json": "https://files.ballistica.net/cache/ba1/9f/df/469e166c6a0d42bca4baae3a6cb6", "assets/build/ba_data/data/languages/hungarian.json": "https://files.ballistica.net/cache/ba1/b2/81/53c8cd7617d649403e539c3a6171", - "assets/build/ba_data/data/languages/indonesian.json": "https://files.ballistica.net/cache/ba1/18/36/799b6271fe8cb0e73b2eabb7f400", + "assets/build/ba_data/data/languages/indonesian.json": "https://files.ballistica.net/cache/ba1/38/74/88d1ed374207750c9a834cddb809", "assets/build/ba_data/data/languages/italian.json": "https://files.ballistica.net/cache/ba1/5f/b2/b9301d67bef699a092a4c04dd522", "assets/build/ba_data/data/languages/korean.json": "https://files.ballistica.net/cache/ba1/7c/38/d4a44c481757d355836f292ede48", "assets/build/ba_data/data/languages/persian.json": "https://files.ballistica.net/cache/ba1/cd/ed/4d6d0778d256ccc0ff2e27b970c6", "assets/build/ba_data/data/languages/polish.json": "https://files.ballistica.net/cache/ba1/67/93/372c2a2428a830056e9ba22bbf95", - "assets/build/ba_data/data/languages/portuguese.json": "https://files.ballistica.net/cache/ba1/c5/d4/f933bd3d80ded2b6ac2ea1af6eb2", + "assets/build/ba_data/data/languages/portuguese.json": "https://files.ballistica.net/cache/ba1/03/14/6b767289325368be52e24ed3a58a", "assets/build/ba_data/data/languages/romanian.json": "https://files.ballistica.net/cache/ba1/d7/06/9d70642d0a4d1e3b1c2149d7a17c", - "assets/build/ba_data/data/languages/russian.json": "https://files.ballistica.net/cache/ba1/6e/c3/df824198c6fe2da6ace053d30641", + "assets/build/ba_data/data/languages/russian.json": "https://files.ballistica.net/cache/ba1/34/2d/9cc17dbd2858e04d0616d1c65ffb", "assets/build/ba_data/data/languages/serbian.json": "https://files.ballistica.net/cache/ba1/4e/91/6f2a9a3ce733908e91377a6ddb9a", "assets/build/ba_data/data/languages/slovak.json": "https://files.ballistica.net/cache/ba1/20/a9/163d189884edf802636bf291e432", - "assets/build/ba_data/data/languages/spanish.json": "https://files.ballistica.net/cache/ba1/6d/b7/dfc80f923378a408010cf4ee627a", + "assets/build/ba_data/data/languages/spanish.json": "https://files.ballistica.net/cache/ba1/29/1e/1c9666647b48f9c37d8559d22606", "assets/build/ba_data/data/languages/swedish.json": "https://files.ballistica.net/cache/ba1/91/0a/35c4baf539d5951fc03a794c0e0b", - "assets/build/ba_data/data/languages/tamil.json": "https://files.ballistica.net/cache/ba1/2b/25/aa93983666b88d1c584f06b742b0", + "assets/build/ba_data/data/languages/tamil.json": "https://files.ballistica.net/cache/ba1/ec/b2/426ec5d0bb98145dc7123766fb5c", "assets/build/ba_data/data/languages/thai.json": "https://files.ballistica.net/cache/ba1/f7/df/7ba5f99c5c2c4c86fc0503fcf0b7", - "assets/build/ba_data/data/languages/turkish.json": "https://files.ballistica.net/cache/ba1/b5/e8/606f6d3dc1f4bffc96128abaef03", + "assets/build/ba_data/data/languages/turkish.json": "https://files.ballistica.net/cache/ba1/52/5e/385f4d430fa82b2ac206277a71d4", "assets/build/ba_data/data/languages/ukrainian.json": "https://files.ballistica.net/cache/ba1/1b/83/844f9e6f4e9e47a2d788d3faa9d2", - "assets/build/ba_data/data/languages/venetian.json": "https://files.ballistica.net/cache/ba1/17/15/973f4101bf2264173bd1c1729426", + "assets/build/ba_data/data/languages/venetian.json": "https://files.ballistica.net/cache/ba1/a6/ed/416638d46950c9ab4f6155b9c334", "assets/build/ba_data/data/languages/vietnamese.json": "https://files.ballistica.net/cache/ba1/1f/ae/abe3f105b3c4b51f6b7942773305", "assets/build/ba_data/data/maps/big_g.json": "https://files.ballistica.net/cache/ba1/47/0a/a617cc85d927b576c4e6fc1091ed", "assets/build/ba_data/data/maps/bridgit.json": "https://files.ballistica.net/cache/ba1/03/4b/57ee9b42854b26f23f81bd8c58ef", @@ -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/df/a3/64ac7606c1bf9ce707dfd3114127", - "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/1f/70/a2d9b6e09c866dbc5f75974da183", - "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/e8/50/64bb044aef2d3d37da810602fe80", - "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/66/54/40159901988438140f6c879772da", - "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/91/65/6a36636f69dfdd76e0ffeb0e0f3a", - "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/8f/52/d5f181b1f444c44dbc9bf7a428dd", - "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/cb/db/d8e1d84660fb800de940d7283ac5", - "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/29/6e/d6238719cabbc11c7f20abc52966", - "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/55/6c/5aea38aadb0683b9baa1fd50e0c6", - "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/0b/2a/5059145781aa5b2747ba1b4c6e26", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/47/ff/7782c66aa8ecdef670e49afe9b3a", - "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/48/69/8d3c26a624375f5c7bc2dcbbf144", - "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/ff/a6/aa0afad6ea5a949908822b72716c", - "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/82/4f/d534d96e93f5d4d70ebf9f7d9c77", - "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/c1/e2/96e411b353287280f3315e7ac63d", - "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/1e/86/9580019dee2099862d0ecabc5aef", - "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/4a/c1/dbf6444578f666b5a8af954ac11c", - "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/fe/6e/1123e3b3d9359307c3eea6c071f3", - "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/02/43/6e56c1d135896956bc0ad874b398", - "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/e9/4f/da92e04a7a7a2cc2839b0d76d7a8", - "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/1b/bc/4d8cc7c9807c8b7a02d67de95dba", - "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/10/e6/ccd40f2a83735c5da9193333cbf1", - "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/eb/3e/91f24852fb1766c9cf273e0952a6", - "build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/6f/64/c1cb80d0f007af1e7a7386281fc2", - "build/prefab/lib/linux_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/12/e5/ed36f54413a114c8d0762c2f57b1", - "build/prefab/lib/linux_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/2c/8c/1597a2fe945c36e76c375fa5e412", - "build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ce/28/61941473817cd934b21cc8447f4d", - "build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/18/e3/01ee52c5bb52687324ecd3bb3f78", - "build/prefab/lib/mac_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/3d/85/62176cf03dd0be0e11ec6ed56230", - "build/prefab/lib/mac_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/cf/62/7587a846e73295a7e12c66d0e19c", - "build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ff/43/3ff93b30de352362dde3a173db18", - "build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/5e/15/0279dbe76b979d494d69c03b0527", - "build/prefab/lib/mac_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/20/e6/7f97b816171100873578dfebc237", - "build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/da/75/32d072333f57926ed2b649b01543", - "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/17/c2/e334283a230cfe50e5d4da8c02d4", - "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/c4/41/6a346833e2193a05b339d596f3dc", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/62/4a/87bc0017df139dbbc0195be774f5", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/fd/44/5db285cf7fd3301cd46f944dab6d", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/2f/09/dedf1229e5fa5ab73cea4b8b575b", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/c8/3e/7f3ce434876f2992a4043f398073", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/ed/a7/2088ab8e7e0ceb2ea768370bb464", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/03/51/0d6c5b45b326d2d7d069f8b371fc", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/77/fe/4f0d3a4ac3f71e4b214c5c5e4cc9", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/42/ef/e9b23bd9661675f6a9ec2bd7745d", + "build/prefab/full/linux_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/0e/af/b1c02ed97cd2be848229dcf5a053", + "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/c6/80/5de16710ccb0b41d1e0067267970", + "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/83/b8/8897303dab143f36e1dccf0f1019", + "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/bd/e1/4bd99de84798c83959d5db9bdc8a", + "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/7e/ba/16df06cda8a5495544d853b9891d", + "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/a9/27/43afc973cb055c64513c8d220236", + "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/26/b4/3ce5f686d549c3a6b1e63c4045ac", + "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/92/24/2b4175234b768d7d45b2f4a967b6", + "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/88/05/75064b0904a2ce5ce15e7f6e6d61", + "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/3b/fd/9a661af315236f37b2c22fd987ee", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/d4/3c/1257420072dceded3147faf3de7d", + "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/f5/1c/d35becd4f0722f9f28bc695f316b", + "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/f1/2e/ea3ce9edaa5d6c11e7306675df38", + "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/42/6d/aaf54051f79f265a281035c0f4cd", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/71/f8/22d3f6458bdee3cd2c5da503c84e", + "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/9a/09/c1c6878c65da376a0d9ab6747c0a", + "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/81/c0/f00f87083acc20e33f278aa4d8d4", + "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/0e/e2/e4c9b3f3dcb379e71eb421beca78", + "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/09/87/21b1d4411cd5b3549627fcc85e8f", + "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/1e/7e/2c4229ced6c44c1cd577262b9a87", + "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a2/9d/285cd73953e62fdb7945c09fb83c", + "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/22/2d/3df4908dfdcdebe772bf3df0daee", + "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/2a/74/763faee36da963364e94996429d5", + "build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/87/9f/4408f47d293436f420ff9338dca6", + "build/prefab/lib/linux_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/4f/e8/2518fd177b5c51f89ef0795b1264", + "build/prefab/lib/linux_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/77/b1/41befd66869830590f00bff7ba97", + "build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/92/a2/8d6f01537d722803aab60cb67e6d", + "build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/fc/be/0e1af48000395cdbe72179dba90a", + "build/prefab/lib/mac_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/20/7a/b31ec8c47d67b7fd23ed2510aae7", + "build/prefab/lib/mac_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a0/b5/b4ffd9769f3b703226e744423a58", + "build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/3b/02/9e8f15c68ca328a7549846d53a8f", + "build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a0/74/b61b74ada26b41f421563b535dd0", + "build/prefab/lib/mac_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ec/5c/08c171db06bd4492a2b414c77488", + "build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/2f/8a/0384cc905ba23bd45afdfcacb882", + "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/63/6f/e6ba3560e0a8e404bb592405de27", + "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/6e/14/c4f70a74e2111e3adb096dfbd215", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/94/90/509608dd38c2bbc509dcf468c260", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/61/7f/f3591f125f13cbb74a41a99225b4", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/b5/11/cebb90659cbd5fbf33fc8f05afb9", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/50/fe/556c95e535ab849bfc7410adf8b6", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/6f/39/8ae7e0225b54ff0fe93cf83bc9be", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/a1/5e/4f797ceb3153f4a687eb7606a5be", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/b6/7a/8ac9e0d6d0188e2beb88f34c981f", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/39/b8/85db5aa7cede25660da4ff36a3a0", "src/ballistica/generated/python_embedded/binding.inc": "https://files.ballistica.net/cache/ba1/25/77/8093dfffddaa80cd513ddaa61867", "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/CHANGELOG.md b/CHANGELOG.md index 0ca7b0c3..ba5ba052 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,6 @@ -### 1.7.14 (build 20957, api 7, 2022-12-03) +### 1.7.15 (build 20960, api 7, 2022-12-04) + +### 1.7.14 (build 20958, api 7, 2022-12-03) - Android Google Play logins now provide V2 accounts with access to all V2 features such as a globally-unique account tag, cloud-console, and workspaces. They should still retain their V1 data as well. - V2 accounts now have a 'Manage Account' button in the app account window which will sign you into a browser with your current account. - Removed Google App Invite functionality which has been deprecated for a while now. Google Play users can still get tickets by sharing the app via codes (same as other platforms). diff --git a/assets/src/ba_data/python/ba/_bootstrap.py b/assets/src/ba_data/python/ba/_bootstrap.py index 96c26654..be5d6018 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 = 20957 + expected_build = 20960 running_build: int = env['build_number'] if running_build != expected_build: print( diff --git a/src/ballistica/ballistica.cc b/src/ballistica/ballistica.cc index 7594d335..829dc500 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 = 20957; -const char* kAppVersion = "1.7.14"; +const int kAppBuildNumber = 20960; +const char* kAppVersion = "1.7.15"; // Our standalone globals. // These are separated out for easy access. diff --git a/tools/efro/dataclassio/_base.py b/tools/efro/dataclassio/_base.py index 134ea001..0402488b 100644 --- a/tools/efro/dataclassio/_base.py +++ b/tools/efro/dataclassio/_base.py @@ -111,6 +111,8 @@ class IOAttrs: boundaries (see efro.util.utc_today()). 'whole_hours', if True, requires datetime values to lie exactly on hour boundaries (see efro.util.utc_this_hour()). + 'whole_minutes', if True, requires datetime values to lie exactly on minute + boundaries (see efro.util.utc_this_minute()). 'soft_default', if passed, injects a default value into dataclass instantiation when the field is not present in the input data. This allows dataclasses to add new non-optional fields while @@ -136,6 +138,7 @@ class IOAttrs: store_default: bool = True whole_days: bool = False whole_hours: bool = False + whole_minutes: bool = False soft_default: Any = MISSING soft_default_factory: Callable[[], Any] | _MissingType = MISSING @@ -145,6 +148,7 @@ class IOAttrs: store_default: bool = store_default, whole_days: bool = whole_days, whole_hours: bool = whole_hours, + whole_minutes: bool = whole_minutes, soft_default: Any = MISSING, soft_default_factory: Callable[[], Any] | _MissingType = MISSING, ): @@ -160,6 +164,8 @@ class IOAttrs: self.whole_days = whole_days if whole_hours != cls.whole_hours: self.whole_hours = whole_hours + if whole_minutes != cls.whole_minutes: + self.whole_minutes = whole_minutes if soft_default is not cls.soft_default: # Do what dataclasses does with its default types and @@ -216,13 +222,18 @@ class IOAttrs: raise ValueError( f'Value {value} at {fieldpath} is not a whole day.' ) - if self.whole_hours: + elif self.whole_hours: if any( x != 0 for x in (value.minute, value.second, value.microsecond) ): raise ValueError( f'Value {value} at {fieldpath}' f' is not a whole hour.' ) + elif self.whole_minutes: + if any(x != 0 for x in (value.second, value.microsecond)): + raise ValueError( + f'Value {value} at {fieldpath}' f' is not a whole minute.' + ) def _get_origin(anntype: Any) -> Any: diff --git a/tools/efrotools/ios.py b/tools/efrotools/ios.py index 4b2bfd3f..db724320 100644 --- a/tools/efrotools/ios.py +++ b/tools/efrotools/ios.py @@ -134,6 +134,7 @@ def _add_build_to_xcarchive( MODES['debug']['configuration'], '-archivePath', str(archivepathbase), + '-allowProvisioningUpdates', ] subprocess.run(args, check=True, capture_output=False) From be9599d0a735606dd94ee90b7dd13f2aab6d7d0b Mon Sep 17 00:00:00 2001 From: Eric Froemling Date: Wed, 7 Dec 2022 22:19:11 -0800 Subject: [PATCH 08/26] tidying --- .efrocachemap | 1186 ++++++++--------- CHANGELOG.md | 8 + assets/src/ba_data/python/ba/_bootstrap.py | 2 +- assets/src/ba_data/python/ba/_plugin.py | 2 +- .../python/bastd/ui/account/v2proxy.py | 9 +- .../src/ba_data/python/bastd/ui/v2upgrade.py | 16 +- src/ballistica/app/app_flavor.cc | 21 +- src/ballistica/ballistica.cc | 4 +- src/ballistica/ui/widget/root_widget.cc | 10 +- src/ballistica/ui/widget/text_widget.cc | 29 +- 10 files changed, 660 insertions(+), 627 deletions(-) diff --git a/.efrocachemap b/.efrocachemap index efcf1ed1..429b7154 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -1,427 +1,427 @@ { - "assets/build/ba_data/audio/achievement.ogg": "https://files.ballistica.net/cache/ba1/58/60/72ea79f720fe3025edccb074795c", - "assets/build/ba_data/audio/actionHero1.ogg": "https://files.ballistica.net/cache/ba1/df/19/3dca52242f89fea536675460662d", - "assets/build/ba_data/audio/actionHero2.ogg": "https://files.ballistica.net/cache/ba1/cf/59/e9370637605e17e06782a3ded253", - "assets/build/ba_data/audio/actionHero3.ogg": "https://files.ballistica.net/cache/ba1/28/90/1bcbfedccddb1dbb75f1be534a40", - "assets/build/ba_data/audio/actionHero4.ogg": "https://files.ballistica.net/cache/ba1/4e/40/b163b9e464e3ad61fbb1669faccf", - "assets/build/ba_data/audio/actionHeroDeath.ogg": "https://files.ballistica.net/cache/ba1/ab/59/f8c8b4374989b7f4291897d12136", - "assets/build/ba_data/audio/actionHeroFall.ogg": "https://files.ballistica.net/cache/ba1/67/10/fbf1be54bb261de5be005b698ac6", - "assets/build/ba_data/audio/actionHeroHit1.ogg": "https://files.ballistica.net/cache/ba1/5b/6f/f33a2387e511c98990b503120332", - "assets/build/ba_data/audio/actionHeroHit2.ogg": "https://files.ballistica.net/cache/ba1/d0/50/1a0773c6d9f75f5a59397cc7f570", - "assets/build/ba_data/audio/activateBeep.ogg": "https://files.ballistica.net/cache/ba1/5a/e7/f46f191ed3bf9141ce584670f5ef", - "assets/build/ba_data/audio/agent1.ogg": "https://files.ballistica.net/cache/ba1/5f/1d/56573ce369bab1278f8f5ca3df20", - "assets/build/ba_data/audio/agent2.ogg": "https://files.ballistica.net/cache/ba1/96/ce/9d2fa9e025c18f6a549308398622", - "assets/build/ba_data/audio/agent3.ogg": "https://files.ballistica.net/cache/ba1/7a/02/192379d0855a384a6f4602070d2f", - "assets/build/ba_data/audio/agent4.ogg": "https://files.ballistica.net/cache/ba1/d6/c2/ded31e0ca74e18fb1cc9b2848eac", - "assets/build/ba_data/audio/agentDeath.ogg": "https://files.ballistica.net/cache/ba1/37/e2/799c72c85d5580ed91f3d07f353f", - "assets/build/ba_data/audio/agentFall.ogg": "https://files.ballistica.net/cache/ba1/f7/2d/b0f45c9b63c00011d0d0726e99dc", - "assets/build/ba_data/audio/agentHit1.ogg": "https://files.ballistica.net/cache/ba1/0d/62/79bcab98bfc875de8caf8cb584ce", - "assets/build/ba_data/audio/agentHit2.ogg": "https://files.ballistica.net/cache/ba1/15/bc/08460f83e57a794f273ca6b6a0ec", - "assets/build/ba_data/audio/alarm.ogg": "https://files.ballistica.net/cache/ba1/ad/60/b59451d596fcc3f01c74622fe91b", - "assets/build/ba_data/audio/ali1.ogg": "https://files.ballistica.net/cache/ba1/75/6f/f1db853370363e61b4b59fdc34f1", - "assets/build/ba_data/audio/ali2.ogg": "https://files.ballistica.net/cache/ba1/47/dd/5fbbbf4636d3f5f1b1ccdbcd7ee9", - "assets/build/ba_data/audio/ali3.ogg": "https://files.ballistica.net/cache/ba1/e7/e2/3d9421fe70a347e421817a2b7281", - "assets/build/ba_data/audio/ali4.ogg": "https://files.ballistica.net/cache/ba1/75/6d/3986f030b46a23325ffe590ae864", - "assets/build/ba_data/audio/aliDeath.ogg": "https://files.ballistica.net/cache/ba1/0d/55/3b5715fc528462a85857209bddf5", - "assets/build/ba_data/audio/aliFall.ogg": "https://files.ballistica.net/cache/ba1/9b/44/4ae14fa4e34460eff4ff79adca82", - "assets/build/ba_data/audio/aliHit1.ogg": "https://files.ballistica.net/cache/ba1/69/7f/34fddf7c9c23d5bdb88765f246f3", - "assets/build/ba_data/audio/aliHit2.ogg": "https://files.ballistica.net/cache/ba1/d3/67/871f6ee7fbe3c0b079c1c376cad4", - "assets/build/ba_data/audio/alien1.ogg": "https://files.ballistica.net/cache/ba1/8d/25/7e7e6484081f461a3c835a40466a", - "assets/build/ba_data/audio/alien2.ogg": "https://files.ballistica.net/cache/ba1/27/17/aeabc20283ce7542d5e5dc959efb", - "assets/build/ba_data/audio/alien3.ogg": "https://files.ballistica.net/cache/ba1/83/2e/46a27a8d9650cb64fd6cd2df865f", - "assets/build/ba_data/audio/alien4.ogg": "https://files.ballistica.net/cache/ba1/37/33/4f765d486286c1f998ae4b68d98e", - "assets/build/ba_data/audio/alienDeath.ogg": "https://files.ballistica.net/cache/ba1/92/99/e9fe339c6cb5d5d91d653f2a2894", - "assets/build/ba_data/audio/alienFall.ogg": "https://files.ballistica.net/cache/ba1/70/8e/8e2fb00c82452632854959c664ce", - "assets/build/ba_data/audio/alienHit1.ogg": "https://files.ballistica.net/cache/ba1/c4/9c/181dd79a43686ebb8cc05851d7ea", - "assets/build/ba_data/audio/alienHit2.ogg": "https://files.ballistica.net/cache/ba1/bb/3e/4238ca124fdf0bdbb9aac13549f8", - "assets/build/ba_data/audio/announceEight.ogg": "https://files.ballistica.net/cache/ba1/27/6a/574c3185d7c35d9480a839c8888a", - "assets/build/ba_data/audio/announceFive.ogg": "https://files.ballistica.net/cache/ba1/11/6f/072ad78bb410d30cf26d6e511d67", - "assets/build/ba_data/audio/announceFour.ogg": "https://files.ballistica.net/cache/ba1/32/f2/c02875245b900e5fbb7a384f2c17", - "assets/build/ba_data/audio/announceNine.ogg": "https://files.ballistica.net/cache/ba1/11/c0/47a7d6d8e578229db28b604932cb", - "assets/build/ba_data/audio/announceOne.ogg": "https://files.ballistica.net/cache/ba1/96/5f/5985e6a5cc5596d507d64908ecfa", - "assets/build/ba_data/audio/announceSeven.ogg": "https://files.ballistica.net/cache/ba1/3a/11/dcc1c4c6573f29852ebe55e5b549", - "assets/build/ba_data/audio/announceSix.ogg": "https://files.ballistica.net/cache/ba1/2a/22/a966bc15bab28ed56f8ff7e5bbfa", - "assets/build/ba_data/audio/announceTen.ogg": "https://files.ballistica.net/cache/ba1/e0/2e/5c614c252c2b3c24e63ae8498dbf", - "assets/build/ba_data/audio/announceThree.ogg": "https://files.ballistica.net/cache/ba1/dc/29/3172eee392826010e9d2fa9c138e", - "assets/build/ba_data/audio/announceTwo.ogg": "https://files.ballistica.net/cache/ba1/43/18/098574d833d394808a07ba36cede", - "assets/build/ba_data/audio/assassin1.ogg": "https://files.ballistica.net/cache/ba1/c3/5f/6598616f4f1f96c40413b71de9e8", - "assets/build/ba_data/audio/assassin2.ogg": "https://files.ballistica.net/cache/ba1/a4/8d/4116a1ea3715f1c4bb788819cd18", - "assets/build/ba_data/audio/assassin3.ogg": "https://files.ballistica.net/cache/ba1/4e/92/ab9b6565d11b89b73aaa265eb8f0", - "assets/build/ba_data/audio/assassin4.ogg": "https://files.ballistica.net/cache/ba1/7b/e0/a40c91b027bace02667c0fcf158c", - "assets/build/ba_data/audio/assassinDeath.ogg": "https://files.ballistica.net/cache/ba1/05/88/f550d7014923a2c6134f12628098", - "assets/build/ba_data/audio/assassinFall.ogg": "https://files.ballistica.net/cache/ba1/dd/df/94392604b6a346f8b11b696c8f1d", - "assets/build/ba_data/audio/assassinHit1.ogg": "https://files.ballistica.net/cache/ba1/c0/6f/de6f72745e850af65cf9a5dbb3a6", - "assets/build/ba_data/audio/assassinHit2.ogg": "https://files.ballistica.net/cache/ba1/9e/e2/a69db7c14065ee8d570a100a263b", - "assets/build/ba_data/audio/bear1.ogg": "https://files.ballistica.net/cache/ba1/72/49/9551e6ff43e4fdd863cca11134f4", - "assets/build/ba_data/audio/bear2.ogg": "https://files.ballistica.net/cache/ba1/d7/1f/2c830ac5e0a0c43f145a20fa2c25", - "assets/build/ba_data/audio/bear3.ogg": "https://files.ballistica.net/cache/ba1/aa/98/9f1a21aa9dac07d05085e8687068", - "assets/build/ba_data/audio/bear4.ogg": "https://files.ballistica.net/cache/ba1/c7/26/69891bac03ddbea748f9baec9f95", - "assets/build/ba_data/audio/bearDeath.ogg": "https://files.ballistica.net/cache/ba1/e9/eb/39834342979b9340776d814902bb", - "assets/build/ba_data/audio/bearFall.ogg": "https://files.ballistica.net/cache/ba1/15/6b/2be51a0c48077b44166ce9b5a133", - "assets/build/ba_data/audio/bearHit1.ogg": "https://files.ballistica.net/cache/ba1/96/22/6f56ec5c0b58ce8faf959c766a61", - "assets/build/ba_data/audio/bearHit2.ogg": "https://files.ballistica.net/cache/ba1/4f/98/5366c6a26a83e9618b8eca54780a", - "assets/build/ba_data/audio/bellHigh.ogg": "https://files.ballistica.net/cache/ba1/7c/02/4bc38047fc4301eb3c195e0539b9", - "assets/build/ba_data/audio/bellLow.ogg": "https://files.ballistica.net/cache/ba1/85/e0/6ebea452dc2a1284e6668f18e6ec", - "assets/build/ba_data/audio/bellMed.ogg": "https://files.ballistica.net/cache/ba1/a2/d0/57fc42d7e5b76024f0221b43cdfe", - "assets/build/ba_data/audio/bigImpact.ogg": "https://files.ballistica.net/cache/ba1/90/6c/07bb89e1e1d59f927c7530c88fe8", - "assets/build/ba_data/audio/bigImpact2.ogg": "https://files.ballistica.net/cache/ba1/04/81/87864481b02fecb9914e3b50e2a6", - "assets/build/ba_data/audio/blank.ogg": "https://files.ballistica.net/cache/ba1/55/70/90a49806365698031bd7c2a1e55f", - "assets/build/ba_data/audio/blip.ogg": "https://files.ballistica.net/cache/ba1/be/d9/c7bae6f1b9900727cdcffe70adad", - "assets/build/ba_data/audio/block.ogg": "https://files.ballistica.net/cache/ba1/f6/5e/e27553fb56edd40e854a8310ce6b", - "assets/build/ba_data/audio/bombDrop01.ogg": "https://files.ballistica.net/cache/ba1/1a/e8/2bd59450bb142dd8edb7fc875337", - "assets/build/ba_data/audio/bombDrop02.ogg": "https://files.ballistica.net/cache/ba1/28/f5/f7601c05201d1cb088f7b01dd244", - "assets/build/ba_data/audio/bombRoll01.ogg": "https://files.ballistica.net/cache/ba1/4b/64/e0c24177793c47547e3f57c7273b", - "assets/build/ba_data/audio/bones1.ogg": "https://files.ballistica.net/cache/ba1/66/99/fc98f957a6db4a93b5fbb5786b4e", - "assets/build/ba_data/audio/bones2.ogg": "https://files.ballistica.net/cache/ba1/a1/38/064ad0b952104f931c1bcc34d747", - "assets/build/ba_data/audio/bones3.ogg": "https://files.ballistica.net/cache/ba1/20/6e/665a3bd95dc7769c95938da89a2b", - "assets/build/ba_data/audio/bonesDeath.ogg": "https://files.ballistica.net/cache/ba1/2c/53/450b0d309913653756599fb54f25", - "assets/build/ba_data/audio/bonesFall.ogg": "https://files.ballistica.net/cache/ba1/b5/94/d157d5a2b02016caf4a3b40c358c", - "assets/build/ba_data/audio/boo.ogg": "https://files.ballistica.net/cache/ba1/9e/b6/e71d3e3cb099fd93034adc78d079", - "assets/build/ba_data/audio/boxDrop.ogg": "https://files.ballistica.net/cache/ba1/4a/b6/c9f4c108be9808134c15cf44e4b2", - "assets/build/ba_data/audio/boxingBell.ogg": "https://files.ballistica.net/cache/ba1/34/e1/05c5c1400662d2fb3a07594db5b7", - "assets/build/ba_data/audio/bunny1.ogg": "https://files.ballistica.net/cache/ba1/24/8f/bb616af82630e9dc7b98f29318a9", - "assets/build/ba_data/audio/bunny2.ogg": "https://files.ballistica.net/cache/ba1/9d/63/3b247d4a4de0a673008868342765", - "assets/build/ba_data/audio/bunny3.ogg": "https://files.ballistica.net/cache/ba1/0e/08/6490c22fe15808b214068bdc7753", - "assets/build/ba_data/audio/bunny4.ogg": "https://files.ballistica.net/cache/ba1/2a/b7/c480591a278edfe518df5e12ec6a", - "assets/build/ba_data/audio/bunnyDeath.ogg": "https://files.ballistica.net/cache/ba1/93/7d/152e5bf4fdd7880c3f0b9abf178d", - "assets/build/ba_data/audio/bunnyFall.ogg": "https://files.ballistica.net/cache/ba1/0c/31/97752e51b1ab8f581d467b453d29", - "assets/build/ba_data/audio/bunnyHit1.ogg": "https://files.ballistica.net/cache/ba1/1a/e9/7b62eeb9abb596b89bfe53c41df2", - "assets/build/ba_data/audio/bunnyHit2.ogg": "https://files.ballistica.net/cache/ba1/37/56/f44055d623b9f16a6d3ea52cf95d", - "assets/build/ba_data/audio/bunnyJump.ogg": "https://files.ballistica.net/cache/ba1/be/92/b63a629718a81effe5858530a2be", - "assets/build/ba_data/audio/cashRegister.ogg": "https://files.ballistica.net/cache/ba1/91/07/33e1d7d98479aeb0386898bc633e", - "assets/build/ba_data/audio/cashRegister2.ogg": "https://files.ballistica.net/cache/ba1/f8/12/74edab7ebda050f913428793f477", - "assets/build/ba_data/audio/charSelectMusic.ogg": "https://files.ballistica.net/cache/ba1/a7/6d/53b41cd118b34d9ab8254dbd2ff1", - "assets/build/ba_data/audio/cheer.ogg": "https://files.ballistica.net/cache/ba1/c7/ff/c962b9c39a35de2004198e9f03f1", - "assets/build/ba_data/audio/click01.ogg": "https://files.ballistica.net/cache/ba1/7e/a6/42511f8b555d460156424bc53f47", - "assets/build/ba_data/audio/corkPop.ogg": "https://files.ballistica.net/cache/ba1/68/a4/2b7c6d678fe1fa09cde1081c83ef", - "assets/build/ba_data/audio/cowboy1.ogg": "https://files.ballistica.net/cache/ba1/1b/0f/a0bea97d774aa221a3941f0e0af2", - "assets/build/ba_data/audio/cowboy2.ogg": "https://files.ballistica.net/cache/ba1/eb/da/b25db53f6a6d4871db7a7829a8b3", - "assets/build/ba_data/audio/cowboy3.ogg": "https://files.ballistica.net/cache/ba1/42/7c/8eeaec50726c9f6bbd62694bffc5", - "assets/build/ba_data/audio/cowboy4.ogg": "https://files.ballistica.net/cache/ba1/c6/f4/a0f56e61df27ced1d7f03b1dc458", - "assets/build/ba_data/audio/cowboyDeath.ogg": "https://files.ballistica.net/cache/ba1/cb/0e/abb677f438cd64b63dd6fc363d4a", - "assets/build/ba_data/audio/cowboyFall.ogg": "https://files.ballistica.net/cache/ba1/1d/af/c302b9caba1d7f736a6dd9f52268", - "assets/build/ba_data/audio/cowboyHit1.ogg": "https://files.ballistica.net/cache/ba1/71/57/0a9213ba8dea0404318893385068", - "assets/build/ba_data/audio/cowboyHit2.ogg": "https://files.ballistica.net/cache/ba1/cb/13/afa6a5a87981e947177695af64d5", - "assets/build/ba_data/audio/crowdChant.ogg": "https://files.ballistica.net/cache/ba1/f5/c0/92c75181f783dae40075d9c2b689", - "assets/build/ba_data/audio/cyborg1.ogg": "https://files.ballistica.net/cache/ba1/47/15/b4930affbf40421447247546fe99", - "assets/build/ba_data/audio/cyborg2.ogg": "https://files.ballistica.net/cache/ba1/b2/af/626e8e08ab19d5854e474b9195aa", - "assets/build/ba_data/audio/cyborg3.ogg": "https://files.ballistica.net/cache/ba1/8c/0c/b25cf168c367368689c2830361ba", - "assets/build/ba_data/audio/cyborg4.ogg": "https://files.ballistica.net/cache/ba1/38/85/714969eb77f14b8b89c1fdf4bb54", - "assets/build/ba_data/audio/cyborgDeath.ogg": "https://files.ballistica.net/cache/ba1/2f/16/437f9756452e7386a6f737e957db", - "assets/build/ba_data/audio/cyborgFall.ogg": "https://files.ballistica.net/cache/ba1/77/db/a912a8c114f815799738da41ad5f", - "assets/build/ba_data/audio/cyborgHit1.ogg": "https://files.ballistica.net/cache/ba1/86/0c/c988a0ec4cf50cadbb3617b51547", - "assets/build/ba_data/audio/cyborgHit2.ogg": "https://files.ballistica.net/cache/ba1/30/86/9a0fd20c447caa136f902c0995aa", - "assets/build/ba_data/audio/cymbal.ogg": "https://files.ballistica.net/cache/ba1/74/c6/0f51346d8bd9ca177d20c913d4bc", - "assets/build/ba_data/audio/debrisFall.ogg": "https://files.ballistica.net/cache/ba1/82/8a/cc77cccd8f885307237e3091a43f", - "assets/build/ba_data/audio/deek.ogg": "https://files.ballistica.net/cache/ba1/4c/cf/d44e49553a8f590e6044d5a29c40", - "assets/build/ba_data/audio/deek2.ogg": "https://files.ballistica.net/cache/ba1/a1/9d/6feb67617bd1d6b0e116ba8f4051", - "assets/build/ba_data/audio/ding.ogg": "https://files.ballistica.net/cache/ba1/49/44/70398a2997c7238349abd56f64e9", - "assets/build/ba_data/audio/dingSmall.ogg": "https://files.ballistica.net/cache/ba1/ce/5d/6de4581beee72fd2dbf78e884f6d", - "assets/build/ba_data/audio/dingSmallHigh.ogg": "https://files.ballistica.net/cache/ba1/d8/6c/c290d65aa888309b14172b4550f5", - "assets/build/ba_data/audio/dripity.ogg": "https://files.ballistica.net/cache/ba1/5a/c7/2012a0547b43f4fe22300ba1e435", - "assets/build/ba_data/audio/drumRoll.ogg": "https://files.ballistica.net/cache/ba1/f9/c9/eb8cdc6911207e1b9fc37c856550", - "assets/build/ba_data/audio/error.ogg": "https://files.ballistica.net/cache/ba1/f0/fb/8db7d282d17f6549439472a17443", - "assets/build/ba_data/audio/explosion01.ogg": "https://files.ballistica.net/cache/ba1/7e/5c/60d2827cf919ce3a2a742c13656d", - "assets/build/ba_data/audio/explosion02.ogg": "https://files.ballistica.net/cache/ba1/40/5b/0ad2e9b46bdbeb5117c6c35d0c06", - "assets/build/ba_data/audio/explosion03.ogg": "https://files.ballistica.net/cache/ba1/fc/55/a9abae0b44d7a38e8965dbe0e82d", - "assets/build/ba_data/audio/explosion04.ogg": "https://files.ballistica.net/cache/ba1/3e/1d/6956a0ebd528c85d928f64e986ad", - "assets/build/ba_data/audio/explosion05.ogg": "https://files.ballistica.net/cache/ba1/1f/6a/ad37d5a4a16390ff4984008c4529", - "assets/build/ba_data/audio/fanfare.ogg": "https://files.ballistica.net/cache/ba1/65/89/78fb925efb8e70a3a7b3b8e6eb22", - "assets/build/ba_data/audio/flagCatcherMusic.ogg": "https://files.ballistica.net/cache/ba1/d2/63/1214d61047ae93562e81ebb5ff31", - "assets/build/ba_data/audio/flyingMusic.ogg": "https://files.ballistica.net/cache/ba1/84/62/853c3e325b4709e59e4d08c05f71", - "assets/build/ba_data/audio/foghorn.ogg": "https://files.ballistica.net/cache/ba1/74/26/2338cc1801cfa18e1e106aeb4ae6", - "assets/build/ba_data/audio/footImpact01.ogg": "https://files.ballistica.net/cache/ba1/d2/86/b525c0f04e5118b20d55cd075b8d", - "assets/build/ba_data/audio/footImpact02.ogg": "https://files.ballistica.net/cache/ba1/cc/c9/3a00e1b3f628412877c88f1be1dd", - "assets/build/ba_data/audio/footImpact03.ogg": "https://files.ballistica.net/cache/ba1/15/43/3e555fb6ea381f384d3ac1646707", - "assets/build/ba_data/audio/forwardMarchMusic.ogg": "https://files.ballistica.net/cache/ba1/4f/bd/c9a96a8949fca5328df20bf6c160", - "assets/build/ba_data/audio/freeze.ogg": "https://files.ballistica.net/cache/ba1/02/ab/e598b181e844a065925f2bf97963", - "assets/build/ba_data/audio/frosty01.ogg": "https://files.ballistica.net/cache/ba1/ef/6d/3400f25717f7f442dd8d1419033e", - "assets/build/ba_data/audio/frosty02.ogg": "https://files.ballistica.net/cache/ba1/76/38/5854a95ec204f41e43b50d263409", - "assets/build/ba_data/audio/frosty03.ogg": "https://files.ballistica.net/cache/ba1/a8/16/60fc348f2edc081c4c338e7956e6", - "assets/build/ba_data/audio/frosty04.ogg": "https://files.ballistica.net/cache/ba1/11/f0/7860caaada9174a47251c9c66018", - "assets/build/ba_data/audio/frosty05.ogg": "https://files.ballistica.net/cache/ba1/45/8f/def4659833a1dbd76f14b13d2bff", - "assets/build/ba_data/audio/frostyDeath.ogg": "https://files.ballistica.net/cache/ba1/d4/bd/d214a161586e03503c21d859b615", - "assets/build/ba_data/audio/frostyFall.ogg": "https://files.ballistica.net/cache/ba1/e9/44/98873e7072b05ab1fda1f35ee9cf", - "assets/build/ba_data/audio/frostyHit01.ogg": "https://files.ballistica.net/cache/ba1/7d/c9/5a6686a9f625692a51845f8b1a9e", - "assets/build/ba_data/audio/frostyHit02.ogg": "https://files.ballistica.net/cache/ba1/65/d3/bd26b06bc0d3840d12971a8ff7a3", - "assets/build/ba_data/audio/frostyHit03.ogg": "https://files.ballistica.net/cache/ba1/62/b8/ff9ae4125d95afff1eabfa70e85f", - "assets/build/ba_data/audio/fuse01.ogg": "https://files.ballistica.net/cache/ba1/e0/33/05a6deab05d5fc024078294911e6", - "assets/build/ba_data/audio/gladiator1.ogg": "https://files.ballistica.net/cache/ba1/62/c9/9a1677c7ac53aa1e2d86b6a41cb8", - "assets/build/ba_data/audio/gladiator2.ogg": "https://files.ballistica.net/cache/ba1/01/03/826a4dc462a2ffde058c229563c4", - "assets/build/ba_data/audio/gladiator3.ogg": "https://files.ballistica.net/cache/ba1/75/ac/4153c1bae224e124e6a0c14f3767", - "assets/build/ba_data/audio/gladiator4.ogg": "https://files.ballistica.net/cache/ba1/41/57/9d42f96a7b4f2501516c76acd8eb", - "assets/build/ba_data/audio/gladiatorDeath.ogg": "https://files.ballistica.net/cache/ba1/0b/3f/7b823002ac4823e692f3e3772e6d", - "assets/build/ba_data/audio/gladiatorFall.ogg": "https://files.ballistica.net/cache/ba1/59/52/bd80868601bbe451ea2b8bbedd3b", - "assets/build/ba_data/audio/gladiatorHit1.ogg": "https://files.ballistica.net/cache/ba1/d5/f1/eec7713ca5613b27827f2cecd23e", - "assets/build/ba_data/audio/gladiatorHit2.ogg": "https://files.ballistica.net/cache/ba1/8d/f6/65d8116517cedabd94498fad52f5", - "assets/build/ba_data/audio/gong.ogg": "https://files.ballistica.net/cache/ba1/22/74/cbebc4aea2e05e0b04acc6505247", - "assets/build/ba_data/audio/grandRompMusic.ogg": "https://files.ballistica.net/cache/ba1/d8/8d/c58f032720cf364033eca76836db", - "assets/build/ba_data/audio/gravelSkid.ogg": "https://files.ballistica.net/cache/ba1/53/45/06c085914c1f9faef2486bb97437", - "assets/build/ba_data/audio/gunCocking.ogg": "https://files.ballistica.net/cache/ba1/d8/ce/edd7befc975296aef73d732bb663", - "assets/build/ba_data/audio/healthPowerup.ogg": "https://files.ballistica.net/cache/ba1/f0/34/72c44aef2241471debca16f03870", - "assets/build/ba_data/audio/hiss.ogg": "https://files.ballistica.net/cache/ba1/04/3a/9b820db7a76beb8271c9737558ba", - "assets/build/ba_data/audio/impactHard.ogg": "https://files.ballistica.net/cache/ba1/30/e7/9e78011593669448536cfc97cfd2", - "assets/build/ba_data/audio/impactHard2.ogg": "https://files.ballistica.net/cache/ba1/3e/5f/4da1dd1467abf87db71303958898", - "assets/build/ba_data/audio/impactHard3.ogg": "https://files.ballistica.net/cache/ba1/19/b6/3350b18401d089a06ed953b664d8", - "assets/build/ba_data/audio/impactMedium.ogg": "https://files.ballistica.net/cache/ba1/fc/50/e6d167d4c54f01a23a8a509c0033", - "assets/build/ba_data/audio/impactMedium2.ogg": "https://files.ballistica.net/cache/ba1/d9/c9/594cee989be6e1101e5b81f84e21", - "assets/build/ba_data/audio/jack01.ogg": "https://files.ballistica.net/cache/ba1/e9/1d/924768dd46f3ebba712f7c4671fd", - "assets/build/ba_data/audio/jack02.ogg": "https://files.ballistica.net/cache/ba1/bd/6b/6f1071d7151a0c2cfb58203d3b0a", - "assets/build/ba_data/audio/jack03.ogg": "https://files.ballistica.net/cache/ba1/fe/2e/ee03645ecc98b87351b36dc8bad8", - "assets/build/ba_data/audio/jack04.ogg": "https://files.ballistica.net/cache/ba1/04/eb/2b842246184c956b63e03a030eb0", - "assets/build/ba_data/audio/jack05.ogg": "https://files.ballistica.net/cache/ba1/ee/9b/e9505d780f8df0b7f52521633033", - "assets/build/ba_data/audio/jack06.ogg": "https://files.ballistica.net/cache/ba1/28/c1/fc96bb381c38fe24db32ce943d39", - "assets/build/ba_data/audio/jackDeath01.ogg": "https://files.ballistica.net/cache/ba1/10/ad/a44b04f740f29112e146f61d08dd", - "assets/build/ba_data/audio/jackFall01.ogg": "https://files.ballistica.net/cache/ba1/d8/69/8185e28dedad83a6ce42412eca0b", - "assets/build/ba_data/audio/jackHit01.ogg": "https://files.ballistica.net/cache/ba1/c9/7d/076eb7ef2e45129e8f7870d2b5fa", - "assets/build/ba_data/audio/jackHit02.ogg": "https://files.ballistica.net/cache/ba1/cc/8c/8196a164dfa4a7304753767bc806", - "assets/build/ba_data/audio/jackHit03.ogg": "https://files.ballistica.net/cache/ba1/c0/93/280556ce2e97fbb3cfd43d4cc6f8", - "assets/build/ba_data/audio/jackHit04.ogg": "https://files.ballistica.net/cache/ba1/7d/2e/59fb210c91477798962076d40bed", - "assets/build/ba_data/audio/jackHit05.ogg": "https://files.ballistica.net/cache/ba1/d9/15/8db623ab332a7adf3087c54eb439", - "assets/build/ba_data/audio/jackHit06.ogg": "https://files.ballistica.net/cache/ba1/14/25/d85c7443244ff9c4b762cfba7d45", - "assets/build/ba_data/audio/jackHit07.ogg": "https://files.ballistica.net/cache/ba1/c3/92/70e73537e642c3de7c0d1514c62c", - "assets/build/ba_data/audio/jumpsuit1.ogg": "https://files.ballistica.net/cache/ba1/1d/e6/caeb8f3d75ad8d00a896493d4981", - "assets/build/ba_data/audio/jumpsuit2.ogg": "https://files.ballistica.net/cache/ba1/9d/65/5bada79073612f81dada09cdd669", - "assets/build/ba_data/audio/jumpsuit3.ogg": "https://files.ballistica.net/cache/ba1/ec/97/1807c9196930f55ed29080374395", - "assets/build/ba_data/audio/jumpsuit4.ogg": "https://files.ballistica.net/cache/ba1/3c/84/d62da6a915e3255434a0929e4ec8", - "assets/build/ba_data/audio/jumpsuitDeath.ogg": "https://files.ballistica.net/cache/ba1/8c/b3/525216f8302f9d948095bfa9799a", - "assets/build/ba_data/audio/jumpsuitFall.ogg": "https://files.ballistica.net/cache/ba1/7f/af/6b411b9a46ad8be33e15dc9e6429", - "assets/build/ba_data/audio/jumpsuitHit1.ogg": "https://files.ballistica.net/cache/ba1/a6/29/bed67bd2fa608427b5b27703a369", - "assets/build/ba_data/audio/jumpsuitHit2.ogg": "https://files.ballistica.net/cache/ba1/de/ff/aac029f85323dfde023607bd5b98", - "assets/build/ba_data/audio/kronk1.ogg": "https://files.ballistica.net/cache/ba1/a5/25/6ffeb4f7c0b479f6ea331fad4cb0", - "assets/build/ba_data/audio/kronk10.ogg": "https://files.ballistica.net/cache/ba1/e0/72/50b27a07c338b3ea9467877fcba6", - "assets/build/ba_data/audio/kronk2.ogg": "https://files.ballistica.net/cache/ba1/d3/4a/ab1f9a3af8ec7a35dc4c84ebec93", - "assets/build/ba_data/audio/kronk3.ogg": "https://files.ballistica.net/cache/ba1/78/3e/04ed2f524aa8c9d7cc20240dd102", - "assets/build/ba_data/audio/kronk4.ogg": "https://files.ballistica.net/cache/ba1/a7/90/67fc1bcc1e29225c6560b22dc797", - "assets/build/ba_data/audio/kronk5.ogg": "https://files.ballistica.net/cache/ba1/47/73/ebadf9e3e762761b486574f92ae5", - "assets/build/ba_data/audio/kronk6.ogg": "https://files.ballistica.net/cache/ba1/d7/12/eb34c17c7eae64861019d8b9d0e4", - "assets/build/ba_data/audio/kronk7.ogg": "https://files.ballistica.net/cache/ba1/50/12/4bbf79acb96de2891d0c04793dd8", - "assets/build/ba_data/audio/kronk8.ogg": "https://files.ballistica.net/cache/ba1/fb/3d/cf3678af97b1e9453b2a5ccf6556", - "assets/build/ba_data/audio/kronk9.ogg": "https://files.ballistica.net/cache/ba1/2b/5d/80ac256b9a0395ce0c1df07198b7", - "assets/build/ba_data/audio/kronkDeath.ogg": "https://files.ballistica.net/cache/ba1/a8/86/adb0bcf982f41aef1266bfef4ac3", - "assets/build/ba_data/audio/kronkFall.ogg": "https://files.ballistica.net/cache/ba1/01/bc/933e24668420f71aa5a7f405166e", - "assets/build/ba_data/audio/laser.ogg": "https://files.ballistica.net/cache/ba1/9e/ef/c95d203792e7c2410cf48b8e6242", - "assets/build/ba_data/audio/laserReverse.ogg": "https://files.ballistica.net/cache/ba1/ee/de/e4e5513a1e0b45bd7c21802a0680", - "assets/build/ba_data/audio/mel01.ogg": "https://files.ballistica.net/cache/ba1/df/e6/9597698cb9abe30ceade8ab682e1", - "assets/build/ba_data/audio/mel02.ogg": "https://files.ballistica.net/cache/ba1/28/0e/41a16319712fc1c0d7999d439dff", - "assets/build/ba_data/audio/mel03.ogg": "https://files.ballistica.net/cache/ba1/bf/b0/5ae8a0a1c92664a078869125aa33", - "assets/build/ba_data/audio/mel04.ogg": "https://files.ballistica.net/cache/ba1/62/8d/30104cf07b07d7f8044324587f8b", - "assets/build/ba_data/audio/mel05.ogg": "https://files.ballistica.net/cache/ba1/a3/ba/7e268b1bf136ab431ed8aa600c92", - "assets/build/ba_data/audio/mel06.ogg": "https://files.ballistica.net/cache/ba1/18/e1/f9a292341b7ae940dcdfc9af6dde", - "assets/build/ba_data/audio/mel07.ogg": "https://files.ballistica.net/cache/ba1/4e/42/c512f97edc448246a89e4c92f9c8", - "assets/build/ba_data/audio/mel08.ogg": "https://files.ballistica.net/cache/ba1/73/52/3930c7eb099dfe89fbd09c90309c", - "assets/build/ba_data/audio/mel09.ogg": "https://files.ballistica.net/cache/ba1/22/79/82f9d313915592a142e8cf0c6e99", - "assets/build/ba_data/audio/mel10.ogg": "https://files.ballistica.net/cache/ba1/a0/3a/067da88e50b7fb576cb30441065e", - "assets/build/ba_data/audio/melDeath01.ogg": "https://files.ballistica.net/cache/ba1/cd/e1/b3a3cf043eba71e1f6fdecb010f2", - "assets/build/ba_data/audio/melFall01.ogg": "https://files.ballistica.net/cache/ba1/fd/48/d9903063f4a5cd445f140280faba", - "assets/build/ba_data/audio/menuMusic.ogg": "https://files.ballistica.net/cache/ba1/61/25/949add05fbdc5d6d163192a5bf96", - "assets/build/ba_data/audio/metalHit.ogg": "https://files.ballistica.net/cache/ba1/ee/80/b0305bfb666556e8931ec5729088", - "assets/build/ba_data/audio/metalSkid.ogg": "https://files.ballistica.net/cache/ba1/de/81/6d1597d6bb6ae20d6715c52b8757", - "assets/build/ba_data/audio/ninjaAttack1.ogg": "https://files.ballistica.net/cache/ba1/b0/ec/7e6ea6898010fc117fe7ab3cfd14", - "assets/build/ba_data/audio/ninjaAttack2.ogg": "https://files.ballistica.net/cache/ba1/b9/2a/1b3045380c083e67252cade17f60", - "assets/build/ba_data/audio/ninjaAttack3.ogg": "https://files.ballistica.net/cache/ba1/83/fe/6854cffa06c237e8ba11aa1c3811", - "assets/build/ba_data/audio/ninjaAttack4.ogg": "https://files.ballistica.net/cache/ba1/09/f7/5b3de6c0c466c3fc6d2f6b19102c", - "assets/build/ba_data/audio/ninjaAttack5.ogg": "https://files.ballistica.net/cache/ba1/ec/42/e0784271bec8a82dfb54201c2e1c", - "assets/build/ba_data/audio/ninjaAttack6.ogg": "https://files.ballistica.net/cache/ba1/b2/e6/20743d838354bbc70b0eab0942e6", - "assets/build/ba_data/audio/ninjaAttack7.ogg": "https://files.ballistica.net/cache/ba1/9e/bb/e7002c6810d6a66d1a9779091364", - "assets/build/ba_data/audio/ninjaDeath1.ogg": "https://files.ballistica.net/cache/ba1/b8/62/c9f0b5aed52a44cda7c1d874f096", - "assets/build/ba_data/audio/ninjaFall1.ogg": "https://files.ballistica.net/cache/ba1/45/f8/461537290f94f4e93e6d127e73eb", - "assets/build/ba_data/audio/ninjaHit1.ogg": "https://files.ballistica.net/cache/ba1/b5/4d/0acb8fe85d7c67ec8afe3005ae2a", - "assets/build/ba_data/audio/ninjaHit2.ogg": "https://files.ballistica.net/cache/ba1/41/7b/bc492022c86f91cd38a203a7dbc8", - "assets/build/ba_data/audio/ninjaHit3.ogg": "https://files.ballistica.net/cache/ba1/21/a9/4bf5331435ab7f0118a769efc82e", - "assets/build/ba_data/audio/ninjaHit4.ogg": "https://files.ballistica.net/cache/ba1/90/9a/6a012a5e6782726a5e2d6fe91f44", - "assets/build/ba_data/audio/ninjaHit5.ogg": "https://files.ballistica.net/cache/ba1/30/ef/7d13306f36cb7827273062c3f2a4", - "assets/build/ba_data/audio/ninjaHit6.ogg": "https://files.ballistica.net/cache/ba1/5f/fe/fb2532d2e6de096a9feeab7f6c17", - "assets/build/ba_data/audio/ninjaHit7.ogg": "https://files.ballistica.net/cache/ba1/57/56/0ba4ab0f1233ef72108ccda9ccfa", - "assets/build/ba_data/audio/ninjaHit8.ogg": "https://files.ballistica.net/cache/ba1/d2/d9/b1fbfc0a864161fc879785b544c5", - "assets/build/ba_data/audio/oldLady1.ogg": "https://files.ballistica.net/cache/ba1/27/9c/4ae89ba2d90c5491a05a9098dfb7", - "assets/build/ba_data/audio/oldLady2.ogg": "https://files.ballistica.net/cache/ba1/6d/55/0f3a7a838905dde023bd93775ebb", - "assets/build/ba_data/audio/oldLady3.ogg": "https://files.ballistica.net/cache/ba1/d8/77/08e31296569e99eaea6e3335dac3", - "assets/build/ba_data/audio/oldLady4.ogg": "https://files.ballistica.net/cache/ba1/b7/96/5f7dd93a643a3ab1f5d6a0a4e8c3", - "assets/build/ba_data/audio/oldLadyDeath.ogg": "https://files.ballistica.net/cache/ba1/71/f0/ee089bbd54bb57734d09477cc2d9", - "assets/build/ba_data/audio/oldLadyFall.ogg": "https://files.ballistica.net/cache/ba1/b3/4b/a3dc06498650caee6290e364f2d6", - "assets/build/ba_data/audio/oldLadyHit1.ogg": "https://files.ballistica.net/cache/ba1/4a/66/358ad6790d13b4b2edcfc3e0f271", - "assets/build/ba_data/audio/oldLadyHit2.ogg": "https://files.ballistica.net/cache/ba1/18/cb/d7c3037b62cd77781fe4f12691fa", - "assets/build/ba_data/audio/ooh.ogg": "https://files.ballistica.net/cache/ba1/b7/28/6cefdb25ff8d908cc3feae409db3", - "assets/build/ba_data/audio/operaSinger1.ogg": "https://files.ballistica.net/cache/ba1/1f/ae/192442b203a9ea76ede63f8c6703", - "assets/build/ba_data/audio/operaSinger2.ogg": "https://files.ballistica.net/cache/ba1/ec/bd/5f82598f65e996cd38808750d31e", - "assets/build/ba_data/audio/operaSinger3.ogg": "https://files.ballistica.net/cache/ba1/6f/05/650ce355834ff955bd92e826bf61", - "assets/build/ba_data/audio/operaSinger4.ogg": "https://files.ballistica.net/cache/ba1/d9/7b/912192363ea7bdefad644d581031", - "assets/build/ba_data/audio/operaSingerDeath.ogg": "https://files.ballistica.net/cache/ba1/80/3b/9f46ff5e3935ef65a5fc241f6f69", - "assets/build/ba_data/audio/operaSingerFall.ogg": "https://files.ballistica.net/cache/ba1/31/87/7a3b7d9a0f30b97ea4c9465b1ed6", - "assets/build/ba_data/audio/operaSingerHit1.ogg": "https://files.ballistica.net/cache/ba1/af/f5/eed5e1c078a8ebb42da718d8eb2c", - "assets/build/ba_data/audio/operaSingerHit2.ogg": "https://files.ballistica.net/cache/ba1/81/9d/d2d943aec38c910aec3cd37ca8ce", - "assets/build/ba_data/audio/orchestraHit.ogg": "https://files.ballistica.net/cache/ba1/10/52/c067809e0e67ada9f51b7df4f905", - "assets/build/ba_data/audio/orchestraHit2.ogg": "https://files.ballistica.net/cache/ba1/cf/c5/f176dba87e6b8e9d8b23f79b6875", - "assets/build/ba_data/audio/orchestraHit3.ogg": "https://files.ballistica.net/cache/ba1/22/db/069cd352d268b36532fe44863a2c", - "assets/build/ba_data/audio/orchestraHit4.ogg": "https://files.ballistica.net/cache/ba1/0d/ca/e27abfc328e28c6ef394d7ae8820", - "assets/build/ba_data/audio/orchestraHitBig1.ogg": "https://files.ballistica.net/cache/ba1/b6/8f/310a8e3b4584274806ec4a623a37", - "assets/build/ba_data/audio/orchestraHitBig2.ogg": "https://files.ballistica.net/cache/ba1/36/7f/4d6affb3c51d5ab2d1f2c8161fbf", - "assets/build/ba_data/audio/penguin1.ogg": "https://files.ballistica.net/cache/ba1/05/e8/6a85b96b711a24d6b3ed85754de6", - "assets/build/ba_data/audio/penguin2.ogg": "https://files.ballistica.net/cache/ba1/a6/1c/684a4571e1e99b214ca21d600e41", - "assets/build/ba_data/audio/penguin3.ogg": "https://files.ballistica.net/cache/ba1/79/13/d728dd568a344cc7383a88a0f05a", - "assets/build/ba_data/audio/penguin4.ogg": "https://files.ballistica.net/cache/ba1/2d/f2/5b11c310268ef32a62b2ba4dcea2", - "assets/build/ba_data/audio/penguinDeath.ogg": "https://files.ballistica.net/cache/ba1/df/68/cd8363872bcef0b18d509685e3d0", - "assets/build/ba_data/audio/penguinFall.ogg": "https://files.ballistica.net/cache/ba1/a3/bb/28be81b10af2e47443e55e114878", - "assets/build/ba_data/audio/penguinHit1.ogg": "https://files.ballistica.net/cache/ba1/11/3a/9cd37ea4d2d61015c395d0e33815", - "assets/build/ba_data/audio/penguinHit2.ogg": "https://files.ballistica.net/cache/ba1/d2/5f/115f8eb45fff640967df5749383c", - "assets/build/ba_data/audio/pixie1.ogg": "https://files.ballistica.net/cache/ba1/f6/d6/8a1395d4d7305e8633f6e1caf0fb", - "assets/build/ba_data/audio/pixie2.ogg": "https://files.ballistica.net/cache/ba1/c0/5b/d0d2547b0887b7d7bbd81500b89a", - "assets/build/ba_data/audio/pixie3.ogg": "https://files.ballistica.net/cache/ba1/95/23/77e22310dd9377bb7a3444ac2bd7", - "assets/build/ba_data/audio/pixie4.ogg": "https://files.ballistica.net/cache/ba1/05/8b/81cf7b359746d76c762e2fd6004d", - "assets/build/ba_data/audio/pixieDeath.ogg": "https://files.ballistica.net/cache/ba1/e7/be/8a191fa33b425029a7e13625fa91", - "assets/build/ba_data/audio/pixieFall.ogg": "https://files.ballistica.net/cache/ba1/d5/64/34231aa7e9d336fa462cfaaec999", - "assets/build/ba_data/audio/pixieHit1.ogg": "https://files.ballistica.net/cache/ba1/e3/05/08b1c6f7e5906e6cb992dfbe514b", - "assets/build/ba_data/audio/pixieHit2.ogg": "https://files.ballistica.net/cache/ba1/ec/3f/c663c857d7530f216052ce814e97", - "assets/build/ba_data/audio/playerDeath.ogg": "https://files.ballistica.net/cache/ba1/96/a2/1e632a728ef300bcae2ff2d717a6", - "assets/build/ba_data/audio/playerLeft.ogg": "https://files.ballistica.net/cache/ba1/79/d8/7713140a3ede3b65e3bcdcba7d26", - "assets/build/ba_data/audio/pop01.ogg": "https://files.ballistica.net/cache/ba1/cc/48/4c7972a8ec6e7dbecc50debf05c9", - "assets/build/ba_data/audio/powerdown01.ogg": "https://files.ballistica.net/cache/ba1/a8/6d/9302b1a73bcbd9764f41875d7380", - "assets/build/ba_data/audio/powerup01.ogg": "https://files.ballistica.net/cache/ba1/fb/d4/deac2edc909c60ca651080a53794", - "assets/build/ba_data/audio/punch01.ogg": "https://files.ballistica.net/cache/ba1/55/4c/c31706350cfbb2a86af697848dab", - "assets/build/ba_data/audio/punchStrong01.ogg": "https://files.ballistica.net/cache/ba1/0d/7a/f1da7cbbd0597e5854a66efc2a88", - "assets/build/ba_data/audio/punchStrong02.ogg": "https://files.ballistica.net/cache/ba1/4e/c0/e100a891c673a56deeee605602b3", - "assets/build/ba_data/audio/punchSwish.ogg": "https://files.ballistica.net/cache/ba1/11/0c/d80e4d0842595fdc0923c4195ceb", - "assets/build/ba_data/audio/punchWeak01.ogg": "https://files.ballistica.net/cache/ba1/20/d3/08715bb8a195bc632c477469aed1", - "assets/build/ba_data/audio/raceBeep1.ogg": "https://files.ballistica.net/cache/ba1/53/5d/c54ae886ee8f56d3bb060fb0dfcb", - "assets/build/ba_data/audio/raceBeep2.ogg": "https://files.ballistica.net/cache/ba1/96/bc/455cf8d28acb205d13f01d4900bc", - "assets/build/ba_data/audio/refWhistle.ogg": "https://files.ballistica.net/cache/ba1/87/77/008ed6d8eac37f8b5aeabd8879c7", - "assets/build/ba_data/audio/robot1.ogg": "https://files.ballistica.net/cache/ba1/18/86/1ff23c315df417652e854b440c34", - "assets/build/ba_data/audio/robot2.ogg": "https://files.ballistica.net/cache/ba1/88/85/9f0ccaf6facb14a0a17d5ec89160", - "assets/build/ba_data/audio/robot3.ogg": "https://files.ballistica.net/cache/ba1/ac/92/647c8b99c83c1230d0709a27107b", - "assets/build/ba_data/audio/robot4.ogg": "https://files.ballistica.net/cache/ba1/ac/1e/6d1decef47d1fe68c36373f44cb4", - "assets/build/ba_data/audio/robotDeath.ogg": "https://files.ballistica.net/cache/ba1/0e/89/8e8dc3869dfa1349cfe6f400bd82", - "assets/build/ba_data/audio/robotFall.ogg": "https://files.ballistica.net/cache/ba1/02/d9/60eddc36b7ee6fbb02ae1ddb6b9e", - "assets/build/ba_data/audio/robotHit1.ogg": "https://files.ballistica.net/cache/ba1/eb/e2/f7f1492bd1ef17599b4253dea8e1", - "assets/build/ba_data/audio/robotHit2.ogg": "https://files.ballistica.net/cache/ba1/72/c3/3c9343953f884808f5452e6c7a1e", - "assets/build/ba_data/audio/runAwayMusic.ogg": "https://files.ballistica.net/cache/ba1/5a/d2/8dd3ec953d5a99a454250cee0cf2", - "assets/build/ba_data/audio/santa01.ogg": "https://files.ballistica.net/cache/ba1/f4/a4/18b599e1a8d2030e5ac71f57caad", - "assets/build/ba_data/audio/santa02.ogg": "https://files.ballistica.net/cache/ba1/c2/68/5bf7fc6c40706a830fa8feafd76d", - "assets/build/ba_data/audio/santa03.ogg": "https://files.ballistica.net/cache/ba1/0f/79/5ba921fe0af18aadc66b56443cd1", - "assets/build/ba_data/audio/santa04.ogg": "https://files.ballistica.net/cache/ba1/c7/7c/99c0b38cd9b457eafcc933efe0c4", - "assets/build/ba_data/audio/santa05.ogg": "https://files.ballistica.net/cache/ba1/e3/2f/03b8d771be498553d76dc3e1ca77", - "assets/build/ba_data/audio/santaDeath.ogg": "https://files.ballistica.net/cache/ba1/af/d2/17ef3bd225d342711fdaeaa13292", - "assets/build/ba_data/audio/santaFall.ogg": "https://files.ballistica.net/cache/ba1/3a/35/e7fd2c83bfa02fb4ef12226093bc", - "assets/build/ba_data/audio/santaHit01.ogg": "https://files.ballistica.net/cache/ba1/e5/a3/8212320d1f05b0abc8219f15283f", - "assets/build/ba_data/audio/santaHit02.ogg": "https://files.ballistica.net/cache/ba1/3f/56/d4f4afae2fe9f7d47fa57b2234c4", - "assets/build/ba_data/audio/santaHit03.ogg": "https://files.ballistica.net/cache/ba1/1d/63/5ba4653014fbc2885db708afd1ae", - "assets/build/ba_data/audio/santaHit04.ogg": "https://files.ballistica.net/cache/ba1/9c/fe/f0a5d119bf94ecd4547e81f12d7d", - "assets/build/ba_data/audio/scamper01.ogg": "https://files.ballistica.net/cache/ba1/b0/c0/77de611e53981f058e85d9d747b3", - "assets/build/ba_data/audio/scaryMusic.ogg": "https://files.ballistica.net/cache/ba1/62/a4/3f9af814e9a4796e994bde555a8f", - "assets/build/ba_data/audio/score.ogg": "https://files.ballistica.net/cache/ba1/5e/94/05dc50f166c99202a4aa2d106fff", - "assets/build/ba_data/audio/scoreHit01.ogg": "https://files.ballistica.net/cache/ba1/81/97/4ffd5ba4357e44df8f3ec37d75ed", - "assets/build/ba_data/audio/scoreHit02.ogg": "https://files.ballistica.net/cache/ba1/74/eb/220feb610faafde1e4601ff1dc65", - "assets/build/ba_data/audio/scoreIncrease.ogg": "https://files.ballistica.net/cache/ba1/cd/31/7ea93db05ec08d109bc53ff27114", - "assets/build/ba_data/audio/scoresEpicMusic.ogg": "https://files.ballistica.net/cache/ba1/16/63/0f6f47b8335573ae995d48671761", - "assets/build/ba_data/audio/shatter.ogg": "https://files.ballistica.net/cache/ba1/8c/10/27917e07d416be160445fbc51b30", - "assets/build/ba_data/audio/shieldDown.ogg": "https://files.ballistica.net/cache/ba1/f3/d8/039af57511dcf0c6a357a8607e31", - "assets/build/ba_data/audio/shieldHit.ogg": "https://files.ballistica.net/cache/ba1/ac/d8/191e528070dcfae914b1cd3a9ac3", - "assets/build/ba_data/audio/shieldUp.ogg": "https://files.ballistica.net/cache/ba1/eb/26/0d5329d330ee90542e8f7827ae9f", - "assets/build/ba_data/audio/skid01.ogg": "https://files.ballistica.net/cache/ba1/4f/0b/e12f1bd0b6e6b6246d5367ba492b", - "assets/build/ba_data/audio/slowEpicMusic.ogg": "https://files.ballistica.net/cache/ba1/5c/2e/7aa87fc4557c43009247e89d1a7e", - "assets/build/ba_data/audio/sparkle01.ogg": "https://files.ballistica.net/cache/ba1/06/97/865ba23d8393f0a6856e5ff9fa9f", - "assets/build/ba_data/audio/sparkle02.ogg": "https://files.ballistica.net/cache/ba1/e9/34/c7306677c23abe96b25005c4b227", - "assets/build/ba_data/audio/sparkle03.ogg": "https://files.ballistica.net/cache/ba1/fc/40/5883d06dc893f796276288494cda", - "assets/build/ba_data/audio/spawn.ogg": "https://files.ballistica.net/cache/ba1/1c/ad/832c7ca8efbd1933d05994b7f97c", - "assets/build/ba_data/audio/spazAttack01.ogg": "https://files.ballistica.net/cache/ba1/d0/af/5bba53f113f3ddd418da226a6383", - "assets/build/ba_data/audio/spazAttack02.ogg": "https://files.ballistica.net/cache/ba1/5c/99/cc38e0ef3afdce2e8957af33b100", - "assets/build/ba_data/audio/spazAttack03.ogg": "https://files.ballistica.net/cache/ba1/3c/1d/8c2d8fb2481e760da082cb976b40", - "assets/build/ba_data/audio/spazAttack04.ogg": "https://files.ballistica.net/cache/ba1/18/7c/d502771339dd6e0ac3425325ef7c", - "assets/build/ba_data/audio/spazDeath01.ogg": "https://files.ballistica.net/cache/ba1/41/96/bef46473014670f54ef9ea16df16", - "assets/build/ba_data/audio/spazEff.ogg": "https://files.ballistica.net/cache/ba1/70/72/d84808938005033bba5ca6955fef", - "assets/build/ba_data/audio/spazFall01.ogg": "https://files.ballistica.net/cache/ba1/aa/76/a7b3444ea49ff74f509108a22a66", - "assets/build/ba_data/audio/spazImpact01.ogg": "https://files.ballistica.net/cache/ba1/47/f1/58a6e673edfee76a535959ac574b", - "assets/build/ba_data/audio/spazImpact02.ogg": "https://files.ballistica.net/cache/ba1/1f/ca/ceb0cfe82f3269ecb595647d01f5", - "assets/build/ba_data/audio/spazImpact03.ogg": "https://files.ballistica.net/cache/ba1/7d/8a/6b5cb7d301808eb014a37e9b6d8f", - "assets/build/ba_data/audio/spazImpact04.ogg": "https://files.ballistica.net/cache/ba1/ad/32/6a3f980d5336cee41807efe6a9d6", - "assets/build/ba_data/audio/spazJump01.ogg": "https://files.ballistica.net/cache/ba1/77/b1/1478ab4c054f555d83f1a49d64b2", - "assets/build/ba_data/audio/spazJump02.ogg": "https://files.ballistica.net/cache/ba1/c3/70/f0acbf2c0916b2ac67b821c91372", - "assets/build/ba_data/audio/spazJump03.ogg": "https://files.ballistica.net/cache/ba1/cc/2c/66a30feb9b4781c8fbde12010ef5", - "assets/build/ba_data/audio/spazJump04.ogg": "https://files.ballistica.net/cache/ba1/91/83/cdcc15feadbd08dd4d899534ecf7", - "assets/build/ba_data/audio/spazOw.ogg": "https://files.ballistica.net/cache/ba1/1e/81/dc0302757a2d0ce8efbed226ce9e", - "assets/build/ba_data/audio/spazPickup01.ogg": "https://files.ballistica.net/cache/ba1/93/bf/c9b53b241bbec978c772c7e14caa", - "assets/build/ba_data/audio/spazScream01.ogg": "https://files.ballistica.net/cache/ba1/79/20/eb98e70397b0cd98149952753ef1", - "assets/build/ba_data/audio/splatter.ogg": "https://files.ballistica.net/cache/ba1/be/05/35059cebfb5658f7d434d32c94d1", - "assets/build/ba_data/audio/sportsMusic.ogg": "https://files.ballistica.net/cache/ba1/ff/cc/ba30edcc58ecc75ad4cf9f13e987", - "assets/build/ba_data/audio/stickyImpact.ogg": "https://files.ballistica.net/cache/ba1/5a/1c/bcfb5574c3ba2b8aec3d04d5937b", - "assets/build/ba_data/audio/superPunch.ogg": "https://files.ballistica.net/cache/ba1/ab/05/7ccdbb7ec4dc2da7e519644b7ab1", - "assets/build/ba_data/audio/superhero1.ogg": "https://files.ballistica.net/cache/ba1/2d/4b/d07a04dba349620a7b4f22e2340c", - "assets/build/ba_data/audio/superhero2.ogg": "https://files.ballistica.net/cache/ba1/35/b3/cf4479013786a22f2d378a998a15", - "assets/build/ba_data/audio/superhero3.ogg": "https://files.ballistica.net/cache/ba1/09/24/9aaf558d4eefad33845179b001f1", - "assets/build/ba_data/audio/superhero4.ogg": "https://files.ballistica.net/cache/ba1/3f/8e/219bab660637500a61f5be205b99", - "assets/build/ba_data/audio/superheroDeath.ogg": "https://files.ballistica.net/cache/ba1/d8/65/a0c7dc72b3a900ee3e9fc3a6c703", - "assets/build/ba_data/audio/superheroFall.ogg": "https://files.ballistica.net/cache/ba1/ba/21/c92b72275739cf682fe687fff10a", - "assets/build/ba_data/audio/superheroHit1.ogg": "https://files.ballistica.net/cache/ba1/fc/23/e15bb8d3e6daf77b4e393123d6f7", - "assets/build/ba_data/audio/superheroHit2.ogg": "https://files.ballistica.net/cache/ba1/f4/05/e2719c56ac77f3db1be03a0feac8", - "assets/build/ba_data/audio/survivalMusic.ogg": "https://files.ballistica.net/cache/ba1/69/45/5993fb4a9b6caba465feae60e3aa", - "assets/build/ba_data/audio/swip.ogg": "https://files.ballistica.net/cache/ba1/b2/fe/1a0796807eeb42160aeed59622f7", - "assets/build/ba_data/audio/swip2.ogg": "https://files.ballistica.net/cache/ba1/08/3d/12d4291235d240dd7e44dbe7f283", - "assets/build/ba_data/audio/swish.ogg": "https://files.ballistica.net/cache/ba1/33/41/3648e08fa50e2cf876f6ffa7fb3e", - "assets/build/ba_data/audio/swish2.ogg": "https://files.ballistica.net/cache/ba1/cc/67/8294681a9e9a88d055f33022a41f", - "assets/build/ba_data/audio/swish3.ogg": "https://files.ballistica.net/cache/ba1/06/35/7e03c8300a493d9c6ec4185b62fb", - "assets/build/ba_data/audio/tap.ogg": "https://files.ballistica.net/cache/ba1/30/7f/9f2a2aabfc63dfdb3e93106f3835", - "assets/build/ba_data/audio/technoHit01.ogg": "https://files.ballistica.net/cache/ba1/61/8a/d322dc58f7f41f34f2937a3879cf", - "assets/build/ba_data/audio/tick.ogg": "https://files.ballistica.net/cache/ba1/f5/cf/722bc46de90a550cab9ca11dd076", - "assets/build/ba_data/audio/ticking.ogg": "https://files.ballistica.net/cache/ba1/fb/55/55e5508fc180a67b2730d731856b", - "assets/build/ba_data/audio/tickingCrazy.ogg": "https://files.ballistica.net/cache/ba1/75/1c/43cea75988866fe0674883d70e08", - "assets/build/ba_data/audio/toTheDeathMusic.ogg": "https://files.ballistica.net/cache/ba1/ee/9a/9d2459da2a3fa0fbc977c639c5c6", - "assets/build/ba_data/audio/trashRummage.ogg": "https://files.ballistica.net/cache/ba1/ce/93/0e1b7d2155bcaccb585b3bcbf8b6", - "assets/build/ba_data/audio/victoryMusic.ogg": "https://files.ballistica.net/cache/ba1/6a/a7/0cf20971661de58dd3ee118856dc", - "assets/build/ba_data/audio/warnBeep.ogg": "https://files.ballistica.net/cache/ba1/51/ab/710c0882ab078f155ee574e124f4", - "assets/build/ba_data/audio/warnBeeps.ogg": "https://files.ballistica.net/cache/ba1/bc/b4/fed2b34f7ec47465b637b49e69fa", - "assets/build/ba_data/audio/warrior1.ogg": "https://files.ballistica.net/cache/ba1/fc/29/a88557dabe502eaa1f4e61e66050", - "assets/build/ba_data/audio/warrior2.ogg": "https://files.ballistica.net/cache/ba1/f1/37/cb391e6b920f278c5b007b381388", - "assets/build/ba_data/audio/warrior3.ogg": "https://files.ballistica.net/cache/ba1/8c/2e/d7c4c7a599a3a368f2d95f247127", - "assets/build/ba_data/audio/warrior4.ogg": "https://files.ballistica.net/cache/ba1/07/51/4796e3f9f9de9c5566740e951222", - "assets/build/ba_data/audio/warriorDeath.ogg": "https://files.ballistica.net/cache/ba1/d9/b6/c2e7f4a83928534e285f7ce1c922", - "assets/build/ba_data/audio/warriorFall.ogg": "https://files.ballistica.net/cache/ba1/2d/c5/ba39d507aa20f054feda013a9f21", - "assets/build/ba_data/audio/warriorHit1.ogg": "https://files.ballistica.net/cache/ba1/4f/83/1cbd4d2fb3e94e5e25979ed097ca", - "assets/build/ba_data/audio/warriorHit2.ogg": "https://files.ballistica.net/cache/ba1/be/ac/36bf2226134a7d319fd12fd6b28a", - "assets/build/ba_data/audio/whenJohnnyComesMarchingHomeMusic.ogg": "https://files.ballistica.net/cache/ba1/08/b1/21ee18cb2db336861c5a04d86f45", - "assets/build/ba_data/audio/witch1.ogg": "https://files.ballistica.net/cache/ba1/67/4e/05132bdb446fbdc1e1915089763b", - "assets/build/ba_data/audio/witch2.ogg": "https://files.ballistica.net/cache/ba1/57/a2/141d27861ab6a6177337d422e428", - "assets/build/ba_data/audio/witch3.ogg": "https://files.ballistica.net/cache/ba1/41/13/88fe3efdbc6b300ea74b8db0c816", - "assets/build/ba_data/audio/witch4.ogg": "https://files.ballistica.net/cache/ba1/1e/6a/67aaa75635a97116ca7bb5761051", - "assets/build/ba_data/audio/witchDeath.ogg": "https://files.ballistica.net/cache/ba1/22/33/2c7098263df931564f14815be5e8", - "assets/build/ba_data/audio/witchFall.ogg": "https://files.ballistica.net/cache/ba1/54/1c/d2de34a6985d56b469f10b7560ef", - "assets/build/ba_data/audio/witchHit1.ogg": "https://files.ballistica.net/cache/ba1/ae/24/430389e6bafba567a096b55228e6", - "assets/build/ba_data/audio/witchHit2.ogg": "https://files.ballistica.net/cache/ba1/c1/56/89955e8ab2fabaa5ff989bdf299e", - "assets/build/ba_data/audio/wizard1.ogg": "https://files.ballistica.net/cache/ba1/ff/6a/f81dc1a4656c6dffd1a36216d1b8", - "assets/build/ba_data/audio/wizard2.ogg": "https://files.ballistica.net/cache/ba1/52/43/f0e9af1d49b8d20bf561f8f9d3a9", - "assets/build/ba_data/audio/wizard3.ogg": "https://files.ballistica.net/cache/ba1/50/ba/716520f2f0137d8f86410a6089fb", - "assets/build/ba_data/audio/wizard4.ogg": "https://files.ballistica.net/cache/ba1/50/cc/2d239102cdc2ace02e79d8b0879c", - "assets/build/ba_data/audio/wizardDeath.ogg": "https://files.ballistica.net/cache/ba1/bb/4c/5e4dc54df830187c63a2bc7922b6", - "assets/build/ba_data/audio/wizardFall.ogg": "https://files.ballistica.net/cache/ba1/25/a5/21d69464843cb9f067541383468d", - "assets/build/ba_data/audio/wizardHit1.ogg": "https://files.ballistica.net/cache/ba1/10/47/be3966c620333be4ca9c30e1a2c4", - "assets/build/ba_data/audio/wizardHit2.ogg": "https://files.ballistica.net/cache/ba1/40/9a/0aed7b1bff3e69c257099ac26c1d", - "assets/build/ba_data/audio/woodDebrisFall.ogg": "https://files.ballistica.net/cache/ba1/94/03/59046559bc61e1e4b01078e778dd", - "assets/build/ba_data/audio/wrestler1.ogg": "https://files.ballistica.net/cache/ba1/52/71/c84d34f895c64d2fb38d880c737e", - "assets/build/ba_data/audio/wrestler2.ogg": "https://files.ballistica.net/cache/ba1/81/1f/c93c1b89d8d434fe84985d7d1af0", - "assets/build/ba_data/audio/wrestler3.ogg": "https://files.ballistica.net/cache/ba1/d8/2e/af82c6b47d77e9fa91b431ae03d1", - "assets/build/ba_data/audio/wrestler4.ogg": "https://files.ballistica.net/cache/ba1/7b/28/3aab8e16de76fc7453ed1e0886a8", - "assets/build/ba_data/audio/wrestlerDeath.ogg": "https://files.ballistica.net/cache/ba1/ae/b3/090c2525c3f697450a142458f6dc", - "assets/build/ba_data/audio/wrestlerFall.ogg": "https://files.ballistica.net/cache/ba1/1f/15/15fb12bb80fa7363b2ba88a4dce3", - "assets/build/ba_data/audio/wrestlerHit1.ogg": "https://files.ballistica.net/cache/ba1/90/b6/403ede16b60bdf089ce92079ef65", - "assets/build/ba_data/audio/wrestlerHit2.ogg": "https://files.ballistica.net/cache/ba1/d8/f7/4b4104842d9a408a9bb757cebabf", - "assets/build/ba_data/audio/zoeAttack01.ogg": "https://files.ballistica.net/cache/ba1/22/66/786bb399ac6bfc406f8fb0f6b3b4", - "assets/build/ba_data/audio/zoeAttack02.ogg": "https://files.ballistica.net/cache/ba1/37/42/60be96146c62bb29b10efae99fbe", - "assets/build/ba_data/audio/zoeAttack03.ogg": "https://files.ballistica.net/cache/ba1/0d/1f/9a71c8ce2aa31ffc2bdaa3341aed", - "assets/build/ba_data/audio/zoeAttack04.ogg": "https://files.ballistica.net/cache/ba1/52/e2/97d0299a564d2b7454fb742d5aab", - "assets/build/ba_data/audio/zoeDeath01.ogg": "https://files.ballistica.net/cache/ba1/fa/aa/f622e55e348e145955e27a4c3e57", - "assets/build/ba_data/audio/zoeEff.ogg": "https://files.ballistica.net/cache/ba1/42/c3/0bf8991471b650a1d2cd320c5ce3", - "assets/build/ba_data/audio/zoeFall01.ogg": "https://files.ballistica.net/cache/ba1/9e/12/ce19febfcbf2b43eb733dbd1626b", - "assets/build/ba_data/audio/zoeImpact01.ogg": "https://files.ballistica.net/cache/ba1/01/8c/90ab117e9c73fc33d556d18b079a", - "assets/build/ba_data/audio/zoeImpact02.ogg": "https://files.ballistica.net/cache/ba1/01/69/21c09400f109285b9d8cb8814d69", - "assets/build/ba_data/audio/zoeImpact03.ogg": "https://files.ballistica.net/cache/ba1/61/72/5bf11492feba95994f75040e36ce", - "assets/build/ba_data/audio/zoeImpact04.ogg": "https://files.ballistica.net/cache/ba1/c1/b1/a1159e8caeb1f5b80fcff55e8244", - "assets/build/ba_data/audio/zoeJump01.ogg": "https://files.ballistica.net/cache/ba1/b1/f0/5220fdb723a42e9177a99f9f5bdc", - "assets/build/ba_data/audio/zoeJump02.ogg": "https://files.ballistica.net/cache/ba1/71/01/4b2e5d9e2fcdfba254290c71a002", - "assets/build/ba_data/audio/zoeJump03.ogg": "https://files.ballistica.net/cache/ba1/66/3b/8ffff9c3d0280b7d1a15c92dfa94", - "assets/build/ba_data/audio/zoeOw.ogg": "https://files.ballistica.net/cache/ba1/60/ad/38269b7f1c7dc20cb9a506cd0681", - "assets/build/ba_data/audio/zoePickup01.ogg": "https://files.ballistica.net/cache/ba1/72/85/d6fc4d16b7081d91fba2850b5b10", - "assets/build/ba_data/audio/zoeScream01.ogg": "https://files.ballistica.net/cache/ba1/e9/ae/1d674d0c086eaa0bd1c3b1db0505", - "assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/65/39/48faf0cc1c930728f3bf2a25e52b", - "assets/build/ba_data/data/languages/arabic.json": "https://files.ballistica.net/cache/ba1/b0/05/e530acaba539f040ce61e22561dc", + "assets/build/ba_data/audio/achievement.ogg": "https://files.ballistica.net/cache/ba1/f3/d5/5e2a71ca6cf6f8aeed9c70a543b6", + "assets/build/ba_data/audio/actionHero1.ogg": "https://files.ballistica.net/cache/ba1/51/2e/c7c47074120f8ae304d6a2402ed3", + "assets/build/ba_data/audio/actionHero2.ogg": "https://files.ballistica.net/cache/ba1/38/e1/087af551c2b25085527493f1f437", + "assets/build/ba_data/audio/actionHero3.ogg": "https://files.ballistica.net/cache/ba1/2d/84/3e8fea6c1fa735dcbd7426eedc86", + "assets/build/ba_data/audio/actionHero4.ogg": "https://files.ballistica.net/cache/ba1/5c/d7/73853336ac71e77e517e7cf366c0", + "assets/build/ba_data/audio/actionHeroDeath.ogg": "https://files.ballistica.net/cache/ba1/c8/13/3eb6536a0d2ae71ac0addc60bef4", + "assets/build/ba_data/audio/actionHeroFall.ogg": "https://files.ballistica.net/cache/ba1/76/32/8890531e4a43a10033197e16446e", + "assets/build/ba_data/audio/actionHeroHit1.ogg": "https://files.ballistica.net/cache/ba1/6b/eb/ef81c3c6287f81bc39bb0c237551", + "assets/build/ba_data/audio/actionHeroHit2.ogg": "https://files.ballistica.net/cache/ba1/14/03/3b04edc89059d34761e1a079159d", + "assets/build/ba_data/audio/activateBeep.ogg": "https://files.ballistica.net/cache/ba1/33/50/4991a97b5591728d75672c1b78d5", + "assets/build/ba_data/audio/agent1.ogg": "https://files.ballistica.net/cache/ba1/c8/a5/d77f655080024706e0fbf64aa630", + "assets/build/ba_data/audio/agent2.ogg": "https://files.ballistica.net/cache/ba1/ad/1e/e14a53f609c4d35b99397872c01d", + "assets/build/ba_data/audio/agent3.ogg": "https://files.ballistica.net/cache/ba1/ec/bd/e1979fa50c9db652b244f65a26a4", + "assets/build/ba_data/audio/agent4.ogg": "https://files.ballistica.net/cache/ba1/b1/e4/4b00d771656f9a76e329abbdf66f", + "assets/build/ba_data/audio/agentDeath.ogg": "https://files.ballistica.net/cache/ba1/b9/24/cb70898bdfd33d2afa3603782b1d", + "assets/build/ba_data/audio/agentFall.ogg": "https://files.ballistica.net/cache/ba1/b3/fc/ab76fab4cf39993b2c17fd7e8a44", + "assets/build/ba_data/audio/agentHit1.ogg": "https://files.ballistica.net/cache/ba1/26/4e/9c2e4088a8051c82a9a1f5c541be", + "assets/build/ba_data/audio/agentHit2.ogg": "https://files.ballistica.net/cache/ba1/01/ce/bc61c328d2d07ed3bfc607345f0c", + "assets/build/ba_data/audio/alarm.ogg": "https://files.ballistica.net/cache/ba1/40/0d/482f43a8226e0bb590afffe8d88f", + "assets/build/ba_data/audio/ali1.ogg": "https://files.ballistica.net/cache/ba1/98/ee/9e5acc253cf99b22ddd26face164", + "assets/build/ba_data/audio/ali2.ogg": "https://files.ballistica.net/cache/ba1/89/c8/991347dda8933633295537040667", + "assets/build/ba_data/audio/ali3.ogg": "https://files.ballistica.net/cache/ba1/61/8d/3d4cb7f8a2af897afb198c4956e2", + "assets/build/ba_data/audio/ali4.ogg": "https://files.ballistica.net/cache/ba1/31/4d/8a2ec328bd4bebe4a09d6698875c", + "assets/build/ba_data/audio/aliDeath.ogg": "https://files.ballistica.net/cache/ba1/34/34/d6ff448b9d6b10d0c1ddbd0e6088", + "assets/build/ba_data/audio/aliFall.ogg": "https://files.ballistica.net/cache/ba1/f1/01/a7ba4c5d77b9388f5be766bf8c30", + "assets/build/ba_data/audio/aliHit1.ogg": "https://files.ballistica.net/cache/ba1/ab/07/6c61513aa526927a4a43ba20e1a5", + "assets/build/ba_data/audio/aliHit2.ogg": "https://files.ballistica.net/cache/ba1/82/e1/050b95514af84a835c6feffac75c", + "assets/build/ba_data/audio/alien1.ogg": "https://files.ballistica.net/cache/ba1/70/80/0614cb0cc13d5cad13656441f7d1", + "assets/build/ba_data/audio/alien2.ogg": "https://files.ballistica.net/cache/ba1/de/05/e83bf8853889ac05ebe35f677aca", + "assets/build/ba_data/audio/alien3.ogg": "https://files.ballistica.net/cache/ba1/cb/24/49815689a4c238fda09800cd6ce7", + "assets/build/ba_data/audio/alien4.ogg": "https://files.ballistica.net/cache/ba1/4b/53/cc8bf4580f987e40d7d95a212c88", + "assets/build/ba_data/audio/alienDeath.ogg": "https://files.ballistica.net/cache/ba1/67/ff/c6e28264cb4e70d0a47803d1f029", + "assets/build/ba_data/audio/alienFall.ogg": "https://files.ballistica.net/cache/ba1/41/5c/f429880141ef4fb3dbb09a5be2bb", + "assets/build/ba_data/audio/alienHit1.ogg": "https://files.ballistica.net/cache/ba1/1a/59/8c3c8a7d2966ad49f80c4480c161", + "assets/build/ba_data/audio/alienHit2.ogg": "https://files.ballistica.net/cache/ba1/d8/c1/9227834c4723eb77d60498bb7bbc", + "assets/build/ba_data/audio/announceEight.ogg": "https://files.ballistica.net/cache/ba1/a5/73/3181472f013bbf691fd13c3fe33e", + "assets/build/ba_data/audio/announceFive.ogg": "https://files.ballistica.net/cache/ba1/b1/b0/f956a5754829263876a05f513927", + "assets/build/ba_data/audio/announceFour.ogg": "https://files.ballistica.net/cache/ba1/16/67/8f50374ba244dadb7dfd6bb19418", + "assets/build/ba_data/audio/announceNine.ogg": "https://files.ballistica.net/cache/ba1/37/9c/14fe574dc0affc296ab26dcb1d86", + "assets/build/ba_data/audio/announceOne.ogg": "https://files.ballistica.net/cache/ba1/17/14/4a3dcf847df5a741e62194e0a37c", + "assets/build/ba_data/audio/announceSeven.ogg": "https://files.ballistica.net/cache/ba1/a3/96/3b3fb67271b7ef4ad82b2e4a7033", + "assets/build/ba_data/audio/announceSix.ogg": "https://files.ballistica.net/cache/ba1/bb/ba/d00e2c4bba08906fcca225fc3dbf", + "assets/build/ba_data/audio/announceTen.ogg": "https://files.ballistica.net/cache/ba1/d2/44/d7ff46fb3327ffffe90683c46e90", + "assets/build/ba_data/audio/announceThree.ogg": "https://files.ballistica.net/cache/ba1/74/b1/a316d295648b50810bec7f4353aa", + "assets/build/ba_data/audio/announceTwo.ogg": "https://files.ballistica.net/cache/ba1/54/09/9ba10d9f168e1cfb4e1e7cde9809", + "assets/build/ba_data/audio/assassin1.ogg": "https://files.ballistica.net/cache/ba1/65/26/caa50e50182a1dc72c274e465119", + "assets/build/ba_data/audio/assassin2.ogg": "https://files.ballistica.net/cache/ba1/8d/0c/e73f4fcbaf240ab760fb3a832968", + "assets/build/ba_data/audio/assassin3.ogg": "https://files.ballistica.net/cache/ba1/d4/0a/a572d49afc3c84c6c39a2dba8774", + "assets/build/ba_data/audio/assassin4.ogg": "https://files.ballistica.net/cache/ba1/e0/27/97c6d449ad47071c27373de3fa6c", + "assets/build/ba_data/audio/assassinDeath.ogg": "https://files.ballistica.net/cache/ba1/f9/ab/b80d408f42d2f139d84df688a41b", + "assets/build/ba_data/audio/assassinFall.ogg": "https://files.ballistica.net/cache/ba1/12/4b/6ed517ee09f0b7fc51750c87a8a9", + "assets/build/ba_data/audio/assassinHit1.ogg": "https://files.ballistica.net/cache/ba1/d8/22/94956386c4cc9ef9e8da556b99b4", + "assets/build/ba_data/audio/assassinHit2.ogg": "https://files.ballistica.net/cache/ba1/b9/e0/fc1d60b14ac521d70fe5d424314e", + "assets/build/ba_data/audio/bear1.ogg": "https://files.ballistica.net/cache/ba1/a3/ab/b4d525a5fadc134f5c21c19d5bde", + "assets/build/ba_data/audio/bear2.ogg": "https://files.ballistica.net/cache/ba1/5e/af/375de0187b1dcf5a44e4c14571e5", + "assets/build/ba_data/audio/bear3.ogg": "https://files.ballistica.net/cache/ba1/3c/08/9e7bc2f2f7eb8c5489f86ff3808f", + "assets/build/ba_data/audio/bear4.ogg": "https://files.ballistica.net/cache/ba1/5f/78/e94c8d86be77fd0a272a0155f0b6", + "assets/build/ba_data/audio/bearDeath.ogg": "https://files.ballistica.net/cache/ba1/a9/c0/1d2ffbe07bfda063c298b1a3ef18", + "assets/build/ba_data/audio/bearFall.ogg": "https://files.ballistica.net/cache/ba1/03/7a/bb7c62149b84fc42ebd53b7b36ba", + "assets/build/ba_data/audio/bearHit1.ogg": "https://files.ballistica.net/cache/ba1/f0/ad/4f5938ad473d69e52c30adfb78cc", + "assets/build/ba_data/audio/bearHit2.ogg": "https://files.ballistica.net/cache/ba1/72/3b/2f9c5939de3020dae6ae35a26d2b", + "assets/build/ba_data/audio/bellHigh.ogg": "https://files.ballistica.net/cache/ba1/f3/ab/d3255a13929c03075000635d9828", + "assets/build/ba_data/audio/bellLow.ogg": "https://files.ballistica.net/cache/ba1/94/ba/39a470a2025506b817412e0bcc70", + "assets/build/ba_data/audio/bellMed.ogg": "https://files.ballistica.net/cache/ba1/0a/2c/c08661be5a50c6380d3a5f4c9c98", + "assets/build/ba_data/audio/bigImpact.ogg": "https://files.ballistica.net/cache/ba1/d5/cb/a157880053224bfef2904b926982", + "assets/build/ba_data/audio/bigImpact2.ogg": "https://files.ballistica.net/cache/ba1/16/6c/9bcef8e5894fccd4011be4470031", + "assets/build/ba_data/audio/blank.ogg": "https://files.ballistica.net/cache/ba1/43/e8/050dba8abace772c813fd6ea350f", + "assets/build/ba_data/audio/blip.ogg": "https://files.ballistica.net/cache/ba1/19/fb/4e031348b1990d8ba9e8e872ca7c", + "assets/build/ba_data/audio/block.ogg": "https://files.ballistica.net/cache/ba1/7d/0f/50a912a4f70b03f4a8a50736fac9", + "assets/build/ba_data/audio/bombDrop01.ogg": "https://files.ballistica.net/cache/ba1/6d/6b/476cd4bd6a01f248311c7e366ce7", + "assets/build/ba_data/audio/bombDrop02.ogg": "https://files.ballistica.net/cache/ba1/90/78/75d94812faf167ba889dfeeb8f2c", + "assets/build/ba_data/audio/bombRoll01.ogg": "https://files.ballistica.net/cache/ba1/08/58/8708df679194214c6a0cf8272f8f", + "assets/build/ba_data/audio/bones1.ogg": "https://files.ballistica.net/cache/ba1/15/e6/69a9048083d8a507cb321343d969", + "assets/build/ba_data/audio/bones2.ogg": "https://files.ballistica.net/cache/ba1/5c/6e/bf1e1b9226442caf8e396f732494", + "assets/build/ba_data/audio/bones3.ogg": "https://files.ballistica.net/cache/ba1/26/14/9c83805427ebb8169ce02da8f4fc", + "assets/build/ba_data/audio/bonesDeath.ogg": "https://files.ballistica.net/cache/ba1/37/af/ee3c9e2e9be28f158d8bfe288271", + "assets/build/ba_data/audio/bonesFall.ogg": "https://files.ballistica.net/cache/ba1/19/58/7d92c6ded9235ed75953c0575278", + "assets/build/ba_data/audio/boo.ogg": "https://files.ballistica.net/cache/ba1/88/1e/61c4c29f9f29c62ae0d739fa616e", + "assets/build/ba_data/audio/boxDrop.ogg": "https://files.ballistica.net/cache/ba1/ac/79/1a3ebb1995a2233e4ff20cc6f414", + "assets/build/ba_data/audio/boxingBell.ogg": "https://files.ballistica.net/cache/ba1/90/ca/e6cd30443468d0d7744ec2cf2b16", + "assets/build/ba_data/audio/bunny1.ogg": "https://files.ballistica.net/cache/ba1/1a/3a/9adf5c4c6f0e19a4ca041dc8bd6c", + "assets/build/ba_data/audio/bunny2.ogg": "https://files.ballistica.net/cache/ba1/b8/bc/9892c3c7e0486cf7964603a07026", + "assets/build/ba_data/audio/bunny3.ogg": "https://files.ballistica.net/cache/ba1/29/1a/daf478872b5e03d1b688a859361f", + "assets/build/ba_data/audio/bunny4.ogg": "https://files.ballistica.net/cache/ba1/3e/8d/f8c04d5b04510a9f819feea4dc38", + "assets/build/ba_data/audio/bunnyDeath.ogg": "https://files.ballistica.net/cache/ba1/05/34/c1209c636ea108f40aa0dfed1f21", + "assets/build/ba_data/audio/bunnyFall.ogg": "https://files.ballistica.net/cache/ba1/f3/4f/d6d25aed763dba1557d81ca841ea", + "assets/build/ba_data/audio/bunnyHit1.ogg": "https://files.ballistica.net/cache/ba1/a0/70/7386446444928a84143a789efb64", + "assets/build/ba_data/audio/bunnyHit2.ogg": "https://files.ballistica.net/cache/ba1/8a/f0/330a2c570abdf21fbfac405c11f8", + "assets/build/ba_data/audio/bunnyJump.ogg": "https://files.ballistica.net/cache/ba1/cd/ce/e9b54b393b37655f4ed98bfa0723", + "assets/build/ba_data/audio/cashRegister.ogg": "https://files.ballistica.net/cache/ba1/58/06/9b16086013a85db51f47c6d6c658", + "assets/build/ba_data/audio/cashRegister2.ogg": "https://files.ballistica.net/cache/ba1/cc/27/75c8a79efacb764dafeadfd1e9a3", + "assets/build/ba_data/audio/charSelectMusic.ogg": "https://files.ballistica.net/cache/ba1/ab/c8/c6fb5b258536ddf3b7a97f4691f3", + "assets/build/ba_data/audio/cheer.ogg": "https://files.ballistica.net/cache/ba1/ec/72/a62df06f59fb0d3cc4d2223e3a0b", + "assets/build/ba_data/audio/click01.ogg": "https://files.ballistica.net/cache/ba1/cd/1d/89da645995d2623342cc42810b05", + "assets/build/ba_data/audio/corkPop.ogg": "https://files.ballistica.net/cache/ba1/4c/25/ecfc72ff2547c9ed956a2be96913", + "assets/build/ba_data/audio/cowboy1.ogg": "https://files.ballistica.net/cache/ba1/43/b4/b59e1b6e7dcae4e844d6175d6c6c", + "assets/build/ba_data/audio/cowboy2.ogg": "https://files.ballistica.net/cache/ba1/1f/27/6a7bb5a31b05c3c3e42bf7f92a5d", + "assets/build/ba_data/audio/cowboy3.ogg": "https://files.ballistica.net/cache/ba1/92/be/7f2f99054217daa9ed6d996286bd", + "assets/build/ba_data/audio/cowboy4.ogg": "https://files.ballistica.net/cache/ba1/21/a9/f50864d9c2b53622e5539941a3ab", + "assets/build/ba_data/audio/cowboyDeath.ogg": "https://files.ballistica.net/cache/ba1/6a/c1/13379d13ff5f656b36e4e3059b3d", + "assets/build/ba_data/audio/cowboyFall.ogg": "https://files.ballistica.net/cache/ba1/86/63/fca5ce3316aeb3e6337bd6690fb6", + "assets/build/ba_data/audio/cowboyHit1.ogg": "https://files.ballistica.net/cache/ba1/a6/17/fa2ebe38c2f299502f5a4e284776", + "assets/build/ba_data/audio/cowboyHit2.ogg": "https://files.ballistica.net/cache/ba1/34/0b/5a7ff85c530ef298b91bd77fd98f", + "assets/build/ba_data/audio/crowdChant.ogg": "https://files.ballistica.net/cache/ba1/4c/9c/a0b17479325017d70898c8a9a848", + "assets/build/ba_data/audio/cyborg1.ogg": "https://files.ballistica.net/cache/ba1/8b/22/5230d73c00fe46a40ef77d334f72", + "assets/build/ba_data/audio/cyborg2.ogg": "https://files.ballistica.net/cache/ba1/51/36/1fb19c92b2b4b72510cc373d9335", + "assets/build/ba_data/audio/cyborg3.ogg": "https://files.ballistica.net/cache/ba1/70/8e/e4761c1425439b83ef84473b5dc4", + "assets/build/ba_data/audio/cyborg4.ogg": "https://files.ballistica.net/cache/ba1/db/dc/8bbe388332ae01492aa2092ca986", + "assets/build/ba_data/audio/cyborgDeath.ogg": "https://files.ballistica.net/cache/ba1/cd/a8/d607304530d35a1c7ee598806a7e", + "assets/build/ba_data/audio/cyborgFall.ogg": "https://files.ballistica.net/cache/ba1/88/5f/7f1fd7e445ff5aaf7b48168ddf47", + "assets/build/ba_data/audio/cyborgHit1.ogg": "https://files.ballistica.net/cache/ba1/fc/9b/5b707a799ba09cd5bf8a2ea2ab74", + "assets/build/ba_data/audio/cyborgHit2.ogg": "https://files.ballistica.net/cache/ba1/02/08/3589fe5d2cc8a5ad377cd412d075", + "assets/build/ba_data/audio/cymbal.ogg": "https://files.ballistica.net/cache/ba1/65/64/d3a28b93481211f36c16c38f541b", + "assets/build/ba_data/audio/debrisFall.ogg": "https://files.ballistica.net/cache/ba1/9c/1d/ab38dee1fc5ae329a48255300f23", + "assets/build/ba_data/audio/deek.ogg": "https://files.ballistica.net/cache/ba1/8a/51/9d0552c98334e99829f19bad4caa", + "assets/build/ba_data/audio/deek2.ogg": "https://files.ballistica.net/cache/ba1/45/ef/a51861737649df69c4cb19f862b9", + "assets/build/ba_data/audio/ding.ogg": "https://files.ballistica.net/cache/ba1/39/16/eea51f23a4e83942eeeeafcfa942", + "assets/build/ba_data/audio/dingSmall.ogg": "https://files.ballistica.net/cache/ba1/59/dc/4370f8812eed876a59477b8232e6", + "assets/build/ba_data/audio/dingSmallHigh.ogg": "https://files.ballistica.net/cache/ba1/b5/ca/c288834b3f18b31cb1637552aad4", + "assets/build/ba_data/audio/dripity.ogg": "https://files.ballistica.net/cache/ba1/b8/7b/ae00fed6e1768c7f7ccd72795716", + "assets/build/ba_data/audio/drumRoll.ogg": "https://files.ballistica.net/cache/ba1/16/bc/a1748c65ceb661b72d2b3fbbfd90", + "assets/build/ba_data/audio/error.ogg": "https://files.ballistica.net/cache/ba1/55/d9/600452cf5c77e7b6867435592297", + "assets/build/ba_data/audio/explosion01.ogg": "https://files.ballistica.net/cache/ba1/79/1d/3fa918960fe627215d33e6fe9114", + "assets/build/ba_data/audio/explosion02.ogg": "https://files.ballistica.net/cache/ba1/b0/6c/49e828c6e79335ce0ed65ca6df87", + "assets/build/ba_data/audio/explosion03.ogg": "https://files.ballistica.net/cache/ba1/84/03/ed1c7b04d456505c3f7b4199c2dd", + "assets/build/ba_data/audio/explosion04.ogg": "https://files.ballistica.net/cache/ba1/1d/c8/b5abced424394b940a8946b519e7", + "assets/build/ba_data/audio/explosion05.ogg": "https://files.ballistica.net/cache/ba1/b9/f7/22bae11a92444fbed2ed7d4c7eb6", + "assets/build/ba_data/audio/fanfare.ogg": "https://files.ballistica.net/cache/ba1/a9/d0/cd2a24f87b42d84dadae61dad923", + "assets/build/ba_data/audio/flagCatcherMusic.ogg": "https://files.ballistica.net/cache/ba1/52/12/9798329b48fc9fdfa8733689554e", + "assets/build/ba_data/audio/flyingMusic.ogg": "https://files.ballistica.net/cache/ba1/31/3c/55634e66c852ff7e54071814790d", + "assets/build/ba_data/audio/foghorn.ogg": "https://files.ballistica.net/cache/ba1/91/d0/ef544e7795ac3870f75767c04fa8", + "assets/build/ba_data/audio/footImpact01.ogg": "https://files.ballistica.net/cache/ba1/bc/e4/7b85048f228b6c173bbc2462ccfb", + "assets/build/ba_data/audio/footImpact02.ogg": "https://files.ballistica.net/cache/ba1/2b/5d/c282f36cbc93c047b73a736a8588", + "assets/build/ba_data/audio/footImpact03.ogg": "https://files.ballistica.net/cache/ba1/d8/b4/2c8d0afa16243ab9fd5f50d73961", + "assets/build/ba_data/audio/forwardMarchMusic.ogg": "https://files.ballistica.net/cache/ba1/ee/ee/197d0ca35ff876ff514f63e19bf5", + "assets/build/ba_data/audio/freeze.ogg": "https://files.ballistica.net/cache/ba1/52/79/dcc91d30bf5da1aa2ea8377098a5", + "assets/build/ba_data/audio/frosty01.ogg": "https://files.ballistica.net/cache/ba1/62/2f/2946eacb868a1e2253b5c732a1d7", + "assets/build/ba_data/audio/frosty02.ogg": "https://files.ballistica.net/cache/ba1/d1/91/dc8a2daa0a2b322d7eb1874ea3ca", + "assets/build/ba_data/audio/frosty03.ogg": "https://files.ballistica.net/cache/ba1/c4/9f/929872d7a36bcda8ea945c203c39", + "assets/build/ba_data/audio/frosty04.ogg": "https://files.ballistica.net/cache/ba1/be/85/85ca0c05ca6197439d606139758e", + "assets/build/ba_data/audio/frosty05.ogg": "https://files.ballistica.net/cache/ba1/87/a7/d63e2469ee4ad6cf763e7e8f4627", + "assets/build/ba_data/audio/frostyDeath.ogg": "https://files.ballistica.net/cache/ba1/d8/a9/27865a436660c0648e96f1840213", + "assets/build/ba_data/audio/frostyFall.ogg": "https://files.ballistica.net/cache/ba1/b4/65/dfa57ab3023b3e5ae704c6c14635", + "assets/build/ba_data/audio/frostyHit01.ogg": "https://files.ballistica.net/cache/ba1/ec/da/f21a0a49e22afac4258536a7d111", + "assets/build/ba_data/audio/frostyHit02.ogg": "https://files.ballistica.net/cache/ba1/e4/f1/374d97cd8701178e246f927ae458", + "assets/build/ba_data/audio/frostyHit03.ogg": "https://files.ballistica.net/cache/ba1/c7/e2/0fc25cbe1ddca8783522d5a8fe26", + "assets/build/ba_data/audio/fuse01.ogg": "https://files.ballistica.net/cache/ba1/97/44/9d62fc0ef5cd235d6b693242b350", + "assets/build/ba_data/audio/gladiator1.ogg": "https://files.ballistica.net/cache/ba1/6b/32/acdb08f2fe53dd2578960ab6691a", + "assets/build/ba_data/audio/gladiator2.ogg": "https://files.ballistica.net/cache/ba1/9d/74/4fb06f51fd7a516b4adcc5814398", + "assets/build/ba_data/audio/gladiator3.ogg": "https://files.ballistica.net/cache/ba1/b2/9d/2e9876baf78462fee1e36096b38b", + "assets/build/ba_data/audio/gladiator4.ogg": "https://files.ballistica.net/cache/ba1/cc/19/480dd490111b5bd957b1fd5a74fd", + "assets/build/ba_data/audio/gladiatorDeath.ogg": "https://files.ballistica.net/cache/ba1/a9/57/b9fd7904277e0992cd6bd8d79fe0", + "assets/build/ba_data/audio/gladiatorFall.ogg": "https://files.ballistica.net/cache/ba1/ed/3b/fc00ab9943309ab581d30e194d91", + "assets/build/ba_data/audio/gladiatorHit1.ogg": "https://files.ballistica.net/cache/ba1/ee/40/f0e73253bf12488efbc0597abb5c", + "assets/build/ba_data/audio/gladiatorHit2.ogg": "https://files.ballistica.net/cache/ba1/45/f7/9958e12b5c7b6090cafa8eb9d5e6", + "assets/build/ba_data/audio/gong.ogg": "https://files.ballistica.net/cache/ba1/a1/e6/119b5a45bdf844d1c4e41fb3f9cb", + "assets/build/ba_data/audio/grandRompMusic.ogg": "https://files.ballistica.net/cache/ba1/8d/29/1099167132da4216f7bde71b5fdf", + "assets/build/ba_data/audio/gravelSkid.ogg": "https://files.ballistica.net/cache/ba1/dc/54/5b7ad32d8836cb6a5924b24bad3c", + "assets/build/ba_data/audio/gunCocking.ogg": "https://files.ballistica.net/cache/ba1/ef/f1/925f4a7b855c2a1e260963a7724e", + "assets/build/ba_data/audio/healthPowerup.ogg": "https://files.ballistica.net/cache/ba1/93/d3/4444d3b37d60da6da1b06d39eb3d", + "assets/build/ba_data/audio/hiss.ogg": "https://files.ballistica.net/cache/ba1/75/19/967eaf13ac18d5344687b31b825b", + "assets/build/ba_data/audio/impactHard.ogg": "https://files.ballistica.net/cache/ba1/41/f8/5a634967c4a301b01af3e39ca662", + "assets/build/ba_data/audio/impactHard2.ogg": "https://files.ballistica.net/cache/ba1/99/a7/7b6ce0554277632223b4eb5098be", + "assets/build/ba_data/audio/impactHard3.ogg": "https://files.ballistica.net/cache/ba1/1e/73/d12e04a1ef2320593095dbf272c8", + "assets/build/ba_data/audio/impactMedium.ogg": "https://files.ballistica.net/cache/ba1/ce/1f/3a8634bb6a2e51c3433263753b2b", + "assets/build/ba_data/audio/impactMedium2.ogg": "https://files.ballistica.net/cache/ba1/29/e4/1ad30c3e4a8329792f9d0377a7f9", + "assets/build/ba_data/audio/jack01.ogg": "https://files.ballistica.net/cache/ba1/b5/85/5fd635abe61994e3b7f76150be72", + "assets/build/ba_data/audio/jack02.ogg": "https://files.ballistica.net/cache/ba1/53/f0/7d36ae98b4dbde81a6aa4417a54e", + "assets/build/ba_data/audio/jack03.ogg": "https://files.ballistica.net/cache/ba1/35/12/5d9d51e11c4cbcc4a51cd7aa7386", + "assets/build/ba_data/audio/jack04.ogg": "https://files.ballistica.net/cache/ba1/5c/8a/66792bd597bc78d3bd69aa8a78d8", + "assets/build/ba_data/audio/jack05.ogg": "https://files.ballistica.net/cache/ba1/e4/64/c07c3fea5e9daf4365e29c4dba4e", + "assets/build/ba_data/audio/jack06.ogg": "https://files.ballistica.net/cache/ba1/28/3d/c4b10bf690fc7cf4105bcec52e60", + "assets/build/ba_data/audio/jackDeath01.ogg": "https://files.ballistica.net/cache/ba1/02/3b/94a7c8dff92d6a4c09812aa210c1", + "assets/build/ba_data/audio/jackFall01.ogg": "https://files.ballistica.net/cache/ba1/80/66/f9351ac9bffd10925e7c691d46ab", + "assets/build/ba_data/audio/jackHit01.ogg": "https://files.ballistica.net/cache/ba1/9d/e3/e8bcd1ec3110176db9e9297af651", + "assets/build/ba_data/audio/jackHit02.ogg": "https://files.ballistica.net/cache/ba1/4b/71/303d9ff5860c3167826574f686a3", + "assets/build/ba_data/audio/jackHit03.ogg": "https://files.ballistica.net/cache/ba1/97/36/cf14a4f0a81294cfb0b4d6f3ba6c", + "assets/build/ba_data/audio/jackHit04.ogg": "https://files.ballistica.net/cache/ba1/53/8a/134add64050d0b7f099ecc1d9010", + "assets/build/ba_data/audio/jackHit05.ogg": "https://files.ballistica.net/cache/ba1/9e/2d/a868226d28ab85b3dbe56ef65f66", + "assets/build/ba_data/audio/jackHit06.ogg": "https://files.ballistica.net/cache/ba1/61/f8/14d3da7441144e9940824d88a957", + "assets/build/ba_data/audio/jackHit07.ogg": "https://files.ballistica.net/cache/ba1/64/ad/e97279ab67cb0e1e8303efc877b5", + "assets/build/ba_data/audio/jumpsuit1.ogg": "https://files.ballistica.net/cache/ba1/39/23/f8edb71f6f85d2cd51a367987d55", + "assets/build/ba_data/audio/jumpsuit2.ogg": "https://files.ballistica.net/cache/ba1/c8/16/0bf8adc42a05a120637f95c19661", + "assets/build/ba_data/audio/jumpsuit3.ogg": "https://files.ballistica.net/cache/ba1/d4/5b/513d63607c2984437943ea8b239b", + "assets/build/ba_data/audio/jumpsuit4.ogg": "https://files.ballistica.net/cache/ba1/30/0a/6c585f5da9f973ba50948384e8a8", + "assets/build/ba_data/audio/jumpsuitDeath.ogg": "https://files.ballistica.net/cache/ba1/e6/90/f6bf19166f69ce0d172a621b469b", + "assets/build/ba_data/audio/jumpsuitFall.ogg": "https://files.ballistica.net/cache/ba1/e9/3c/fe21b00dd90b42953fa103988cd5", + "assets/build/ba_data/audio/jumpsuitHit1.ogg": "https://files.ballistica.net/cache/ba1/8a/3b/1f9ec398374b21ccf34f012401e5", + "assets/build/ba_data/audio/jumpsuitHit2.ogg": "https://files.ballistica.net/cache/ba1/9f/51/4b0e7300f2ddd43a03cc71718099", + "assets/build/ba_data/audio/kronk1.ogg": "https://files.ballistica.net/cache/ba1/77/52/74e8e3da507f7df42ab089e452ab", + "assets/build/ba_data/audio/kronk10.ogg": "https://files.ballistica.net/cache/ba1/c3/82/c4446a9eeb01db9eed2b934964e0", + "assets/build/ba_data/audio/kronk2.ogg": "https://files.ballistica.net/cache/ba1/27/37/ecdd7aefbb819df2dfa9de5df7f4", + "assets/build/ba_data/audio/kronk3.ogg": "https://files.ballistica.net/cache/ba1/1b/a3/f23b1d69fa4573fd3c87f1ff87e2", + "assets/build/ba_data/audio/kronk4.ogg": "https://files.ballistica.net/cache/ba1/e3/a8/50dccbe9ef4a6b7521a855717e9b", + "assets/build/ba_data/audio/kronk5.ogg": "https://files.ballistica.net/cache/ba1/e9/ff/fb7221fdba9ab8b39e74551d8c0e", + "assets/build/ba_data/audio/kronk6.ogg": "https://files.ballistica.net/cache/ba1/39/2b/c713770379a6bd408f8d448da0fc", + "assets/build/ba_data/audio/kronk7.ogg": "https://files.ballistica.net/cache/ba1/c2/50/a63b1059cb5082c04f0b1ae9b906", + "assets/build/ba_data/audio/kronk8.ogg": "https://files.ballistica.net/cache/ba1/8c/f2/20f9eb4f6b6d506c60a927db227c", + "assets/build/ba_data/audio/kronk9.ogg": "https://files.ballistica.net/cache/ba1/30/7a/8d1ca7b2f70aa304b58bf51c6de5", + "assets/build/ba_data/audio/kronkDeath.ogg": "https://files.ballistica.net/cache/ba1/08/b6/edf2245909ded074251df0a80ab7", + "assets/build/ba_data/audio/kronkFall.ogg": "https://files.ballistica.net/cache/ba1/36/3d/3f91c7274573b339420f0d2eec27", + "assets/build/ba_data/audio/laser.ogg": "https://files.ballistica.net/cache/ba1/d8/25/e850a6eefb28c0eb0ce443d820b9", + "assets/build/ba_data/audio/laserReverse.ogg": "https://files.ballistica.net/cache/ba1/bc/af/71cd60f6a0503600f9d23480e6dc", + "assets/build/ba_data/audio/mel01.ogg": "https://files.ballistica.net/cache/ba1/0c/f0/a65788b2f969e3d11c57edc86407", + "assets/build/ba_data/audio/mel02.ogg": "https://files.ballistica.net/cache/ba1/ae/e5/4a39d0d13d8e564779e2e49d050b", + "assets/build/ba_data/audio/mel03.ogg": "https://files.ballistica.net/cache/ba1/22/d4/fbaccc9afab4a40b78076fc92033", + "assets/build/ba_data/audio/mel04.ogg": "https://files.ballistica.net/cache/ba1/24/b9/97f82742ff350c73371d74c98d5b", + "assets/build/ba_data/audio/mel05.ogg": "https://files.ballistica.net/cache/ba1/28/e8/11247575d0932a20631522746d43", + "assets/build/ba_data/audio/mel06.ogg": "https://files.ballistica.net/cache/ba1/6e/d9/29959b895cb35593873ad9960936", + "assets/build/ba_data/audio/mel07.ogg": "https://files.ballistica.net/cache/ba1/bc/c4/cf7acca65fdf775d6a88c066cd79", + "assets/build/ba_data/audio/mel08.ogg": "https://files.ballistica.net/cache/ba1/0c/5c/d5fbecac8eec27b2d26dc80b4d4d", + "assets/build/ba_data/audio/mel09.ogg": "https://files.ballistica.net/cache/ba1/f5/0d/ad46aa724824e20476d5facd7d27", + "assets/build/ba_data/audio/mel10.ogg": "https://files.ballistica.net/cache/ba1/39/cb/b1adf0dfca2564a53a60e39e0bf9", + "assets/build/ba_data/audio/melDeath01.ogg": "https://files.ballistica.net/cache/ba1/6a/39/a7cbb7d831fa85582848785a6a06", + "assets/build/ba_data/audio/melFall01.ogg": "https://files.ballistica.net/cache/ba1/c2/49/cd61d684370771adf48d5cec915c", + "assets/build/ba_data/audio/menuMusic.ogg": "https://files.ballistica.net/cache/ba1/c2/bd/677235d772c411df8bd3f857166d", + "assets/build/ba_data/audio/metalHit.ogg": "https://files.ballistica.net/cache/ba1/3f/5e/efc8799297357fca2cc7b9a8262b", + "assets/build/ba_data/audio/metalSkid.ogg": "https://files.ballistica.net/cache/ba1/61/ca/606fa387056d1467ba86287f2b2f", + "assets/build/ba_data/audio/ninjaAttack1.ogg": "https://files.ballistica.net/cache/ba1/78/e2/8034c596aed2d221535b77bb158f", + "assets/build/ba_data/audio/ninjaAttack2.ogg": "https://files.ballistica.net/cache/ba1/43/48/5248ae17008e761a75619f65d5b1", + "assets/build/ba_data/audio/ninjaAttack3.ogg": "https://files.ballistica.net/cache/ba1/6e/7d/43b4f3366d5677b1195e48320d42", + "assets/build/ba_data/audio/ninjaAttack4.ogg": "https://files.ballistica.net/cache/ba1/cb/95/92066a1a15bf9ec2eebd41175c0c", + "assets/build/ba_data/audio/ninjaAttack5.ogg": "https://files.ballistica.net/cache/ba1/b8/66/d4759b1dc0f8d9ac8c711d3efed0", + "assets/build/ba_data/audio/ninjaAttack6.ogg": "https://files.ballistica.net/cache/ba1/8d/eb/0bfb920a3a2cf8cad1a6dc698185", + "assets/build/ba_data/audio/ninjaAttack7.ogg": "https://files.ballistica.net/cache/ba1/51/fd/753d3d6fa8b70dfe3ca98ea6b5a8", + "assets/build/ba_data/audio/ninjaDeath1.ogg": "https://files.ballistica.net/cache/ba1/0e/4e/68afa0525b0128f3426d373a707c", + "assets/build/ba_data/audio/ninjaFall1.ogg": "https://files.ballistica.net/cache/ba1/9f/86/9846c88411f44e5798b1df0972ef", + "assets/build/ba_data/audio/ninjaHit1.ogg": "https://files.ballistica.net/cache/ba1/52/33/06e556d1f2d4394345b0ec136269", + "assets/build/ba_data/audio/ninjaHit2.ogg": "https://files.ballistica.net/cache/ba1/ec/47/dbe01b83be6dece26568dab8f9cd", + "assets/build/ba_data/audio/ninjaHit3.ogg": "https://files.ballistica.net/cache/ba1/b5/2f/a9be291152d452626b876789ab55", + "assets/build/ba_data/audio/ninjaHit4.ogg": "https://files.ballistica.net/cache/ba1/d8/2e/f2b560eba8426001dd7185d5ac36", + "assets/build/ba_data/audio/ninjaHit5.ogg": "https://files.ballistica.net/cache/ba1/6c/1e/3e7ee3fd14ed569c8017e1a46dd2", + "assets/build/ba_data/audio/ninjaHit6.ogg": "https://files.ballistica.net/cache/ba1/81/64/44964a4230cdccb1900e995607fb", + "assets/build/ba_data/audio/ninjaHit7.ogg": "https://files.ballistica.net/cache/ba1/d7/e4/e7dfb867ee3cb8e180d5e331a3b6", + "assets/build/ba_data/audio/ninjaHit8.ogg": "https://files.ballistica.net/cache/ba1/b9/39/10bd0494ac058da08f3742bae9cf", + "assets/build/ba_data/audio/oldLady1.ogg": "https://files.ballistica.net/cache/ba1/9e/36/929c80893b25e634af15c590e9a5", + "assets/build/ba_data/audio/oldLady2.ogg": "https://files.ballistica.net/cache/ba1/5e/8d/2eba5556abbeae8c7dd8f5894248", + "assets/build/ba_data/audio/oldLady3.ogg": "https://files.ballistica.net/cache/ba1/48/23/5dcf088300c2ab9d3b954556f793", + "assets/build/ba_data/audio/oldLady4.ogg": "https://files.ballistica.net/cache/ba1/17/8d/2cf274325b17734183919426511f", + "assets/build/ba_data/audio/oldLadyDeath.ogg": "https://files.ballistica.net/cache/ba1/19/ab/34226d428d14053928448d9d8399", + "assets/build/ba_data/audio/oldLadyFall.ogg": "https://files.ballistica.net/cache/ba1/24/c1/e118eece3a257218ee1108949033", + "assets/build/ba_data/audio/oldLadyHit1.ogg": "https://files.ballistica.net/cache/ba1/5b/46/a5793c4ccf547a06eb5425141204", + "assets/build/ba_data/audio/oldLadyHit2.ogg": "https://files.ballistica.net/cache/ba1/ab/55/4f80974d72476a870ea2c2f6a687", + "assets/build/ba_data/audio/ooh.ogg": "https://files.ballistica.net/cache/ba1/44/df/7ba3b19fd9975767a62caabdbf1a", + "assets/build/ba_data/audio/operaSinger1.ogg": "https://files.ballistica.net/cache/ba1/af/af/d69f491131ebb178c9c89917b6ef", + "assets/build/ba_data/audio/operaSinger2.ogg": "https://files.ballistica.net/cache/ba1/6e/71/17ce065c420dfd6195649737744e", + "assets/build/ba_data/audio/operaSinger3.ogg": "https://files.ballistica.net/cache/ba1/ba/7a/a520afa6dddad1cb486701d0f50a", + "assets/build/ba_data/audio/operaSinger4.ogg": "https://files.ballistica.net/cache/ba1/c7/c9/b5d93a459ccd408783feff0dbbdf", + "assets/build/ba_data/audio/operaSingerDeath.ogg": "https://files.ballistica.net/cache/ba1/1b/6c/697b633102c8f3356f38cbcae8ae", + "assets/build/ba_data/audio/operaSingerFall.ogg": "https://files.ballistica.net/cache/ba1/d7/3a/89f237631614bcde93a2d6ba81ef", + "assets/build/ba_data/audio/operaSingerHit1.ogg": "https://files.ballistica.net/cache/ba1/e0/af/7a6f40e6e86130f2599dc366ece1", + "assets/build/ba_data/audio/operaSingerHit2.ogg": "https://files.ballistica.net/cache/ba1/c5/7e/3cd98dd46903eb55e1694dca8296", + "assets/build/ba_data/audio/orchestraHit.ogg": "https://files.ballistica.net/cache/ba1/54/a5/c93bbcfa5529df5df8b62b705578", + "assets/build/ba_data/audio/orchestraHit2.ogg": "https://files.ballistica.net/cache/ba1/96/05/a886a29b1927a28c99d810273e42", + "assets/build/ba_data/audio/orchestraHit3.ogg": "https://files.ballistica.net/cache/ba1/47/b0/ab1b857b3f88df03723829ac78ea", + "assets/build/ba_data/audio/orchestraHit4.ogg": "https://files.ballistica.net/cache/ba1/6f/44/5784023d13f904e13a44479c5170", + "assets/build/ba_data/audio/orchestraHitBig1.ogg": "https://files.ballistica.net/cache/ba1/c5/d3/be6de216457c53352552c34ec767", + "assets/build/ba_data/audio/orchestraHitBig2.ogg": "https://files.ballistica.net/cache/ba1/aa/4d/04abd9530e2b51099cda23185e88", + "assets/build/ba_data/audio/penguin1.ogg": "https://files.ballistica.net/cache/ba1/96/d0/67cdc12f275accdf71dc23750a89", + "assets/build/ba_data/audio/penguin2.ogg": "https://files.ballistica.net/cache/ba1/67/02/c6995bad0d80928ba610b9275eed", + "assets/build/ba_data/audio/penguin3.ogg": "https://files.ballistica.net/cache/ba1/b0/be/1d7fe761ebcd38887bd23da88a0f", + "assets/build/ba_data/audio/penguin4.ogg": "https://files.ballistica.net/cache/ba1/f1/c2/76455bec3a5125d5d773d227542c", + "assets/build/ba_data/audio/penguinDeath.ogg": "https://files.ballistica.net/cache/ba1/94/75/5fe589c3d2f15f94fbb66fdbdff2", + "assets/build/ba_data/audio/penguinFall.ogg": "https://files.ballistica.net/cache/ba1/d6/19/f3f6a990b1eba8bff6b23d51f66f", + "assets/build/ba_data/audio/penguinHit1.ogg": "https://files.ballistica.net/cache/ba1/cf/04/fc0f40439c99cfdafc5e8adf919c", + "assets/build/ba_data/audio/penguinHit2.ogg": "https://files.ballistica.net/cache/ba1/c9/9b/aff906f79da44fcffd024fd2c414", + "assets/build/ba_data/audio/pixie1.ogg": "https://files.ballistica.net/cache/ba1/6b/62/a03872005d47928b34a8cae3c56f", + "assets/build/ba_data/audio/pixie2.ogg": "https://files.ballistica.net/cache/ba1/73/84/8dbcb839ca1a8cf624996b8bd550", + "assets/build/ba_data/audio/pixie3.ogg": "https://files.ballistica.net/cache/ba1/65/74/36b05c07dcac3ad08d5473f063a7", + "assets/build/ba_data/audio/pixie4.ogg": "https://files.ballistica.net/cache/ba1/f9/34/b282ee64a0a9d50de1e68a4c78a8", + "assets/build/ba_data/audio/pixieDeath.ogg": "https://files.ballistica.net/cache/ba1/55/e9/3513ac4e4dd75c9bfa797baf5557", + "assets/build/ba_data/audio/pixieFall.ogg": "https://files.ballistica.net/cache/ba1/9c/e6/f9b96eb8b9b31168a637e94cca62", + "assets/build/ba_data/audio/pixieHit1.ogg": "https://files.ballistica.net/cache/ba1/af/aa/40aed668f4a77ba0ff846beb48cf", + "assets/build/ba_data/audio/pixieHit2.ogg": "https://files.ballistica.net/cache/ba1/20/5e/5469a39cef7f67883e7f2b2737b2", + "assets/build/ba_data/audio/playerDeath.ogg": "https://files.ballistica.net/cache/ba1/45/d7/92d04d7e47a582ff63bf501da304", + "assets/build/ba_data/audio/playerLeft.ogg": "https://files.ballistica.net/cache/ba1/bd/c0/4d7d3a7d0c0c1908475e38d9771f", + "assets/build/ba_data/audio/pop01.ogg": "https://files.ballistica.net/cache/ba1/1f/66/8b1b6e78a9decc0c04aab3cb4d3e", + "assets/build/ba_data/audio/powerdown01.ogg": "https://files.ballistica.net/cache/ba1/ba/a9/8eb9e21fc9dbdade9f22460ae2ad", + "assets/build/ba_data/audio/powerup01.ogg": "https://files.ballistica.net/cache/ba1/11/74/3a8fd75ad5960711d2a77d763cd8", + "assets/build/ba_data/audio/punch01.ogg": "https://files.ballistica.net/cache/ba1/ad/a0/72e7f5b6e87061d8449b24e9f090", + "assets/build/ba_data/audio/punchStrong01.ogg": "https://files.ballistica.net/cache/ba1/f3/be/874d91f1e10210ed03f23a371392", + "assets/build/ba_data/audio/punchStrong02.ogg": "https://files.ballistica.net/cache/ba1/84/03/1ce099a47735a96e5579df9326f0", + "assets/build/ba_data/audio/punchSwish.ogg": "https://files.ballistica.net/cache/ba1/58/c0/6372b960fa643d5747054222c3bc", + "assets/build/ba_data/audio/punchWeak01.ogg": "https://files.ballistica.net/cache/ba1/29/2b/371db05ecc5731a21560e7a85435", + "assets/build/ba_data/audio/raceBeep1.ogg": "https://files.ballistica.net/cache/ba1/79/b9/dd9b60672fd3e051bb3e3db733d7", + "assets/build/ba_data/audio/raceBeep2.ogg": "https://files.ballistica.net/cache/ba1/c4/0b/5f2bc2d964f82a35880c57f9fc31", + "assets/build/ba_data/audio/refWhistle.ogg": "https://files.ballistica.net/cache/ba1/90/c9/e226f4a37985cb01d95f87693dec", + "assets/build/ba_data/audio/robot1.ogg": "https://files.ballistica.net/cache/ba1/30/50/88b5c8147d71e8e791699f19a319", + "assets/build/ba_data/audio/robot2.ogg": "https://files.ballistica.net/cache/ba1/13/59/0fd5790f64a4614ace6c4be28600", + "assets/build/ba_data/audio/robot3.ogg": "https://files.ballistica.net/cache/ba1/10/3d/1c9c8038c0e778e484004f4ed919", + "assets/build/ba_data/audio/robot4.ogg": "https://files.ballistica.net/cache/ba1/bc/46/0a237edb9874e3253d9f2f7a343f", + "assets/build/ba_data/audio/robotDeath.ogg": "https://files.ballistica.net/cache/ba1/6b/ea/5911c543539be1aee409623f872c", + "assets/build/ba_data/audio/robotFall.ogg": "https://files.ballistica.net/cache/ba1/46/0c/162aac5f716710940f16827901d7", + "assets/build/ba_data/audio/robotHit1.ogg": "https://files.ballistica.net/cache/ba1/f8/47/bf2af36ad0bdd9b930d85fea3d24", + "assets/build/ba_data/audio/robotHit2.ogg": "https://files.ballistica.net/cache/ba1/0b/88/cb0f04ca63cef24f538067344313", + "assets/build/ba_data/audio/runAwayMusic.ogg": "https://files.ballistica.net/cache/ba1/53/04/fdf9a3fde90e048552c1ed637a30", + "assets/build/ba_data/audio/santa01.ogg": "https://files.ballistica.net/cache/ba1/63/c4/70457ef8a719e7f94ee4c24d5cdc", + "assets/build/ba_data/audio/santa02.ogg": "https://files.ballistica.net/cache/ba1/83/71/9697c0bdccb20aa069d846e4389f", + "assets/build/ba_data/audio/santa03.ogg": "https://files.ballistica.net/cache/ba1/5e/be/9f7e11ce57f5fa818e0fdff5a0cb", + "assets/build/ba_data/audio/santa04.ogg": "https://files.ballistica.net/cache/ba1/45/6f/e747cbfec5265c14c5020bf49a44", + "assets/build/ba_data/audio/santa05.ogg": "https://files.ballistica.net/cache/ba1/9e/3c/413f723a07a39e5b77b0e6b302fa", + "assets/build/ba_data/audio/santaDeath.ogg": "https://files.ballistica.net/cache/ba1/ed/34/c4ec2ab2c509c898dbc0335457e0", + "assets/build/ba_data/audio/santaFall.ogg": "https://files.ballistica.net/cache/ba1/fd/70/39172ca4d9b9e3893ef1afafee19", + "assets/build/ba_data/audio/santaHit01.ogg": "https://files.ballistica.net/cache/ba1/3c/9e/1fe24503070a707835a92e9cd146", + "assets/build/ba_data/audio/santaHit02.ogg": "https://files.ballistica.net/cache/ba1/c2/9b/42a45c7ddbd129e1720488267c0b", + "assets/build/ba_data/audio/santaHit03.ogg": "https://files.ballistica.net/cache/ba1/bb/e6/8e35f024ec235c71c421d19f5b93", + "assets/build/ba_data/audio/santaHit04.ogg": "https://files.ballistica.net/cache/ba1/1c/21/3695395ec8f3a5647e6582e63ca9", + "assets/build/ba_data/audio/scamper01.ogg": "https://files.ballistica.net/cache/ba1/32/15/16615413a664fa3e0d542bb8ce3c", + "assets/build/ba_data/audio/scaryMusic.ogg": "https://files.ballistica.net/cache/ba1/d3/3d/70feb213476ea0edf898d77f835f", + "assets/build/ba_data/audio/score.ogg": "https://files.ballistica.net/cache/ba1/c1/09/048f19bf5fcf19493d27ba38ab50", + "assets/build/ba_data/audio/scoreHit01.ogg": "https://files.ballistica.net/cache/ba1/67/a9/ad05c6978fff7168d5bd66c58acd", + "assets/build/ba_data/audio/scoreHit02.ogg": "https://files.ballistica.net/cache/ba1/fa/fd/2ba45d36a85fad745e35120ad018", + "assets/build/ba_data/audio/scoreIncrease.ogg": "https://files.ballistica.net/cache/ba1/17/f9/e86c215312751e8aae0f949f5bbb", + "assets/build/ba_data/audio/scoresEpicMusic.ogg": "https://files.ballistica.net/cache/ba1/1e/49/71e9b044eac0a44ab164e9d32dd3", + "assets/build/ba_data/audio/shatter.ogg": "https://files.ballistica.net/cache/ba1/e6/c0/8cce4c7319f2c1e8509d80304a08", + "assets/build/ba_data/audio/shieldDown.ogg": "https://files.ballistica.net/cache/ba1/03/12/41ae30770b3a307a38db273b945b", + "assets/build/ba_data/audio/shieldHit.ogg": "https://files.ballistica.net/cache/ba1/24/37/95c9f92135dcd51460ac47d6f872", + "assets/build/ba_data/audio/shieldUp.ogg": "https://files.ballistica.net/cache/ba1/fe/d8/a2ccd8c6a875995d9cb2ea19b15f", + "assets/build/ba_data/audio/skid01.ogg": "https://files.ballistica.net/cache/ba1/9f/74/75e3aa4f69b481ce71a288782572", + "assets/build/ba_data/audio/slowEpicMusic.ogg": "https://files.ballistica.net/cache/ba1/0d/43/64ec39569be59bba8f4059814a3c", + "assets/build/ba_data/audio/sparkle01.ogg": "https://files.ballistica.net/cache/ba1/0c/95/849c30c8f047e1b8445dbac2169f", + "assets/build/ba_data/audio/sparkle02.ogg": "https://files.ballistica.net/cache/ba1/89/77/035cc2335b6fc20b1cf37116eb1e", + "assets/build/ba_data/audio/sparkle03.ogg": "https://files.ballistica.net/cache/ba1/a0/80/88f0a22537e0db0a6337b2731d65", + "assets/build/ba_data/audio/spawn.ogg": "https://files.ballistica.net/cache/ba1/a8/1b/3080a33a5046a077986b9e977ecf", + "assets/build/ba_data/audio/spazAttack01.ogg": "https://files.ballistica.net/cache/ba1/28/14/ca3231a4a6f1b0929304b6f5c677", + "assets/build/ba_data/audio/spazAttack02.ogg": "https://files.ballistica.net/cache/ba1/8a/39/372d94e8c3a45514ac6456f97cc6", + "assets/build/ba_data/audio/spazAttack03.ogg": "https://files.ballistica.net/cache/ba1/5c/b0/8a10049b4b79f37ac0d5e2cb729d", + "assets/build/ba_data/audio/spazAttack04.ogg": "https://files.ballistica.net/cache/ba1/21/7e/a07f84f98336c748f6c1fc41b03e", + "assets/build/ba_data/audio/spazDeath01.ogg": "https://files.ballistica.net/cache/ba1/a1/91/7d96496edf684c752f85805ed03e", + "assets/build/ba_data/audio/spazEff.ogg": "https://files.ballistica.net/cache/ba1/86/79/68f7629d5a7df81cb0025109543b", + "assets/build/ba_data/audio/spazFall01.ogg": "https://files.ballistica.net/cache/ba1/83/24/7f069b84819f9e1156f088a72330", + "assets/build/ba_data/audio/spazImpact01.ogg": "https://files.ballistica.net/cache/ba1/9e/10/ffc51d16bc2a83a0f389563fa4d8", + "assets/build/ba_data/audio/spazImpact02.ogg": "https://files.ballistica.net/cache/ba1/29/27/628e5eb7225e100c9db5eff47b7e", + "assets/build/ba_data/audio/spazImpact03.ogg": "https://files.ballistica.net/cache/ba1/e6/17/ce670ea95902dcb89b0ca1f13eff", + "assets/build/ba_data/audio/spazImpact04.ogg": "https://files.ballistica.net/cache/ba1/55/9b/578090fb0611ac68da563714cd15", + "assets/build/ba_data/audio/spazJump01.ogg": "https://files.ballistica.net/cache/ba1/18/b2/4ed2eeba37d777b05c5377edbb96", + "assets/build/ba_data/audio/spazJump02.ogg": "https://files.ballistica.net/cache/ba1/cf/4f/add95e67b04e418c42240b1bb81f", + "assets/build/ba_data/audio/spazJump03.ogg": "https://files.ballistica.net/cache/ba1/30/d5/1d400ec73f5ca9923fdeb0b9843d", + "assets/build/ba_data/audio/spazJump04.ogg": "https://files.ballistica.net/cache/ba1/8d/32/2bfe88854b1f3788ecab1286d3bb", + "assets/build/ba_data/audio/spazOw.ogg": "https://files.ballistica.net/cache/ba1/72/a5/1b6f1bc2a9ec191eb45df24c1260", + "assets/build/ba_data/audio/spazPickup01.ogg": "https://files.ballistica.net/cache/ba1/d8/ee/1adfe00ecba727c8e2f54ff99ecd", + "assets/build/ba_data/audio/spazScream01.ogg": "https://files.ballistica.net/cache/ba1/a0/85/4ab16778763244d19550d2725007", + "assets/build/ba_data/audio/splatter.ogg": "https://files.ballistica.net/cache/ba1/4a/26/0438d4aa28b3d805b4f9469ff430", + "assets/build/ba_data/audio/sportsMusic.ogg": "https://files.ballistica.net/cache/ba1/2b/ef/0b0da5f5558997e8da86d266c289", + "assets/build/ba_data/audio/stickyImpact.ogg": "https://files.ballistica.net/cache/ba1/e8/07/05fd7dcee09235c6862d82bf73a7", + "assets/build/ba_data/audio/superPunch.ogg": "https://files.ballistica.net/cache/ba1/5d/e8/7954ca2e8f594472029cefc44abe", + "assets/build/ba_data/audio/superhero1.ogg": "https://files.ballistica.net/cache/ba1/26/6a/76a0f5f8285b3da815e9b28a00f9", + "assets/build/ba_data/audio/superhero2.ogg": "https://files.ballistica.net/cache/ba1/69/51/b854b7ba2f70c5ce7db207bc6fce", + "assets/build/ba_data/audio/superhero3.ogg": "https://files.ballistica.net/cache/ba1/c4/eb/599d6ca19ec9de46167250b3b23a", + "assets/build/ba_data/audio/superhero4.ogg": "https://files.ballistica.net/cache/ba1/3d/2c/8975784a8372ad489ac23234648f", + "assets/build/ba_data/audio/superheroDeath.ogg": "https://files.ballistica.net/cache/ba1/d2/6a/b14eebbb9b36638b481957f391d6", + "assets/build/ba_data/audio/superheroFall.ogg": "https://files.ballistica.net/cache/ba1/97/35/5cef7eeb9baf16770e9caa114e92", + "assets/build/ba_data/audio/superheroHit1.ogg": "https://files.ballistica.net/cache/ba1/81/72/3691463b32aa02b60c8bc9381670", + "assets/build/ba_data/audio/superheroHit2.ogg": "https://files.ballistica.net/cache/ba1/c8/e2/055ee4668f243b5f03c045d96acb", + "assets/build/ba_data/audio/survivalMusic.ogg": "https://files.ballistica.net/cache/ba1/9f/88/8b4f0a3fee6ffc29fbca70a69169", + "assets/build/ba_data/audio/swip.ogg": "https://files.ballistica.net/cache/ba1/a7/f7/f508ac8b231edd24c7b08a91372f", + "assets/build/ba_data/audio/swip2.ogg": "https://files.ballistica.net/cache/ba1/59/44/4e8ac27af8ba0f097509ac69a463", + "assets/build/ba_data/audio/swish.ogg": "https://files.ballistica.net/cache/ba1/80/b9/d898557d66baa07d9974b512f2f3", + "assets/build/ba_data/audio/swish2.ogg": "https://files.ballistica.net/cache/ba1/57/ac/37be94b2d53925f5b8019c3b5223", + "assets/build/ba_data/audio/swish3.ogg": "https://files.ballistica.net/cache/ba1/e3/23/5765d25bf9ca7865062762d20958", + "assets/build/ba_data/audio/tap.ogg": "https://files.ballistica.net/cache/ba1/ca/50/ffa77d494f5c376c52521a840373", + "assets/build/ba_data/audio/technoHit01.ogg": "https://files.ballistica.net/cache/ba1/7e/34/183c1d6cd701df425544a82945b6", + "assets/build/ba_data/audio/tick.ogg": "https://files.ballistica.net/cache/ba1/cf/e9/4df7effb9d488f56c37270a2327e", + "assets/build/ba_data/audio/ticking.ogg": "https://files.ballistica.net/cache/ba1/9f/59/0b9e8bf7cc6b01f65de3c826b3bd", + "assets/build/ba_data/audio/tickingCrazy.ogg": "https://files.ballistica.net/cache/ba1/7d/12/0443e477795a08d7d9be906fd31e", + "assets/build/ba_data/audio/toTheDeathMusic.ogg": "https://files.ballistica.net/cache/ba1/70/90/eb2a7dc0930ad6193b2a128d1ded", + "assets/build/ba_data/audio/trashRummage.ogg": "https://files.ballistica.net/cache/ba1/a3/9e/4bad0c6f8cf0181a074c0db268bd", + "assets/build/ba_data/audio/victoryMusic.ogg": "https://files.ballistica.net/cache/ba1/e9/75/ad082ff65c5eb7ba8860eefddcc6", + "assets/build/ba_data/audio/warnBeep.ogg": "https://files.ballistica.net/cache/ba1/f3/77/44e2ee98b8e7b3dc5569384f6892", + "assets/build/ba_data/audio/warnBeeps.ogg": "https://files.ballistica.net/cache/ba1/39/6b/e9c7e668c92c3a57887ba985f1d7", + "assets/build/ba_data/audio/warrior1.ogg": "https://files.ballistica.net/cache/ba1/e2/e7/50aac508d38459b89f7f20ca6a65", + "assets/build/ba_data/audio/warrior2.ogg": "https://files.ballistica.net/cache/ba1/ea/d8/8f9e551260821562c74b40902dc7", + "assets/build/ba_data/audio/warrior3.ogg": "https://files.ballistica.net/cache/ba1/a7/1f/e1124eadd95de2ec3a84c363212a", + "assets/build/ba_data/audio/warrior4.ogg": "https://files.ballistica.net/cache/ba1/8f/b1/48e4fb2b0579ddd72eab6f12a82d", + "assets/build/ba_data/audio/warriorDeath.ogg": "https://files.ballistica.net/cache/ba1/bb/d1/38b90afa71375d47860f366aeb2b", + "assets/build/ba_data/audio/warriorFall.ogg": "https://files.ballistica.net/cache/ba1/96/f3/0c5c750fe674c954dee6ece08f47", + "assets/build/ba_data/audio/warriorHit1.ogg": "https://files.ballistica.net/cache/ba1/df/cb/c9f76841387056afa9b627109e99", + "assets/build/ba_data/audio/warriorHit2.ogg": "https://files.ballistica.net/cache/ba1/bd/f0/1e452100c63643021569c67ea84e", + "assets/build/ba_data/audio/whenJohnnyComesMarchingHomeMusic.ogg": "https://files.ballistica.net/cache/ba1/70/21/845fab94e28de4e7d3a32f324cec", + "assets/build/ba_data/audio/witch1.ogg": "https://files.ballistica.net/cache/ba1/d4/e9/6bcf7711b82eff57f6fff7dfd105", + "assets/build/ba_data/audio/witch2.ogg": "https://files.ballistica.net/cache/ba1/5d/22/b623c8e812aa4201a8934efd8c96", + "assets/build/ba_data/audio/witch3.ogg": "https://files.ballistica.net/cache/ba1/1f/79/05a3b9bf99133fc8eee029196c4d", + "assets/build/ba_data/audio/witch4.ogg": "https://files.ballistica.net/cache/ba1/ee/ea/97d02b3f426d18347a4d1f2661fd", + "assets/build/ba_data/audio/witchDeath.ogg": "https://files.ballistica.net/cache/ba1/d4/56/16bc17b0d2db5711626b9d8915ca", + "assets/build/ba_data/audio/witchFall.ogg": "https://files.ballistica.net/cache/ba1/6a/4b/0985084c16924181f0eb05112a42", + "assets/build/ba_data/audio/witchHit1.ogg": "https://files.ballistica.net/cache/ba1/69/0c/ffa2798e33057a4cfa0307c88925", + "assets/build/ba_data/audio/witchHit2.ogg": "https://files.ballistica.net/cache/ba1/9e/1a/e8fec979fe35dcaa1a32accedd2d", + "assets/build/ba_data/audio/wizard1.ogg": "https://files.ballistica.net/cache/ba1/45/a7/33b69b914db880b5b19a44a8f27b", + "assets/build/ba_data/audio/wizard2.ogg": "https://files.ballistica.net/cache/ba1/cc/e8/6c64dcca9841a2789fa246f65f59", + "assets/build/ba_data/audio/wizard3.ogg": "https://files.ballistica.net/cache/ba1/0c/77/0e14626535e9acfe1fe830d8d3f0", + "assets/build/ba_data/audio/wizard4.ogg": "https://files.ballistica.net/cache/ba1/30/b1/44f24e09c52566fbd64bb37f6473", + "assets/build/ba_data/audio/wizardDeath.ogg": "https://files.ballistica.net/cache/ba1/ff/4c/28fc077e921be23eadd9536ed221", + "assets/build/ba_data/audio/wizardFall.ogg": "https://files.ballistica.net/cache/ba1/d9/61/bf168c3a660ce70c96d7f8dacd5e", + "assets/build/ba_data/audio/wizardHit1.ogg": "https://files.ballistica.net/cache/ba1/a1/fb/3fd68f1549b44fc95e8c87b43bbc", + "assets/build/ba_data/audio/wizardHit2.ogg": "https://files.ballistica.net/cache/ba1/49/b9/1c27fc4c2f18c99c678fdb5f3490", + "assets/build/ba_data/audio/woodDebrisFall.ogg": "https://files.ballistica.net/cache/ba1/f3/a7/f82ddbe7e83444230afeec303e35", + "assets/build/ba_data/audio/wrestler1.ogg": "https://files.ballistica.net/cache/ba1/c1/a2/5b6e78bc9d43e8a888b414cb2ebe", + "assets/build/ba_data/audio/wrestler2.ogg": "https://files.ballistica.net/cache/ba1/ae/4a/39462e42896acc930da1809783e5", + "assets/build/ba_data/audio/wrestler3.ogg": "https://files.ballistica.net/cache/ba1/d6/0e/e666a0e052192a3ebc9118e6054a", + "assets/build/ba_data/audio/wrestler4.ogg": "https://files.ballistica.net/cache/ba1/b9/45/00628b126d880b07f99cb3c88e9c", + "assets/build/ba_data/audio/wrestlerDeath.ogg": "https://files.ballistica.net/cache/ba1/e3/ce/8a2f4185272123a46928b363e463", + "assets/build/ba_data/audio/wrestlerFall.ogg": "https://files.ballistica.net/cache/ba1/38/11/6213afb48a5475abc777c50f6f04", + "assets/build/ba_data/audio/wrestlerHit1.ogg": "https://files.ballistica.net/cache/ba1/7f/21/e7bd8c213a715e1392da9df1102d", + "assets/build/ba_data/audio/wrestlerHit2.ogg": "https://files.ballistica.net/cache/ba1/78/34/7fd99caed03ac1a198f2ca742987", + "assets/build/ba_data/audio/zoeAttack01.ogg": "https://files.ballistica.net/cache/ba1/a3/72/529aa45b6af5f6d2425c0bc5b741", + "assets/build/ba_data/audio/zoeAttack02.ogg": "https://files.ballistica.net/cache/ba1/f2/ed/b7246a01f9b4954aaaffdab248ee", + "assets/build/ba_data/audio/zoeAttack03.ogg": "https://files.ballistica.net/cache/ba1/49/e3/1da9b2bfbd0cef256db00f574926", + "assets/build/ba_data/audio/zoeAttack04.ogg": "https://files.ballistica.net/cache/ba1/95/c5/ef38e886dac699512e14554a48e3", + "assets/build/ba_data/audio/zoeDeath01.ogg": "https://files.ballistica.net/cache/ba1/31/14/a8e435a2f2eddd369b70309f2f8a", + "assets/build/ba_data/audio/zoeEff.ogg": "https://files.ballistica.net/cache/ba1/98/96/0923d815c9289c055a1a52659d5c", + "assets/build/ba_data/audio/zoeFall01.ogg": "https://files.ballistica.net/cache/ba1/85/db/c40e9dafa5ba884ab472ae043f5b", + "assets/build/ba_data/audio/zoeImpact01.ogg": "https://files.ballistica.net/cache/ba1/a0/de/093690e3eaaadadafe681ebded41", + "assets/build/ba_data/audio/zoeImpact02.ogg": "https://files.ballistica.net/cache/ba1/7a/93/3a154d5e094d4632e70dc8dff278", + "assets/build/ba_data/audio/zoeImpact03.ogg": "https://files.ballistica.net/cache/ba1/5a/31/6afc47d8cbe7853fac94e0159ef8", + "assets/build/ba_data/audio/zoeImpact04.ogg": "https://files.ballistica.net/cache/ba1/34/8f/e4c8f77726440042b78dd45a75ae", + "assets/build/ba_data/audio/zoeJump01.ogg": "https://files.ballistica.net/cache/ba1/ce/e9/2e360d4613c831d4ccc70bf94606", + "assets/build/ba_data/audio/zoeJump02.ogg": "https://files.ballistica.net/cache/ba1/b2/08/b13746522a47bc19059ab22d5a73", + "assets/build/ba_data/audio/zoeJump03.ogg": "https://files.ballistica.net/cache/ba1/dd/a4/05eccfb646c7dcd0787254cbfd76", + "assets/build/ba_data/audio/zoeOw.ogg": "https://files.ballistica.net/cache/ba1/d3/68/5898b2d11bf5a9dc3b7b6f4dfb5a", + "assets/build/ba_data/audio/zoePickup01.ogg": "https://files.ballistica.net/cache/ba1/59/c7/7b10339dda2f9d126971f50e189c", + "assets/build/ba_data/audio/zoeScream01.ogg": "https://files.ballistica.net/cache/ba1/64/b1/d26efaadfce16f328075758deb6c", + "assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/df/d4/b9814c484722df1380894b9f8661", + "assets/build/ba_data/data/languages/arabic.json": "https://files.ballistica.net/cache/ba1/c5/81/e386a592e4fdf702b9089f106610", "assets/build/ba_data/data/languages/belarussian.json": "https://files.ballistica.net/cache/ba1/61/03/89070ca765e06da3a419a579f503", "assets/build/ba_data/data/languages/chinese.json": "https://files.ballistica.net/cache/ba1/d3/84/5e7df03070af059070ad1bd93cee", "assets/build/ba_data/data/languages/chinesetraditional.json": "https://files.ballistica.net/cache/ba1/c2/a4/993d5f0f30d0670d7053466929b6", @@ -439,9 +439,9 @@ "assets/build/ba_data/data/languages/hindi.json": "https://files.ballistica.net/cache/ba1/9f/df/469e166c6a0d42bca4baae3a6cb6", "assets/build/ba_data/data/languages/hungarian.json": "https://files.ballistica.net/cache/ba1/b2/81/53c8cd7617d649403e539c3a6171", "assets/build/ba_data/data/languages/indonesian.json": "https://files.ballistica.net/cache/ba1/38/74/88d1ed374207750c9a834cddb809", - "assets/build/ba_data/data/languages/italian.json": "https://files.ballistica.net/cache/ba1/5f/b2/b9301d67bef699a092a4c04dd522", + "assets/build/ba_data/data/languages/italian.json": "https://files.ballistica.net/cache/ba1/ce/09/20c87e343b41ec5dc43138ce071e", "assets/build/ba_data/data/languages/korean.json": "https://files.ballistica.net/cache/ba1/7c/38/d4a44c481757d355836f292ede48", - "assets/build/ba_data/data/languages/persian.json": "https://files.ballistica.net/cache/ba1/cd/ed/4d6d0778d256ccc0ff2e27b970c6", + "assets/build/ba_data/data/languages/persian.json": "https://files.ballistica.net/cache/ba1/db/14/2f441ccb65023775dc8139a63f3f", "assets/build/ba_data/data/languages/polish.json": "https://files.ballistica.net/cache/ba1/67/93/372c2a2428a830056e9ba22bbf95", "assets/build/ba_data/data/languages/portuguese.json": "https://files.ballistica.net/cache/ba1/03/14/6b767289325368be52e24ed3a58a", "assets/build/ba_data/data/languages/romanian.json": "https://files.ballistica.net/cache/ba1/d7/06/9d70642d0a4d1e3b1c2149d7a17c", @@ -451,9 +451,9 @@ "assets/build/ba_data/data/languages/spanish.json": "https://files.ballistica.net/cache/ba1/29/1e/1c9666647b48f9c37d8559d22606", "assets/build/ba_data/data/languages/swedish.json": "https://files.ballistica.net/cache/ba1/91/0a/35c4baf539d5951fc03a794c0e0b", "assets/build/ba_data/data/languages/tamil.json": "https://files.ballistica.net/cache/ba1/ec/b2/426ec5d0bb98145dc7123766fb5c", - "assets/build/ba_data/data/languages/thai.json": "https://files.ballistica.net/cache/ba1/f7/df/7ba5f99c5c2c4c86fc0503fcf0b7", + "assets/build/ba_data/data/languages/thai.json": "https://files.ballistica.net/cache/ba1/d6/16/523c643358880b03b233ed88e557", "assets/build/ba_data/data/languages/turkish.json": "https://files.ballistica.net/cache/ba1/52/5e/385f4d430fa82b2ac206277a71d4", - "assets/build/ba_data/data/languages/ukrainian.json": "https://files.ballistica.net/cache/ba1/1b/83/844f9e6f4e9e47a2d788d3faa9d2", + "assets/build/ba_data/data/languages/ukrainian.json": "https://files.ballistica.net/cache/ba1/73/7b/b8822b5632a8d3c7cf134e2859cc", "assets/build/ba_data/data/languages/venetian.json": "https://files.ballistica.net/cache/ba1/a6/ed/416638d46950c9ab4f6155b9c334", "assets/build/ba_data/data/languages/vietnamese.json": "https://files.ballistica.net/cache/ba1/1f/ae/abe3f105b3c4b51f6b7942773305", "assets/build/ba_data/data/maps/big_g.json": "https://files.ballistica.net/cache/ba1/47/0a/a617cc85d927b576c4e6fc1091ed", @@ -1073,7 +1073,7 @@ "assets/build/ba_data/textures/actionHeroColor.dds": "https://files.ballistica.net/cache/ba1/62/91/355fa26219c26750e46ad358dbc7", "assets/build/ba_data/textures/actionHeroColor.ktx": "https://files.ballistica.net/cache/ba1/01/ce/95415b6b29f60015900b2f33db42", "assets/build/ba_data/textures/actionHeroColor.pvr": "https://files.ballistica.net/cache/ba1/0d/03/832309d85531d4be991b6f7a9107", - "assets/build/ba_data/textures/actionHeroColorMask.dds": "https://files.ballistica.net/cache/ba1/5c/c0/7f52de795a1f08ffa72030cf9178", + "assets/build/ba_data/textures/actionHeroColorMask.dds": "https://files.ballistica.net/cache/ba1/7d/8d/5b94b6e589f7f67ecc310e2cfa3c", "assets/build/ba_data/textures/actionHeroColorMask.ktx": "https://files.ballistica.net/cache/ba1/07/ed/6791e01ac69bb61cdffade59808f", "assets/build/ba_data/textures/actionHeroColorMask.pvr": "https://files.ballistica.net/cache/ba1/22/40/d50cbe4fa13a3294638bb1b42c72", "assets/build/ba_data/textures/actionHeroColorMask_preview.png": "https://files.ballistica.net/cache/ba1/83/2f/9a009e8f2cc9b956043511db105c", @@ -1090,15 +1090,15 @@ "assets/build/ba_data/textures/advancedIcon.ktx": "https://files.ballistica.net/cache/ba1/87/6d/1758aaf14120f6c418e2ecdb410f", "assets/build/ba_data/textures/advancedIcon.pvr": "https://files.ballistica.net/cache/ba1/39/00/237c07cd4a239ca69f90ba571e07", "assets/build/ba_data/textures/advancedIcon_preview.png": "https://files.ballistica.net/cache/ba1/21/d5/3a3a834112b84befe910c15df2b6", - "assets/build/ba_data/textures/agentColor.dds": "https://files.ballistica.net/cache/ba1/05/19/15d35284e062e8d037dfece71af5", + "assets/build/ba_data/textures/agentColor.dds": "https://files.ballistica.net/cache/ba1/17/c2/2a9cc0d3c88e048cce4e75880328", "assets/build/ba_data/textures/agentColor.ktx": "https://files.ballistica.net/cache/ba1/ff/8a/3e375971f932cba1e4c8800129e8", "assets/build/ba_data/textures/agentColor.pvr": "https://files.ballistica.net/cache/ba1/f8/3a/438fae77e7ad607345ff883c272d", - "assets/build/ba_data/textures/agentColorMask.dds": "https://files.ballistica.net/cache/ba1/dc/b1/a5a98e27864377a91452abcfba66", + "assets/build/ba_data/textures/agentColorMask.dds": "https://files.ballistica.net/cache/ba1/4f/ab/db5c3baed96dbec309c33ca13258", "assets/build/ba_data/textures/agentColorMask.ktx": "https://files.ballistica.net/cache/ba1/64/9a/255eeabf2f4a5626d478b41f2268", "assets/build/ba_data/textures/agentColorMask.pvr": "https://files.ballistica.net/cache/ba1/6a/d2/7a311a8525c02f7c8edb974e9651", "assets/build/ba_data/textures/agentColorMask_preview.png": "https://files.ballistica.net/cache/ba1/78/ec/c4ddf22b95d893fa467412334ff5", "assets/build/ba_data/textures/agentColor_preview.png": "https://files.ballistica.net/cache/ba1/9f/1b/1c128a69900d438c220ca7885dc7", - "assets/build/ba_data/textures/agentIcon.dds": "https://files.ballistica.net/cache/ba1/b4/ea/bc2ed456f6536711e03d292121fa", + "assets/build/ba_data/textures/agentIcon.dds": "https://files.ballistica.net/cache/ba1/64/37/c020b7e02cf7a7b90eec2e094395", "assets/build/ba_data/textures/agentIcon.ktx": "https://files.ballistica.net/cache/ba1/eb/1e/e73199f7c33e9002e92fe363a23b", "assets/build/ba_data/textures/agentIcon.pvr": "https://files.ballistica.net/cache/ba1/5e/2d/e18e2133517fdcc8cb7ac28b31a8", "assets/build/ba_data/textures/agentIconColorMask.dds": "https://files.ballistica.net/cache/ba1/b1/9a/ecb2300afababd460ca4bae36d96", @@ -1106,11 +1106,11 @@ "assets/build/ba_data/textures/agentIconColorMask.pvr": "https://files.ballistica.net/cache/ba1/22/24/8aadc852761e3f2c0fbf9d2f025a", "assets/build/ba_data/textures/agentIconColorMask_preview.png": "https://files.ballistica.net/cache/ba1/e2/02/85032b1257accbb85ad1904018ef", "assets/build/ba_data/textures/agentIcon_preview.png": "https://files.ballistica.net/cache/ba1/49/70/68d243aeff2de4e474e9a22ee6ef", - "assets/build/ba_data/textures/aliBSRemoteIOSQR.dds": "https://files.ballistica.net/cache/ba1/b7/69/9c4a96ceb3f84c6670355cac136d", + "assets/build/ba_data/textures/aliBSRemoteIOSQR.dds": "https://files.ballistica.net/cache/ba1/32/c7/d95e248a28236f7495f285a9e65f", "assets/build/ba_data/textures/aliBSRemoteIOSQR.ktx": "https://files.ballistica.net/cache/ba1/10/a6/2cc21c0bae6eb45208974d8b1f60", "assets/build/ba_data/textures/aliBSRemoteIOSQR.pvr": "https://files.ballistica.net/cache/ba1/56/8f/3f31426a93b70d4c1c7c54050473", "assets/build/ba_data/textures/aliBSRemoteIOSQR_preview.png": "https://files.ballistica.net/cache/ba1/96/d8/d37b845efc618616a8e1fd0dd04b", - "assets/build/ba_data/textures/aliColor.dds": "https://files.ballistica.net/cache/ba1/54/17/1d3b7c4d9577908ed773ad11dad2", + "assets/build/ba_data/textures/aliColor.dds": "https://files.ballistica.net/cache/ba1/d8/6d/edff4cac631ca75db279ccfb1399", "assets/build/ba_data/textures/aliColor.ktx": "https://files.ballistica.net/cache/ba1/ed/f3/3005b276e2b231be8170102c1cd7", "assets/build/ba_data/textures/aliColor.pvr": "https://files.ballistica.net/cache/ba1/f3/bd/2c82648f6ef242ca4b34fd278629", "assets/build/ba_data/textures/aliColorMask.dds": "https://files.ballistica.net/cache/ba1/68/bb/c7db9f1886a6d3fd5cdb308f3cef", @@ -1118,14 +1118,14 @@ "assets/build/ba_data/textures/aliColorMask.pvr": "https://files.ballistica.net/cache/ba1/31/2a/ddb2a68bdfb3b175be2d3d6bcade", "assets/build/ba_data/textures/aliColorMask_preview.png": "https://files.ballistica.net/cache/ba1/3b/05/0dd47cdf3a3ac437e5e276f5fd86", "assets/build/ba_data/textures/aliColor_preview.png": "https://files.ballistica.net/cache/ba1/cb/93/d9230bee0324b2eec4bb8519dae3", - "assets/build/ba_data/textures/aliControllerQR.dds": "https://files.ballistica.net/cache/ba1/55/0a/44ecb9f5cf4e5c02b83089d0d13b", + "assets/build/ba_data/textures/aliControllerQR.dds": "https://files.ballistica.net/cache/ba1/68/f4/742194ee422ce66e9c0c4c7a2c66", "assets/build/ba_data/textures/aliControllerQR.ktx": "https://files.ballistica.net/cache/ba1/56/50/6d84e5b788b25b4e7275d20ce635", "assets/build/ba_data/textures/aliControllerQR.pvr": "https://files.ballistica.net/cache/ba1/22/8d/34c3d66662866cc806c81ee13517", "assets/build/ba_data/textures/aliControllerQR_preview.png": "https://files.ballistica.net/cache/ba1/59/83/a2dce8f9ec55f87cf450813a31c1", - "assets/build/ba_data/textures/aliIcon.dds": "https://files.ballistica.net/cache/ba1/bf/c9/ad39ef333825bbd5d6f5462d1a11", + "assets/build/ba_data/textures/aliIcon.dds": "https://files.ballistica.net/cache/ba1/a0/a6/f4fc06a5e3967f1cfc35eb627706", "assets/build/ba_data/textures/aliIcon.ktx": "https://files.ballistica.net/cache/ba1/d1/ee/7c1c37d57cdb70d854ecdfb235ed", "assets/build/ba_data/textures/aliIcon.pvr": "https://files.ballistica.net/cache/ba1/b6/04/931fbed4b2a9c75ae7745a88ed40", - "assets/build/ba_data/textures/aliIconColorMask.dds": "https://files.ballistica.net/cache/ba1/58/bc/04f52451d42f051acb8409ab965b", + "assets/build/ba_data/textures/aliIconColorMask.dds": "https://files.ballistica.net/cache/ba1/64/09/2fdf334c8cb3661bdbecdd2d2dd4", "assets/build/ba_data/textures/aliIconColorMask.ktx": "https://files.ballistica.net/cache/ba1/78/89/c3e95a7c3794e4c86ece540aa3a3", "assets/build/ba_data/textures/aliIconColorMask.pvr": "https://files.ballistica.net/cache/ba1/7a/81/d269ece740203c2e1a9a3c9523af", "assets/build/ba_data/textures/aliIconColorMask_preview.png": "https://files.ballistica.net/cache/ba1/0f/8d/203f6ec0ff5a8dd380330a0f3853", @@ -1137,7 +1137,7 @@ "assets/build/ba_data/textures/alienColor.dds": "https://files.ballistica.net/cache/ba1/b3/63/1ec79e210306f871f4d24b7a005e", "assets/build/ba_data/textures/alienColor.ktx": "https://files.ballistica.net/cache/ba1/97/fe/96c9ab440866a08d2510109eaaff", "assets/build/ba_data/textures/alienColor.pvr": "https://files.ballistica.net/cache/ba1/39/dc/bb457bc12cd61482e2c7edfa457c", - "assets/build/ba_data/textures/alienColorMask.dds": "https://files.ballistica.net/cache/ba1/ce/51/a41c4af1205bd33dc8647898e4b6", + "assets/build/ba_data/textures/alienColorMask.dds": "https://files.ballistica.net/cache/ba1/12/8c/4b32a6cb77e2d4b840b7fd19ec8a", "assets/build/ba_data/textures/alienColorMask.ktx": "https://files.ballistica.net/cache/ba1/a7/3e/7759a1566e2dacd35c0a23304fc7", "assets/build/ba_data/textures/alienColorMask.pvr": "https://files.ballistica.net/cache/ba1/70/70/49e327a70992f6f2cd57a69e182b", "assets/build/ba_data/textures/alienColorMask_preview.png": "https://files.ballistica.net/cache/ba1/6a/7c/7e2fe077f46778b639b58d533ef8", @@ -1150,15 +1150,15 @@ "assets/build/ba_data/textures/alienIconColorMask.pvr": "https://files.ballistica.net/cache/ba1/0b/8a/54fa4a11a7d066ff0cbc6c741451", "assets/build/ba_data/textures/alienIconColorMask_preview.png": "https://files.ballistica.net/cache/ba1/55/bc/686e349c8557f232c6404bc22371", "assets/build/ba_data/textures/alienIcon_preview.png": "https://files.ballistica.net/cache/ba1/4c/c9/12ab7e3cf9f1af93c608ce1bcefb", - "assets/build/ba_data/textures/alwaysLandBGColor.dds": "https://files.ballistica.net/cache/ba1/88/d6/3afdd31b573a08eb0cf3771f86bb", + "assets/build/ba_data/textures/alwaysLandBGColor.dds": "https://files.ballistica.net/cache/ba1/3e/1e/ee38b7626761d3ead1f2fec82070", "assets/build/ba_data/textures/alwaysLandBGColor.ktx": "https://files.ballistica.net/cache/ba1/5a/80/c2ff48e9f0f3e549f105e926dd3d", "assets/build/ba_data/textures/alwaysLandBGColor.pvr": "https://files.ballistica.net/cache/ba1/2d/c0/c236df146c22606a3d290139e5b3", "assets/build/ba_data/textures/alwaysLandBGColor_preview.png": "https://files.ballistica.net/cache/ba1/59/9c/933c8322bf93c02968e6f440ae59", - "assets/build/ba_data/textures/alwaysLandLevelColor.dds": "https://files.ballistica.net/cache/ba1/1e/da/7e0f8f4f82a9728a9996fe4b76bc", + "assets/build/ba_data/textures/alwaysLandLevelColor.dds": "https://files.ballistica.net/cache/ba1/8a/5e/a2d2c01be327dd3fc34e46706b43", "assets/build/ba_data/textures/alwaysLandLevelColor.ktx": "https://files.ballistica.net/cache/ba1/13/bd/5458fc8068b06a20ec00d2e35c2e", "assets/build/ba_data/textures/alwaysLandLevelColor.pvr": "https://files.ballistica.net/cache/ba1/29/12/7c1b247f977a20c2d70069f95787", "assets/build/ba_data/textures/alwaysLandLevelColor_preview.png": "https://files.ballistica.net/cache/ba1/4a/61/15580dd303e1682c7c2f63e890da", - "assets/build/ba_data/textures/alwaysLandPreview.dds": "https://files.ballistica.net/cache/ba1/de/5e/62854d25f37a4f2151716dcbb5e0", + "assets/build/ba_data/textures/alwaysLandPreview.dds": "https://files.ballistica.net/cache/ba1/36/6c/c1c4fcc4464359de5403244d3e30", "assets/build/ba_data/textures/alwaysLandPreview.ktx": "https://files.ballistica.net/cache/ba1/44/1b/8985da2a7c0670089ec086237de2", "assets/build/ba_data/textures/alwaysLandPreview.pvr": "https://files.ballistica.net/cache/ba1/8b/bb/db84d43e0acd251940d39ad52622", "assets/build/ba_data/textures/alwaysLandPreview_preview.png": "https://files.ballistica.net/cache/ba1/c7/6d/d633bbe5ad1fb1478a49cc51f702", @@ -1173,7 +1173,7 @@ "assets/build/ba_data/textures/assassinColor.dds": "https://files.ballistica.net/cache/ba1/74/4c/15d8400e13ddef0e6712bf52dd6e", "assets/build/ba_data/textures/assassinColor.ktx": "https://files.ballistica.net/cache/ba1/77/1e/340bae7b1759427c0cf4ef6f200a", "assets/build/ba_data/textures/assassinColor.pvr": "https://files.ballistica.net/cache/ba1/88/27/2a6734a37b350a8fe9d4313169ae", - "assets/build/ba_data/textures/assassinColorMask.dds": "https://files.ballistica.net/cache/ba1/b9/72/87c5ff1b72de68f5751140508d0e", + "assets/build/ba_data/textures/assassinColorMask.dds": "https://files.ballistica.net/cache/ba1/e2/e5/dc0bcae56faf7203eda79a9397d0", "assets/build/ba_data/textures/assassinColorMask.ktx": "https://files.ballistica.net/cache/ba1/52/6b/126ba01cd6e6f883e0a6695aec9c", "assets/build/ba_data/textures/assassinColorMask.pvr": "https://files.ballistica.net/cache/ba1/c0/2c/5b137a905b0719022101f82f581d", "assets/build/ba_data/textures/assassinColorMask_preview.png": "https://files.ballistica.net/cache/ba1/b0/c5/cb9321a0aca799d83159479d602c", @@ -1198,7 +1198,7 @@ "assets/build/ba_data/textures/bar.ktx": "https://files.ballistica.net/cache/ba1/69/25/7c811b9c7e77e6c7d1df1a047991", "assets/build/ba_data/textures/bar.pvr": "https://files.ballistica.net/cache/ba1/1c/b7/605cdb8193d4190f3a90a173cc90", "assets/build/ba_data/textures/bar_preview.png": "https://files.ballistica.net/cache/ba1/b6/63/94b82a98ae1305b0f6b57fe32e8b", - "assets/build/ba_data/textures/bearColor.dds": "https://files.ballistica.net/cache/ba1/e3/9a/f6b129a0fe2933fb23643e71d9ef", + "assets/build/ba_data/textures/bearColor.dds": "https://files.ballistica.net/cache/ba1/8d/13/f83d6f1249673ad7ba10996d0ac8", "assets/build/ba_data/textures/bearColor.ktx": "https://files.ballistica.net/cache/ba1/62/fc/be9341da4cfa66a8ce63807a3a8e", "assets/build/ba_data/textures/bearColor.pvr": "https://files.ballistica.net/cache/ba1/c3/f7/1773a5033ab0a6689d01e0683a63", "assets/build/ba_data/textures/bearColorMask.dds": "https://files.ballistica.net/cache/ba1/38/04/166ea3d73ed0af9b285db1b7e6c0", @@ -1209,19 +1209,19 @@ "assets/build/ba_data/textures/bearIcon.dds": "https://files.ballistica.net/cache/ba1/cd/80/163ac24028fd5d8ce484040d4176", "assets/build/ba_data/textures/bearIcon.ktx": "https://files.ballistica.net/cache/ba1/01/f7/c2ef1c82862e74f74386c6341cb8", "assets/build/ba_data/textures/bearIcon.pvr": "https://files.ballistica.net/cache/ba1/87/83/c856c8fb48ba9d7a7fd9869746f2", - "assets/build/ba_data/textures/bearIconColorMask.dds": "https://files.ballistica.net/cache/ba1/78/c9/123f72ce037631bb8f1906b8fd92", + "assets/build/ba_data/textures/bearIconColorMask.dds": "https://files.ballistica.net/cache/ba1/60/b8/634304bf7f29d239d63dd89ce96b", "assets/build/ba_data/textures/bearIconColorMask.ktx": "https://files.ballistica.net/cache/ba1/ad/75/804e6901f09e75348f1d480c5ae8", "assets/build/ba_data/textures/bearIconColorMask.pvr": "https://files.ballistica.net/cache/ba1/ce/23/1fd7ce03b72db0dc6b3903d8146f", "assets/build/ba_data/textures/bearIconColorMask_preview.png": "https://files.ballistica.net/cache/ba1/72/1c/9775c5e7acec13a491299b998703", "assets/build/ba_data/textures/bearIcon_preview.png": "https://files.ballistica.net/cache/ba1/d9/d2/b74a4de7ca068c378d78c745331b", - "assets/build/ba_data/textures/bg.dds": "https://files.ballistica.net/cache/ba1/92/e3/7beb6a9b50408b92e02a94965664", + "assets/build/ba_data/textures/bg.dds": "https://files.ballistica.net/cache/ba1/2e/60/a4e78e526ace713727738e3a5587", "assets/build/ba_data/textures/bg.ktx": "https://files.ballistica.net/cache/ba1/97/6c/b965850bfa25cf9db805b921d291", "assets/build/ba_data/textures/bg.pvr": "https://files.ballistica.net/cache/ba1/11/84/be878cc8fbe77a3ffdb4cd4ce125", "assets/build/ba_data/textures/bg_preview.png": "https://files.ballistica.net/cache/ba1/6a/77/7613140be4610b02dcb0372111ed", - "assets/build/ba_data/textures/bigG.dds": "https://files.ballistica.net/cache/ba1/49/34/fe6162a12af04927e4c3489dcfff", + "assets/build/ba_data/textures/bigG.dds": "https://files.ballistica.net/cache/ba1/2e/74/5d1c4fe9f920a291846c62c7d65e", "assets/build/ba_data/textures/bigG.ktx": "https://files.ballistica.net/cache/ba1/df/1c/526de060409ebbd5235592943e94", "assets/build/ba_data/textures/bigG.pvr": "https://files.ballistica.net/cache/ba1/41/82/532ef83baefbde887504c11ce140", - "assets/build/ba_data/textures/bigGPreview.dds": "https://files.ballistica.net/cache/ba1/2b/1c/8fb6a40e7e08419473d22e23cfcc", + "assets/build/ba_data/textures/bigGPreview.dds": "https://files.ballistica.net/cache/ba1/93/0e/842e2e3a11f71802c81a5de450a6", "assets/build/ba_data/textures/bigGPreview.ktx": "https://files.ballistica.net/cache/ba1/4a/28/d3c6f8ad9f0c65cd7a422d9177dd", "assets/build/ba_data/textures/bigGPreview.pvr": "https://files.ballistica.net/cache/ba1/4f/b4/9b4069351815040b2af7c4c9b498", "assets/build/ba_data/textures/bigGPreview_preview.png": "https://files.ballistica.net/cache/ba1/4b/24/f4b442bc8ed68d6f3f740ffb19fd", @@ -1237,16 +1237,16 @@ "assets/build/ba_data/textures/bombColor.dds": "https://files.ballistica.net/cache/ba1/5e/2b/492e68d77e6be9d6399e49435a8d", "assets/build/ba_data/textures/bombColor.ktx": "https://files.ballistica.net/cache/ba1/bc/9f/c7a76334cf56bb0bb93d1f720b40", "assets/build/ba_data/textures/bombColor.pvr": "https://files.ballistica.net/cache/ba1/c7/bb/89159008de3b624bcb90b3c25568", - "assets/build/ba_data/textures/bombColorIce.dds": "https://files.ballistica.net/cache/ba1/ab/ed/3f5a8f9f2fb8d1e60f34f1f1701b", + "assets/build/ba_data/textures/bombColorIce.dds": "https://files.ballistica.net/cache/ba1/27/d6/7790056abb3e73e7ffd01920dfb8", "assets/build/ba_data/textures/bombColorIce.ktx": "https://files.ballistica.net/cache/ba1/4b/2d/c8cfa1990fa1f211de36679a3665", "assets/build/ba_data/textures/bombColorIce.pvr": "https://files.ballistica.net/cache/ba1/71/aa/3127d32782835de9fa0fab8c7395", "assets/build/ba_data/textures/bombColorIce_preview.png": "https://files.ballistica.net/cache/ba1/ec/3a/96b5191c5e7662be273c311fa826", "assets/build/ba_data/textures/bombColor_preview.png": "https://files.ballistica.net/cache/ba1/a5/65/878c8aa7876031426f5adf3aeb79", - "assets/build/ba_data/textures/bombStickyColor.dds": "https://files.ballistica.net/cache/ba1/c2/2d/cf8b630173546f03926c56258724", + "assets/build/ba_data/textures/bombStickyColor.dds": "https://files.ballistica.net/cache/ba1/b9/54/8e1dc631ecdb5a045441e96ea2e9", "assets/build/ba_data/textures/bombStickyColor.ktx": "https://files.ballistica.net/cache/ba1/be/83/f3b7ca04ca377e2df7359784d6cf", "assets/build/ba_data/textures/bombStickyColor.pvr": "https://files.ballistica.net/cache/ba1/14/a3/90a633e9edd9f826d89d2f610a0d", "assets/build/ba_data/textures/bombStickyColor_preview.png": "https://files.ballistica.net/cache/ba1/c0/98/05587d954ce791ba5caa41af943f", - "assets/build/ba_data/textures/bonesColor.dds": "https://files.ballistica.net/cache/ba1/02/23/f9f6293644faaff5d3fe2f49408f", + "assets/build/ba_data/textures/bonesColor.dds": "https://files.ballistica.net/cache/ba1/31/d5/90d0088aa8435ff2eb9c3b79ebc0", "assets/build/ba_data/textures/bonesColor.ktx": "https://files.ballistica.net/cache/ba1/51/24/beed81e702c15d04b4f94388a328", "assets/build/ba_data/textures/bonesColor.pvr": "https://files.ballistica.net/cache/ba1/84/85/d3822cbf93732d312b64dd0d2b26", "assets/build/ba_data/textures/bonesColorMask.dds": "https://files.ballistica.net/cache/ba1/9e/57/bc0c41cf259d94e11814170d0137", @@ -1266,7 +1266,7 @@ "assets/build/ba_data/textures/boxingGlovesColor.ktx": "https://files.ballistica.net/cache/ba1/9c/c1/fcb445a18de7bb2adb9c93644840", "assets/build/ba_data/textures/boxingGlovesColor.pvr": "https://files.ballistica.net/cache/ba1/93/a9/c6d48979dc6c72c70f5c39ccabff", "assets/build/ba_data/textures/boxingGlovesColor_preview.png": "https://files.ballistica.net/cache/ba1/75/d2/6056b445e3c8da206f4d7574c623", - "assets/build/ba_data/textures/bridgitLevelColor.dds": "https://files.ballistica.net/cache/ba1/91/ab/184a0bbeba1c1bb79d28168709be", + "assets/build/ba_data/textures/bridgitLevelColor.dds": "https://files.ballistica.net/cache/ba1/04/af/6c34a515c1e52a5f9c4303683853", "assets/build/ba_data/textures/bridgitLevelColor.ktx": "https://files.ballistica.net/cache/ba1/30/08/4f5fec91381abc98c3382763cad9", "assets/build/ba_data/textures/bridgitLevelColor.pvr": "https://files.ballistica.net/cache/ba1/6f/89/65a75daf364c9f3aec77c73bc343", "assets/build/ba_data/textures/bridgitLevelColor_preview.png": "https://files.ballistica.net/cache/ba1/c9/fd/7e9daa40ebce9e08d2daf07aef49", @@ -1274,7 +1274,7 @@ "assets/build/ba_data/textures/bridgitPreview.ktx": "https://files.ballistica.net/cache/ba1/d4/d9/6f936f48e988e335ee1949c2219d", "assets/build/ba_data/textures/bridgitPreview.pvr": "https://files.ballistica.net/cache/ba1/51/18/4716016fd0d40a0bb94cdac9c627", "assets/build/ba_data/textures/bridgitPreview_preview.png": "https://files.ballistica.net/cache/ba1/c8/77/01fcaf507ca7c4575a76bff62ff0", - "assets/build/ba_data/textures/bunnyColor.dds": "https://files.ballistica.net/cache/ba1/fc/32/5452de45237f804355667a2584ba", + "assets/build/ba_data/textures/bunnyColor.dds": "https://files.ballistica.net/cache/ba1/9e/30/d07e0031093130e6cbc23a135e45", "assets/build/ba_data/textures/bunnyColor.ktx": "https://files.ballistica.net/cache/ba1/52/88/9b31fa2ce14ef7b98631cb36e769", "assets/build/ba_data/textures/bunnyColor.pvr": "https://files.ballistica.net/cache/ba1/6b/33/e48393656bbbf7a146d4e246fdc9", "assets/build/ba_data/textures/bunnyColorMask.dds": "https://files.ballistica.net/cache/ba1/b8/f2/7570c919e1f06c66c7236524d53f", @@ -1282,7 +1282,7 @@ "assets/build/ba_data/textures/bunnyColorMask.pvr": "https://files.ballistica.net/cache/ba1/db/91/d3ad07cabd17cffa0d9591532477", "assets/build/ba_data/textures/bunnyColorMask_preview.png": "https://files.ballistica.net/cache/ba1/72/b8/27c36d27c73d19f496f955fa50e2", "assets/build/ba_data/textures/bunnyColor_preview.png": "https://files.ballistica.net/cache/ba1/cb/f2/861b06f9154cd59a8e20802a0875", - "assets/build/ba_data/textures/bunnyIcon.dds": "https://files.ballistica.net/cache/ba1/ca/2e/0352302668a840b50cf83b7d69b3", + "assets/build/ba_data/textures/bunnyIcon.dds": "https://files.ballistica.net/cache/ba1/3a/8c/c4615ce15d075e64da5768272ee7", "assets/build/ba_data/textures/bunnyIcon.ktx": "https://files.ballistica.net/cache/ba1/da/92/e1ce1ba464ffc9ce57bfe87dd792", "assets/build/ba_data/textures/bunnyIcon.pvr": "https://files.ballistica.net/cache/ba1/6e/03/4848e2435ac4f9938a98a7adaf25", "assets/build/ba_data/textures/bunnyIconColorMask.dds": "https://files.ballistica.net/cache/ba1/d2/5d/7427e249e21960ab7f5e738f833d", @@ -1353,14 +1353,14 @@ "assets/build/ba_data/textures/circle.dds": "https://files.ballistica.net/cache/ba1/88/a6/c2e3db7c1c6aab2ad9b05d7074b4", "assets/build/ba_data/textures/circle.ktx": "https://files.ballistica.net/cache/ba1/85/cd/0d9bd306a8f91a9ed661f99529b2", "assets/build/ba_data/textures/circle.pvr": "https://files.ballistica.net/cache/ba1/3a/a2/d61927bc0770e37848ddd6712876", - "assets/build/ba_data/textures/circleNoAlpha.dds": "https://files.ballistica.net/cache/ba1/90/8b/7c1942e8bd58a3f2f20fc4be7173", + "assets/build/ba_data/textures/circleNoAlpha.dds": "https://files.ballistica.net/cache/ba1/e9/c1/6af34d954867f725dbb7c63026f1", "assets/build/ba_data/textures/circleNoAlpha.ktx": "https://files.ballistica.net/cache/ba1/e4/83/17f847e9f832201929a30f1ea535", "assets/build/ba_data/textures/circleNoAlpha.pvr": "https://files.ballistica.net/cache/ba1/23/d1/6d053de8f4ab7871c3275920cf18", "assets/build/ba_data/textures/circleNoAlpha_preview.png": "https://files.ballistica.net/cache/ba1/5c/9d/0ffc70edd5440cea9d5b22810aa2", "assets/build/ba_data/textures/circleOutline.dds": "https://files.ballistica.net/cache/ba1/a4/c2/e0a5bf011be78509dbef899b8f28", "assets/build/ba_data/textures/circleOutline.ktx": "https://files.ballistica.net/cache/ba1/ce/91/5fe4f6f2ade655564632f78ddb32", "assets/build/ba_data/textures/circleOutline.pvr": "https://files.ballistica.net/cache/ba1/df/7a/6de156c06892d833f7ebd264e772", - "assets/build/ba_data/textures/circleOutlineNoAlpha.dds": "https://files.ballistica.net/cache/ba1/60/0e/c7d019fe5cd651e26967c97c4969", + "assets/build/ba_data/textures/circleOutlineNoAlpha.dds": "https://files.ballistica.net/cache/ba1/86/32/c8fe0fbf2003b7883216b19984fa", "assets/build/ba_data/textures/circleOutlineNoAlpha.ktx": "https://files.ballistica.net/cache/ba1/3d/19/19c290ceb02d8d41740c864e7793", "assets/build/ba_data/textures/circleOutlineNoAlpha.pvr": "https://files.ballistica.net/cache/ba1/b0/56/02950e983c0fb55e9bc491b8860c", "assets/build/ba_data/textures/circleOutlineNoAlpha_preview.png": "https://files.ballistica.net/cache/ba1/fc/b5/7d4368c1ff5655ecd7b22234cf54", @@ -1382,18 +1382,18 @@ "assets/build/ba_data/textures/controllerIcon.ktx": "https://files.ballistica.net/cache/ba1/14/16/a15ad29481944559f81f54fdfe20", "assets/build/ba_data/textures/controllerIcon.pvr": "https://files.ballistica.net/cache/ba1/fe/01/befdbde27b052c35d3b12d80e80f", "assets/build/ba_data/textures/controllerIcon_preview.png": "https://files.ballistica.net/cache/ba1/59/a5/1465197ee1267ba0e0b25c43d80f", - "assets/build/ba_data/textures/courtyardLevelColor.dds": "https://files.ballistica.net/cache/ba1/b2/e1/fb40e54fac2969cbaa71682af9ce", + "assets/build/ba_data/textures/courtyardLevelColor.dds": "https://files.ballistica.net/cache/ba1/46/f5/b4e9bdd3e30776884339293408eb", "assets/build/ba_data/textures/courtyardLevelColor.ktx": "https://files.ballistica.net/cache/ba1/bd/56/4b6d7c0144fc37f99f35c52ab009", "assets/build/ba_data/textures/courtyardLevelColor.pvr": "https://files.ballistica.net/cache/ba1/77/97/bf195499e7e18777f02bb87061d7", "assets/build/ba_data/textures/courtyardLevelColor_preview.png": "https://files.ballistica.net/cache/ba1/91/bf/617c0d77529aa079200fdf75173d", - "assets/build/ba_data/textures/courtyardPreview.dds": "https://files.ballistica.net/cache/ba1/cf/c7/5e5a25f7b6b1c0840d66d203e030", + "assets/build/ba_data/textures/courtyardPreview.dds": "https://files.ballistica.net/cache/ba1/52/e5/cfdaab9a05d3f5706c7e5be114a1", "assets/build/ba_data/textures/courtyardPreview.ktx": "https://files.ballistica.net/cache/ba1/58/1c/ceeccf17dd5f3f1beb9af1ab720a", "assets/build/ba_data/textures/courtyardPreview.pvr": "https://files.ballistica.net/cache/ba1/a4/e8/9f1afe13ee2ebb9f6754a5f00f26", "assets/build/ba_data/textures/courtyardPreview_preview.png": "https://files.ballistica.net/cache/ba1/cb/40/06faf314dd35177a6d0e2a041bb7", "assets/build/ba_data/textures/cowboyColor.dds": "https://files.ballistica.net/cache/ba1/a4/49/f004e03fe36543d89dd8d1a6ed7f", "assets/build/ba_data/textures/cowboyColor.ktx": "https://files.ballistica.net/cache/ba1/00/30/f2ae84970bd0697725b821f2f152", "assets/build/ba_data/textures/cowboyColor.pvr": "https://files.ballistica.net/cache/ba1/45/1a/5bbcf702a33fd48e2b9a7016323f", - "assets/build/ba_data/textures/cowboyColorMask.dds": "https://files.ballistica.net/cache/ba1/52/2f/874896a060d55f6498656cb8ba1d", + "assets/build/ba_data/textures/cowboyColorMask.dds": "https://files.ballistica.net/cache/ba1/bd/6a/6158fd65af4641bcd936045005a2", "assets/build/ba_data/textures/cowboyColorMask.ktx": "https://files.ballistica.net/cache/ba1/51/68/9145727dc989afded72318e673c7", "assets/build/ba_data/textures/cowboyColorMask.pvr": "https://files.ballistica.net/cache/ba1/69/44/41ab993ebfc0a1aa32e431582fb4", "assets/build/ba_data/textures/cowboyColorMask_preview.png": "https://files.ballistica.net/cache/ba1/93/43/7bb7d6df6b89daa507ead29d4f2a", @@ -1406,11 +1406,11 @@ "assets/build/ba_data/textures/cowboyIconColorMask.pvr": "https://files.ballistica.net/cache/ba1/b9/bf/be1704729e7714781060d58d65c2", "assets/build/ba_data/textures/cowboyIconColorMask_preview.png": "https://files.ballistica.net/cache/ba1/ca/e7/0bc54a6b3fd60923c951fc97d790", "assets/build/ba_data/textures/cowboyIcon_preview.png": "https://files.ballistica.net/cache/ba1/1c/67/f2c47c042d89c220e78e7ebce5ed", - "assets/build/ba_data/textures/cragCastleLevelColor.dds": "https://files.ballistica.net/cache/ba1/fe/9a/3d8efc6b02fe3f071b832d41dacb", + "assets/build/ba_data/textures/cragCastleLevelColor.dds": "https://files.ballistica.net/cache/ba1/89/88/9723a3035d39ef69cf3f3c7bda03", "assets/build/ba_data/textures/cragCastleLevelColor.ktx": "https://files.ballistica.net/cache/ba1/ea/44/3b99b25e09c05fc6e85583866694", "assets/build/ba_data/textures/cragCastleLevelColor.pvr": "https://files.ballistica.net/cache/ba1/1e/9a/9b5125e165f5ebaecc8f1934a2c1", "assets/build/ba_data/textures/cragCastleLevelColor_preview.png": "https://files.ballistica.net/cache/ba1/b4/6c/6b8f525be822459dd4bd6548b2a8", - "assets/build/ba_data/textures/cragCastlePreview.dds": "https://files.ballistica.net/cache/ba1/fb/22/e6c8a874a13b94a688ba5421141a", + "assets/build/ba_data/textures/cragCastlePreview.dds": "https://files.ballistica.net/cache/ba1/87/12/9abc61fcd67f230597f166220d60", "assets/build/ba_data/textures/cragCastlePreview.ktx": "https://files.ballistica.net/cache/ba1/0c/b2/890cb8167c41cd2c220daa3db7a9", "assets/build/ba_data/textures/cragCastlePreview.pvr": "https://files.ballistica.net/cache/ba1/c9/61/1c57e31b464b26c5e6c125d38944", "assets/build/ba_data/textures/cragCastlePreview_preview.png": "https://files.ballistica.net/cache/ba1/b1/b2/d49537dbba63c3cbc25b3989a2e2", @@ -1430,18 +1430,18 @@ "assets/build/ba_data/textures/cuteSpaz.ktx": "https://files.ballistica.net/cache/ba1/9a/65/5bfc1d1ef2bb7ac9b767e70d6015", "assets/build/ba_data/textures/cuteSpaz.pvr": "https://files.ballistica.net/cache/ba1/ff/ec/9172f64f96803393de8da58f7566", "assets/build/ba_data/textures/cuteSpaz_preview.png": "https://files.ballistica.net/cache/ba1/e9/74/364547fef623e7bbbbc8a92a9efa", - "assets/build/ba_data/textures/cyborgColor.dds": "https://files.ballistica.net/cache/ba1/93/d4/75c140eff1c3cc45e1766fc0e95c", + "assets/build/ba_data/textures/cyborgColor.dds": "https://files.ballistica.net/cache/ba1/35/94/7e5c288cb0f17bd904f3a66ee6f7", "assets/build/ba_data/textures/cyborgColor.ktx": "https://files.ballistica.net/cache/ba1/d0/d6/e611760948207bebc5cec40721ee", "assets/build/ba_data/textures/cyborgColor.pvr": "https://files.ballistica.net/cache/ba1/3b/b4/14499682862c916ba7e6df183445", - "assets/build/ba_data/textures/cyborgColorMask.dds": "https://files.ballistica.net/cache/ba1/34/e0/24881a8cabf3b48f1e68635b0096", + "assets/build/ba_data/textures/cyborgColorMask.dds": "https://files.ballistica.net/cache/ba1/28/57/0bd64f9f7d5573a9e1fd1c5f422d", "assets/build/ba_data/textures/cyborgColorMask.ktx": "https://files.ballistica.net/cache/ba1/09/49/64a4b4bd11d7f43ee3e3b4557ccb", "assets/build/ba_data/textures/cyborgColorMask.pvr": "https://files.ballistica.net/cache/ba1/aa/8f/2017c219d46766b0a8a58b12ef80", "assets/build/ba_data/textures/cyborgColorMask_preview.png": "https://files.ballistica.net/cache/ba1/b2/c8/1ca1bb73d93dd93169977aef26eb", "assets/build/ba_data/textures/cyborgColor_preview.png": "https://files.ballistica.net/cache/ba1/23/68/de2999bc4db759030c77dd372e23", - "assets/build/ba_data/textures/cyborgIcon.dds": "https://files.ballistica.net/cache/ba1/5a/55/c63bdf0b63c76da7b387b4bebecb", + "assets/build/ba_data/textures/cyborgIcon.dds": "https://files.ballistica.net/cache/ba1/99/c3/8eed2f236f66aef901d452cdb98b", "assets/build/ba_data/textures/cyborgIcon.ktx": "https://files.ballistica.net/cache/ba1/de/ab/4d5b2163047d3fb9b05d43c9183d", "assets/build/ba_data/textures/cyborgIcon.pvr": "https://files.ballistica.net/cache/ba1/0c/7b/b47a4bfbbfd8607ea06375963485", - "assets/build/ba_data/textures/cyborgIconColorMask.dds": "https://files.ballistica.net/cache/ba1/ad/20/71a5de426d081b99c1abe672474a", + "assets/build/ba_data/textures/cyborgIconColorMask.dds": "https://files.ballistica.net/cache/ba1/9d/2a/1852d636d06de05bff2ffac52d9c", "assets/build/ba_data/textures/cyborgIconColorMask.ktx": "https://files.ballistica.net/cache/ba1/20/95/85096b550149fb17500c673a9589", "assets/build/ba_data/textures/cyborgIconColorMask.pvr": "https://files.ballistica.net/cache/ba1/1f/70/35e302e1a91d78ab23cb3e936bde", "assets/build/ba_data/textures/cyborgIconColorMask_preview.png": "https://files.ballistica.net/cache/ba1/09/bb/e6563f614b2cda0ca5da89b80b2a", @@ -1450,15 +1450,15 @@ "assets/build/ba_data/textures/discordLogo.ktx": "https://files.ballistica.net/cache/ba1/a2/ad/24c11330f25cd763640872fbd16e", "assets/build/ba_data/textures/discordLogo.pvr": "https://files.ballistica.net/cache/ba1/2b/41/7b2e332fbfe4c74cc8c76be16fd0", "assets/build/ba_data/textures/discordLogo_preview.png": "https://files.ballistica.net/cache/ba1/ad/88/2fc2f22f8ee9925df99dbc47d315", - "assets/build/ba_data/textures/doomShroomBGColor.dds": "https://files.ballistica.net/cache/ba1/5c/2b/88deea7de0cf4b7e3250ca76bcc1", + "assets/build/ba_data/textures/doomShroomBGColor.dds": "https://files.ballistica.net/cache/ba1/12/cc/3fa62b5809176403776958657571", "assets/build/ba_data/textures/doomShroomBGColor.ktx": "https://files.ballistica.net/cache/ba1/db/35/7f5884df9de36467179b45e8e241", "assets/build/ba_data/textures/doomShroomBGColor.pvr": "https://files.ballistica.net/cache/ba1/65/5d/fc508d48f3703e91cfbfce0187ed", "assets/build/ba_data/textures/doomShroomBGColor_preview.png": "https://files.ballistica.net/cache/ba1/b5/7e/995e3c648eb68d4c72c4e50be7e6", - "assets/build/ba_data/textures/doomShroomLevelColor.dds": "https://files.ballistica.net/cache/ba1/cd/1e/f297f1c37249810e7aaffca591a4", + "assets/build/ba_data/textures/doomShroomLevelColor.dds": "https://files.ballistica.net/cache/ba1/ac/a4/03513b905d7379ee44e6e686056d", "assets/build/ba_data/textures/doomShroomLevelColor.ktx": "https://files.ballistica.net/cache/ba1/6c/96/d887b3d3cf79d2264ad2e601193d", "assets/build/ba_data/textures/doomShroomLevelColor.pvr": "https://files.ballistica.net/cache/ba1/e2/15/8303117a33a96a61376dad6f5e9d", "assets/build/ba_data/textures/doomShroomLevelColor_preview.png": "https://files.ballistica.net/cache/ba1/61/cf/327dd838ebab6875b92ee28c3bcd", - "assets/build/ba_data/textures/doomShroomPreview.dds": "https://files.ballistica.net/cache/ba1/d7/c7/888bb15afe907f3a37006e76b3af", + "assets/build/ba_data/textures/doomShroomPreview.dds": "https://files.ballistica.net/cache/ba1/f5/68/bd828096f33579d65a44c5357933", "assets/build/ba_data/textures/doomShroomPreview.ktx": "https://files.ballistica.net/cache/ba1/f6/3c/20abd773a8502a0954d62c0917c7", "assets/build/ba_data/textures/doomShroomPreview.pvr": "https://files.ballistica.net/cache/ba1/d3/92/aca35e87cb29f4da683e88859a21", "assets/build/ba_data/textures/doomShroomPreview_preview.png": "https://files.ballistica.net/cache/ba1/19/85/7ec1b3b28c5bc564fd0a106d2423", @@ -1498,7 +1498,7 @@ "assets/build/ba_data/textures/empty.ktx": "https://files.ballistica.net/cache/ba1/1c/1a/c944b4615540bebbd2337f37a36e", "assets/build/ba_data/textures/empty.pvr": "https://files.ballistica.net/cache/ba1/e1/85/0e5d594e57336cf14b4914ebb37c", "assets/build/ba_data/textures/empty_preview.png": "https://files.ballistica.net/cache/ba1/27/1d/936488a18c78f387f2f4ec562545", - "assets/build/ba_data/textures/explosion.dds": "https://files.ballistica.net/cache/ba1/e7/95/a6d20541c8ffff02583799ab77ba", + "assets/build/ba_data/textures/explosion.dds": "https://files.ballistica.net/cache/ba1/da/1f/fac45c02f2f889b62335f3f85d77", "assets/build/ba_data/textures/explosion.ktx": "https://files.ballistica.net/cache/ba1/72/e7/7db06c8ab6f0dd8dfc48162824b1", "assets/build/ba_data/textures/explosion.pvr": "https://files.ballistica.net/cache/ba1/38/42/e4de72086e36187dcb5e4005f4e9", "assets/build/ba_data/textures/explosion_preview.png": "https://files.ballistica.net/cache/ba1/6f/01/8a6cf54d2e9b24c87c00ea2ca9c3", @@ -1514,11 +1514,11 @@ "assets/build/ba_data/textures/file.ktx": "https://files.ballistica.net/cache/ba1/d5/f6/a80ff58c84435b33a05a1e61016e", "assets/build/ba_data/textures/file.pvr": "https://files.ballistica.net/cache/ba1/5f/25/e6079cc54364d95d6101fc74bdba", "assets/build/ba_data/textures/file_preview.png": "https://files.ballistica.net/cache/ba1/ef/c6/71a8f503449908b15a40ce3b5b03", - "assets/build/ba_data/textures/flagColor.dds": "https://files.ballistica.net/cache/ba1/4a/ce/2682d3720bff14ec43bdfcaca346", + "assets/build/ba_data/textures/flagColor.dds": "https://files.ballistica.net/cache/ba1/ee/84/655bd471f8265bc7d61f95beda16", "assets/build/ba_data/textures/flagColor.ktx": "https://files.ballistica.net/cache/ba1/81/3c/f16914e9d68d64ce59a1f7681bff", "assets/build/ba_data/textures/flagColor.pvr": "https://files.ballistica.net/cache/ba1/e0/b0/06fd752a0f3563252d6dee64dcb3", "assets/build/ba_data/textures/flagColor_preview.png": "https://files.ballistica.net/cache/ba1/0b/33/50db4a9487b0ef8d65f2628776e5", - "assets/build/ba_data/textures/flagPoleColor.dds": "https://files.ballistica.net/cache/ba1/22/e0/43555f1a8a4bff7088c33ccd179e", + "assets/build/ba_data/textures/flagPoleColor.dds": "https://files.ballistica.net/cache/ba1/ba/7a/25e2cd1d33d4f323682716489099", "assets/build/ba_data/textures/flagPoleColor.ktx": "https://files.ballistica.net/cache/ba1/0f/56/7d16d9b2af848d004da2012c2cf7", "assets/build/ba_data/textures/flagPoleColor.pvr": "https://files.ballistica.net/cache/ba1/7b/63/e163c96ff68bb242e8b9ef339711", "assets/build/ba_data/textures/flagPoleColor_preview.png": "https://files.ballistica.net/cache/ba1/e0/e4/6c41b0bfd6796344ba60d0bdf189", @@ -1578,10 +1578,10 @@ "assets/build/ba_data/textures/fontSmall7.ktx": "https://files.ballistica.net/cache/ba1/14/d0/23e59a31103533757dea7ffae94e", "assets/build/ba_data/textures/fontSmall7.pvr": "https://files.ballistica.net/cache/ba1/48/b5/26321b2643219162a713170ab9b8", "assets/build/ba_data/textures/fontSmall7_preview.png": "https://files.ballistica.net/cache/ba1/70/56/13b940fb6d0ba48023e7fac6f184", - "assets/build/ba_data/textures/footballStadium.dds": "https://files.ballistica.net/cache/ba1/c6/f3/1906912b8e4d923a0ec975de5e8f", + "assets/build/ba_data/textures/footballStadium.dds": "https://files.ballistica.net/cache/ba1/37/98/82cd29605606ef50ec7f7f1a2b38", "assets/build/ba_data/textures/footballStadium.ktx": "https://files.ballistica.net/cache/ba1/00/bf/6b8e37071ad1d6e33f30f1998bed", "assets/build/ba_data/textures/footballStadium.pvr": "https://files.ballistica.net/cache/ba1/92/69/f2c5577a1de103343ddcb01d6104", - "assets/build/ba_data/textures/footballStadiumPreview.dds": "https://files.ballistica.net/cache/ba1/d9/7f/b42a16567ea5ae5a85faa027e4ce", + "assets/build/ba_data/textures/footballStadiumPreview.dds": "https://files.ballistica.net/cache/ba1/f6/f3/032deefbd09bdb75806d9ed813c2", "assets/build/ba_data/textures/footballStadiumPreview.ktx": "https://files.ballistica.net/cache/ba1/96/f2/6cf9b95e27aeca2d8be08feedaef", "assets/build/ba_data/textures/footballStadiumPreview.pvr": "https://files.ballistica.net/cache/ba1/3f/1b/ce5faa6a8678c3b7d0a461c9509b", "assets/build/ba_data/textures/footballStadiumPreview_preview.png": "https://files.ballistica.net/cache/ba1/a7/c8/393d085e92e185e6c43ab28cd5ee", @@ -1590,15 +1590,15 @@ "assets/build/ba_data/textures/frameInset.ktx": "https://files.ballistica.net/cache/ba1/61/d7/264cfcdd0d07d67ac90827969caa", "assets/build/ba_data/textures/frameInset.pvr": "https://files.ballistica.net/cache/ba1/d1/ef/b0dd66aab3c8cf21933dc53f0c8f", "assets/build/ba_data/textures/frameInset_preview.png": "https://files.ballistica.net/cache/ba1/51/2f/a18329872f0d0b71f0a333c0db81", - "assets/build/ba_data/textures/frostyColor.dds": "https://files.ballistica.net/cache/ba1/6d/c6/2a49a0ec7810e7431c35752d3d37", + "assets/build/ba_data/textures/frostyColor.dds": "https://files.ballistica.net/cache/ba1/8c/ae/6ca51f72866944ce9691c8a1a7d5", "assets/build/ba_data/textures/frostyColor.ktx": "https://files.ballistica.net/cache/ba1/17/6c/fe178ee04831b332ff771bade627", "assets/build/ba_data/textures/frostyColor.pvr": "https://files.ballistica.net/cache/ba1/f8/fb/83779ec75b8113a47b9368ad6992", - "assets/build/ba_data/textures/frostyColorMask.dds": "https://files.ballistica.net/cache/ba1/7c/a3/3cd619ea33d9e222af6da8ce7ccc", + "assets/build/ba_data/textures/frostyColorMask.dds": "https://files.ballistica.net/cache/ba1/f0/aa/0c7c2dfc831bb96d76b2c1719597", "assets/build/ba_data/textures/frostyColorMask.ktx": "https://files.ballistica.net/cache/ba1/5d/ff/5a82bf1855c957357d277dec18c7", "assets/build/ba_data/textures/frostyColorMask.pvr": "https://files.ballistica.net/cache/ba1/d2/e3/5ccf3bc21b48180ef890cfd1ebab", "assets/build/ba_data/textures/frostyColorMask_preview.png": "https://files.ballistica.net/cache/ba1/44/6f/795803f91fbf1628e708a6a293a4", "assets/build/ba_data/textures/frostyColor_preview.png": "https://files.ballistica.net/cache/ba1/cd/3c/f7e49e7cf8164f754c2384f35e55", - "assets/build/ba_data/textures/frostyIcon.dds": "https://files.ballistica.net/cache/ba1/17/76/45c5a0a3d416259aab598bad0303", + "assets/build/ba_data/textures/frostyIcon.dds": "https://files.ballistica.net/cache/ba1/52/39/1044bf10f62219a9c804efec91ea", "assets/build/ba_data/textures/frostyIcon.ktx": "https://files.ballistica.net/cache/ba1/74/b4/d498eb65a6a3b562e9eb6195131b", "assets/build/ba_data/textures/frostyIcon.pvr": "https://files.ballistica.net/cache/ba1/a2/a6/589107d7ab94e8ba9dec5895ba6d", "assets/build/ba_data/textures/frostyIconColorMask.dds": "https://files.ballistica.net/cache/ba1/af/d5/5421823e52ef7bb86d1e24a610c4", @@ -1606,7 +1606,7 @@ "assets/build/ba_data/textures/frostyIconColorMask.pvr": "https://files.ballistica.net/cache/ba1/8e/98/89e07ef5493074a2c4cbb7aa1592", "assets/build/ba_data/textures/frostyIconColorMask_preview.png": "https://files.ballistica.net/cache/ba1/ef/77/6b17bc9b8d8d3fa37760ed4d96ac", "assets/build/ba_data/textures/frostyIcon_preview.png": "https://files.ballistica.net/cache/ba1/3e/dd/9cc6d8f3f494b586237b050a4e06", - "assets/build/ba_data/textures/fuse.dds": "https://files.ballistica.net/cache/ba1/9a/72/5eb4b3235d38ec3f69c61fdb0445", + "assets/build/ba_data/textures/fuse.dds": "https://files.ballistica.net/cache/ba1/4b/72/e7709195c5903f968c33209dc1ed", "assets/build/ba_data/textures/fuse.ktx": "https://files.ballistica.net/cache/ba1/49/ea/71c5c7dcbdcb213c036460d59117", "assets/build/ba_data/textures/fuse.pvr": "https://files.ballistica.net/cache/ba1/48/3a/710945756ee605974820d4c98e49", "assets/build/ba_data/textures/fuse_preview.png": "https://files.ballistica.net/cache/ba1/f1/69/975f7d19d7db9a01d78ecb33bfe2", @@ -1625,7 +1625,7 @@ "assets/build/ba_data/textures/gladiatorColor.dds": "https://files.ballistica.net/cache/ba1/a8/6a/2b8eb1e0f4c15993e98be5395e4c", "assets/build/ba_data/textures/gladiatorColor.ktx": "https://files.ballistica.net/cache/ba1/20/13/e491823b8cc38a52400f9d74a209", "assets/build/ba_data/textures/gladiatorColor.pvr": "https://files.ballistica.net/cache/ba1/14/60/1d4a45b0036538368348613ad01f", - "assets/build/ba_data/textures/gladiatorColorMask.dds": "https://files.ballistica.net/cache/ba1/d2/ac/02d7c9a4320ed6a8b416d48f2665", + "assets/build/ba_data/textures/gladiatorColorMask.dds": "https://files.ballistica.net/cache/ba1/05/7f/ee686ec23643b388502639d98879", "assets/build/ba_data/textures/gladiatorColorMask.ktx": "https://files.ballistica.net/cache/ba1/1e/ae/f91222e92e938c0fc8be66103cb5", "assets/build/ba_data/textures/gladiatorColorMask.pvr": "https://files.ballistica.net/cache/ba1/46/18/4ad8171ff791a86b03160648afcf", "assets/build/ba_data/textures/gladiatorColorMask_preview.png": "https://files.ballistica.net/cache/ba1/87/45/0621a7a40782a938a8f66f8985ae", @@ -1670,10 +1670,10 @@ "assets/build/ba_data/textures/heart.ktx": "https://files.ballistica.net/cache/ba1/b7/b1/8db1d5e585578b16ad0e7dac922e", "assets/build/ba_data/textures/heart.pvr": "https://files.ballistica.net/cache/ba1/b1/78/46eb38e941aa94b7a8c654c1ef38", "assets/build/ba_data/textures/heart_preview.png": "https://files.ballistica.net/cache/ba1/3c/d8/bc7b73e6920382202f1bf27b7b40", - "assets/build/ba_data/textures/hockeyStadium.dds": "https://files.ballistica.net/cache/ba1/bc/a0/0ddbb1707aab5481582f40b5042c", + "assets/build/ba_data/textures/hockeyStadium.dds": "https://files.ballistica.net/cache/ba1/8e/19/703679fb5ac0e07d577d2727ab27", "assets/build/ba_data/textures/hockeyStadium.ktx": "https://files.ballistica.net/cache/ba1/57/14/4a768367b5a3ada80b8b866320ae", "assets/build/ba_data/textures/hockeyStadium.pvr": "https://files.ballistica.net/cache/ba1/f4/e4/65792658b9ef354781472d5f82ba", - "assets/build/ba_data/textures/hockeyStadiumPreview.dds": "https://files.ballistica.net/cache/ba1/3c/d6/a0f39559e614781ef7590cf98826", + "assets/build/ba_data/textures/hockeyStadiumPreview.dds": "https://files.ballistica.net/cache/ba1/e0/84/38b2f0294f016bf122dcbfa226d2", "assets/build/ba_data/textures/hockeyStadiumPreview.ktx": "https://files.ballistica.net/cache/ba1/af/05/69b7f2c83e332b6ec410163a59fd", "assets/build/ba_data/textures/hockeyStadiumPreview.pvr": "https://files.ballistica.net/cache/ba1/4c/fb/7bcd3e1d5f830558cd01206c57e6", "assets/build/ba_data/textures/hockeyStadiumPreview_preview.png": "https://files.ballistica.net/cache/ba1/d8/99/5d6922a337009674a13b647e06c5", @@ -1690,7 +1690,7 @@ "assets/build/ba_data/textures/iircadeLogo.ktx": "https://files.ballistica.net/cache/ba1/58/b9/848fbac7a1c7ad6a9b2efd758ff1", "assets/build/ba_data/textures/iircadeLogo.pvr": "https://files.ballistica.net/cache/ba1/19/ba/66f832c978d9cf46f991e4811401", "assets/build/ba_data/textures/iircadeLogo_preview.png": "https://files.ballistica.net/cache/ba1/c7/d6/0740136951cbc17907f6192357b2", - "assets/build/ba_data/textures/impactBombColor.dds": "https://files.ballistica.net/cache/ba1/a6/70/8486c52fb904e18e9b13f4850b5e", + "assets/build/ba_data/textures/impactBombColor.dds": "https://files.ballistica.net/cache/ba1/59/f6/810262f238679951f7702f2ed1a5", "assets/build/ba_data/textures/impactBombColor.ktx": "https://files.ballistica.net/cache/ba1/fc/3b/e1051061b1ed03bcbfdc6b9f8c79", "assets/build/ba_data/textures/impactBombColor.pvr": "https://files.ballistica.net/cache/ba1/d6/d9/0f81193db5aa44780ee8bb0943b9", "assets/build/ba_data/textures/impactBombColorLit.dds": "https://files.ballistica.net/cache/ba1/fe/65/a55aba9c983239516c96f28fd4b2", @@ -1702,15 +1702,15 @@ "assets/build/ba_data/textures/inventoryIcon.ktx": "https://files.ballistica.net/cache/ba1/3c/ca/1a61ddc33fbae07060b3ffe24531", "assets/build/ba_data/textures/inventoryIcon.pvr": "https://files.ballistica.net/cache/ba1/a7/e3/6fe1d29dd307067b5b42aa1e78ca", "assets/build/ba_data/textures/inventoryIcon_preview.png": "https://files.ballistica.net/cache/ba1/5d/95/fc2f9cf29120f6e5714a82b49762", - "assets/build/ba_data/textures/jackColor.dds": "https://files.ballistica.net/cache/ba1/9c/16/c4c568eec16b4ac15110e2213107", + "assets/build/ba_data/textures/jackColor.dds": "https://files.ballistica.net/cache/ba1/3e/bb/562defe30cd5860a6648aa8c3127", "assets/build/ba_data/textures/jackColor.ktx": "https://files.ballistica.net/cache/ba1/b4/92/c66d4bd99efdd17578c1ab40eb38", "assets/build/ba_data/textures/jackColor.pvr": "https://files.ballistica.net/cache/ba1/93/f0/b67389b8a52446f9d60119b4e4b0", - "assets/build/ba_data/textures/jackColorMask.dds": "https://files.ballistica.net/cache/ba1/33/86/4e8b48b1274373302fed850899f3", + "assets/build/ba_data/textures/jackColorMask.dds": "https://files.ballistica.net/cache/ba1/74/c3/18ed606a334e8096ab0f9a6b6045", "assets/build/ba_data/textures/jackColorMask.ktx": "https://files.ballistica.net/cache/ba1/c9/40/a44ca36c9fcb3ca51fb61dbaa2cf", "assets/build/ba_data/textures/jackColorMask.pvr": "https://files.ballistica.net/cache/ba1/32/89/9243f17fdd9d8c3d7c9cc8a26191", "assets/build/ba_data/textures/jackColorMask_preview.png": "https://files.ballistica.net/cache/ba1/71/92/54cc17903955e0b923f64bb746a7", "assets/build/ba_data/textures/jackColor_preview.png": "https://files.ballistica.net/cache/ba1/83/f8/daf0dc5014e0220a8e4bc8d1113a", - "assets/build/ba_data/textures/jackIcon.dds": "https://files.ballistica.net/cache/ba1/42/a1/c6f5a537e23a509a22a13870470f", + "assets/build/ba_data/textures/jackIcon.dds": "https://files.ballistica.net/cache/ba1/0c/1f/ec2d1e00f2b409df11b485667334", "assets/build/ba_data/textures/jackIcon.ktx": "https://files.ballistica.net/cache/ba1/e8/5d/e5e222130b790f5239089333fd92", "assets/build/ba_data/textures/jackIcon.pvr": "https://files.ballistica.net/cache/ba1/da/f9/29d46bb6b052d5aad5a81efa994e", "assets/build/ba_data/textures/jackIconColorMask.dds": "https://files.ballistica.net/cache/ba1/1e/8e/395cb09dbe9ca002ad0d5532f6bd", @@ -1721,7 +1721,7 @@ "assets/build/ba_data/textures/jumpsuitColor.dds": "https://files.ballistica.net/cache/ba1/5b/9c/4761afb2e6fc3e0f8ef028d317be", "assets/build/ba_data/textures/jumpsuitColor.ktx": "https://files.ballistica.net/cache/ba1/45/25/6084698fbdd038fbd750fc72dd28", "assets/build/ba_data/textures/jumpsuitColor.pvr": "https://files.ballistica.net/cache/ba1/6c/77/39fe91748b79f2aabc640f38fd2a", - "assets/build/ba_data/textures/jumpsuitColorMask.dds": "https://files.ballistica.net/cache/ba1/04/00/8fbe70c2d5bc499f842e76b6a71d", + "assets/build/ba_data/textures/jumpsuitColorMask.dds": "https://files.ballistica.net/cache/ba1/c3/3c/5ad8f955187c9825ea9871fa3c3c", "assets/build/ba_data/textures/jumpsuitColorMask.ktx": "https://files.ballistica.net/cache/ba1/50/c2/79341c7081f28d70de09cb6db116", "assets/build/ba_data/textures/jumpsuitColorMask.pvr": "https://files.ballistica.net/cache/ba1/51/1e/5f4580d17068abebb0f8d2609c3c", "assets/build/ba_data/textures/jumpsuitColorMask_preview.png": "https://files.ballistica.net/cache/ba1/6f/05/15f3184259761adc208e2dd659ca", @@ -1734,26 +1734,26 @@ "assets/build/ba_data/textures/jumpsuitIconColorMask.pvr": "https://files.ballistica.net/cache/ba1/77/e0/1326a95629aec5d0a447f4694dc8", "assets/build/ba_data/textures/jumpsuitIconColorMask_preview.png": "https://files.ballistica.net/cache/ba1/d0/81/c975a77166d8bac47d63340960b4", "assets/build/ba_data/textures/jumpsuitIcon_preview.png": "https://files.ballistica.net/cache/ba1/06/1f/0f16b73da3b140ae91a645ad3920", - "assets/build/ba_data/textures/kronk.dds": "https://files.ballistica.net/cache/ba1/79/99/217e4d40c7107337bf4ff402e020", + "assets/build/ba_data/textures/kronk.dds": "https://files.ballistica.net/cache/ba1/41/b3/1173def9511feb2ebc516e070ed6", "assets/build/ba_data/textures/kronk.ktx": "https://files.ballistica.net/cache/ba1/80/d7/0f40cc83961456cca52f50d87657", "assets/build/ba_data/textures/kronk.pvr": "https://files.ballistica.net/cache/ba1/4d/74/fb56c0df66aa36551ae4ac73a141", - "assets/build/ba_data/textures/kronkColorMask.dds": "https://files.ballistica.net/cache/ba1/f7/e2/92c6c2179b0ea3dcaa85f357e3d7", + "assets/build/ba_data/textures/kronkColorMask.dds": "https://files.ballistica.net/cache/ba1/fa/9c/bba4cffffd4d7e7bdc53bd27819b", "assets/build/ba_data/textures/kronkColorMask.ktx": "https://files.ballistica.net/cache/ba1/de/23/7ab48fef2af0a1253b2eb6a083ab", "assets/build/ba_data/textures/kronkColorMask.pvr": "https://files.ballistica.net/cache/ba1/d4/ab/0df43e24f6aa11608a2f9b2bda6d", "assets/build/ba_data/textures/kronkColorMask_preview.png": "https://files.ballistica.net/cache/ba1/5c/14/80f2148210e89e8ca6b3b03b6e10", "assets/build/ba_data/textures/kronkIcon.dds": "https://files.ballistica.net/cache/ba1/d2/66/367fb5a09d45419be710683f0b8a", "assets/build/ba_data/textures/kronkIcon.ktx": "https://files.ballistica.net/cache/ba1/0b/23/ca03de39efd26cc2ca53a46f70b4", "assets/build/ba_data/textures/kronkIcon.pvr": "https://files.ballistica.net/cache/ba1/d7/2c/17a833f010265c66243ec90fcf09", - "assets/build/ba_data/textures/kronkIconColorMask.dds": "https://files.ballistica.net/cache/ba1/ec/4f/d9c86c700f2feaf28767f666a836", + "assets/build/ba_data/textures/kronkIconColorMask.dds": "https://files.ballistica.net/cache/ba1/8b/b1/d2f52c09816856963fa41e1e8b83", "assets/build/ba_data/textures/kronkIconColorMask.ktx": "https://files.ballistica.net/cache/ba1/41/41/5c76cd5af36248308d96cf1b4bcd", "assets/build/ba_data/textures/kronkIconColorMask.pvr": "https://files.ballistica.net/cache/ba1/4c/0c/41d95110ecda25e0e66a3876cce4", "assets/build/ba_data/textures/kronkIconColorMask_preview.png": "https://files.ballistica.net/cache/ba1/a3/24/7b66c17a8bae4ef0f9f3ca4a95ca", "assets/build/ba_data/textures/kronkIcon_preview.png": "https://files.ballistica.net/cache/ba1/5f/28/4ca750d54dcb57ad82f3bbacd2e5", "assets/build/ba_data/textures/kronk_preview.png": "https://files.ballistica.net/cache/ba1/0b/2e/083f0a0c74bec4b4f629e2bdd2a0", - "assets/build/ba_data/textures/lakeFrigid.dds": "https://files.ballistica.net/cache/ba1/de/16/41f8895b19d81123ab48ad72f38d", + "assets/build/ba_data/textures/lakeFrigid.dds": "https://files.ballistica.net/cache/ba1/52/fb/3df33cd21b7e6cfa4e4f9b03add5", "assets/build/ba_data/textures/lakeFrigid.ktx": "https://files.ballistica.net/cache/ba1/d2/ad/c28e092d9eeea2c5643d1d89613f", "assets/build/ba_data/textures/lakeFrigid.pvr": "https://files.ballistica.net/cache/ba1/f8/c0/53f0c6ec9f5ec37514b07d0c3506", - "assets/build/ba_data/textures/lakeFrigidPreview.dds": "https://files.ballistica.net/cache/ba1/eb/fd/9d832e847a72de6f62a02403abc5", + "assets/build/ba_data/textures/lakeFrigidPreview.dds": "https://files.ballistica.net/cache/ba1/23/9b/b65965dc2da90a77737df299527f", "assets/build/ba_data/textures/lakeFrigidPreview.ktx": "https://files.ballistica.net/cache/ba1/8f/d5/185af314124e8ca312475205704e", "assets/build/ba_data/textures/lakeFrigidPreview.pvr": "https://files.ballistica.net/cache/ba1/9b/2d/8b05ecb7e85b4dd42613e3e0ff89", "assets/build/ba_data/textures/lakeFrigidPreview_preview.png": "https://files.ballistica.net/cache/ba1/80/ef/8283d6c6c7f144b1dd187262b661", @@ -1830,10 +1830,10 @@ "assets/build/ba_data/textures/medalSilver.ktx": "https://files.ballistica.net/cache/ba1/68/84/934ab97c1014e98ffd6bbb24ad89", "assets/build/ba_data/textures/medalSilver.pvr": "https://files.ballistica.net/cache/ba1/37/e8/0f2d99b80e98d8388cbb1fb81aed", "assets/build/ba_data/textures/medalSilver_preview.png": "https://files.ballistica.net/cache/ba1/1c/38/7e840a4f3b6f7c15e21b22628603", - "assets/build/ba_data/textures/melColor.dds": "https://files.ballistica.net/cache/ba1/c6/f1/ef8f3740635ec2b601f73afe0424", + "assets/build/ba_data/textures/melColor.dds": "https://files.ballistica.net/cache/ba1/bd/29/6743f3197828fb39a9f424788023", "assets/build/ba_data/textures/melColor.ktx": "https://files.ballistica.net/cache/ba1/fa/a1/645eb759ffd7b046fe91ff4f9f8b", "assets/build/ba_data/textures/melColor.pvr": "https://files.ballistica.net/cache/ba1/b1/90/45696ef2a4717ce5f3e1838e31f1", - "assets/build/ba_data/textures/melColorMask.dds": "https://files.ballistica.net/cache/ba1/b7/64/9ae23dc4897fd612952d3193c023", + "assets/build/ba_data/textures/melColorMask.dds": "https://files.ballistica.net/cache/ba1/0c/95/4cce7a44347eef0356dd96dbae60", "assets/build/ba_data/textures/melColorMask.ktx": "https://files.ballistica.net/cache/ba1/bb/ed/2e666f6e2d647b45874645084028", "assets/build/ba_data/textures/melColorMask.pvr": "https://files.ballistica.net/cache/ba1/af/a4/002bc32b803774a668ce8953014e", "assets/build/ba_data/textures/melColorMask_preview.png": "https://files.ballistica.net/cache/ba1/58/ee/347860a4fc2faf37f1fa3013ce18", @@ -1841,12 +1841,12 @@ "assets/build/ba_data/textures/melIcon.dds": "https://files.ballistica.net/cache/ba1/0e/b2/683438456569eacf65b24f18b66f", "assets/build/ba_data/textures/melIcon.ktx": "https://files.ballistica.net/cache/ba1/a6/fb/e0f4945bea0edf83729dadf52f24", "assets/build/ba_data/textures/melIcon.pvr": "https://files.ballistica.net/cache/ba1/b6/ec/ed46dda142a62f35c28720878c8f", - "assets/build/ba_data/textures/melIconColorMask.dds": "https://files.ballistica.net/cache/ba1/61/b4/637cf663cd1df1d6adacfcbc148c", + "assets/build/ba_data/textures/melIconColorMask.dds": "https://files.ballistica.net/cache/ba1/5a/db/4439edcfbbef9ea932fb7d56e26a", "assets/build/ba_data/textures/melIconColorMask.ktx": "https://files.ballistica.net/cache/ba1/64/e0/2f0de4aca98350b0cecbaea53cda", "assets/build/ba_data/textures/melIconColorMask.pvr": "https://files.ballistica.net/cache/ba1/ba/94/c1955a495fcb9156ef4415105fa3", "assets/build/ba_data/textures/melIconColorMask_preview.png": "https://files.ballistica.net/cache/ba1/60/9b/38b259d63b5b8c17e0e8f4a09682", "assets/build/ba_data/textures/melIcon_preview.png": "https://files.ballistica.net/cache/ba1/cf/1d/5fd4405703e177ab90cc331e2809", - "assets/build/ba_data/textures/menuBG.dds": "https://files.ballistica.net/cache/ba1/66/38/e19d5d26e0c3b7750ad612288f51", + "assets/build/ba_data/textures/menuBG.dds": "https://files.ballistica.net/cache/ba1/7c/60/840dbf0ae2e0273c5553a81a9613", "assets/build/ba_data/textures/menuBG.ktx": "https://files.ballistica.net/cache/ba1/f9/f7/a09f825ab514e1a57fcf67149798", "assets/build/ba_data/textures/menuBG.pvr": "https://files.ballistica.net/cache/ba1/2e/8a/11960533b874cb081c384a521710", "assets/build/ba_data/textures/menuBG_preview.png": "https://files.ballistica.net/cache/ba1/03/1c/9a07cf577bdf39e58effdbc2e242", @@ -1862,11 +1862,11 @@ "assets/build/ba_data/textures/meter.ktx": "https://files.ballistica.net/cache/ba1/b5/e7/3ba3d4c7c7e05081eb033ae5da8f", "assets/build/ba_data/textures/meter.pvr": "https://files.ballistica.net/cache/ba1/58/de/ab83ad9e0d9b434ca42811030ef9", "assets/build/ba_data/textures/meter_preview.png": "https://files.ballistica.net/cache/ba1/09/b7/40a1a187d7b057defa6f32c6b372", - "assets/build/ba_data/textures/monkeyFaceLevelColor.dds": "https://files.ballistica.net/cache/ba1/e8/41/cfcdc67b1adbf50621ae9ebdafef", + "assets/build/ba_data/textures/monkeyFaceLevelColor.dds": "https://files.ballistica.net/cache/ba1/c6/29/e07d5663f90bec057f4c0a175baa", "assets/build/ba_data/textures/monkeyFaceLevelColor.ktx": "https://files.ballistica.net/cache/ba1/33/d0/e2600748ebab847b7a146350a3c9", "assets/build/ba_data/textures/monkeyFaceLevelColor.pvr": "https://files.ballistica.net/cache/ba1/09/98/9491294da842980b75739e8d1c59", "assets/build/ba_data/textures/monkeyFaceLevelColor_preview.png": "https://files.ballistica.net/cache/ba1/2f/84/fd142ba957ead4acb7b4081a3771", - "assets/build/ba_data/textures/monkeyFacePreview.dds": "https://files.ballistica.net/cache/ba1/7d/53/6c90a28662f70e03ae967a63151c", + "assets/build/ba_data/textures/monkeyFacePreview.dds": "https://files.ballistica.net/cache/ba1/3d/14/795c5ec8cf2e1b5c49e1dba05341", "assets/build/ba_data/textures/monkeyFacePreview.ktx": "https://files.ballistica.net/cache/ba1/ff/83/d340f1495861ebb97bd7f766ccbb", "assets/build/ba_data/textures/monkeyFacePreview.pvr": "https://files.ballistica.net/cache/ba1/85/e7/807edc04137ee1a3b7767e90d692", "assets/build/ba_data/textures/monkeyFacePreview_preview.png": "https://files.ballistica.net/cache/ba1/5c/62/929429eb7fd47b21edf6dd8d8f63", @@ -1874,19 +1874,19 @@ "assets/build/ba_data/textures/multiplayerExamples.ktx": "https://files.ballistica.net/cache/ba1/48/2c/081cf255b138824720c0b49d2e1e", "assets/build/ba_data/textures/multiplayerExamples.pvr": "https://files.ballistica.net/cache/ba1/d1/db/8902cdbf501bf919e5f9f0ada2b4", "assets/build/ba_data/textures/multiplayerExamples_preview.png": "https://files.ballistica.net/cache/ba1/ea/7c/acf4240ca1fa313126060a8258f0", - "assets/build/ba_data/textures/natureBackgroundColor.dds": "https://files.ballistica.net/cache/ba1/41/5a/2821b371bfb514531fd617be39cd", + "assets/build/ba_data/textures/natureBackgroundColor.dds": "https://files.ballistica.net/cache/ba1/78/ff/45c52ff0f98ffabcd472e68e3a04", "assets/build/ba_data/textures/natureBackgroundColor.ktx": "https://files.ballistica.net/cache/ba1/60/09/50676eca6d0599eabf895f18aa21", "assets/build/ba_data/textures/natureBackgroundColor.pvr": "https://files.ballistica.net/cache/ba1/1f/37/b4950cf37311fc39f53235adb190", "assets/build/ba_data/textures/natureBackgroundColor_preview.png": "https://files.ballistica.net/cache/ba1/61/91/2af689aba61ee35bc281a8c2fc88", - "assets/build/ba_data/textures/neoSpazColor.dds": "https://files.ballistica.net/cache/ba1/e7/77/ba83d0d9a1472d495d3ebaa182c4", + "assets/build/ba_data/textures/neoSpazColor.dds": "https://files.ballistica.net/cache/ba1/91/44/f06dba5c1cb7fda6d62e2c0c5484", "assets/build/ba_data/textures/neoSpazColor.ktx": "https://files.ballistica.net/cache/ba1/d1/d7/797152df3d1260338405ea0ea59f", "assets/build/ba_data/textures/neoSpazColor.pvr": "https://files.ballistica.net/cache/ba1/8b/68/60b1e0bc0c6295fba84e493c313d", - "assets/build/ba_data/textures/neoSpazColorMask.dds": "https://files.ballistica.net/cache/ba1/05/ff/08bba0e201d0eea3ead5746ca96f", + "assets/build/ba_data/textures/neoSpazColorMask.dds": "https://files.ballistica.net/cache/ba1/72/05/774cf76faed583a54d1658e17402", "assets/build/ba_data/textures/neoSpazColorMask.ktx": "https://files.ballistica.net/cache/ba1/ef/f6/84779b7eb27ccbbcdb77f3b6f2fb", "assets/build/ba_data/textures/neoSpazColorMask.pvr": "https://files.ballistica.net/cache/ba1/a2/a8/4aa145599bd4b8c53d87624553e2", "assets/build/ba_data/textures/neoSpazColorMask_preview.png": "https://files.ballistica.net/cache/ba1/62/88/1239b81fe081de88c08ac7434bc3", "assets/build/ba_data/textures/neoSpazColor_preview.png": "https://files.ballistica.net/cache/ba1/23/2c/b541bf04f85d1aa5de3b475b82d2", - "assets/build/ba_data/textures/neoSpazIcon.dds": "https://files.ballistica.net/cache/ba1/e0/6e/59525196623212ac76d96d9cd3bb", + "assets/build/ba_data/textures/neoSpazIcon.dds": "https://files.ballistica.net/cache/ba1/d9/ef/2e3e5cb4151c3ac209c0774dea79", "assets/build/ba_data/textures/neoSpazIcon.ktx": "https://files.ballistica.net/cache/ba1/d2/b5/f7c3badf697bc9dd82cffd17352c", "assets/build/ba_data/textures/neoSpazIcon.pvr": "https://files.ballistica.net/cache/ba1/47/c1/5ee2e1475e142aa8468b2d50c752", "assets/build/ba_data/textures/neoSpazIconColorMask.dds": "https://files.ballistica.net/cache/ba1/60/46/4e61726cb5e2c81b0e0af5a7cd5e", @@ -1898,15 +1898,15 @@ "assets/build/ba_data/textures/nextLevelIcon.ktx": "https://files.ballistica.net/cache/ba1/b2/84/0bb105ab76cc15c66f52ecbefcf7", "assets/build/ba_data/textures/nextLevelIcon.pvr": "https://files.ballistica.net/cache/ba1/0b/8d/087ad0de136250c54e42f4dca92f", "assets/build/ba_data/textures/nextLevelIcon_preview.png": "https://files.ballistica.net/cache/ba1/76/5f/ffae5ff97775780301b96a1a3f52", - "assets/build/ba_data/textures/ninjaColor.dds": "https://files.ballistica.net/cache/ba1/e7/25/60195fddd30365324328f09e1230", + "assets/build/ba_data/textures/ninjaColor.dds": "https://files.ballistica.net/cache/ba1/d3/5c/67af280eab6793195bb039488ce1", "assets/build/ba_data/textures/ninjaColor.ktx": "https://files.ballistica.net/cache/ba1/2a/a1/22d137826995da608c2e3898083e", "assets/build/ba_data/textures/ninjaColor.pvr": "https://files.ballistica.net/cache/ba1/2d/0c/6a9364e38112591a5f77de741ca2", - "assets/build/ba_data/textures/ninjaColorMask.dds": "https://files.ballistica.net/cache/ba1/db/da/51021e6f1482e5664af808b29b00", + "assets/build/ba_data/textures/ninjaColorMask.dds": "https://files.ballistica.net/cache/ba1/02/06/3c07252b18ba88964bba62b8a656", "assets/build/ba_data/textures/ninjaColorMask.ktx": "https://files.ballistica.net/cache/ba1/1d/68/ee8c4f656d583b49638f3cb40b4e", "assets/build/ba_data/textures/ninjaColorMask.pvr": "https://files.ballistica.net/cache/ba1/06/0a/58e0e29f5b9f503afcfc1a93f052", "assets/build/ba_data/textures/ninjaColorMask_preview.png": "https://files.ballistica.net/cache/ba1/8c/22/0103111a22390dd49615eaf2a4c3", "assets/build/ba_data/textures/ninjaColor_preview.png": "https://files.ballistica.net/cache/ba1/d9/d9/52cf79858329ee664417fa86325a", - "assets/build/ba_data/textures/ninjaIcon.dds": "https://files.ballistica.net/cache/ba1/a4/34/ac0523aa0d224b5668966a1ce6cd", + "assets/build/ba_data/textures/ninjaIcon.dds": "https://files.ballistica.net/cache/ba1/38/30/a7b91f95d0d38b8d31558ca83680", "assets/build/ba_data/textures/ninjaIcon.ktx": "https://files.ballistica.net/cache/ba1/fb/be/7acdbf4b9e212c3a20bf7b7ffe1a", "assets/build/ba_data/textures/ninjaIcon.pvr": "https://files.ballistica.net/cache/ba1/1a/c3/a5843f74115717fcbeb44cb792df", "assets/build/ba_data/textures/ninjaIconColorMask.dds": "https://files.ballistica.net/cache/ba1/b8/eb/6b4811f664e79059a8604db820d6", @@ -1925,7 +1925,7 @@ "assets/build/ba_data/textures/oldLadyColor.dds": "https://files.ballistica.net/cache/ba1/9c/9a/7b82b343061f5b2f8f2b281abf07", "assets/build/ba_data/textures/oldLadyColor.ktx": "https://files.ballistica.net/cache/ba1/e9/a6/b2c434cba993f176a1fbce5e017c", "assets/build/ba_data/textures/oldLadyColor.pvr": "https://files.ballistica.net/cache/ba1/49/6e/5d95e58db32fafff298781d3c379", - "assets/build/ba_data/textures/oldLadyColorMask.dds": "https://files.ballistica.net/cache/ba1/e5/91/354e94e932df33f458ee0bf6e1a0", + "assets/build/ba_data/textures/oldLadyColorMask.dds": "https://files.ballistica.net/cache/ba1/e3/9e/dc76d3799d4e1900d605745f71e6", "assets/build/ba_data/textures/oldLadyColorMask.ktx": "https://files.ballistica.net/cache/ba1/81/da/80cd97c5f4c228ea585d4c6b1906", "assets/build/ba_data/textures/oldLadyColorMask.pvr": "https://files.ballistica.net/cache/ba1/b7/fc/328a89dfc0578184d0cd9be05e5f", "assets/build/ba_data/textures/oldLadyColorMask_preview.png": "https://files.ballistica.net/cache/ba1/f7/23/f290703d2c69f7f115151907afdd", @@ -1941,7 +1941,7 @@ "assets/build/ba_data/textures/operaSingerColor.dds": "https://files.ballistica.net/cache/ba1/06/40/1d46db18bbf308f1e8e88ed25c7d", "assets/build/ba_data/textures/operaSingerColor.ktx": "https://files.ballistica.net/cache/ba1/a9/34/bac2cb5bfa5cfac1b5a209e77a36", "assets/build/ba_data/textures/operaSingerColor.pvr": "https://files.ballistica.net/cache/ba1/1b/e3/4a871e36791bf302c0ecb68426a7", - "assets/build/ba_data/textures/operaSingerColorMask.dds": "https://files.ballistica.net/cache/ba1/a6/c8/eb903a977a1c83792b5a9485357a", + "assets/build/ba_data/textures/operaSingerColorMask.dds": "https://files.ballistica.net/cache/ba1/e4/57/7f6534987c17b43ac14da7aa15cc", "assets/build/ba_data/textures/operaSingerColorMask.ktx": "https://files.ballistica.net/cache/ba1/ad/76/24839951a638bcdbd2f399e26b96", "assets/build/ba_data/textures/operaSingerColorMask.pvr": "https://files.ballistica.net/cache/ba1/1e/56/ce51acda0e9f77cf8450c4871503", "assets/build/ba_data/textures/operaSingerColorMask_preview.png": "https://files.ballistica.net/cache/ba1/99/5e/a20ff9e112ae711dff9d9b0602c0", @@ -1974,34 +1974,34 @@ "assets/build/ba_data/textures/ouyaYButton.ktx": "https://files.ballistica.net/cache/ba1/dd/99/0a8364d55243d59174e449445c40", "assets/build/ba_data/textures/ouyaYButton.pvr": "https://files.ballistica.net/cache/ba1/2d/f8/ebd32f8ca2f65f450641eda0e4b3", "assets/build/ba_data/textures/ouyaYButton_preview.png": "https://files.ballistica.net/cache/ba1/a0/39/27eb09f33ca04d133a2c86d30f87", - "assets/build/ba_data/textures/penguinColor.dds": "https://files.ballistica.net/cache/ba1/46/06/98a0d4e3a61c17eabca8a5addac9", + "assets/build/ba_data/textures/penguinColor.dds": "https://files.ballistica.net/cache/ba1/b0/90/b5e0f65db8428e7f58a677fc8712", "assets/build/ba_data/textures/penguinColor.ktx": "https://files.ballistica.net/cache/ba1/e8/a4/4bebf5671504129dd5daa25a8eaf", "assets/build/ba_data/textures/penguinColor.pvr": "https://files.ballistica.net/cache/ba1/5c/7b/af36d581b9c5e920609861c4fab0", - "assets/build/ba_data/textures/penguinColorMask.dds": "https://files.ballistica.net/cache/ba1/ea/71/c0d2e8b03f5e02a17e884c332691", + "assets/build/ba_data/textures/penguinColorMask.dds": "https://files.ballistica.net/cache/ba1/70/9c/9b96ade9b7231f07ae0580e4f60f", "assets/build/ba_data/textures/penguinColorMask.ktx": "https://files.ballistica.net/cache/ba1/8a/10/60999fce550b8de1444f1d05f263", "assets/build/ba_data/textures/penguinColorMask.pvr": "https://files.ballistica.net/cache/ba1/46/27/d3978fdfac00e02373d9298e755f", "assets/build/ba_data/textures/penguinColorMask_preview.png": "https://files.ballistica.net/cache/ba1/a9/f6/99954cafdabea10227ac0943a206", "assets/build/ba_data/textures/penguinColor_preview.png": "https://files.ballistica.net/cache/ba1/d5/4d/bb509ed353b4dd0e1e5231ddb59d", - "assets/build/ba_data/textures/penguinIcon.dds": "https://files.ballistica.net/cache/ba1/8b/01/d805bef78053a8bc2980fa9e987d", + "assets/build/ba_data/textures/penguinIcon.dds": "https://files.ballistica.net/cache/ba1/2c/07/d519ac490eec7432713ce7b85473", "assets/build/ba_data/textures/penguinIcon.ktx": "https://files.ballistica.net/cache/ba1/5a/d8/daadfc2654dd77d31caf4e0796d0", "assets/build/ba_data/textures/penguinIcon.pvr": "https://files.ballistica.net/cache/ba1/87/1c/dcbc92cc2fe862c43e81d587b1fe", - "assets/build/ba_data/textures/penguinIconColorMask.dds": "https://files.ballistica.net/cache/ba1/f0/0d/71a45142684d98ec7004eab7cfcd", + "assets/build/ba_data/textures/penguinIconColorMask.dds": "https://files.ballistica.net/cache/ba1/b7/be/a11bb4ae3d7535c43ca02afd0ee3", "assets/build/ba_data/textures/penguinIconColorMask.ktx": "https://files.ballistica.net/cache/ba1/b2/10/73b6efac0d2df908570c53ded344", "assets/build/ba_data/textures/penguinIconColorMask.pvr": "https://files.ballistica.net/cache/ba1/25/26/0551afc2a52c6a6426ff3c21e4f4", "assets/build/ba_data/textures/penguinIconColorMask_preview.png": "https://files.ballistica.net/cache/ba1/7c/0e/7df9e0157fd40450e0b5935cdc41", "assets/build/ba_data/textures/penguinIcon_preview.png": "https://files.ballistica.net/cache/ba1/db/bf/98796d0f0d33bc200c896ba82109", - "assets/build/ba_data/textures/pixieColor.dds": "https://files.ballistica.net/cache/ba1/75/cc/389a63b73cfcbae4aed11b8b710a", + "assets/build/ba_data/textures/pixieColor.dds": "https://files.ballistica.net/cache/ba1/f0/f6/90a78ac8b17c8b3b6cb258f078ed", "assets/build/ba_data/textures/pixieColor.ktx": "https://files.ballistica.net/cache/ba1/23/90/c836828f9342e6bd21612ff78938", "assets/build/ba_data/textures/pixieColor.pvr": "https://files.ballistica.net/cache/ba1/3d/ce/acca60b5cde2111bd62d90adc41e", - "assets/build/ba_data/textures/pixieColorMask.dds": "https://files.ballistica.net/cache/ba1/82/27/8c1fe9eec5b984f42fca3d3e9381", + "assets/build/ba_data/textures/pixieColorMask.dds": "https://files.ballistica.net/cache/ba1/7f/8f/4eaddebfa9dfb7909c7cdad4b576", "assets/build/ba_data/textures/pixieColorMask.ktx": "https://files.ballistica.net/cache/ba1/59/fe/138ccc612be62ef4a30b9adfbcf9", "assets/build/ba_data/textures/pixieColorMask.pvr": "https://files.ballistica.net/cache/ba1/57/84/72b8fc64aad487d406fc876b1b42", "assets/build/ba_data/textures/pixieColorMask_preview.png": "https://files.ballistica.net/cache/ba1/8a/7e/51ba798eac9278727df8a804ba35", "assets/build/ba_data/textures/pixieColor_preview.png": "https://files.ballistica.net/cache/ba1/07/86/d9bab7a777b2e38107403edfcd50", - "assets/build/ba_data/textures/pixieIcon.dds": "https://files.ballistica.net/cache/ba1/68/32/7d731f50bf51e633df18254034a3", + "assets/build/ba_data/textures/pixieIcon.dds": "https://files.ballistica.net/cache/ba1/b7/f4/fd43b64dacef89608c5ab6db0377", "assets/build/ba_data/textures/pixieIcon.ktx": "https://files.ballistica.net/cache/ba1/e8/25/576bf3a4e9e2dba964c5f18b6622", "assets/build/ba_data/textures/pixieIcon.pvr": "https://files.ballistica.net/cache/ba1/21/72/ba1ca96c4f017c11cffaec11d788", - "assets/build/ba_data/textures/pixieIconColorMask.dds": "https://files.ballistica.net/cache/ba1/3c/25/1f57bdf36447463ad1065a614c7f", + "assets/build/ba_data/textures/pixieIconColorMask.dds": "https://files.ballistica.net/cache/ba1/1d/8c/bcfcc534447ae4a5eb33effa157c", "assets/build/ba_data/textures/pixieIconColorMask.ktx": "https://files.ballistica.net/cache/ba1/76/3f/caf7f06633052fa327db6eaa39d6", "assets/build/ba_data/textures/pixieIconColorMask.pvr": "https://files.ballistica.net/cache/ba1/1f/1e/da8a3c0f1a42acbe09140e29609d", "assets/build/ba_data/textures/pixieIconColorMask_preview.png": "https://files.ballistica.net/cache/ba1/18/f4/e96160f142153a37f9e0919c883e", @@ -2014,7 +2014,7 @@ "assets/build/ba_data/textures/powerupBomb.ktx": "https://files.ballistica.net/cache/ba1/1b/bc/5bf3f52c9f880476221d63a41ee1", "assets/build/ba_data/textures/powerupBomb.pvr": "https://files.ballistica.net/cache/ba1/99/05/7144537430a306d45efbd75f733f", "assets/build/ba_data/textures/powerupBomb_preview.png": "https://files.ballistica.net/cache/ba1/75/17/31e7f1997e0f3304b597a062efa7", - "assets/build/ba_data/textures/powerupCurse.dds": "https://files.ballistica.net/cache/ba1/6f/cd/50c78074de3f655afe1d029ffce8", + "assets/build/ba_data/textures/powerupCurse.dds": "https://files.ballistica.net/cache/ba1/2e/ff/9c66e6f7c1a973155e68ab5560a8", "assets/build/ba_data/textures/powerupCurse.ktx": "https://files.ballistica.net/cache/ba1/40/4f/0648e5b36ad56442fdba6e07ce6c", "assets/build/ba_data/textures/powerupCurse.pvr": "https://files.ballistica.net/cache/ba1/31/2b/01f49d263a0915691651ae6b8196", "assets/build/ba_data/textures/powerupCurse_preview.png": "https://files.ballistica.net/cache/ba1/07/21/962169962af41bec8c43cf3d01a1", @@ -2022,7 +2022,7 @@ "assets/build/ba_data/textures/powerupHealth.ktx": "https://files.ballistica.net/cache/ba1/be/3e/5bd4f2ac8d7bf972571f89992264", "assets/build/ba_data/textures/powerupHealth.pvr": "https://files.ballistica.net/cache/ba1/64/ec/f1507c9ed94d0bd4b0c9ab8569da", "assets/build/ba_data/textures/powerupHealth_preview.png": "https://files.ballistica.net/cache/ba1/42/11/e09c9daf2dadf44be3b9249e3fa4", - "assets/build/ba_data/textures/powerupIceBombs.dds": "https://files.ballistica.net/cache/ba1/9f/4d/af9b3707142271e4b6090c19f330", + "assets/build/ba_data/textures/powerupIceBombs.dds": "https://files.ballistica.net/cache/ba1/03/8e/96c1d4ef593ea45528f2dda9853c", "assets/build/ba_data/textures/powerupIceBombs.ktx": "https://files.ballistica.net/cache/ba1/27/6e/3b2b5fa2e68a073db9ed5c67da39", "assets/build/ba_data/textures/powerupIceBombs.pvr": "https://files.ballistica.net/cache/ba1/b3/32/b9c0df53502d4402b36b8bdba951", "assets/build/ba_data/textures/powerupIceBombs_preview.png": "https://files.ballistica.net/cache/ba1/61/8b/7f43a09b4ca30edef5099cecbbb1", @@ -2030,7 +2030,7 @@ "assets/build/ba_data/textures/powerupImpactBombs.ktx": "https://files.ballistica.net/cache/ba1/49/0c/df4b313585f897592ccee9d5c542", "assets/build/ba_data/textures/powerupImpactBombs.pvr": "https://files.ballistica.net/cache/ba1/f2/1b/8b6c447613d2bbec20cff630b1f1", "assets/build/ba_data/textures/powerupImpactBombs_preview.png": "https://files.ballistica.net/cache/ba1/0c/33/5d041471446792bb5da31291b869", - "assets/build/ba_data/textures/powerupLandMines.dds": "https://files.ballistica.net/cache/ba1/99/f8/ea06e3d99018797fe82841988cce", + "assets/build/ba_data/textures/powerupLandMines.dds": "https://files.ballistica.net/cache/ba1/8b/96/2731079019cf1688415831619c76", "assets/build/ba_data/textures/powerupLandMines.ktx": "https://files.ballistica.net/cache/ba1/79/ac/333130d040444c03fbcf7302e35b", "assets/build/ba_data/textures/powerupLandMines.pvr": "https://files.ballistica.net/cache/ba1/2b/7a/4ac9f04cfa3a59e19fd3ddd72b2e", "assets/build/ba_data/textures/powerupLandMines_preview.png": "https://files.ballistica.net/cache/ba1/21/bc/b619e59db015ed4cc8020972a336", @@ -2046,31 +2046,31 @@ "assets/build/ba_data/textures/powerupSpeed.ktx": "https://files.ballistica.net/cache/ba1/2e/fc/63e2a260e55d0d33ed0dc4400cb0", "assets/build/ba_data/textures/powerupSpeed.pvr": "https://files.ballistica.net/cache/ba1/35/c1/657cc9772d575786c21d2575034d", "assets/build/ba_data/textures/powerupSpeed_preview.png": "https://files.ballistica.net/cache/ba1/f1/2a/278da1921f939809afad254fbb03", - "assets/build/ba_data/textures/powerupStickyBombs.dds": "https://files.ballistica.net/cache/ba1/02/93/92f9be86367f44404b8257bdbf6c", + "assets/build/ba_data/textures/powerupStickyBombs.dds": "https://files.ballistica.net/cache/ba1/eb/e0/0191d68d9daf896e9d2298c57941", "assets/build/ba_data/textures/powerupStickyBombs.ktx": "https://files.ballistica.net/cache/ba1/fd/1b/0a64a4e0149e6c9acc3bd5710283", "assets/build/ba_data/textures/powerupStickyBombs.pvr": "https://files.ballistica.net/cache/ba1/f5/44/ea00c858e1fdd2c73ae953b6fbe5", "assets/build/ba_data/textures/powerupStickyBombs_preview.png": "https://files.ballistica.net/cache/ba1/76/67/7e11feb9a7f94a68be36128e9afd", - "assets/build/ba_data/textures/puckColor.dds": "https://files.ballistica.net/cache/ba1/14/5f/893c54c1ccb320272450c24d232b", + "assets/build/ba_data/textures/puckColor.dds": "https://files.ballistica.net/cache/ba1/55/0f/0ad93b23a0a4d86ce4799135b26d", "assets/build/ba_data/textures/puckColor.ktx": "https://files.ballistica.net/cache/ba1/91/a8/49adfe0386637b17fd0d5df798d5", "assets/build/ba_data/textures/puckColor.pvr": "https://files.ballistica.net/cache/ba1/00/54/b9d50d210bfba69387909e6e91de", "assets/build/ba_data/textures/puckColor_preview.png": "https://files.ballistica.net/cache/ba1/bd/c4/4a3a3dcb8c1084a34479d43dcaed", - "assets/build/ba_data/textures/rampageBGColor.dds": "https://files.ballistica.net/cache/ba1/37/a1/a11281d3002afc84c3d28db58395", + "assets/build/ba_data/textures/rampageBGColor.dds": "https://files.ballistica.net/cache/ba1/34/2b/e98df914e71d6789e771ea70a264", "assets/build/ba_data/textures/rampageBGColor.ktx": "https://files.ballistica.net/cache/ba1/b0/39/acaf74037621c74a29a72576ee20", "assets/build/ba_data/textures/rampageBGColor.pvr": "https://files.ballistica.net/cache/ba1/6b/9d/54521c22a5e2de98eabfb985fa85", - "assets/build/ba_data/textures/rampageBGColor2.dds": "https://files.ballistica.net/cache/ba1/08/35/b2aca6e05626aaf870cceb35ba8e", + "assets/build/ba_data/textures/rampageBGColor2.dds": "https://files.ballistica.net/cache/ba1/22/94/8c49d6e549a2f08076d48417fb40", "assets/build/ba_data/textures/rampageBGColor2.ktx": "https://files.ballistica.net/cache/ba1/60/23/d866c382fc22fdea03bf2527d147", "assets/build/ba_data/textures/rampageBGColor2.pvr": "https://files.ballistica.net/cache/ba1/3e/69/d3c1a9d7f8910199598f010efd8a", "assets/build/ba_data/textures/rampageBGColor2_preview.png": "https://files.ballistica.net/cache/ba1/79/f6/068a9185d32b580a4e73806d8d12", "assets/build/ba_data/textures/rampageBGColor_preview.png": "https://files.ballistica.net/cache/ba1/38/39/0a2366c421eacc7c5a051c430e15", - "assets/build/ba_data/textures/rampageLevelColor.dds": "https://files.ballistica.net/cache/ba1/fe/40/41c878b5db3ebe47686d8a605cf6", + "assets/build/ba_data/textures/rampageLevelColor.dds": "https://files.ballistica.net/cache/ba1/81/69/f4b28c3c4713d96e3cb208bcfbce", "assets/build/ba_data/textures/rampageLevelColor.ktx": "https://files.ballistica.net/cache/ba1/ef/06/d2ac2ec0f775180b62e341a5890f", "assets/build/ba_data/textures/rampageLevelColor.pvr": "https://files.ballistica.net/cache/ba1/8a/74/ff813c81875c81cd8ccd345c5a27", "assets/build/ba_data/textures/rampageLevelColor_preview.png": "https://files.ballistica.net/cache/ba1/b9/db/0920892160b677dac33844acb9e3", - "assets/build/ba_data/textures/rampagePreview.dds": "https://files.ballistica.net/cache/ba1/15/af/3089f17f4e969b3780c92ef1ba58", + "assets/build/ba_data/textures/rampagePreview.dds": "https://files.ballistica.net/cache/ba1/09/56/67a073d1abfec5e861e3412bca94", "assets/build/ba_data/textures/rampagePreview.ktx": "https://files.ballistica.net/cache/ba1/b3/80/783d2507b45af55ebe7d9e4aa7b1", "assets/build/ba_data/textures/rampagePreview.pvr": "https://files.ballistica.net/cache/ba1/97/d2/99028f0da86ef4d61a70da709c29", "assets/build/ba_data/textures/rampagePreview_preview.png": "https://files.ballistica.net/cache/ba1/4f/64/6469bc8cfe52cdd9590c1edbc89c", - "assets/build/ba_data/textures/reflectionChar_+x.dds": "https://files.ballistica.net/cache/ba1/5b/6d/76948a60ad687d91d4db8696ff35", + "assets/build/ba_data/textures/reflectionChar_+x.dds": "https://files.ballistica.net/cache/ba1/2c/ec/82270cbcd6f3fc72aa1c69036163", "assets/build/ba_data/textures/reflectionChar_+x.ktx": "https://files.ballistica.net/cache/ba1/d2/31/6eb2af3d54a5a9b194f5fd5a0cd7", "assets/build/ba_data/textures/reflectionChar_+x.pvr": "https://files.ballistica.net/cache/ba1/45/72/1bf60fc63ee6024e2c62026e1d13", "assets/build/ba_data/textures/reflectionChar_+x_preview.png": "https://files.ballistica.net/cache/ba1/3e/19/1545732b54357b959468baeadb05", @@ -2086,7 +2086,7 @@ "assets/build/ba_data/textures/reflectionChar_-x.ktx": "https://files.ballistica.net/cache/ba1/7b/a7/6592e876e7c31687e11e019a305d", "assets/build/ba_data/textures/reflectionChar_-x.pvr": "https://files.ballistica.net/cache/ba1/88/fb/372bde1b68e238da396a7576088f", "assets/build/ba_data/textures/reflectionChar_-x_preview.png": "https://files.ballistica.net/cache/ba1/81/8f/422c1c54b3021abc70a4aa64b3fd", - "assets/build/ba_data/textures/reflectionChar_-y.dds": "https://files.ballistica.net/cache/ba1/25/03/628a5da0305261041300f75ef756", + "assets/build/ba_data/textures/reflectionChar_-y.dds": "https://files.ballistica.net/cache/ba1/45/c3/d1f2ffdb624d2236eb41e93b79cc", "assets/build/ba_data/textures/reflectionChar_-y.ktx": "https://files.ballistica.net/cache/ba1/25/1f/4e5b9240dcf6ea6639fb81f3579a", "assets/build/ba_data/textures/reflectionChar_-y.pvr": "https://files.ballistica.net/cache/ba1/4e/ee/7cdca1ae6b1458a443262c5a4e9c", "assets/build/ba_data/textures/reflectionChar_-y_preview.png": "https://files.ballistica.net/cache/ba1/ba/70/f2f188b95e2735467e823c94504a", @@ -2094,7 +2094,7 @@ "assets/build/ba_data/textures/reflectionChar_-z.ktx": "https://files.ballistica.net/cache/ba1/96/56/0f9aef42c876c3d2832ba570de79", "assets/build/ba_data/textures/reflectionChar_-z.pvr": "https://files.ballistica.net/cache/ba1/60/68/cb7fefc89119f14265c58200afde", "assets/build/ba_data/textures/reflectionChar_-z_preview.png": "https://files.ballistica.net/cache/ba1/b5/10/70b59c9cd551b44f8422867a38c2", - "assets/build/ba_data/textures/reflectionPowerup_+x.dds": "https://files.ballistica.net/cache/ba1/4b/3d/76538e3f18edb2a373bb3b591314", + "assets/build/ba_data/textures/reflectionPowerup_+x.dds": "https://files.ballistica.net/cache/ba1/aa/16/e46748f64851d1f0fd6c3b0bab9a", "assets/build/ba_data/textures/reflectionPowerup_+x.ktx": "https://files.ballistica.net/cache/ba1/a6/9b/682e676c993ae660475b4467fa6a", "assets/build/ba_data/textures/reflectionPowerup_+x.pvr": "https://files.ballistica.net/cache/ba1/f9/45/2b58be3bf14314607a25143fb477", "assets/build/ba_data/textures/reflectionPowerup_+x_preview.png": "https://files.ballistica.net/cache/ba1/66/cc/5021c0239527286f8c8f63aad21a", @@ -2126,11 +2126,11 @@ "assets/build/ba_data/textures/reflectionSharp_+y.ktx": "https://files.ballistica.net/cache/ba1/2c/a5/141e266b590226ee4a3474ac874e", "assets/build/ba_data/textures/reflectionSharp_+y.pvr": "https://files.ballistica.net/cache/ba1/a5/10/cdd96a99404584f090032ca60e62", "assets/build/ba_data/textures/reflectionSharp_+y_preview.png": "https://files.ballistica.net/cache/ba1/0f/58/f04fac2b705b92c8b0e11036a8ff", - "assets/build/ba_data/textures/reflectionSharp_+z.dds": "https://files.ballistica.net/cache/ba1/2a/be/a4ec2fb348452797276aa8a7ea52", + "assets/build/ba_data/textures/reflectionSharp_+z.dds": "https://files.ballistica.net/cache/ba1/ac/4b/db6e2bf52594a0cb882d17579bec", "assets/build/ba_data/textures/reflectionSharp_+z.ktx": "https://files.ballistica.net/cache/ba1/21/2c/51df5254932dac26b7068bc1e044", "assets/build/ba_data/textures/reflectionSharp_+z.pvr": "https://files.ballistica.net/cache/ba1/e4/87/2eaf17f6a15512b4326c7a2ae395", "assets/build/ba_data/textures/reflectionSharp_+z_preview.png": "https://files.ballistica.net/cache/ba1/1f/14/cd9fa509c22fea0f73a5eb76ac54", - "assets/build/ba_data/textures/reflectionSharp_-x.dds": "https://files.ballistica.net/cache/ba1/8f/2f/def7cd6049055701946f6ba7efcb", + "assets/build/ba_data/textures/reflectionSharp_-x.dds": "https://files.ballistica.net/cache/ba1/d7/b4/19de232b288604ffd66e48b182cf", "assets/build/ba_data/textures/reflectionSharp_-x.ktx": "https://files.ballistica.net/cache/ba1/04/cf/03b8b252c6d0a14b4a74df1697b2", "assets/build/ba_data/textures/reflectionSharp_-x.pvr": "https://files.ballistica.net/cache/ba1/f3/5b/36f37a9ca99d555c8950524ca118", "assets/build/ba_data/textures/reflectionSharp_-x_preview.png": "https://files.ballistica.net/cache/ba1/80/18/f2f8c9ce1f0dc8f297e0b29def1b", @@ -2142,7 +2142,7 @@ "assets/build/ba_data/textures/reflectionSharp_-z.ktx": "https://files.ballistica.net/cache/ba1/09/79/7c34e93c1453fa653098644dc902", "assets/build/ba_data/textures/reflectionSharp_-z.pvr": "https://files.ballistica.net/cache/ba1/08/d2/fa84664b3558ce68269581d52ab3", "assets/build/ba_data/textures/reflectionSharp_-z_preview.png": "https://files.ballistica.net/cache/ba1/e0/6e/de9a4cfdcb483bf92a63ac64e435", - "assets/build/ba_data/textures/reflectionSharper_+x.dds": "https://files.ballistica.net/cache/ba1/ed/05/68ad6e013833ba230bee61037591", + "assets/build/ba_data/textures/reflectionSharper_+x.dds": "https://files.ballistica.net/cache/ba1/86/21/0ed2cff91343e7d697e3fdbc9d15", "assets/build/ba_data/textures/reflectionSharper_+x.ktx": "https://files.ballistica.net/cache/ba1/ab/9b/243e80e52d6f837f206472054489", "assets/build/ba_data/textures/reflectionSharper_+x.pvr": "https://files.ballistica.net/cache/ba1/70/29/f1847b9d9c4892e3d383c8136b28", "assets/build/ba_data/textures/reflectionSharper_+x_preview.png": "https://files.ballistica.net/cache/ba1/22/db/1afb62440951a98fcf57663d5884", @@ -2210,7 +2210,7 @@ "assets/build/ba_data/textures/reflectionSoft_-y.ktx": "https://files.ballistica.net/cache/ba1/c7/af/7e09853ae6f0487e3a4122ac31d5", "assets/build/ba_data/textures/reflectionSoft_-y.pvr": "https://files.ballistica.net/cache/ba1/80/81/e5428d62dd5a31f708a68b258366", "assets/build/ba_data/textures/reflectionSoft_-y_preview.png": "https://files.ballistica.net/cache/ba1/2f/e1/b0cee0f161188752abcba04c9291", - "assets/build/ba_data/textures/reflectionSoft_-z.dds": "https://files.ballistica.net/cache/ba1/14/be/6bab80deb23a5105dd1ddd57740b", + "assets/build/ba_data/textures/reflectionSoft_-z.dds": "https://files.ballistica.net/cache/ba1/35/65/f84fc0c302b96ffde8d816c118c4", "assets/build/ba_data/textures/reflectionSoft_-z.ktx": "https://files.ballistica.net/cache/ba1/55/b2/45ec181ec07cd28be1a089b6bb79", "assets/build/ba_data/textures/reflectionSoft_-z.pvr": "https://files.ballistica.net/cache/ba1/67/6e/271b323497b797718b7d9bd3f939", "assets/build/ba_data/textures/reflectionSoft_-z_preview.png": "https://files.ballistica.net/cache/ba1/6f/38/dce6d5c26bc45005b9355b030c94", @@ -2229,7 +2229,7 @@ "assets/build/ba_data/textures/robotColor.dds": "https://files.ballistica.net/cache/ba1/a3/c0/2f7089d363c3e22b4ab10cd1c589", "assets/build/ba_data/textures/robotColor.ktx": "https://files.ballistica.net/cache/ba1/9a/9d/dbdec15776fd014e03eb1808ad28", "assets/build/ba_data/textures/robotColor.pvr": "https://files.ballistica.net/cache/ba1/9d/24/cc381a8ff6e80947618a97d36107", - "assets/build/ba_data/textures/robotColorMask.dds": "https://files.ballistica.net/cache/ba1/ec/0e/d1b4b152415679464cd0bf773b94", + "assets/build/ba_data/textures/robotColorMask.dds": "https://files.ballistica.net/cache/ba1/9f/89/248c558b1f019a7e37c24c6f2c74", "assets/build/ba_data/textures/robotColorMask.ktx": "https://files.ballistica.net/cache/ba1/19/4e/6bf15a0ac4ba4ad3bedd5eb3a3f3", "assets/build/ba_data/textures/robotColorMask.pvr": "https://files.ballistica.net/cache/ba1/ee/88/47d89b21335c4ba8916ff4eb11fd", "assets/build/ba_data/textures/robotColorMask_preview.png": "https://files.ballistica.net/cache/ba1/03/fd/c13045e5beed778e19f9a70f81ea", @@ -2242,18 +2242,18 @@ "assets/build/ba_data/textures/robotIconColorMask.pvr": "https://files.ballistica.net/cache/ba1/b8/65/40642024959c225ce4704b954f8f", "assets/build/ba_data/textures/robotIconColorMask_preview.png": "https://files.ballistica.net/cache/ba1/3a/c2/771b5f4aa159f61383b8bbefa291", "assets/build/ba_data/textures/robotIcon_preview.png": "https://files.ballistica.net/cache/ba1/7a/b8/1dad64c97fa4655f70490004cedc", - "assets/build/ba_data/textures/roundaboutLevelColor.dds": "https://files.ballistica.net/cache/ba1/69/bd/5a0e33f022abb454eebf4b9668ab", + "assets/build/ba_data/textures/roundaboutLevelColor.dds": "https://files.ballistica.net/cache/ba1/b6/df/cc3d90cdccfc1e07c99a4a5a5851", "assets/build/ba_data/textures/roundaboutLevelColor.ktx": "https://files.ballistica.net/cache/ba1/19/f8/d8ea41097c6dfe7bec255d85ea0a", "assets/build/ba_data/textures/roundaboutLevelColor.pvr": "https://files.ballistica.net/cache/ba1/0a/5a/19e1f33492b7ae2a9f100cf26fff", "assets/build/ba_data/textures/roundaboutLevelColor_preview.png": "https://files.ballistica.net/cache/ba1/18/c7/7dbe95a06d9e877fbe848f415141", - "assets/build/ba_data/textures/roundaboutPreview.dds": "https://files.ballistica.net/cache/ba1/a8/c2/d800722b8b7e172fcf19227abf05", + "assets/build/ba_data/textures/roundaboutPreview.dds": "https://files.ballistica.net/cache/ba1/c5/62/00e8ad165d2350b7136784bc0dc7", "assets/build/ba_data/textures/roundaboutPreview.ktx": "https://files.ballistica.net/cache/ba1/1f/63/e4776ec44e00a0d736aec31f1dfb", "assets/build/ba_data/textures/roundaboutPreview.pvr": "https://files.ballistica.net/cache/ba1/65/1a/019c03931b513047b9a5fcb7e8af", "assets/build/ba_data/textures/roundaboutPreview_preview.png": "https://files.ballistica.net/cache/ba1/d4/df/d26e050aac7285a6f453185f0046", - "assets/build/ba_data/textures/santaColor.dds": "https://files.ballistica.net/cache/ba1/5f/a1/91e228dda47c28f430ec2ff226b8", + "assets/build/ba_data/textures/santaColor.dds": "https://files.ballistica.net/cache/ba1/26/e6/febe3c69537cb30d8f1988cd405d", "assets/build/ba_data/textures/santaColor.ktx": "https://files.ballistica.net/cache/ba1/cc/f4/de2aaaf8cc855afaaceb1e618409", "assets/build/ba_data/textures/santaColor.pvr": "https://files.ballistica.net/cache/ba1/b6/22/85dfce13ccc2a531a42a91d4dd89", - "assets/build/ba_data/textures/santaColorMask.dds": "https://files.ballistica.net/cache/ba1/8a/9c/db332211cdc1deb5d60ce035d5a8", + "assets/build/ba_data/textures/santaColorMask.dds": "https://files.ballistica.net/cache/ba1/5e/5f/6c47e8aa0cdfc92d06bfd3a23b6d", "assets/build/ba_data/textures/santaColorMask.ktx": "https://files.ballistica.net/cache/ba1/b7/b0/9ebd903f0d9e491fa6a65181de19", "assets/build/ba_data/textures/santaColorMask.pvr": "https://files.ballistica.net/cache/ba1/a8/8c/6ab8ad9a2ea2e907635286163e57", "assets/build/ba_data/textures/santaColorMask_preview.png": "https://files.ballistica.net/cache/ba1/01/c4/436aca37ae86e73db9b7c856056a", @@ -2261,7 +2261,7 @@ "assets/build/ba_data/textures/santaIcon.dds": "https://files.ballistica.net/cache/ba1/50/10/67dc3f02df57883342cc345cf72e", "assets/build/ba_data/textures/santaIcon.ktx": "https://files.ballistica.net/cache/ba1/b7/6c/f22cde80b89403aeb4e950d8e2d2", "assets/build/ba_data/textures/santaIcon.pvr": "https://files.ballistica.net/cache/ba1/a0/4c/24e260da5e86b10a86049503b986", - "assets/build/ba_data/textures/santaIconColorMask.dds": "https://files.ballistica.net/cache/ba1/9e/36/dbeba27f8008aa3404864070f5bc", + "assets/build/ba_data/textures/santaIconColorMask.dds": "https://files.ballistica.net/cache/ba1/6c/54/c155cd9278a8411441fe9f68f09b", "assets/build/ba_data/textures/santaIconColorMask.ktx": "https://files.ballistica.net/cache/ba1/32/7a/c2d2cc16c7be82dbcff72a376f70", "assets/build/ba_data/textures/santaIconColorMask.pvr": "https://files.ballistica.net/cache/ba1/25/db/3dfff995ae0b87511a6bb7cc8b79", "assets/build/ba_data/textures/santaIconColorMask_preview.png": "https://files.ballistica.net/cache/ba1/ca/f2/a9f44952811c708bd50525d4da30", @@ -2310,7 +2310,7 @@ "assets/build/ba_data/textures/slash.ktx": "https://files.ballistica.net/cache/ba1/54/cb/a35780a274f021fc1044b45daf99", "assets/build/ba_data/textures/slash.pvr": "https://files.ballistica.net/cache/ba1/b6/d2/fa0617f78a81fc0eacb962484729", "assets/build/ba_data/textures/slash_preview.png": "https://files.ballistica.net/cache/ba1/33/2f/060dad5afdba8162d7a3ad082df0", - "assets/build/ba_data/textures/smoke.dds": "https://files.ballistica.net/cache/ba1/c1/b5/f1c19535edd6f9abc74b85a9673a", + "assets/build/ba_data/textures/smoke.dds": "https://files.ballistica.net/cache/ba1/66/a6/714c50394e08e6709f9470f2f02d", "assets/build/ba_data/textures/smoke.ktx": "https://files.ballistica.net/cache/ba1/8c/d8/74ac19c7930bbd695f533ec09fa3", "assets/build/ba_data/textures/smoke.pvr": "https://files.ballistica.net/cache/ba1/d7/a5/014c007053212e96096b545626ea", "assets/build/ba_data/textures/smoke_preview.png": "https://files.ballistica.net/cache/ba1/b1/c6/52443210c0229920389219868dcc", @@ -2326,7 +2326,7 @@ "assets/build/ba_data/textures/softRectVertical.pvr": "https://files.ballistica.net/cache/ba1/4d/19/857d457d9b5a0279a80dceea2cd3", "assets/build/ba_data/textures/softRectVertical_preview.png": "https://files.ballistica.net/cache/ba1/56/0f/524a88de51160a96224fb40249c1", "assets/build/ba_data/textures/softRect_preview.png": "https://files.ballistica.net/cache/ba1/5e/31/512ca0d886a0d866f194f875c3db", - "assets/build/ba_data/textures/sparks.dds": "https://files.ballistica.net/cache/ba1/89/77/00c8ba51a9cf06bfc0a0a427efc3", + "assets/build/ba_data/textures/sparks.dds": "https://files.ballistica.net/cache/ba1/0a/c4/0514ac00c5978979f65fbdf1b56e", "assets/build/ba_data/textures/sparks.ktx": "https://files.ballistica.net/cache/ba1/3d/6d/beee025480e5711ecd52bc5f6b07", "assets/build/ba_data/textures/sparks.pvr": "https://files.ballistica.net/cache/ba1/39/af/5b9e1081c0973f5e853c11fa06bc", "assets/build/ba_data/textures/sparks_preview.png": "https://files.ballistica.net/cache/ba1/19/fc/4a53d76b56ea0f0c3d5eaeed93b4", @@ -2338,11 +2338,11 @@ "assets/build/ba_data/textures/startButton.ktx": "https://files.ballistica.net/cache/ba1/ef/9a/9323a447cb7cf8fa119bbeadbf7c", "assets/build/ba_data/textures/startButton.pvr": "https://files.ballistica.net/cache/ba1/a8/25/74bd9ee857764fba362a0ecdc9b3", "assets/build/ba_data/textures/startButton_preview.png": "https://files.ballistica.net/cache/ba1/ba/d5/48858f0b1a1e0e4043762d4b0216", - "assets/build/ba_data/textures/stepRightUpLevelColor.dds": "https://files.ballistica.net/cache/ba1/aa/27/277f7741294d367810f01ef150f8", + "assets/build/ba_data/textures/stepRightUpLevelColor.dds": "https://files.ballistica.net/cache/ba1/58/51/eec340a570c3797198bcd9c7c205", "assets/build/ba_data/textures/stepRightUpLevelColor.ktx": "https://files.ballistica.net/cache/ba1/6f/35/3380ac50585bce22311666d28782", "assets/build/ba_data/textures/stepRightUpLevelColor.pvr": "https://files.ballistica.net/cache/ba1/8b/fb/eba3c0faa304123c784c888d0c65", "assets/build/ba_data/textures/stepRightUpLevelColor_preview.png": "https://files.ballistica.net/cache/ba1/5d/b9/bcdca38ad1d808b541b8008d5555", - "assets/build/ba_data/textures/stepRightUpPreview.dds": "https://files.ballistica.net/cache/ba1/ce/8f/8843ebbc561cf5dd44eb657b797d", + "assets/build/ba_data/textures/stepRightUpPreview.dds": "https://files.ballistica.net/cache/ba1/26/45/d61d7173f3875fb5a8e7a748b2df", "assets/build/ba_data/textures/stepRightUpPreview.ktx": "https://files.ballistica.net/cache/ba1/bd/75/7b19bfb14c8a73ae9a42156d70f2", "assets/build/ba_data/textures/stepRightUpPreview.pvr": "https://files.ballistica.net/cache/ba1/fe/44/e09c5a523cb3e8576709256c79a9", "assets/build/ba_data/textures/stepRightUpPreview_preview.png": "https://files.ballistica.net/cache/ba1/ad/ff/086bca9f87fdc17bae4bd55e904f", @@ -2365,7 +2365,7 @@ "assets/build/ba_data/textures/superheroColor.dds": "https://files.ballistica.net/cache/ba1/20/22/1e1f70c67cdbf49ce120b454f76a", "assets/build/ba_data/textures/superheroColor.ktx": "https://files.ballistica.net/cache/ba1/6d/7c/bc6c4f9b237301fefea90f27f9a0", "assets/build/ba_data/textures/superheroColor.pvr": "https://files.ballistica.net/cache/ba1/48/12/34feeaf8bb9724e3d084b96cda3b", - "assets/build/ba_data/textures/superheroColorMask.dds": "https://files.ballistica.net/cache/ba1/68/a5/b09635c375edc462cf4b102c3236", + "assets/build/ba_data/textures/superheroColorMask.dds": "https://files.ballistica.net/cache/ba1/3b/2f/c7890bc048477e15698c7663b3d4", "assets/build/ba_data/textures/superheroColorMask.ktx": "https://files.ballistica.net/cache/ba1/a5/19/f7169d492c759f9f3416887df9d5", "assets/build/ba_data/textures/superheroColorMask.pvr": "https://files.ballistica.net/cache/ba1/39/dc/256d7b9203f90032bbe21cec3a03", "assets/build/ba_data/textures/superheroColorMask_preview.png": "https://files.ballistica.net/cache/ba1/7d/f0/d05466477b420b25ff7dd881c87b", @@ -2382,11 +2382,11 @@ "assets/build/ba_data/textures/textClearButton.ktx": "https://files.ballistica.net/cache/ba1/05/60/2ae6636eb10907f2973342229949", "assets/build/ba_data/textures/textClearButton.pvr": "https://files.ballistica.net/cache/ba1/b1/32/dc45a735786df68c442b16a62a57", "assets/build/ba_data/textures/textClearButton_preview.png": "https://files.ballistica.net/cache/ba1/12/64/67e74f9e5d77ba1230304ea40497", - "assets/build/ba_data/textures/thePadLevelColor.dds": "https://files.ballistica.net/cache/ba1/61/17/6fb9d7fef2499c9ef5e3eb7ac928", + "assets/build/ba_data/textures/thePadLevelColor.dds": "https://files.ballistica.net/cache/ba1/7c/0d/09d84d8de458a7bcc7343b65ab9f", "assets/build/ba_data/textures/thePadLevelColor.ktx": "https://files.ballistica.net/cache/ba1/4e/34/bf0d6a8b0e64cf7fef14b1ec9da5", "assets/build/ba_data/textures/thePadLevelColor.pvr": "https://files.ballistica.net/cache/ba1/27/ad/471ab1086db8d6669040fc48742a", "assets/build/ba_data/textures/thePadLevelColor_preview.png": "https://files.ballistica.net/cache/ba1/88/1d/42616ff95265cb0d0db6c353a044", - "assets/build/ba_data/textures/thePadPreview.dds": "https://files.ballistica.net/cache/ba1/12/67/c64f2c3a5726712453400859e0f3", + "assets/build/ba_data/textures/thePadPreview.dds": "https://files.ballistica.net/cache/ba1/cd/ee/a4e2f05ada77eab50013534e46fc", "assets/build/ba_data/textures/thePadPreview.ktx": "https://files.ballistica.net/cache/ba1/5e/11/ff9caf9657a7c439b2e0fab39049", "assets/build/ba_data/textures/thePadPreview.pvr": "https://files.ballistica.net/cache/ba1/5a/8f/4061a1deafca6ba331738f6c9db8", "assets/build/ba_data/textures/thePadPreview_preview.png": "https://files.ballistica.net/cache/ba1/94/12/ec4cc8f0378cf62f811122e6faec", @@ -2410,11 +2410,11 @@ "assets/build/ba_data/textures/ticketsMore.pvr": "https://files.ballistica.net/cache/ba1/59/1a/73c4109d96e85316c2c46ff2c025", "assets/build/ba_data/textures/ticketsMore_preview.png": "https://files.ballistica.net/cache/ba1/24/01/32ba85edd6394dd56562f64eee09", "assets/build/ba_data/textures/tickets_preview.png": "https://files.ballistica.net/cache/ba1/90/ce/b693dd116e50d1b0eff488cfdd98", - "assets/build/ba_data/textures/tipTopBGColor.dds": "https://files.ballistica.net/cache/ba1/19/bf/258c624e1b3e3e3efabeefe3dd20", + "assets/build/ba_data/textures/tipTopBGColor.dds": "https://files.ballistica.net/cache/ba1/ac/31/d9009e21104f4131117610ba03a0", "assets/build/ba_data/textures/tipTopBGColor.ktx": "https://files.ballistica.net/cache/ba1/39/8c/a9f1ba489b23f5d899bb3f9941b1", "assets/build/ba_data/textures/tipTopBGColor.pvr": "https://files.ballistica.net/cache/ba1/1b/0d/89ecc99bc58aa985f00f7097177a", "assets/build/ba_data/textures/tipTopBGColor_preview.png": "https://files.ballistica.net/cache/ba1/54/0b/9978639a58e703cece49de6523b7", - "assets/build/ba_data/textures/tipTopLevelColor.dds": "https://files.ballistica.net/cache/ba1/d9/9d/5887220819a9bceaf547349cc1f3", + "assets/build/ba_data/textures/tipTopLevelColor.dds": "https://files.ballistica.net/cache/ba1/5f/d8/d29d224f0fcdcbf04ce625945baf", "assets/build/ba_data/textures/tipTopLevelColor.ktx": "https://files.ballistica.net/cache/ba1/4f/77/17f60fceaa239805af2bb7a169be", "assets/build/ba_data/textures/tipTopLevelColor.pvr": "https://files.ballistica.net/cache/ba1/8b/20/240ddac5158fb481ce41c50a86ce", "assets/build/ba_data/textures/tipTopLevelColor_preview.png": "https://files.ballistica.net/cache/ba1/75/88/019f15db873f836c5651b1b12130", @@ -2434,15 +2434,15 @@ "assets/build/ba_data/textures/touchArrowsActions.pvr": "https://files.ballistica.net/cache/ba1/74/1b/7642cfb899d1337073b10855d01d", "assets/build/ba_data/textures/touchArrowsActions_preview.png": "https://files.ballistica.net/cache/ba1/3c/21/1933b01847e20ed77164097aaea5", "assets/build/ba_data/textures/touchArrows_preview.png": "https://files.ballistica.net/cache/ba1/14/bd/595019a7e3b87bd844f8a60bf04c", - "assets/build/ba_data/textures/towerDLevelColor.dds": "https://files.ballistica.net/cache/ba1/8a/1f/997dafb004fe5b2122c66ae66302", + "assets/build/ba_data/textures/towerDLevelColor.dds": "https://files.ballistica.net/cache/ba1/08/c1/8925800c38503c077829f7b3fa96", "assets/build/ba_data/textures/towerDLevelColor.ktx": "https://files.ballistica.net/cache/ba1/8d/42/47252953095838210efdf6abc37d", "assets/build/ba_data/textures/towerDLevelColor.pvr": "https://files.ballistica.net/cache/ba1/9f/18/de2d35f9737871b3a1a914561428", "assets/build/ba_data/textures/towerDLevelColor_preview.png": "https://files.ballistica.net/cache/ba1/d4/e2/96ed47c7c856cf772a74f7385fab", - "assets/build/ba_data/textures/towerDPreview.dds": "https://files.ballistica.net/cache/ba1/4f/91/7de86add4cdc30060477c93e2aa6", + "assets/build/ba_data/textures/towerDPreview.dds": "https://files.ballistica.net/cache/ba1/de/cc/3810b38d96b849375c4d9a416665", "assets/build/ba_data/textures/towerDPreview.ktx": "https://files.ballistica.net/cache/ba1/e9/3a/d62eb672f3f26757b59f4d6d9e48", "assets/build/ba_data/textures/towerDPreview.pvr": "https://files.ballistica.net/cache/ba1/be/40/cc2ad06c0c08a1b937a2165f3bdb", "assets/build/ba_data/textures/towerDPreview_preview.png": "https://files.ballistica.net/cache/ba1/20/80/2314d36626f44f2ded99773ce267", - "assets/build/ba_data/textures/treesColor.dds": "https://files.ballistica.net/cache/ba1/a9/c6/e78e8aecedb379288c5a2d6e41f0", + "assets/build/ba_data/textures/treesColor.dds": "https://files.ballistica.net/cache/ba1/ff/c9/f24bda9787c79435fea19b8ff647", "assets/build/ba_data/textures/treesColor.ktx": "https://files.ballistica.net/cache/ba1/e7/19/2b8b0c8cfd26839ebd1d514354b7", "assets/build/ba_data/textures/treesColor.pvr": "https://files.ballistica.net/cache/ba1/03/b2/159518817084766a2cc464ba0a1b", "assets/build/ba_data/textures/treesColor_preview.png": "https://files.ballistica.net/cache/ba1/72/2b/7addb4861a6a8cd09748248e4de4", @@ -2470,14 +2470,14 @@ "assets/build/ba_data/textures/usersButton.ktx": "https://files.ballistica.net/cache/ba1/5b/e6/34fb5d6f905c30b3a2b9aa9e5734", "assets/build/ba_data/textures/usersButton.pvr": "https://files.ballistica.net/cache/ba1/0a/de/0f45f12e34557fb1141d7a266a0d", "assets/build/ba_data/textures/usersButton_preview.png": "https://files.ballistica.net/cache/ba1/1a/fc/7d74541cd06ad5db3de119418f81", - "assets/build/ba_data/textures/vrFillMound.dds": "https://files.ballistica.net/cache/ba1/bc/b3/8e14500bb766cf3639ea003cd9af", + "assets/build/ba_data/textures/vrFillMound.dds": "https://files.ballistica.net/cache/ba1/03/2e/06c7ee248c6adef3fde077f4e4e1", "assets/build/ba_data/textures/vrFillMound.ktx": "https://files.ballistica.net/cache/ba1/5d/1e/e86c34fd33355e21955d3d48bfe6", "assets/build/ba_data/textures/vrFillMound.pvr": "https://files.ballistica.net/cache/ba1/e8/da/46ed26badb88b6fd10abc37f35f6", "assets/build/ba_data/textures/vrFillMound_preview.png": "https://files.ballistica.net/cache/ba1/fd/33/4f817cfe06d2f8a04c395a9dc960", "assets/build/ba_data/textures/warriorColor.dds": "https://files.ballistica.net/cache/ba1/f2/51/d42750c9df1f55f39c134c925c7f", "assets/build/ba_data/textures/warriorColor.ktx": "https://files.ballistica.net/cache/ba1/e7/72/6f9a3314300c12b5ffd99a4d0000", "assets/build/ba_data/textures/warriorColor.pvr": "https://files.ballistica.net/cache/ba1/f2/63/d8bf3ba74b47932b4465847ef133", - "assets/build/ba_data/textures/warriorColorMask.dds": "https://files.ballistica.net/cache/ba1/e4/4c/e0ccd356704be279c55ad5d7bc68", + "assets/build/ba_data/textures/warriorColorMask.dds": "https://files.ballistica.net/cache/ba1/9f/d5/4787b04a7004e2b830f37cea8f2d", "assets/build/ba_data/textures/warriorColorMask.ktx": "https://files.ballistica.net/cache/ba1/d4/22/c8c01a12e9ec10f214659ce9faa4", "assets/build/ba_data/textures/warriorColorMask.pvr": "https://files.ballistica.net/cache/ba1/17/c5/87586c89935377cb8d4336713094", "assets/build/ba_data/textures/warriorColorMask_preview.png": "https://files.ballistica.net/cache/ba1/d9/97/16b01e9e4bf3bdc8c57672526158", @@ -2509,7 +2509,7 @@ "assets/build/ba_data/textures/witchColor.dds": "https://files.ballistica.net/cache/ba1/41/36/4b562ef0323d0b3ad88fea31bec8", "assets/build/ba_data/textures/witchColor.ktx": "https://files.ballistica.net/cache/ba1/f2/32/d61ee331287b1c4e508a1f6ea317", "assets/build/ba_data/textures/witchColor.pvr": "https://files.ballistica.net/cache/ba1/e5/f4/1ae61921f42efa27ed72120337a1", - "assets/build/ba_data/textures/witchColorMask.dds": "https://files.ballistica.net/cache/ba1/85/13/5d498983b93a3b27565525e60e03", + "assets/build/ba_data/textures/witchColorMask.dds": "https://files.ballistica.net/cache/ba1/39/b4/db14abde641fa3b63447936f2f9b", "assets/build/ba_data/textures/witchColorMask.ktx": "https://files.ballistica.net/cache/ba1/e0/23/4fb45223a969626489041af0de9f", "assets/build/ba_data/textures/witchColorMask.pvr": "https://files.ballistica.net/cache/ba1/ab/d9/d03a2366b07854e7c82cd0e1e443", "assets/build/ba_data/textures/witchColorMask_preview.png": "https://files.ballistica.net/cache/ba1/49/7f/61faa30b3b091c142c1212a85019", @@ -2522,18 +2522,18 @@ "assets/build/ba_data/textures/witchIconColorMask.pvr": "https://files.ballistica.net/cache/ba1/2e/76/a2b8bfd7868a47c11b2c5fd1660b", "assets/build/ba_data/textures/witchIconColorMask_preview.png": "https://files.ballistica.net/cache/ba1/49/bc/8479175256d1e62e607b2c392f2d", "assets/build/ba_data/textures/witchIcon_preview.png": "https://files.ballistica.net/cache/ba1/5f/96/cb2eb1c3a9fb0240f5748c5c1da5", - "assets/build/ba_data/textures/wizardColor.dds": "https://files.ballistica.net/cache/ba1/ec/e9/fcbc0fc4d1fc397f8ec5b498337f", + "assets/build/ba_data/textures/wizardColor.dds": "https://files.ballistica.net/cache/ba1/91/1b/af0d8cd18532d766b4b129317ed4", "assets/build/ba_data/textures/wizardColor.ktx": "https://files.ballistica.net/cache/ba1/50/da/d0569142ec7924ca40eccf82a930", "assets/build/ba_data/textures/wizardColor.pvr": "https://files.ballistica.net/cache/ba1/11/dc/b7f4a083ef2a93d7834b3d841443", - "assets/build/ba_data/textures/wizardColorMask.dds": "https://files.ballistica.net/cache/ba1/b4/32/3d46d2e5920e7530b384d7626617", + "assets/build/ba_data/textures/wizardColorMask.dds": "https://files.ballistica.net/cache/ba1/ad/cc/a104746ef03fa4a788e118424fc4", "assets/build/ba_data/textures/wizardColorMask.ktx": "https://files.ballistica.net/cache/ba1/0d/0d/80e2b947ebd3dbde1330682f62a4", "assets/build/ba_data/textures/wizardColorMask.pvr": "https://files.ballistica.net/cache/ba1/5a/7c/9933e396902aca69b786468d1c38", "assets/build/ba_data/textures/wizardColorMask_preview.png": "https://files.ballistica.net/cache/ba1/44/93/65a9e806485cd757e6a05655916a", "assets/build/ba_data/textures/wizardColor_preview.png": "https://files.ballistica.net/cache/ba1/cf/3c/3db3b3f5b6dab73f8b8a5353fe1a", - "assets/build/ba_data/textures/wizardIcon.dds": "https://files.ballistica.net/cache/ba1/e6/2f/74df3fe2e97c960ff1ca64aed588", + "assets/build/ba_data/textures/wizardIcon.dds": "https://files.ballistica.net/cache/ba1/0a/79/2ccd8ee9c225bf6a969f8f29d5d9", "assets/build/ba_data/textures/wizardIcon.ktx": "https://files.ballistica.net/cache/ba1/b9/3d/2c10de406177de22b8e89c9cb3b3", "assets/build/ba_data/textures/wizardIcon.pvr": "https://files.ballistica.net/cache/ba1/e3/c0/7d62f35ec06d5c4442a92b175cc0", - "assets/build/ba_data/textures/wizardIconColorMask.dds": "https://files.ballistica.net/cache/ba1/b5/16/7f556e4b852a94400388b4c96db4", + "assets/build/ba_data/textures/wizardIconColorMask.dds": "https://files.ballistica.net/cache/ba1/f1/aa/65c24f94a227616f5ef7d1f77bb8", "assets/build/ba_data/textures/wizardIconColorMask.ktx": "https://files.ballistica.net/cache/ba1/91/17/307bfa8af7dc435aa92dd38158f6", "assets/build/ba_data/textures/wizardIconColorMask.pvr": "https://files.ballistica.net/cache/ba1/3e/31/19cb4995ec02f1884bd35b29a464", "assets/build/ba_data/textures/wizardIconColorMask_preview.png": "https://files.ballistica.net/cache/ba1/20/24/700221546a08f3bc9c31e751ebcc", @@ -2541,7 +2541,7 @@ "assets/build/ba_data/textures/wrestlerColor.dds": "https://files.ballistica.net/cache/ba1/1f/d5/d21adac8982ad713b0bbdbb7ee6c", "assets/build/ba_data/textures/wrestlerColor.ktx": "https://files.ballistica.net/cache/ba1/d7/22/bf15886b227531620eec6462be2d", "assets/build/ba_data/textures/wrestlerColor.pvr": "https://files.ballistica.net/cache/ba1/ab/76/9f573919ed6b9e635f4a014584ba", - "assets/build/ba_data/textures/wrestlerColorMask.dds": "https://files.ballistica.net/cache/ba1/fb/a5/472ae89a40a52d189c9337c179fa", + "assets/build/ba_data/textures/wrestlerColorMask.dds": "https://files.ballistica.net/cache/ba1/9f/98/98d3c41b83875f850abc3b2c31df", "assets/build/ba_data/textures/wrestlerColorMask.ktx": "https://files.ballistica.net/cache/ba1/21/1f/eebe5e1fe740412aad15026d21b5", "assets/build/ba_data/textures/wrestlerColorMask.pvr": "https://files.ballistica.net/cache/ba1/36/43/ef6da6107379ac3f74204a34c529", "assets/build/ba_data/textures/wrestlerColorMask_preview.png": "https://files.ballistica.net/cache/ba1/0c/5f/8619903636053dc0ff1858bf3451", @@ -2554,26 +2554,26 @@ "assets/build/ba_data/textures/wrestlerIconColorMask.pvr": "https://files.ballistica.net/cache/ba1/7b/5d/83a1a0f4d7b06303d5da137e5847", "assets/build/ba_data/textures/wrestlerIconColorMask_preview.png": "https://files.ballistica.net/cache/ba1/b5/74/774b56f03e583df47388c552c63e", "assets/build/ba_data/textures/wrestlerIcon_preview.png": "https://files.ballistica.net/cache/ba1/38/71/8b5f4d69dde24101ce0d69747486", - "assets/build/ba_data/textures/zigZagLevelColor.dds": "https://files.ballistica.net/cache/ba1/df/17/9994816ad67f481800bae16f2db2", + "assets/build/ba_data/textures/zigZagLevelColor.dds": "https://files.ballistica.net/cache/ba1/ea/cf/a59f7ca3b2f0d7a08e3ad42d83ab", "assets/build/ba_data/textures/zigZagLevelColor.ktx": "https://files.ballistica.net/cache/ba1/c1/1e/82884d1423ce4a7d641003e84bfb", "assets/build/ba_data/textures/zigZagLevelColor.pvr": "https://files.ballistica.net/cache/ba1/56/df/c53d264147677138e47799ea990e", "assets/build/ba_data/textures/zigZagLevelColor_preview.png": "https://files.ballistica.net/cache/ba1/cd/d7/b45e95db0117c4fe5d957136b4bb", - "assets/build/ba_data/textures/zigzagPreview.dds": "https://files.ballistica.net/cache/ba1/6c/13/64e4a3570343f8a8965b8c6bb318", + "assets/build/ba_data/textures/zigzagPreview.dds": "https://files.ballistica.net/cache/ba1/00/3b/3a7f2ab4aed12f4d911e94093002", "assets/build/ba_data/textures/zigzagPreview.ktx": "https://files.ballistica.net/cache/ba1/33/ca/b022d38b1306d8382c2ecdb270b9", "assets/build/ba_data/textures/zigzagPreview.pvr": "https://files.ballistica.net/cache/ba1/0e/21/4f296b4440f8467c904221d18400", "assets/build/ba_data/textures/zigzagPreview_preview.png": "https://files.ballistica.net/cache/ba1/f4/32/1f69e507893d054aca0371c31248", - "assets/build/ba_data/textures/zoeColor.dds": "https://files.ballistica.net/cache/ba1/05/e4/93016a653b2bb3433138594c9c0e", + "assets/build/ba_data/textures/zoeColor.dds": "https://files.ballistica.net/cache/ba1/82/6e/c531db13a3eff5a2e37c32af79c1", "assets/build/ba_data/textures/zoeColor.ktx": "https://files.ballistica.net/cache/ba1/8d/80/906fb08660e1fcde3f5997108abf", "assets/build/ba_data/textures/zoeColor.pvr": "https://files.ballistica.net/cache/ba1/4a/74/8ca47effb87502b7334398e967be", - "assets/build/ba_data/textures/zoeColorMask.dds": "https://files.ballistica.net/cache/ba1/b6/06/e4086e65b697d7de1c8864f49029", + "assets/build/ba_data/textures/zoeColorMask.dds": "https://files.ballistica.net/cache/ba1/eb/a5/a71bc5739b02d7101dbd29e6b81b", "assets/build/ba_data/textures/zoeColorMask.ktx": "https://files.ballistica.net/cache/ba1/b9/32/91c389da7403df50125cddc37575", "assets/build/ba_data/textures/zoeColorMask.pvr": "https://files.ballistica.net/cache/ba1/f4/6a/4cbdbcf47abdb7f8fdc8d283451e", "assets/build/ba_data/textures/zoeColorMask_preview.png": "https://files.ballistica.net/cache/ba1/ca/0e/66481610316607e9adcb456467d1", "assets/build/ba_data/textures/zoeColor_preview.png": "https://files.ballistica.net/cache/ba1/3b/3e/91abd548d271a97df63b327a1f82", - "assets/build/ba_data/textures/zoeIcon.dds": "https://files.ballistica.net/cache/ba1/da/63/063fc70b4a22b7a0f32ca8e9f8b4", + "assets/build/ba_data/textures/zoeIcon.dds": "https://files.ballistica.net/cache/ba1/23/d4/d1b9a5a9fd790beb494b823f7a35", "assets/build/ba_data/textures/zoeIcon.ktx": "https://files.ballistica.net/cache/ba1/fd/75/88d1a4355980906272cf904bd722", "assets/build/ba_data/textures/zoeIcon.pvr": "https://files.ballistica.net/cache/ba1/7c/66/7959cdfaa884068bdb11db1ef330", - "assets/build/ba_data/textures/zoeIconColorMask.dds": "https://files.ballistica.net/cache/ba1/75/06/c186a1ad6e54ba6d8862b23c2136", + "assets/build/ba_data/textures/zoeIconColorMask.dds": "https://files.ballistica.net/cache/ba1/0b/61/f5e3848c72b5359e129ed7fd9ee0", "assets/build/ba_data/textures/zoeIconColorMask.ktx": "https://files.ballistica.net/cache/ba1/bd/eb/deb5899cffa81a665248e3062363", "assets/build/ba_data/textures/zoeIconColorMask.pvr": "https://files.ballistica.net/cache/ba1/2b/dc/22df1ef245a7f368060d2eecb839", "assets/build/ba_data/textures/zoeIconColorMask_preview.png": "https://files.ballistica.net/cache/ba1/d5/08/7d5e28abf51591fb4923892f43dd", @@ -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/0e/af/b1c02ed97cd2be848229dcf5a053", - "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/c6/80/5de16710ccb0b41d1e0067267970", - "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/83/b8/8897303dab143f36e1dccf0f1019", - "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/bd/e1/4bd99de84798c83959d5db9bdc8a", - "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/7e/ba/16df06cda8a5495544d853b9891d", - "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/a9/27/43afc973cb055c64513c8d220236", - "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/26/b4/3ce5f686d549c3a6b1e63c4045ac", - "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/92/24/2b4175234b768d7d45b2f4a967b6", - "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/88/05/75064b0904a2ce5ce15e7f6e6d61", - "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/3b/fd/9a661af315236f37b2c22fd987ee", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/d4/3c/1257420072dceded3147faf3de7d", - "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/f5/1c/d35becd4f0722f9f28bc695f316b", - "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/f1/2e/ea3ce9edaa5d6c11e7306675df38", - "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/42/6d/aaf54051f79f265a281035c0f4cd", - "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/71/f8/22d3f6458bdee3cd2c5da503c84e", - "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/9a/09/c1c6878c65da376a0d9ab6747c0a", - "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/81/c0/f00f87083acc20e33f278aa4d8d4", - "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/0e/e2/e4c9b3f3dcb379e71eb421beca78", - "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/09/87/21b1d4411cd5b3549627fcc85e8f", - "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/1e/7e/2c4229ced6c44c1cd577262b9a87", - "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a2/9d/285cd73953e62fdb7945c09fb83c", + "build/prefab/full/linux_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/72/15/a3419621532792868f14916bd34a", + "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/18/ac/ee5f88a1c29b499ffa41a69cdf38", + "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/ac/47/e5ec1b1a7a8b9c84e2f2f2b8300e", + "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/60/7f/59e5077df04a756b7afc627a4c7b", + "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/db/2d/49a6bbb0d77513f30a07687f051c", + "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/f0/7b/dcaeb5c6221bf5257e45581e926b", + "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/56/3e/f81e23d9b0bf3f4c6359f6428801", + "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/1f/9a/5afb53b0a127144f92203e40c25b", + "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/61/e0/a4ba0178462217007cf112667c13", + "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/c6/c2/4b35be76f242ba55a9344476abd7", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/e8/9a/efc48010be9a619bb7b634027075", + "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/21/ee/92682d84a0db7135e8f408489cce", + "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/7a/32/230627534f1fcace63c79d0bd8d5", + "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/2f/96/1df9bb9cdac82d644faf3c13b4cd", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/64/55/aab8e044fd15398a88d31c9fb51b", + "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/6c/9c/49105190245fbcab5cd93005ab81", + "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/fb/49/9e0f204242ae3b8d24341674325d", + "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/22/b6/219dd7ff36d458f41dcedb01c212", + "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/7d/c3/b10f13471461e58a36e44a342788", + "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/4e/eb/508149422a89e63891d110a9ab81", + "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/28/9d/ecf9b1e3f0cc39c627007a6625ec", "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/22/2d/3df4908dfdcdebe772bf3df0daee", - "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/2a/74/763faee36da963364e94996429d5", + "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/76/a1/1487a3b3320bbaf56f966294f1e6", "build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/87/9f/4408f47d293436f420ff9338dca6", - "build/prefab/lib/linux_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/4f/e8/2518fd177b5c51f89ef0795b1264", + "build/prefab/lib/linux_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/b1/e2/cb8a3c638ea0ae97bd7ad843d65c", "build/prefab/lib/linux_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/77/b1/41befd66869830590f00bff7ba97", - "build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/92/a2/8d6f01537d722803aab60cb67e6d", + "build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/58/58/64ca6d95f17cc2c0f3dd622e726c", "build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/fc/be/0e1af48000395cdbe72179dba90a", "build/prefab/lib/mac_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/20/7a/b31ec8c47d67b7fd23ed2510aae7", "build/prefab/lib/mac_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a0/b5/b4ffd9769f3b703226e744423a58", "build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/3b/02/9e8f15c68ca328a7549846d53a8f", "build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a0/74/b61b74ada26b41f421563b535dd0", - "build/prefab/lib/mac_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ec/5c/08c171db06bd4492a2b414c77488", + "build/prefab/lib/mac_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/cb/76/6be6a4353ba029f0926d44a2bc38", "build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/2f/8a/0384cc905ba23bd45afdfcacb882", - "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/63/6f/e6ba3560e0a8e404bb592405de27", + "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/55/ea/ac29558ce9735f704fc1fc32d769", "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/6e/14/c4f70a74e2111e3adb096dfbd215", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/94/90/509608dd38c2bbc509dcf468c260", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/61/7f/f3591f125f13cbb74a41a99225b4", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/b5/11/cebb90659cbd5fbf33fc8f05afb9", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/50/fe/556c95e535ab849bfc7410adf8b6", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/6f/39/8ae7e0225b54ff0fe93cf83bc9be", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/a1/5e/4f797ceb3153f4a687eb7606a5be", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/b6/7a/8ac9e0d6d0188e2beb88f34c981f", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/39/b8/85db5aa7cede25660da4ff36a3a0", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/b9/e0/02fdc0a225e6ec118ed7f5244b58", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/d1/43/754722685a834ab3779850af54af", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/79/2d/b37cf8c48d05b6a7313552506c4a", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/df/ef/849dacb5977c53749d8516ec4a85", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/bd/ee/c751ff7a69e4174eef5040d07b2e", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/00/9d/25c03c0cfc21ab1a619806a3e300", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/5f/e7/338348603f27430ea5adb4089d0b", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/c6/6e/1126f1605e6e46a822e89a2147b9", "src/ballistica/generated/python_embedded/binding.inc": "https://files.ballistica.net/cache/ba1/25/77/8093dfffddaa80cd513ddaa61867", "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/CHANGELOG.md b/CHANGELOG.md index ba5ba052..4095fb1f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,11 @@ +### 1.7.16 (build 20961, api 7, 2022-12-06) +- Fixed a bug where profile names encased in curly brackets could cause harmless error messages. +- Android will no longer log errors on ba.open_url() calls if a browser is not available (it still just falls back to the in-app dialog in that case). +- The 'Upgrade' button for device accounts now signs you out and closes the upgrade window to hopefully make it more clear that you need to sign in with your newly created/upgraded BombSquad account. + ### 1.7.15 (build 20960, api 7, 2022-12-04) +- The cancel button on the 'Sign in with a Bombsquad Account' popup no longer respond to system cancel buttons (escape key, android back button, etc). Turns out some Android people were pressing back repeatedly to come back from a browser after signing in and immediately canceling their sign in attempts in the game before they completed. Hopefully this will avoid some frustration. +- Fixed an issue where back presses could result in multiple main menu windows appearing. ### 1.7.14 (build 20958, api 7, 2022-12-03) - Android Google Play logins now provide V2 accounts with access to all V2 features such as a globally-unique account tag, cloud-console, and workspaces. They should still retain their V1 data as well. @@ -15,6 +22,7 @@ - Fixed a low level event-loop issue that in some cases was preventing the Android version from properly pausing/resuming the app or managing connections while in the background. If you look at the devices section on ballistica.net you should now see your device disappear when you background the app and reappear when you foreground it. Please holler if not. - Device accounts are now marked as deprecated, and signing in with one now brings up an 'upgrade' UI which allows converting it to a V2 account. It is my hope to push the entire client ecosystem to V2 accounts as quickly as possible since trying to support both independent V1 accounts and V2 accounts is a substantial technical burden. - Fixed an issue where Log calls made within `Thread::PushThreadMessage()` could result in deadlock. +- Fixed an issue where some Android hardware buttons could theoretically cause rogue game controller button presses (due to downcasting int values > 255 into a uint8 value). ### 1.7.13 (build 20919, api 7, 2022-11-03) - Android target-sdk has been updated to 33 (Android 13). Please holler if anything seems broken or is behaving differently than before on Android. diff --git a/assets/src/ba_data/python/ba/_bootstrap.py b/assets/src/ba_data/python/ba/_bootstrap.py index be5d6018..ba6ab50d 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 = 20960 + expected_build = 20961 running_build: int = env['build_number'] if running_build != expected_build: print( diff --git a/assets/src/ba_data/python/ba/_plugin.py b/assets/src/ba_data/python/ba/_plugin.py index 3e896887..b9812980 100644 --- a/assets/src/ba_data/python/ba/_plugin.py +++ b/assets/src/ba_data/python/ba/_plugin.py @@ -173,7 +173,7 @@ class PluginSubsystem: color=(1, 1, 0), ) plugnames = ', '.join(disappeared_plugs) - logging.warning( + logging.info( '%d plugin(s) no longer found: %s.', len(disappeared_plugs), plugnames, diff --git a/assets/src/ba_data/python/bastd/ui/account/v2proxy.py b/assets/src/ba_data/python/bastd/ui/account/v2proxy.py index a2d4fb76..d782fcf7 100644 --- a/assets/src/ba_data/python/bastd/ui/account/v2proxy.py +++ b/assets/src/ba_data/python/bastd/ui/account/v2proxy.py @@ -67,11 +67,14 @@ class V2ProxySignInWindow(ba.Window): label=ba.Lstr(resource='cancelText'), on_activate_call=self._done, autoselect=True, + color=(0.55, 0.5, 0.6), textcolor=(0.75, 0.7, 0.8), ) - ba.containerwidget( - edit=self._root_widget, cancel_button=self._cancel_button - ) + + if bool(False): + ba.containerwidget( + edit=self._root_widget, cancel_button=self._cancel_button + ) self._update_timer: ba.Timer | None = None diff --git a/assets/src/ba_data/python/bastd/ui/v2upgrade.py b/assets/src/ba_data/python/bastd/ui/v2upgrade.py index ed61e170..7210c95e 100644 --- a/assets/src/ba_data/python/bastd/ui/v2upgrade.py +++ b/assets/src/ba_data/python/bastd/ui/v2upgrade.py @@ -88,17 +88,13 @@ class V2UpgradeWindow(ba.Window): on_activate_call=show_what_is_v2_page, ) - bamasteraddr = ba.internal.get_master_server_address(version=2) upgrade_button = ba.buttonwidget( parent=self._root_widget, position=(self._width - button_width - 20, 25), size=(button_width, 65), autoselect=True, label=ba.Lstr(resource='upgradeText'), - on_activate_call=ba.Call( - ba.open_url, - f'{bamasteraddr}/v2uda/{self._code}', - ), + on_activate_call=self._upgrade_press, ) ba.containerwidget( @@ -107,5 +103,15 @@ class V2UpgradeWindow(ba.Window): cancel_button=cancel_button, ) + def _upgrade_press(self) -> None: + # Get rid of the window and sign out before kicking the + # user over to a browser to do the upgrade. This hopefully + # makes it more clear when they come back that they need to + # sign in with the 'BombSquad account' option. + ba.containerwidget(edit=self._root_widget, transition='out_left') + ba.internal.sign_out_v1() + bamasteraddr = ba.internal.get_master_server_address(version=2) + ba.open_url(f'{bamasteraddr}/v2uda/{self._code}') + def _done(self) -> None: ba.containerwidget(edit=self._root_widget, transition='out_left') diff --git a/src/ballistica/app/app_flavor.cc b/src/ballistica/app/app_flavor.cc index d6a2b1ed..0d237d87 100644 --- a/src/ballistica/app/app_flavor.cc +++ b/src/ballistica/app/app_flavor.cc @@ -257,10 +257,13 @@ void AppFlavor::PauseApp() { auto threads{Thread::GetStillPausingThreads()}; running_thread_count = threads.size(); if (running_thread_count == 0) { - Log(LogLevel::kDebug, - "PauseApp() completed in " - + std::to_string(Platform::GetCurrentMilliseconds() - start_time) - + "ms."); + if (g_buildconfig.debug_build()) { + Log(LogLevel::kDebug, + "PauseApp() completed in " + + std::to_string(Platform::GetCurrentMilliseconds() + - start_time) + + "ms."); + } return; } } @@ -282,10 +285,12 @@ void AppFlavor::ResumeApp() { assert(sys_paused_app_); sys_paused_app_ = false; UpdatePauseResume(); - Log(LogLevel::kDebug, - "ResumeApp() completed in " - + std::to_string(Platform::GetCurrentMilliseconds() - start_time) - + "ms."); + if (g_buildconfig.debug_build()) { + Log(LogLevel::kDebug, + "ResumeApp() completed in " + + std::to_string(Platform::GetCurrentMilliseconds() - start_time) + + "ms."); + } } void AppFlavor::DidFinishRenderingFrame(FrameDef* frame) {} diff --git a/src/ballistica/ballistica.cc b/src/ballistica/ballistica.cc index 829dc500..310acbd1 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 = 20960; -const char* kAppVersion = "1.7.15"; +const int kAppBuildNumber = 20961; +const char* kAppVersion = "1.7.16"; // Our standalone globals. // These are separated out for easy access. diff --git a/src/ballistica/ui/widget/root_widget.cc b/src/ballistica/ui/widget/root_widget.cc index 976dd8e8..c9028fc9 100644 --- a/src/ballistica/ui/widget/root_widget.cc +++ b/src/ballistica/ui/widget/root_widget.cc @@ -1108,7 +1108,15 @@ void RootWidget::SetOverlayWidget(StackWidget* w) { overlay_stack_widget_ = w; } -void RootWidget::OnCancelCustom() { g_ui->PushBackButtonCall(nullptr); } +void RootWidget::OnCancelCustom() { + // Need to revisit this. If the cancel event it pushes is not handled, it will + // wind up back here where it pushes another back call. This cycle repeats + // forever until something comes along which does handle cancel events and + // then it gets them all. Current repro case is Sign-in-with-BombSquad-Account + // window - press escape a few times while that is up and then click cancel; + // This code is only used for toolbar mode so should be safe to leave it + // disabled for now. g_ui->PushBackButtonCall(nullptr); +} auto RootWidget::GetSpecialWidget(const std::string& s) const -> Widget* { if (s == "party_button") { diff --git a/src/ballistica/ui/widget/text_widget.cc b/src/ballistica/ui/widget/text_widget.cc index c45241e9..ab40826d 100644 --- a/src/ballistica/ui/widget/text_widget.cc +++ b/src/ballistica/ui/widget/text_widget.cc @@ -441,20 +441,23 @@ void TextWidget::SetText(const std::string& text_in_raw) { bool do_format_check{}; bool print_false_positives{}; - if (g_buildconfig.debug_build()) { - do_format_check = explicit_bool(true); - } else { - if (text_in_raw.size() > 1 && text_in_raw[0] == '{' - && text_in_raw[text_in_raw.size() - 1] == '}') { - // Ok, its got bounds like json; now if its either missing quotes or a - // colon then let's check it. - if (!strstr(text_in_raw.c_str(), "\"") - || !strstr(text_in_raw.c_str(), ":")) { - do_format_check = true; + // Only non-editable text support resource-strings. + if (!editable_) { + if (g_buildconfig.debug_build()) { + do_format_check = explicit_bool(true); + } else { + if (text_in_raw.size() > 1 && text_in_raw[0] == '{' + && text_in_raw[text_in_raw.size() - 1] == '}') { + // Ok, its got bounds like json; now if its either missing quotes or a + // colon then let's check it. + if (!strstr(text_in_raw.c_str(), "\"") + || !strstr(text_in_raw.c_str(), ":")) { + do_format_check = true; - // We wanna avoid doing this check when we don't have to. - // so lets print if we get a false positive - print_false_positives = true; + // We wanna avoid doing this check when we don't have to. + // so lets print if we get a false positive + print_false_positives = true; + } } } } From 1032dbe71bce720e34f8cbd36a1aaa8087749acf Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 7 Dec 2022 22:30:35 -0800 Subject: [PATCH 09/26] asset rebuild --- .efrocachemap | 1174 ++++++++++---------- CHANGELOG.md | 2 +- assets/src/ba_data/python/ba/_bootstrap.py | 2 +- src/ballistica/ballistica.cc | 2 +- 4 files changed, 590 insertions(+), 590 deletions(-) diff --git a/.efrocachemap b/.efrocachemap index 429b7154..a12af0c5 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -1,425 +1,425 @@ { - "assets/build/ba_data/audio/achievement.ogg": "https://files.ballistica.net/cache/ba1/f3/d5/5e2a71ca6cf6f8aeed9c70a543b6", - "assets/build/ba_data/audio/actionHero1.ogg": "https://files.ballistica.net/cache/ba1/51/2e/c7c47074120f8ae304d6a2402ed3", - "assets/build/ba_data/audio/actionHero2.ogg": "https://files.ballistica.net/cache/ba1/38/e1/087af551c2b25085527493f1f437", - "assets/build/ba_data/audio/actionHero3.ogg": "https://files.ballistica.net/cache/ba1/2d/84/3e8fea6c1fa735dcbd7426eedc86", - "assets/build/ba_data/audio/actionHero4.ogg": "https://files.ballistica.net/cache/ba1/5c/d7/73853336ac71e77e517e7cf366c0", - "assets/build/ba_data/audio/actionHeroDeath.ogg": "https://files.ballistica.net/cache/ba1/c8/13/3eb6536a0d2ae71ac0addc60bef4", - "assets/build/ba_data/audio/actionHeroFall.ogg": "https://files.ballistica.net/cache/ba1/76/32/8890531e4a43a10033197e16446e", - "assets/build/ba_data/audio/actionHeroHit1.ogg": "https://files.ballistica.net/cache/ba1/6b/eb/ef81c3c6287f81bc39bb0c237551", - "assets/build/ba_data/audio/actionHeroHit2.ogg": "https://files.ballistica.net/cache/ba1/14/03/3b04edc89059d34761e1a079159d", - "assets/build/ba_data/audio/activateBeep.ogg": "https://files.ballistica.net/cache/ba1/33/50/4991a97b5591728d75672c1b78d5", - "assets/build/ba_data/audio/agent1.ogg": "https://files.ballistica.net/cache/ba1/c8/a5/d77f655080024706e0fbf64aa630", - "assets/build/ba_data/audio/agent2.ogg": "https://files.ballistica.net/cache/ba1/ad/1e/e14a53f609c4d35b99397872c01d", - "assets/build/ba_data/audio/agent3.ogg": "https://files.ballistica.net/cache/ba1/ec/bd/e1979fa50c9db652b244f65a26a4", - "assets/build/ba_data/audio/agent4.ogg": "https://files.ballistica.net/cache/ba1/b1/e4/4b00d771656f9a76e329abbdf66f", - "assets/build/ba_data/audio/agentDeath.ogg": "https://files.ballistica.net/cache/ba1/b9/24/cb70898bdfd33d2afa3603782b1d", - "assets/build/ba_data/audio/agentFall.ogg": "https://files.ballistica.net/cache/ba1/b3/fc/ab76fab4cf39993b2c17fd7e8a44", - "assets/build/ba_data/audio/agentHit1.ogg": "https://files.ballistica.net/cache/ba1/26/4e/9c2e4088a8051c82a9a1f5c541be", - "assets/build/ba_data/audio/agentHit2.ogg": "https://files.ballistica.net/cache/ba1/01/ce/bc61c328d2d07ed3bfc607345f0c", - "assets/build/ba_data/audio/alarm.ogg": "https://files.ballistica.net/cache/ba1/40/0d/482f43a8226e0bb590afffe8d88f", - "assets/build/ba_data/audio/ali1.ogg": "https://files.ballistica.net/cache/ba1/98/ee/9e5acc253cf99b22ddd26face164", - "assets/build/ba_data/audio/ali2.ogg": "https://files.ballistica.net/cache/ba1/89/c8/991347dda8933633295537040667", - "assets/build/ba_data/audio/ali3.ogg": "https://files.ballistica.net/cache/ba1/61/8d/3d4cb7f8a2af897afb198c4956e2", - "assets/build/ba_data/audio/ali4.ogg": "https://files.ballistica.net/cache/ba1/31/4d/8a2ec328bd4bebe4a09d6698875c", - "assets/build/ba_data/audio/aliDeath.ogg": "https://files.ballistica.net/cache/ba1/34/34/d6ff448b9d6b10d0c1ddbd0e6088", - "assets/build/ba_data/audio/aliFall.ogg": "https://files.ballistica.net/cache/ba1/f1/01/a7ba4c5d77b9388f5be766bf8c30", - "assets/build/ba_data/audio/aliHit1.ogg": "https://files.ballistica.net/cache/ba1/ab/07/6c61513aa526927a4a43ba20e1a5", - "assets/build/ba_data/audio/aliHit2.ogg": "https://files.ballistica.net/cache/ba1/82/e1/050b95514af84a835c6feffac75c", - "assets/build/ba_data/audio/alien1.ogg": "https://files.ballistica.net/cache/ba1/70/80/0614cb0cc13d5cad13656441f7d1", - "assets/build/ba_data/audio/alien2.ogg": "https://files.ballistica.net/cache/ba1/de/05/e83bf8853889ac05ebe35f677aca", - "assets/build/ba_data/audio/alien3.ogg": "https://files.ballistica.net/cache/ba1/cb/24/49815689a4c238fda09800cd6ce7", - "assets/build/ba_data/audio/alien4.ogg": "https://files.ballistica.net/cache/ba1/4b/53/cc8bf4580f987e40d7d95a212c88", - "assets/build/ba_data/audio/alienDeath.ogg": "https://files.ballistica.net/cache/ba1/67/ff/c6e28264cb4e70d0a47803d1f029", - "assets/build/ba_data/audio/alienFall.ogg": "https://files.ballistica.net/cache/ba1/41/5c/f429880141ef4fb3dbb09a5be2bb", - "assets/build/ba_data/audio/alienHit1.ogg": "https://files.ballistica.net/cache/ba1/1a/59/8c3c8a7d2966ad49f80c4480c161", - "assets/build/ba_data/audio/alienHit2.ogg": "https://files.ballistica.net/cache/ba1/d8/c1/9227834c4723eb77d60498bb7bbc", - "assets/build/ba_data/audio/announceEight.ogg": "https://files.ballistica.net/cache/ba1/a5/73/3181472f013bbf691fd13c3fe33e", - "assets/build/ba_data/audio/announceFive.ogg": "https://files.ballistica.net/cache/ba1/b1/b0/f956a5754829263876a05f513927", - "assets/build/ba_data/audio/announceFour.ogg": "https://files.ballistica.net/cache/ba1/16/67/8f50374ba244dadb7dfd6bb19418", - "assets/build/ba_data/audio/announceNine.ogg": "https://files.ballistica.net/cache/ba1/37/9c/14fe574dc0affc296ab26dcb1d86", - "assets/build/ba_data/audio/announceOne.ogg": "https://files.ballistica.net/cache/ba1/17/14/4a3dcf847df5a741e62194e0a37c", - "assets/build/ba_data/audio/announceSeven.ogg": "https://files.ballistica.net/cache/ba1/a3/96/3b3fb67271b7ef4ad82b2e4a7033", - "assets/build/ba_data/audio/announceSix.ogg": "https://files.ballistica.net/cache/ba1/bb/ba/d00e2c4bba08906fcca225fc3dbf", - "assets/build/ba_data/audio/announceTen.ogg": "https://files.ballistica.net/cache/ba1/d2/44/d7ff46fb3327ffffe90683c46e90", - "assets/build/ba_data/audio/announceThree.ogg": "https://files.ballistica.net/cache/ba1/74/b1/a316d295648b50810bec7f4353aa", - "assets/build/ba_data/audio/announceTwo.ogg": "https://files.ballistica.net/cache/ba1/54/09/9ba10d9f168e1cfb4e1e7cde9809", - "assets/build/ba_data/audio/assassin1.ogg": "https://files.ballistica.net/cache/ba1/65/26/caa50e50182a1dc72c274e465119", - "assets/build/ba_data/audio/assassin2.ogg": "https://files.ballistica.net/cache/ba1/8d/0c/e73f4fcbaf240ab760fb3a832968", - "assets/build/ba_data/audio/assassin3.ogg": "https://files.ballistica.net/cache/ba1/d4/0a/a572d49afc3c84c6c39a2dba8774", - "assets/build/ba_data/audio/assassin4.ogg": "https://files.ballistica.net/cache/ba1/e0/27/97c6d449ad47071c27373de3fa6c", - "assets/build/ba_data/audio/assassinDeath.ogg": "https://files.ballistica.net/cache/ba1/f9/ab/b80d408f42d2f139d84df688a41b", - "assets/build/ba_data/audio/assassinFall.ogg": "https://files.ballistica.net/cache/ba1/12/4b/6ed517ee09f0b7fc51750c87a8a9", - "assets/build/ba_data/audio/assassinHit1.ogg": "https://files.ballistica.net/cache/ba1/d8/22/94956386c4cc9ef9e8da556b99b4", - "assets/build/ba_data/audio/assassinHit2.ogg": "https://files.ballistica.net/cache/ba1/b9/e0/fc1d60b14ac521d70fe5d424314e", - "assets/build/ba_data/audio/bear1.ogg": "https://files.ballistica.net/cache/ba1/a3/ab/b4d525a5fadc134f5c21c19d5bde", - "assets/build/ba_data/audio/bear2.ogg": "https://files.ballistica.net/cache/ba1/5e/af/375de0187b1dcf5a44e4c14571e5", - "assets/build/ba_data/audio/bear3.ogg": "https://files.ballistica.net/cache/ba1/3c/08/9e7bc2f2f7eb8c5489f86ff3808f", - "assets/build/ba_data/audio/bear4.ogg": "https://files.ballistica.net/cache/ba1/5f/78/e94c8d86be77fd0a272a0155f0b6", - "assets/build/ba_data/audio/bearDeath.ogg": "https://files.ballistica.net/cache/ba1/a9/c0/1d2ffbe07bfda063c298b1a3ef18", - "assets/build/ba_data/audio/bearFall.ogg": "https://files.ballistica.net/cache/ba1/03/7a/bb7c62149b84fc42ebd53b7b36ba", - "assets/build/ba_data/audio/bearHit1.ogg": "https://files.ballistica.net/cache/ba1/f0/ad/4f5938ad473d69e52c30adfb78cc", - "assets/build/ba_data/audio/bearHit2.ogg": "https://files.ballistica.net/cache/ba1/72/3b/2f9c5939de3020dae6ae35a26d2b", - "assets/build/ba_data/audio/bellHigh.ogg": "https://files.ballistica.net/cache/ba1/f3/ab/d3255a13929c03075000635d9828", - "assets/build/ba_data/audio/bellLow.ogg": "https://files.ballistica.net/cache/ba1/94/ba/39a470a2025506b817412e0bcc70", - "assets/build/ba_data/audio/bellMed.ogg": "https://files.ballistica.net/cache/ba1/0a/2c/c08661be5a50c6380d3a5f4c9c98", - "assets/build/ba_data/audio/bigImpact.ogg": "https://files.ballistica.net/cache/ba1/d5/cb/a157880053224bfef2904b926982", - "assets/build/ba_data/audio/bigImpact2.ogg": "https://files.ballistica.net/cache/ba1/16/6c/9bcef8e5894fccd4011be4470031", - "assets/build/ba_data/audio/blank.ogg": "https://files.ballistica.net/cache/ba1/43/e8/050dba8abace772c813fd6ea350f", - "assets/build/ba_data/audio/blip.ogg": "https://files.ballistica.net/cache/ba1/19/fb/4e031348b1990d8ba9e8e872ca7c", - "assets/build/ba_data/audio/block.ogg": "https://files.ballistica.net/cache/ba1/7d/0f/50a912a4f70b03f4a8a50736fac9", - "assets/build/ba_data/audio/bombDrop01.ogg": "https://files.ballistica.net/cache/ba1/6d/6b/476cd4bd6a01f248311c7e366ce7", - "assets/build/ba_data/audio/bombDrop02.ogg": "https://files.ballistica.net/cache/ba1/90/78/75d94812faf167ba889dfeeb8f2c", - "assets/build/ba_data/audio/bombRoll01.ogg": "https://files.ballistica.net/cache/ba1/08/58/8708df679194214c6a0cf8272f8f", - "assets/build/ba_data/audio/bones1.ogg": "https://files.ballistica.net/cache/ba1/15/e6/69a9048083d8a507cb321343d969", - "assets/build/ba_data/audio/bones2.ogg": "https://files.ballistica.net/cache/ba1/5c/6e/bf1e1b9226442caf8e396f732494", - "assets/build/ba_data/audio/bones3.ogg": "https://files.ballistica.net/cache/ba1/26/14/9c83805427ebb8169ce02da8f4fc", - "assets/build/ba_data/audio/bonesDeath.ogg": "https://files.ballistica.net/cache/ba1/37/af/ee3c9e2e9be28f158d8bfe288271", - "assets/build/ba_data/audio/bonesFall.ogg": "https://files.ballistica.net/cache/ba1/19/58/7d92c6ded9235ed75953c0575278", - "assets/build/ba_data/audio/boo.ogg": "https://files.ballistica.net/cache/ba1/88/1e/61c4c29f9f29c62ae0d739fa616e", - "assets/build/ba_data/audio/boxDrop.ogg": "https://files.ballistica.net/cache/ba1/ac/79/1a3ebb1995a2233e4ff20cc6f414", - "assets/build/ba_data/audio/boxingBell.ogg": "https://files.ballistica.net/cache/ba1/90/ca/e6cd30443468d0d7744ec2cf2b16", - "assets/build/ba_data/audio/bunny1.ogg": "https://files.ballistica.net/cache/ba1/1a/3a/9adf5c4c6f0e19a4ca041dc8bd6c", - "assets/build/ba_data/audio/bunny2.ogg": "https://files.ballistica.net/cache/ba1/b8/bc/9892c3c7e0486cf7964603a07026", - "assets/build/ba_data/audio/bunny3.ogg": "https://files.ballistica.net/cache/ba1/29/1a/daf478872b5e03d1b688a859361f", - "assets/build/ba_data/audio/bunny4.ogg": "https://files.ballistica.net/cache/ba1/3e/8d/f8c04d5b04510a9f819feea4dc38", - "assets/build/ba_data/audio/bunnyDeath.ogg": "https://files.ballistica.net/cache/ba1/05/34/c1209c636ea108f40aa0dfed1f21", - "assets/build/ba_data/audio/bunnyFall.ogg": "https://files.ballistica.net/cache/ba1/f3/4f/d6d25aed763dba1557d81ca841ea", - "assets/build/ba_data/audio/bunnyHit1.ogg": "https://files.ballistica.net/cache/ba1/a0/70/7386446444928a84143a789efb64", - "assets/build/ba_data/audio/bunnyHit2.ogg": "https://files.ballistica.net/cache/ba1/8a/f0/330a2c570abdf21fbfac405c11f8", - "assets/build/ba_data/audio/bunnyJump.ogg": "https://files.ballistica.net/cache/ba1/cd/ce/e9b54b393b37655f4ed98bfa0723", - "assets/build/ba_data/audio/cashRegister.ogg": "https://files.ballistica.net/cache/ba1/58/06/9b16086013a85db51f47c6d6c658", - "assets/build/ba_data/audio/cashRegister2.ogg": "https://files.ballistica.net/cache/ba1/cc/27/75c8a79efacb764dafeadfd1e9a3", - "assets/build/ba_data/audio/charSelectMusic.ogg": "https://files.ballistica.net/cache/ba1/ab/c8/c6fb5b258536ddf3b7a97f4691f3", - "assets/build/ba_data/audio/cheer.ogg": "https://files.ballistica.net/cache/ba1/ec/72/a62df06f59fb0d3cc4d2223e3a0b", - "assets/build/ba_data/audio/click01.ogg": "https://files.ballistica.net/cache/ba1/cd/1d/89da645995d2623342cc42810b05", - "assets/build/ba_data/audio/corkPop.ogg": "https://files.ballistica.net/cache/ba1/4c/25/ecfc72ff2547c9ed956a2be96913", - "assets/build/ba_data/audio/cowboy1.ogg": "https://files.ballistica.net/cache/ba1/43/b4/b59e1b6e7dcae4e844d6175d6c6c", - "assets/build/ba_data/audio/cowboy2.ogg": "https://files.ballistica.net/cache/ba1/1f/27/6a7bb5a31b05c3c3e42bf7f92a5d", - "assets/build/ba_data/audio/cowboy3.ogg": "https://files.ballistica.net/cache/ba1/92/be/7f2f99054217daa9ed6d996286bd", - "assets/build/ba_data/audio/cowboy4.ogg": "https://files.ballistica.net/cache/ba1/21/a9/f50864d9c2b53622e5539941a3ab", - "assets/build/ba_data/audio/cowboyDeath.ogg": "https://files.ballistica.net/cache/ba1/6a/c1/13379d13ff5f656b36e4e3059b3d", - "assets/build/ba_data/audio/cowboyFall.ogg": "https://files.ballistica.net/cache/ba1/86/63/fca5ce3316aeb3e6337bd6690fb6", - "assets/build/ba_data/audio/cowboyHit1.ogg": "https://files.ballistica.net/cache/ba1/a6/17/fa2ebe38c2f299502f5a4e284776", - "assets/build/ba_data/audio/cowboyHit2.ogg": "https://files.ballistica.net/cache/ba1/34/0b/5a7ff85c530ef298b91bd77fd98f", - "assets/build/ba_data/audio/crowdChant.ogg": "https://files.ballistica.net/cache/ba1/4c/9c/a0b17479325017d70898c8a9a848", - "assets/build/ba_data/audio/cyborg1.ogg": "https://files.ballistica.net/cache/ba1/8b/22/5230d73c00fe46a40ef77d334f72", - "assets/build/ba_data/audio/cyborg2.ogg": "https://files.ballistica.net/cache/ba1/51/36/1fb19c92b2b4b72510cc373d9335", - "assets/build/ba_data/audio/cyborg3.ogg": "https://files.ballistica.net/cache/ba1/70/8e/e4761c1425439b83ef84473b5dc4", - "assets/build/ba_data/audio/cyborg4.ogg": "https://files.ballistica.net/cache/ba1/db/dc/8bbe388332ae01492aa2092ca986", - "assets/build/ba_data/audio/cyborgDeath.ogg": "https://files.ballistica.net/cache/ba1/cd/a8/d607304530d35a1c7ee598806a7e", - "assets/build/ba_data/audio/cyborgFall.ogg": "https://files.ballistica.net/cache/ba1/88/5f/7f1fd7e445ff5aaf7b48168ddf47", - "assets/build/ba_data/audio/cyborgHit1.ogg": "https://files.ballistica.net/cache/ba1/fc/9b/5b707a799ba09cd5bf8a2ea2ab74", - "assets/build/ba_data/audio/cyborgHit2.ogg": "https://files.ballistica.net/cache/ba1/02/08/3589fe5d2cc8a5ad377cd412d075", - "assets/build/ba_data/audio/cymbal.ogg": "https://files.ballistica.net/cache/ba1/65/64/d3a28b93481211f36c16c38f541b", - "assets/build/ba_data/audio/debrisFall.ogg": "https://files.ballistica.net/cache/ba1/9c/1d/ab38dee1fc5ae329a48255300f23", - "assets/build/ba_data/audio/deek.ogg": "https://files.ballistica.net/cache/ba1/8a/51/9d0552c98334e99829f19bad4caa", - "assets/build/ba_data/audio/deek2.ogg": "https://files.ballistica.net/cache/ba1/45/ef/a51861737649df69c4cb19f862b9", - "assets/build/ba_data/audio/ding.ogg": "https://files.ballistica.net/cache/ba1/39/16/eea51f23a4e83942eeeeafcfa942", - "assets/build/ba_data/audio/dingSmall.ogg": "https://files.ballistica.net/cache/ba1/59/dc/4370f8812eed876a59477b8232e6", - "assets/build/ba_data/audio/dingSmallHigh.ogg": "https://files.ballistica.net/cache/ba1/b5/ca/c288834b3f18b31cb1637552aad4", - "assets/build/ba_data/audio/dripity.ogg": "https://files.ballistica.net/cache/ba1/b8/7b/ae00fed6e1768c7f7ccd72795716", - "assets/build/ba_data/audio/drumRoll.ogg": "https://files.ballistica.net/cache/ba1/16/bc/a1748c65ceb661b72d2b3fbbfd90", - "assets/build/ba_data/audio/error.ogg": "https://files.ballistica.net/cache/ba1/55/d9/600452cf5c77e7b6867435592297", - "assets/build/ba_data/audio/explosion01.ogg": "https://files.ballistica.net/cache/ba1/79/1d/3fa918960fe627215d33e6fe9114", - "assets/build/ba_data/audio/explosion02.ogg": "https://files.ballistica.net/cache/ba1/b0/6c/49e828c6e79335ce0ed65ca6df87", - "assets/build/ba_data/audio/explosion03.ogg": "https://files.ballistica.net/cache/ba1/84/03/ed1c7b04d456505c3f7b4199c2dd", - "assets/build/ba_data/audio/explosion04.ogg": "https://files.ballistica.net/cache/ba1/1d/c8/b5abced424394b940a8946b519e7", - "assets/build/ba_data/audio/explosion05.ogg": "https://files.ballistica.net/cache/ba1/b9/f7/22bae11a92444fbed2ed7d4c7eb6", - "assets/build/ba_data/audio/fanfare.ogg": "https://files.ballistica.net/cache/ba1/a9/d0/cd2a24f87b42d84dadae61dad923", - "assets/build/ba_data/audio/flagCatcherMusic.ogg": "https://files.ballistica.net/cache/ba1/52/12/9798329b48fc9fdfa8733689554e", - "assets/build/ba_data/audio/flyingMusic.ogg": "https://files.ballistica.net/cache/ba1/31/3c/55634e66c852ff7e54071814790d", - "assets/build/ba_data/audio/foghorn.ogg": "https://files.ballistica.net/cache/ba1/91/d0/ef544e7795ac3870f75767c04fa8", - "assets/build/ba_data/audio/footImpact01.ogg": "https://files.ballistica.net/cache/ba1/bc/e4/7b85048f228b6c173bbc2462ccfb", - "assets/build/ba_data/audio/footImpact02.ogg": "https://files.ballistica.net/cache/ba1/2b/5d/c282f36cbc93c047b73a736a8588", - "assets/build/ba_data/audio/footImpact03.ogg": "https://files.ballistica.net/cache/ba1/d8/b4/2c8d0afa16243ab9fd5f50d73961", - "assets/build/ba_data/audio/forwardMarchMusic.ogg": "https://files.ballistica.net/cache/ba1/ee/ee/197d0ca35ff876ff514f63e19bf5", - "assets/build/ba_data/audio/freeze.ogg": "https://files.ballistica.net/cache/ba1/52/79/dcc91d30bf5da1aa2ea8377098a5", - "assets/build/ba_data/audio/frosty01.ogg": "https://files.ballistica.net/cache/ba1/62/2f/2946eacb868a1e2253b5c732a1d7", - "assets/build/ba_data/audio/frosty02.ogg": "https://files.ballistica.net/cache/ba1/d1/91/dc8a2daa0a2b322d7eb1874ea3ca", - "assets/build/ba_data/audio/frosty03.ogg": "https://files.ballistica.net/cache/ba1/c4/9f/929872d7a36bcda8ea945c203c39", - "assets/build/ba_data/audio/frosty04.ogg": "https://files.ballistica.net/cache/ba1/be/85/85ca0c05ca6197439d606139758e", - "assets/build/ba_data/audio/frosty05.ogg": "https://files.ballistica.net/cache/ba1/87/a7/d63e2469ee4ad6cf763e7e8f4627", - "assets/build/ba_data/audio/frostyDeath.ogg": "https://files.ballistica.net/cache/ba1/d8/a9/27865a436660c0648e96f1840213", - "assets/build/ba_data/audio/frostyFall.ogg": "https://files.ballistica.net/cache/ba1/b4/65/dfa57ab3023b3e5ae704c6c14635", - "assets/build/ba_data/audio/frostyHit01.ogg": "https://files.ballistica.net/cache/ba1/ec/da/f21a0a49e22afac4258536a7d111", - "assets/build/ba_data/audio/frostyHit02.ogg": "https://files.ballistica.net/cache/ba1/e4/f1/374d97cd8701178e246f927ae458", - "assets/build/ba_data/audio/frostyHit03.ogg": "https://files.ballistica.net/cache/ba1/c7/e2/0fc25cbe1ddca8783522d5a8fe26", - "assets/build/ba_data/audio/fuse01.ogg": "https://files.ballistica.net/cache/ba1/97/44/9d62fc0ef5cd235d6b693242b350", - "assets/build/ba_data/audio/gladiator1.ogg": "https://files.ballistica.net/cache/ba1/6b/32/acdb08f2fe53dd2578960ab6691a", - "assets/build/ba_data/audio/gladiator2.ogg": "https://files.ballistica.net/cache/ba1/9d/74/4fb06f51fd7a516b4adcc5814398", - "assets/build/ba_data/audio/gladiator3.ogg": "https://files.ballistica.net/cache/ba1/b2/9d/2e9876baf78462fee1e36096b38b", - "assets/build/ba_data/audio/gladiator4.ogg": "https://files.ballistica.net/cache/ba1/cc/19/480dd490111b5bd957b1fd5a74fd", - "assets/build/ba_data/audio/gladiatorDeath.ogg": "https://files.ballistica.net/cache/ba1/a9/57/b9fd7904277e0992cd6bd8d79fe0", - "assets/build/ba_data/audio/gladiatorFall.ogg": "https://files.ballistica.net/cache/ba1/ed/3b/fc00ab9943309ab581d30e194d91", - "assets/build/ba_data/audio/gladiatorHit1.ogg": "https://files.ballistica.net/cache/ba1/ee/40/f0e73253bf12488efbc0597abb5c", - "assets/build/ba_data/audio/gladiatorHit2.ogg": "https://files.ballistica.net/cache/ba1/45/f7/9958e12b5c7b6090cafa8eb9d5e6", - "assets/build/ba_data/audio/gong.ogg": "https://files.ballistica.net/cache/ba1/a1/e6/119b5a45bdf844d1c4e41fb3f9cb", - "assets/build/ba_data/audio/grandRompMusic.ogg": "https://files.ballistica.net/cache/ba1/8d/29/1099167132da4216f7bde71b5fdf", - "assets/build/ba_data/audio/gravelSkid.ogg": "https://files.ballistica.net/cache/ba1/dc/54/5b7ad32d8836cb6a5924b24bad3c", - "assets/build/ba_data/audio/gunCocking.ogg": "https://files.ballistica.net/cache/ba1/ef/f1/925f4a7b855c2a1e260963a7724e", - "assets/build/ba_data/audio/healthPowerup.ogg": "https://files.ballistica.net/cache/ba1/93/d3/4444d3b37d60da6da1b06d39eb3d", - "assets/build/ba_data/audio/hiss.ogg": "https://files.ballistica.net/cache/ba1/75/19/967eaf13ac18d5344687b31b825b", - "assets/build/ba_data/audio/impactHard.ogg": "https://files.ballistica.net/cache/ba1/41/f8/5a634967c4a301b01af3e39ca662", - "assets/build/ba_data/audio/impactHard2.ogg": "https://files.ballistica.net/cache/ba1/99/a7/7b6ce0554277632223b4eb5098be", - "assets/build/ba_data/audio/impactHard3.ogg": "https://files.ballistica.net/cache/ba1/1e/73/d12e04a1ef2320593095dbf272c8", - "assets/build/ba_data/audio/impactMedium.ogg": "https://files.ballistica.net/cache/ba1/ce/1f/3a8634bb6a2e51c3433263753b2b", - "assets/build/ba_data/audio/impactMedium2.ogg": "https://files.ballistica.net/cache/ba1/29/e4/1ad30c3e4a8329792f9d0377a7f9", - "assets/build/ba_data/audio/jack01.ogg": "https://files.ballistica.net/cache/ba1/b5/85/5fd635abe61994e3b7f76150be72", - "assets/build/ba_data/audio/jack02.ogg": "https://files.ballistica.net/cache/ba1/53/f0/7d36ae98b4dbde81a6aa4417a54e", - "assets/build/ba_data/audio/jack03.ogg": "https://files.ballistica.net/cache/ba1/35/12/5d9d51e11c4cbcc4a51cd7aa7386", - "assets/build/ba_data/audio/jack04.ogg": "https://files.ballistica.net/cache/ba1/5c/8a/66792bd597bc78d3bd69aa8a78d8", - "assets/build/ba_data/audio/jack05.ogg": "https://files.ballistica.net/cache/ba1/e4/64/c07c3fea5e9daf4365e29c4dba4e", - "assets/build/ba_data/audio/jack06.ogg": "https://files.ballistica.net/cache/ba1/28/3d/c4b10bf690fc7cf4105bcec52e60", - "assets/build/ba_data/audio/jackDeath01.ogg": "https://files.ballistica.net/cache/ba1/02/3b/94a7c8dff92d6a4c09812aa210c1", - "assets/build/ba_data/audio/jackFall01.ogg": "https://files.ballistica.net/cache/ba1/80/66/f9351ac9bffd10925e7c691d46ab", - "assets/build/ba_data/audio/jackHit01.ogg": "https://files.ballistica.net/cache/ba1/9d/e3/e8bcd1ec3110176db9e9297af651", - "assets/build/ba_data/audio/jackHit02.ogg": "https://files.ballistica.net/cache/ba1/4b/71/303d9ff5860c3167826574f686a3", - "assets/build/ba_data/audio/jackHit03.ogg": "https://files.ballistica.net/cache/ba1/97/36/cf14a4f0a81294cfb0b4d6f3ba6c", - "assets/build/ba_data/audio/jackHit04.ogg": "https://files.ballistica.net/cache/ba1/53/8a/134add64050d0b7f099ecc1d9010", - "assets/build/ba_data/audio/jackHit05.ogg": "https://files.ballistica.net/cache/ba1/9e/2d/a868226d28ab85b3dbe56ef65f66", - "assets/build/ba_data/audio/jackHit06.ogg": "https://files.ballistica.net/cache/ba1/61/f8/14d3da7441144e9940824d88a957", - "assets/build/ba_data/audio/jackHit07.ogg": "https://files.ballistica.net/cache/ba1/64/ad/e97279ab67cb0e1e8303efc877b5", - "assets/build/ba_data/audio/jumpsuit1.ogg": "https://files.ballistica.net/cache/ba1/39/23/f8edb71f6f85d2cd51a367987d55", - "assets/build/ba_data/audio/jumpsuit2.ogg": "https://files.ballistica.net/cache/ba1/c8/16/0bf8adc42a05a120637f95c19661", - "assets/build/ba_data/audio/jumpsuit3.ogg": "https://files.ballistica.net/cache/ba1/d4/5b/513d63607c2984437943ea8b239b", - "assets/build/ba_data/audio/jumpsuit4.ogg": "https://files.ballistica.net/cache/ba1/30/0a/6c585f5da9f973ba50948384e8a8", - "assets/build/ba_data/audio/jumpsuitDeath.ogg": "https://files.ballistica.net/cache/ba1/e6/90/f6bf19166f69ce0d172a621b469b", - "assets/build/ba_data/audio/jumpsuitFall.ogg": "https://files.ballistica.net/cache/ba1/e9/3c/fe21b00dd90b42953fa103988cd5", - "assets/build/ba_data/audio/jumpsuitHit1.ogg": "https://files.ballistica.net/cache/ba1/8a/3b/1f9ec398374b21ccf34f012401e5", - "assets/build/ba_data/audio/jumpsuitHit2.ogg": "https://files.ballistica.net/cache/ba1/9f/51/4b0e7300f2ddd43a03cc71718099", - "assets/build/ba_data/audio/kronk1.ogg": "https://files.ballistica.net/cache/ba1/77/52/74e8e3da507f7df42ab089e452ab", - "assets/build/ba_data/audio/kronk10.ogg": "https://files.ballistica.net/cache/ba1/c3/82/c4446a9eeb01db9eed2b934964e0", - "assets/build/ba_data/audio/kronk2.ogg": "https://files.ballistica.net/cache/ba1/27/37/ecdd7aefbb819df2dfa9de5df7f4", - "assets/build/ba_data/audio/kronk3.ogg": "https://files.ballistica.net/cache/ba1/1b/a3/f23b1d69fa4573fd3c87f1ff87e2", - "assets/build/ba_data/audio/kronk4.ogg": "https://files.ballistica.net/cache/ba1/e3/a8/50dccbe9ef4a6b7521a855717e9b", - "assets/build/ba_data/audio/kronk5.ogg": "https://files.ballistica.net/cache/ba1/e9/ff/fb7221fdba9ab8b39e74551d8c0e", - "assets/build/ba_data/audio/kronk6.ogg": "https://files.ballistica.net/cache/ba1/39/2b/c713770379a6bd408f8d448da0fc", - "assets/build/ba_data/audio/kronk7.ogg": "https://files.ballistica.net/cache/ba1/c2/50/a63b1059cb5082c04f0b1ae9b906", - "assets/build/ba_data/audio/kronk8.ogg": "https://files.ballistica.net/cache/ba1/8c/f2/20f9eb4f6b6d506c60a927db227c", - "assets/build/ba_data/audio/kronk9.ogg": "https://files.ballistica.net/cache/ba1/30/7a/8d1ca7b2f70aa304b58bf51c6de5", - "assets/build/ba_data/audio/kronkDeath.ogg": "https://files.ballistica.net/cache/ba1/08/b6/edf2245909ded074251df0a80ab7", - "assets/build/ba_data/audio/kronkFall.ogg": "https://files.ballistica.net/cache/ba1/36/3d/3f91c7274573b339420f0d2eec27", - "assets/build/ba_data/audio/laser.ogg": "https://files.ballistica.net/cache/ba1/d8/25/e850a6eefb28c0eb0ce443d820b9", - "assets/build/ba_data/audio/laserReverse.ogg": "https://files.ballistica.net/cache/ba1/bc/af/71cd60f6a0503600f9d23480e6dc", - "assets/build/ba_data/audio/mel01.ogg": "https://files.ballistica.net/cache/ba1/0c/f0/a65788b2f969e3d11c57edc86407", - "assets/build/ba_data/audio/mel02.ogg": "https://files.ballistica.net/cache/ba1/ae/e5/4a39d0d13d8e564779e2e49d050b", - "assets/build/ba_data/audio/mel03.ogg": "https://files.ballistica.net/cache/ba1/22/d4/fbaccc9afab4a40b78076fc92033", - "assets/build/ba_data/audio/mel04.ogg": "https://files.ballistica.net/cache/ba1/24/b9/97f82742ff350c73371d74c98d5b", - "assets/build/ba_data/audio/mel05.ogg": "https://files.ballistica.net/cache/ba1/28/e8/11247575d0932a20631522746d43", - "assets/build/ba_data/audio/mel06.ogg": "https://files.ballistica.net/cache/ba1/6e/d9/29959b895cb35593873ad9960936", - "assets/build/ba_data/audio/mel07.ogg": "https://files.ballistica.net/cache/ba1/bc/c4/cf7acca65fdf775d6a88c066cd79", - "assets/build/ba_data/audio/mel08.ogg": "https://files.ballistica.net/cache/ba1/0c/5c/d5fbecac8eec27b2d26dc80b4d4d", - "assets/build/ba_data/audio/mel09.ogg": "https://files.ballistica.net/cache/ba1/f5/0d/ad46aa724824e20476d5facd7d27", - "assets/build/ba_data/audio/mel10.ogg": "https://files.ballistica.net/cache/ba1/39/cb/b1adf0dfca2564a53a60e39e0bf9", - "assets/build/ba_data/audio/melDeath01.ogg": "https://files.ballistica.net/cache/ba1/6a/39/a7cbb7d831fa85582848785a6a06", - "assets/build/ba_data/audio/melFall01.ogg": "https://files.ballistica.net/cache/ba1/c2/49/cd61d684370771adf48d5cec915c", - "assets/build/ba_data/audio/menuMusic.ogg": "https://files.ballistica.net/cache/ba1/c2/bd/677235d772c411df8bd3f857166d", - "assets/build/ba_data/audio/metalHit.ogg": "https://files.ballistica.net/cache/ba1/3f/5e/efc8799297357fca2cc7b9a8262b", - "assets/build/ba_data/audio/metalSkid.ogg": "https://files.ballistica.net/cache/ba1/61/ca/606fa387056d1467ba86287f2b2f", - "assets/build/ba_data/audio/ninjaAttack1.ogg": "https://files.ballistica.net/cache/ba1/78/e2/8034c596aed2d221535b77bb158f", - "assets/build/ba_data/audio/ninjaAttack2.ogg": "https://files.ballistica.net/cache/ba1/43/48/5248ae17008e761a75619f65d5b1", - "assets/build/ba_data/audio/ninjaAttack3.ogg": "https://files.ballistica.net/cache/ba1/6e/7d/43b4f3366d5677b1195e48320d42", - "assets/build/ba_data/audio/ninjaAttack4.ogg": "https://files.ballistica.net/cache/ba1/cb/95/92066a1a15bf9ec2eebd41175c0c", - "assets/build/ba_data/audio/ninjaAttack5.ogg": "https://files.ballistica.net/cache/ba1/b8/66/d4759b1dc0f8d9ac8c711d3efed0", - "assets/build/ba_data/audio/ninjaAttack6.ogg": "https://files.ballistica.net/cache/ba1/8d/eb/0bfb920a3a2cf8cad1a6dc698185", - "assets/build/ba_data/audio/ninjaAttack7.ogg": "https://files.ballistica.net/cache/ba1/51/fd/753d3d6fa8b70dfe3ca98ea6b5a8", - "assets/build/ba_data/audio/ninjaDeath1.ogg": "https://files.ballistica.net/cache/ba1/0e/4e/68afa0525b0128f3426d373a707c", - "assets/build/ba_data/audio/ninjaFall1.ogg": "https://files.ballistica.net/cache/ba1/9f/86/9846c88411f44e5798b1df0972ef", - "assets/build/ba_data/audio/ninjaHit1.ogg": "https://files.ballistica.net/cache/ba1/52/33/06e556d1f2d4394345b0ec136269", - "assets/build/ba_data/audio/ninjaHit2.ogg": "https://files.ballistica.net/cache/ba1/ec/47/dbe01b83be6dece26568dab8f9cd", - "assets/build/ba_data/audio/ninjaHit3.ogg": "https://files.ballistica.net/cache/ba1/b5/2f/a9be291152d452626b876789ab55", - "assets/build/ba_data/audio/ninjaHit4.ogg": "https://files.ballistica.net/cache/ba1/d8/2e/f2b560eba8426001dd7185d5ac36", - "assets/build/ba_data/audio/ninjaHit5.ogg": "https://files.ballistica.net/cache/ba1/6c/1e/3e7ee3fd14ed569c8017e1a46dd2", - "assets/build/ba_data/audio/ninjaHit6.ogg": "https://files.ballistica.net/cache/ba1/81/64/44964a4230cdccb1900e995607fb", - "assets/build/ba_data/audio/ninjaHit7.ogg": "https://files.ballistica.net/cache/ba1/d7/e4/e7dfb867ee3cb8e180d5e331a3b6", - "assets/build/ba_data/audio/ninjaHit8.ogg": "https://files.ballistica.net/cache/ba1/b9/39/10bd0494ac058da08f3742bae9cf", - "assets/build/ba_data/audio/oldLady1.ogg": "https://files.ballistica.net/cache/ba1/9e/36/929c80893b25e634af15c590e9a5", - "assets/build/ba_data/audio/oldLady2.ogg": "https://files.ballistica.net/cache/ba1/5e/8d/2eba5556abbeae8c7dd8f5894248", - "assets/build/ba_data/audio/oldLady3.ogg": "https://files.ballistica.net/cache/ba1/48/23/5dcf088300c2ab9d3b954556f793", - "assets/build/ba_data/audio/oldLady4.ogg": "https://files.ballistica.net/cache/ba1/17/8d/2cf274325b17734183919426511f", - "assets/build/ba_data/audio/oldLadyDeath.ogg": "https://files.ballistica.net/cache/ba1/19/ab/34226d428d14053928448d9d8399", - "assets/build/ba_data/audio/oldLadyFall.ogg": "https://files.ballistica.net/cache/ba1/24/c1/e118eece3a257218ee1108949033", - "assets/build/ba_data/audio/oldLadyHit1.ogg": "https://files.ballistica.net/cache/ba1/5b/46/a5793c4ccf547a06eb5425141204", - "assets/build/ba_data/audio/oldLadyHit2.ogg": "https://files.ballistica.net/cache/ba1/ab/55/4f80974d72476a870ea2c2f6a687", - "assets/build/ba_data/audio/ooh.ogg": "https://files.ballistica.net/cache/ba1/44/df/7ba3b19fd9975767a62caabdbf1a", - "assets/build/ba_data/audio/operaSinger1.ogg": "https://files.ballistica.net/cache/ba1/af/af/d69f491131ebb178c9c89917b6ef", - "assets/build/ba_data/audio/operaSinger2.ogg": "https://files.ballistica.net/cache/ba1/6e/71/17ce065c420dfd6195649737744e", - "assets/build/ba_data/audio/operaSinger3.ogg": "https://files.ballistica.net/cache/ba1/ba/7a/a520afa6dddad1cb486701d0f50a", - "assets/build/ba_data/audio/operaSinger4.ogg": "https://files.ballistica.net/cache/ba1/c7/c9/b5d93a459ccd408783feff0dbbdf", - "assets/build/ba_data/audio/operaSingerDeath.ogg": "https://files.ballistica.net/cache/ba1/1b/6c/697b633102c8f3356f38cbcae8ae", - "assets/build/ba_data/audio/operaSingerFall.ogg": "https://files.ballistica.net/cache/ba1/d7/3a/89f237631614bcde93a2d6ba81ef", - "assets/build/ba_data/audio/operaSingerHit1.ogg": "https://files.ballistica.net/cache/ba1/e0/af/7a6f40e6e86130f2599dc366ece1", - "assets/build/ba_data/audio/operaSingerHit2.ogg": "https://files.ballistica.net/cache/ba1/c5/7e/3cd98dd46903eb55e1694dca8296", - "assets/build/ba_data/audio/orchestraHit.ogg": "https://files.ballistica.net/cache/ba1/54/a5/c93bbcfa5529df5df8b62b705578", - "assets/build/ba_data/audio/orchestraHit2.ogg": "https://files.ballistica.net/cache/ba1/96/05/a886a29b1927a28c99d810273e42", - "assets/build/ba_data/audio/orchestraHit3.ogg": "https://files.ballistica.net/cache/ba1/47/b0/ab1b857b3f88df03723829ac78ea", - "assets/build/ba_data/audio/orchestraHit4.ogg": "https://files.ballistica.net/cache/ba1/6f/44/5784023d13f904e13a44479c5170", - "assets/build/ba_data/audio/orchestraHitBig1.ogg": "https://files.ballistica.net/cache/ba1/c5/d3/be6de216457c53352552c34ec767", - "assets/build/ba_data/audio/orchestraHitBig2.ogg": "https://files.ballistica.net/cache/ba1/aa/4d/04abd9530e2b51099cda23185e88", - "assets/build/ba_data/audio/penguin1.ogg": "https://files.ballistica.net/cache/ba1/96/d0/67cdc12f275accdf71dc23750a89", - "assets/build/ba_data/audio/penguin2.ogg": "https://files.ballistica.net/cache/ba1/67/02/c6995bad0d80928ba610b9275eed", - "assets/build/ba_data/audio/penguin3.ogg": "https://files.ballistica.net/cache/ba1/b0/be/1d7fe761ebcd38887bd23da88a0f", - "assets/build/ba_data/audio/penguin4.ogg": "https://files.ballistica.net/cache/ba1/f1/c2/76455bec3a5125d5d773d227542c", - "assets/build/ba_data/audio/penguinDeath.ogg": "https://files.ballistica.net/cache/ba1/94/75/5fe589c3d2f15f94fbb66fdbdff2", - "assets/build/ba_data/audio/penguinFall.ogg": "https://files.ballistica.net/cache/ba1/d6/19/f3f6a990b1eba8bff6b23d51f66f", - "assets/build/ba_data/audio/penguinHit1.ogg": "https://files.ballistica.net/cache/ba1/cf/04/fc0f40439c99cfdafc5e8adf919c", - "assets/build/ba_data/audio/penguinHit2.ogg": "https://files.ballistica.net/cache/ba1/c9/9b/aff906f79da44fcffd024fd2c414", - "assets/build/ba_data/audio/pixie1.ogg": "https://files.ballistica.net/cache/ba1/6b/62/a03872005d47928b34a8cae3c56f", - "assets/build/ba_data/audio/pixie2.ogg": "https://files.ballistica.net/cache/ba1/73/84/8dbcb839ca1a8cf624996b8bd550", - "assets/build/ba_data/audio/pixie3.ogg": "https://files.ballistica.net/cache/ba1/65/74/36b05c07dcac3ad08d5473f063a7", - "assets/build/ba_data/audio/pixie4.ogg": "https://files.ballistica.net/cache/ba1/f9/34/b282ee64a0a9d50de1e68a4c78a8", - "assets/build/ba_data/audio/pixieDeath.ogg": "https://files.ballistica.net/cache/ba1/55/e9/3513ac4e4dd75c9bfa797baf5557", - "assets/build/ba_data/audio/pixieFall.ogg": "https://files.ballistica.net/cache/ba1/9c/e6/f9b96eb8b9b31168a637e94cca62", - "assets/build/ba_data/audio/pixieHit1.ogg": "https://files.ballistica.net/cache/ba1/af/aa/40aed668f4a77ba0ff846beb48cf", - "assets/build/ba_data/audio/pixieHit2.ogg": "https://files.ballistica.net/cache/ba1/20/5e/5469a39cef7f67883e7f2b2737b2", - "assets/build/ba_data/audio/playerDeath.ogg": "https://files.ballistica.net/cache/ba1/45/d7/92d04d7e47a582ff63bf501da304", - "assets/build/ba_data/audio/playerLeft.ogg": "https://files.ballistica.net/cache/ba1/bd/c0/4d7d3a7d0c0c1908475e38d9771f", - "assets/build/ba_data/audio/pop01.ogg": "https://files.ballistica.net/cache/ba1/1f/66/8b1b6e78a9decc0c04aab3cb4d3e", - "assets/build/ba_data/audio/powerdown01.ogg": "https://files.ballistica.net/cache/ba1/ba/a9/8eb9e21fc9dbdade9f22460ae2ad", - "assets/build/ba_data/audio/powerup01.ogg": "https://files.ballistica.net/cache/ba1/11/74/3a8fd75ad5960711d2a77d763cd8", - "assets/build/ba_data/audio/punch01.ogg": "https://files.ballistica.net/cache/ba1/ad/a0/72e7f5b6e87061d8449b24e9f090", - "assets/build/ba_data/audio/punchStrong01.ogg": "https://files.ballistica.net/cache/ba1/f3/be/874d91f1e10210ed03f23a371392", - "assets/build/ba_data/audio/punchStrong02.ogg": "https://files.ballistica.net/cache/ba1/84/03/1ce099a47735a96e5579df9326f0", - "assets/build/ba_data/audio/punchSwish.ogg": "https://files.ballistica.net/cache/ba1/58/c0/6372b960fa643d5747054222c3bc", - "assets/build/ba_data/audio/punchWeak01.ogg": "https://files.ballistica.net/cache/ba1/29/2b/371db05ecc5731a21560e7a85435", - "assets/build/ba_data/audio/raceBeep1.ogg": "https://files.ballistica.net/cache/ba1/79/b9/dd9b60672fd3e051bb3e3db733d7", - "assets/build/ba_data/audio/raceBeep2.ogg": "https://files.ballistica.net/cache/ba1/c4/0b/5f2bc2d964f82a35880c57f9fc31", - "assets/build/ba_data/audio/refWhistle.ogg": "https://files.ballistica.net/cache/ba1/90/c9/e226f4a37985cb01d95f87693dec", - "assets/build/ba_data/audio/robot1.ogg": "https://files.ballistica.net/cache/ba1/30/50/88b5c8147d71e8e791699f19a319", - "assets/build/ba_data/audio/robot2.ogg": "https://files.ballistica.net/cache/ba1/13/59/0fd5790f64a4614ace6c4be28600", - "assets/build/ba_data/audio/robot3.ogg": "https://files.ballistica.net/cache/ba1/10/3d/1c9c8038c0e778e484004f4ed919", - "assets/build/ba_data/audio/robot4.ogg": "https://files.ballistica.net/cache/ba1/bc/46/0a237edb9874e3253d9f2f7a343f", - "assets/build/ba_data/audio/robotDeath.ogg": "https://files.ballistica.net/cache/ba1/6b/ea/5911c543539be1aee409623f872c", - "assets/build/ba_data/audio/robotFall.ogg": "https://files.ballistica.net/cache/ba1/46/0c/162aac5f716710940f16827901d7", - "assets/build/ba_data/audio/robotHit1.ogg": "https://files.ballistica.net/cache/ba1/f8/47/bf2af36ad0bdd9b930d85fea3d24", - "assets/build/ba_data/audio/robotHit2.ogg": "https://files.ballistica.net/cache/ba1/0b/88/cb0f04ca63cef24f538067344313", - "assets/build/ba_data/audio/runAwayMusic.ogg": "https://files.ballistica.net/cache/ba1/53/04/fdf9a3fde90e048552c1ed637a30", - "assets/build/ba_data/audio/santa01.ogg": "https://files.ballistica.net/cache/ba1/63/c4/70457ef8a719e7f94ee4c24d5cdc", - "assets/build/ba_data/audio/santa02.ogg": "https://files.ballistica.net/cache/ba1/83/71/9697c0bdccb20aa069d846e4389f", - "assets/build/ba_data/audio/santa03.ogg": "https://files.ballistica.net/cache/ba1/5e/be/9f7e11ce57f5fa818e0fdff5a0cb", - "assets/build/ba_data/audio/santa04.ogg": "https://files.ballistica.net/cache/ba1/45/6f/e747cbfec5265c14c5020bf49a44", - "assets/build/ba_data/audio/santa05.ogg": "https://files.ballistica.net/cache/ba1/9e/3c/413f723a07a39e5b77b0e6b302fa", - "assets/build/ba_data/audio/santaDeath.ogg": "https://files.ballistica.net/cache/ba1/ed/34/c4ec2ab2c509c898dbc0335457e0", - "assets/build/ba_data/audio/santaFall.ogg": "https://files.ballistica.net/cache/ba1/fd/70/39172ca4d9b9e3893ef1afafee19", - "assets/build/ba_data/audio/santaHit01.ogg": "https://files.ballistica.net/cache/ba1/3c/9e/1fe24503070a707835a92e9cd146", - "assets/build/ba_data/audio/santaHit02.ogg": "https://files.ballistica.net/cache/ba1/c2/9b/42a45c7ddbd129e1720488267c0b", - "assets/build/ba_data/audio/santaHit03.ogg": "https://files.ballistica.net/cache/ba1/bb/e6/8e35f024ec235c71c421d19f5b93", - "assets/build/ba_data/audio/santaHit04.ogg": "https://files.ballistica.net/cache/ba1/1c/21/3695395ec8f3a5647e6582e63ca9", - "assets/build/ba_data/audio/scamper01.ogg": "https://files.ballistica.net/cache/ba1/32/15/16615413a664fa3e0d542bb8ce3c", - "assets/build/ba_data/audio/scaryMusic.ogg": "https://files.ballistica.net/cache/ba1/d3/3d/70feb213476ea0edf898d77f835f", - "assets/build/ba_data/audio/score.ogg": "https://files.ballistica.net/cache/ba1/c1/09/048f19bf5fcf19493d27ba38ab50", - "assets/build/ba_data/audio/scoreHit01.ogg": "https://files.ballistica.net/cache/ba1/67/a9/ad05c6978fff7168d5bd66c58acd", - "assets/build/ba_data/audio/scoreHit02.ogg": "https://files.ballistica.net/cache/ba1/fa/fd/2ba45d36a85fad745e35120ad018", - "assets/build/ba_data/audio/scoreIncrease.ogg": "https://files.ballistica.net/cache/ba1/17/f9/e86c215312751e8aae0f949f5bbb", - "assets/build/ba_data/audio/scoresEpicMusic.ogg": "https://files.ballistica.net/cache/ba1/1e/49/71e9b044eac0a44ab164e9d32dd3", - "assets/build/ba_data/audio/shatter.ogg": "https://files.ballistica.net/cache/ba1/e6/c0/8cce4c7319f2c1e8509d80304a08", - "assets/build/ba_data/audio/shieldDown.ogg": "https://files.ballistica.net/cache/ba1/03/12/41ae30770b3a307a38db273b945b", - "assets/build/ba_data/audio/shieldHit.ogg": "https://files.ballistica.net/cache/ba1/24/37/95c9f92135dcd51460ac47d6f872", - "assets/build/ba_data/audio/shieldUp.ogg": "https://files.ballistica.net/cache/ba1/fe/d8/a2ccd8c6a875995d9cb2ea19b15f", - "assets/build/ba_data/audio/skid01.ogg": "https://files.ballistica.net/cache/ba1/9f/74/75e3aa4f69b481ce71a288782572", - "assets/build/ba_data/audio/slowEpicMusic.ogg": "https://files.ballistica.net/cache/ba1/0d/43/64ec39569be59bba8f4059814a3c", - "assets/build/ba_data/audio/sparkle01.ogg": "https://files.ballistica.net/cache/ba1/0c/95/849c30c8f047e1b8445dbac2169f", - "assets/build/ba_data/audio/sparkle02.ogg": "https://files.ballistica.net/cache/ba1/89/77/035cc2335b6fc20b1cf37116eb1e", - "assets/build/ba_data/audio/sparkle03.ogg": "https://files.ballistica.net/cache/ba1/a0/80/88f0a22537e0db0a6337b2731d65", - "assets/build/ba_data/audio/spawn.ogg": "https://files.ballistica.net/cache/ba1/a8/1b/3080a33a5046a077986b9e977ecf", - "assets/build/ba_data/audio/spazAttack01.ogg": "https://files.ballistica.net/cache/ba1/28/14/ca3231a4a6f1b0929304b6f5c677", - "assets/build/ba_data/audio/spazAttack02.ogg": "https://files.ballistica.net/cache/ba1/8a/39/372d94e8c3a45514ac6456f97cc6", - "assets/build/ba_data/audio/spazAttack03.ogg": "https://files.ballistica.net/cache/ba1/5c/b0/8a10049b4b79f37ac0d5e2cb729d", - "assets/build/ba_data/audio/spazAttack04.ogg": "https://files.ballistica.net/cache/ba1/21/7e/a07f84f98336c748f6c1fc41b03e", - "assets/build/ba_data/audio/spazDeath01.ogg": "https://files.ballistica.net/cache/ba1/a1/91/7d96496edf684c752f85805ed03e", - "assets/build/ba_data/audio/spazEff.ogg": "https://files.ballistica.net/cache/ba1/86/79/68f7629d5a7df81cb0025109543b", - "assets/build/ba_data/audio/spazFall01.ogg": "https://files.ballistica.net/cache/ba1/83/24/7f069b84819f9e1156f088a72330", - "assets/build/ba_data/audio/spazImpact01.ogg": "https://files.ballistica.net/cache/ba1/9e/10/ffc51d16bc2a83a0f389563fa4d8", - "assets/build/ba_data/audio/spazImpact02.ogg": "https://files.ballistica.net/cache/ba1/29/27/628e5eb7225e100c9db5eff47b7e", - "assets/build/ba_data/audio/spazImpact03.ogg": "https://files.ballistica.net/cache/ba1/e6/17/ce670ea95902dcb89b0ca1f13eff", - "assets/build/ba_data/audio/spazImpact04.ogg": "https://files.ballistica.net/cache/ba1/55/9b/578090fb0611ac68da563714cd15", - "assets/build/ba_data/audio/spazJump01.ogg": "https://files.ballistica.net/cache/ba1/18/b2/4ed2eeba37d777b05c5377edbb96", - "assets/build/ba_data/audio/spazJump02.ogg": "https://files.ballistica.net/cache/ba1/cf/4f/add95e67b04e418c42240b1bb81f", - "assets/build/ba_data/audio/spazJump03.ogg": "https://files.ballistica.net/cache/ba1/30/d5/1d400ec73f5ca9923fdeb0b9843d", - "assets/build/ba_data/audio/spazJump04.ogg": "https://files.ballistica.net/cache/ba1/8d/32/2bfe88854b1f3788ecab1286d3bb", - "assets/build/ba_data/audio/spazOw.ogg": "https://files.ballistica.net/cache/ba1/72/a5/1b6f1bc2a9ec191eb45df24c1260", - "assets/build/ba_data/audio/spazPickup01.ogg": "https://files.ballistica.net/cache/ba1/d8/ee/1adfe00ecba727c8e2f54ff99ecd", - "assets/build/ba_data/audio/spazScream01.ogg": "https://files.ballistica.net/cache/ba1/a0/85/4ab16778763244d19550d2725007", - "assets/build/ba_data/audio/splatter.ogg": "https://files.ballistica.net/cache/ba1/4a/26/0438d4aa28b3d805b4f9469ff430", - "assets/build/ba_data/audio/sportsMusic.ogg": "https://files.ballistica.net/cache/ba1/2b/ef/0b0da5f5558997e8da86d266c289", - "assets/build/ba_data/audio/stickyImpact.ogg": "https://files.ballistica.net/cache/ba1/e8/07/05fd7dcee09235c6862d82bf73a7", - "assets/build/ba_data/audio/superPunch.ogg": "https://files.ballistica.net/cache/ba1/5d/e8/7954ca2e8f594472029cefc44abe", - "assets/build/ba_data/audio/superhero1.ogg": "https://files.ballistica.net/cache/ba1/26/6a/76a0f5f8285b3da815e9b28a00f9", - "assets/build/ba_data/audio/superhero2.ogg": "https://files.ballistica.net/cache/ba1/69/51/b854b7ba2f70c5ce7db207bc6fce", - "assets/build/ba_data/audio/superhero3.ogg": "https://files.ballistica.net/cache/ba1/c4/eb/599d6ca19ec9de46167250b3b23a", - "assets/build/ba_data/audio/superhero4.ogg": "https://files.ballistica.net/cache/ba1/3d/2c/8975784a8372ad489ac23234648f", - "assets/build/ba_data/audio/superheroDeath.ogg": "https://files.ballistica.net/cache/ba1/d2/6a/b14eebbb9b36638b481957f391d6", - "assets/build/ba_data/audio/superheroFall.ogg": "https://files.ballistica.net/cache/ba1/97/35/5cef7eeb9baf16770e9caa114e92", - "assets/build/ba_data/audio/superheroHit1.ogg": "https://files.ballistica.net/cache/ba1/81/72/3691463b32aa02b60c8bc9381670", - "assets/build/ba_data/audio/superheroHit2.ogg": "https://files.ballistica.net/cache/ba1/c8/e2/055ee4668f243b5f03c045d96acb", - "assets/build/ba_data/audio/survivalMusic.ogg": "https://files.ballistica.net/cache/ba1/9f/88/8b4f0a3fee6ffc29fbca70a69169", - "assets/build/ba_data/audio/swip.ogg": "https://files.ballistica.net/cache/ba1/a7/f7/f508ac8b231edd24c7b08a91372f", - "assets/build/ba_data/audio/swip2.ogg": "https://files.ballistica.net/cache/ba1/59/44/4e8ac27af8ba0f097509ac69a463", - "assets/build/ba_data/audio/swish.ogg": "https://files.ballistica.net/cache/ba1/80/b9/d898557d66baa07d9974b512f2f3", - "assets/build/ba_data/audio/swish2.ogg": "https://files.ballistica.net/cache/ba1/57/ac/37be94b2d53925f5b8019c3b5223", - "assets/build/ba_data/audio/swish3.ogg": "https://files.ballistica.net/cache/ba1/e3/23/5765d25bf9ca7865062762d20958", - "assets/build/ba_data/audio/tap.ogg": "https://files.ballistica.net/cache/ba1/ca/50/ffa77d494f5c376c52521a840373", - "assets/build/ba_data/audio/technoHit01.ogg": "https://files.ballistica.net/cache/ba1/7e/34/183c1d6cd701df425544a82945b6", - "assets/build/ba_data/audio/tick.ogg": "https://files.ballistica.net/cache/ba1/cf/e9/4df7effb9d488f56c37270a2327e", - "assets/build/ba_data/audio/ticking.ogg": "https://files.ballistica.net/cache/ba1/9f/59/0b9e8bf7cc6b01f65de3c826b3bd", - "assets/build/ba_data/audio/tickingCrazy.ogg": "https://files.ballistica.net/cache/ba1/7d/12/0443e477795a08d7d9be906fd31e", - "assets/build/ba_data/audio/toTheDeathMusic.ogg": "https://files.ballistica.net/cache/ba1/70/90/eb2a7dc0930ad6193b2a128d1ded", - "assets/build/ba_data/audio/trashRummage.ogg": "https://files.ballistica.net/cache/ba1/a3/9e/4bad0c6f8cf0181a074c0db268bd", - "assets/build/ba_data/audio/victoryMusic.ogg": "https://files.ballistica.net/cache/ba1/e9/75/ad082ff65c5eb7ba8860eefddcc6", - "assets/build/ba_data/audio/warnBeep.ogg": "https://files.ballistica.net/cache/ba1/f3/77/44e2ee98b8e7b3dc5569384f6892", - "assets/build/ba_data/audio/warnBeeps.ogg": "https://files.ballistica.net/cache/ba1/39/6b/e9c7e668c92c3a57887ba985f1d7", - "assets/build/ba_data/audio/warrior1.ogg": "https://files.ballistica.net/cache/ba1/e2/e7/50aac508d38459b89f7f20ca6a65", - "assets/build/ba_data/audio/warrior2.ogg": "https://files.ballistica.net/cache/ba1/ea/d8/8f9e551260821562c74b40902dc7", - "assets/build/ba_data/audio/warrior3.ogg": "https://files.ballistica.net/cache/ba1/a7/1f/e1124eadd95de2ec3a84c363212a", - "assets/build/ba_data/audio/warrior4.ogg": "https://files.ballistica.net/cache/ba1/8f/b1/48e4fb2b0579ddd72eab6f12a82d", - "assets/build/ba_data/audio/warriorDeath.ogg": "https://files.ballistica.net/cache/ba1/bb/d1/38b90afa71375d47860f366aeb2b", - "assets/build/ba_data/audio/warriorFall.ogg": "https://files.ballistica.net/cache/ba1/96/f3/0c5c750fe674c954dee6ece08f47", - "assets/build/ba_data/audio/warriorHit1.ogg": "https://files.ballistica.net/cache/ba1/df/cb/c9f76841387056afa9b627109e99", - "assets/build/ba_data/audio/warriorHit2.ogg": "https://files.ballistica.net/cache/ba1/bd/f0/1e452100c63643021569c67ea84e", - "assets/build/ba_data/audio/whenJohnnyComesMarchingHomeMusic.ogg": "https://files.ballistica.net/cache/ba1/70/21/845fab94e28de4e7d3a32f324cec", - "assets/build/ba_data/audio/witch1.ogg": "https://files.ballistica.net/cache/ba1/d4/e9/6bcf7711b82eff57f6fff7dfd105", - "assets/build/ba_data/audio/witch2.ogg": "https://files.ballistica.net/cache/ba1/5d/22/b623c8e812aa4201a8934efd8c96", - "assets/build/ba_data/audio/witch3.ogg": "https://files.ballistica.net/cache/ba1/1f/79/05a3b9bf99133fc8eee029196c4d", - "assets/build/ba_data/audio/witch4.ogg": "https://files.ballistica.net/cache/ba1/ee/ea/97d02b3f426d18347a4d1f2661fd", - "assets/build/ba_data/audio/witchDeath.ogg": "https://files.ballistica.net/cache/ba1/d4/56/16bc17b0d2db5711626b9d8915ca", - "assets/build/ba_data/audio/witchFall.ogg": "https://files.ballistica.net/cache/ba1/6a/4b/0985084c16924181f0eb05112a42", - "assets/build/ba_data/audio/witchHit1.ogg": "https://files.ballistica.net/cache/ba1/69/0c/ffa2798e33057a4cfa0307c88925", - "assets/build/ba_data/audio/witchHit2.ogg": "https://files.ballistica.net/cache/ba1/9e/1a/e8fec979fe35dcaa1a32accedd2d", - "assets/build/ba_data/audio/wizard1.ogg": "https://files.ballistica.net/cache/ba1/45/a7/33b69b914db880b5b19a44a8f27b", - "assets/build/ba_data/audio/wizard2.ogg": "https://files.ballistica.net/cache/ba1/cc/e8/6c64dcca9841a2789fa246f65f59", - "assets/build/ba_data/audio/wizard3.ogg": "https://files.ballistica.net/cache/ba1/0c/77/0e14626535e9acfe1fe830d8d3f0", - "assets/build/ba_data/audio/wizard4.ogg": "https://files.ballistica.net/cache/ba1/30/b1/44f24e09c52566fbd64bb37f6473", - "assets/build/ba_data/audio/wizardDeath.ogg": "https://files.ballistica.net/cache/ba1/ff/4c/28fc077e921be23eadd9536ed221", - "assets/build/ba_data/audio/wizardFall.ogg": "https://files.ballistica.net/cache/ba1/d9/61/bf168c3a660ce70c96d7f8dacd5e", - "assets/build/ba_data/audio/wizardHit1.ogg": "https://files.ballistica.net/cache/ba1/a1/fb/3fd68f1549b44fc95e8c87b43bbc", - "assets/build/ba_data/audio/wizardHit2.ogg": "https://files.ballistica.net/cache/ba1/49/b9/1c27fc4c2f18c99c678fdb5f3490", - "assets/build/ba_data/audio/woodDebrisFall.ogg": "https://files.ballistica.net/cache/ba1/f3/a7/f82ddbe7e83444230afeec303e35", - "assets/build/ba_data/audio/wrestler1.ogg": "https://files.ballistica.net/cache/ba1/c1/a2/5b6e78bc9d43e8a888b414cb2ebe", - "assets/build/ba_data/audio/wrestler2.ogg": "https://files.ballistica.net/cache/ba1/ae/4a/39462e42896acc930da1809783e5", - "assets/build/ba_data/audio/wrestler3.ogg": "https://files.ballistica.net/cache/ba1/d6/0e/e666a0e052192a3ebc9118e6054a", - "assets/build/ba_data/audio/wrestler4.ogg": "https://files.ballistica.net/cache/ba1/b9/45/00628b126d880b07f99cb3c88e9c", - "assets/build/ba_data/audio/wrestlerDeath.ogg": "https://files.ballistica.net/cache/ba1/e3/ce/8a2f4185272123a46928b363e463", - "assets/build/ba_data/audio/wrestlerFall.ogg": "https://files.ballistica.net/cache/ba1/38/11/6213afb48a5475abc777c50f6f04", - "assets/build/ba_data/audio/wrestlerHit1.ogg": "https://files.ballistica.net/cache/ba1/7f/21/e7bd8c213a715e1392da9df1102d", - "assets/build/ba_data/audio/wrestlerHit2.ogg": "https://files.ballistica.net/cache/ba1/78/34/7fd99caed03ac1a198f2ca742987", - "assets/build/ba_data/audio/zoeAttack01.ogg": "https://files.ballistica.net/cache/ba1/a3/72/529aa45b6af5f6d2425c0bc5b741", - "assets/build/ba_data/audio/zoeAttack02.ogg": "https://files.ballistica.net/cache/ba1/f2/ed/b7246a01f9b4954aaaffdab248ee", - "assets/build/ba_data/audio/zoeAttack03.ogg": "https://files.ballistica.net/cache/ba1/49/e3/1da9b2bfbd0cef256db00f574926", - "assets/build/ba_data/audio/zoeAttack04.ogg": "https://files.ballistica.net/cache/ba1/95/c5/ef38e886dac699512e14554a48e3", - "assets/build/ba_data/audio/zoeDeath01.ogg": "https://files.ballistica.net/cache/ba1/31/14/a8e435a2f2eddd369b70309f2f8a", - "assets/build/ba_data/audio/zoeEff.ogg": "https://files.ballistica.net/cache/ba1/98/96/0923d815c9289c055a1a52659d5c", - "assets/build/ba_data/audio/zoeFall01.ogg": "https://files.ballistica.net/cache/ba1/85/db/c40e9dafa5ba884ab472ae043f5b", - "assets/build/ba_data/audio/zoeImpact01.ogg": "https://files.ballistica.net/cache/ba1/a0/de/093690e3eaaadadafe681ebded41", - "assets/build/ba_data/audio/zoeImpact02.ogg": "https://files.ballistica.net/cache/ba1/7a/93/3a154d5e094d4632e70dc8dff278", - "assets/build/ba_data/audio/zoeImpact03.ogg": "https://files.ballistica.net/cache/ba1/5a/31/6afc47d8cbe7853fac94e0159ef8", - "assets/build/ba_data/audio/zoeImpact04.ogg": "https://files.ballistica.net/cache/ba1/34/8f/e4c8f77726440042b78dd45a75ae", - "assets/build/ba_data/audio/zoeJump01.ogg": "https://files.ballistica.net/cache/ba1/ce/e9/2e360d4613c831d4ccc70bf94606", - "assets/build/ba_data/audio/zoeJump02.ogg": "https://files.ballistica.net/cache/ba1/b2/08/b13746522a47bc19059ab22d5a73", - "assets/build/ba_data/audio/zoeJump03.ogg": "https://files.ballistica.net/cache/ba1/dd/a4/05eccfb646c7dcd0787254cbfd76", - "assets/build/ba_data/audio/zoeOw.ogg": "https://files.ballistica.net/cache/ba1/d3/68/5898b2d11bf5a9dc3b7b6f4dfb5a", - "assets/build/ba_data/audio/zoePickup01.ogg": "https://files.ballistica.net/cache/ba1/59/c7/7b10339dda2f9d126971f50e189c", - "assets/build/ba_data/audio/zoeScream01.ogg": "https://files.ballistica.net/cache/ba1/64/b1/d26efaadfce16f328075758deb6c", + "assets/build/ba_data/audio/achievement.ogg": "https://files.ballistica.net/cache/ba1/58/60/72ea79f720fe3025edccb074795c", + "assets/build/ba_data/audio/actionHero1.ogg": "https://files.ballistica.net/cache/ba1/df/19/3dca52242f89fea536675460662d", + "assets/build/ba_data/audio/actionHero2.ogg": "https://files.ballistica.net/cache/ba1/cf/59/e9370637605e17e06782a3ded253", + "assets/build/ba_data/audio/actionHero3.ogg": "https://files.ballistica.net/cache/ba1/28/90/1bcbfedccddb1dbb75f1be534a40", + "assets/build/ba_data/audio/actionHero4.ogg": "https://files.ballistica.net/cache/ba1/4e/40/b163b9e464e3ad61fbb1669faccf", + "assets/build/ba_data/audio/actionHeroDeath.ogg": "https://files.ballistica.net/cache/ba1/ab/59/f8c8b4374989b7f4291897d12136", + "assets/build/ba_data/audio/actionHeroFall.ogg": "https://files.ballistica.net/cache/ba1/67/10/fbf1be54bb261de5be005b698ac6", + "assets/build/ba_data/audio/actionHeroHit1.ogg": "https://files.ballistica.net/cache/ba1/5b/6f/f33a2387e511c98990b503120332", + "assets/build/ba_data/audio/actionHeroHit2.ogg": "https://files.ballistica.net/cache/ba1/d0/50/1a0773c6d9f75f5a59397cc7f570", + "assets/build/ba_data/audio/activateBeep.ogg": "https://files.ballistica.net/cache/ba1/5a/e7/f46f191ed3bf9141ce584670f5ef", + "assets/build/ba_data/audio/agent1.ogg": "https://files.ballistica.net/cache/ba1/5f/1d/56573ce369bab1278f8f5ca3df20", + "assets/build/ba_data/audio/agent2.ogg": "https://files.ballistica.net/cache/ba1/96/ce/9d2fa9e025c18f6a549308398622", + "assets/build/ba_data/audio/agent3.ogg": "https://files.ballistica.net/cache/ba1/7a/02/192379d0855a384a6f4602070d2f", + "assets/build/ba_data/audio/agent4.ogg": "https://files.ballistica.net/cache/ba1/d6/c2/ded31e0ca74e18fb1cc9b2848eac", + "assets/build/ba_data/audio/agentDeath.ogg": "https://files.ballistica.net/cache/ba1/37/e2/799c72c85d5580ed91f3d07f353f", + "assets/build/ba_data/audio/agentFall.ogg": "https://files.ballistica.net/cache/ba1/f7/2d/b0f45c9b63c00011d0d0726e99dc", + "assets/build/ba_data/audio/agentHit1.ogg": "https://files.ballistica.net/cache/ba1/0d/62/79bcab98bfc875de8caf8cb584ce", + "assets/build/ba_data/audio/agentHit2.ogg": "https://files.ballistica.net/cache/ba1/15/bc/08460f83e57a794f273ca6b6a0ec", + "assets/build/ba_data/audio/alarm.ogg": "https://files.ballistica.net/cache/ba1/ad/60/b59451d596fcc3f01c74622fe91b", + "assets/build/ba_data/audio/ali1.ogg": "https://files.ballistica.net/cache/ba1/75/6f/f1db853370363e61b4b59fdc34f1", + "assets/build/ba_data/audio/ali2.ogg": "https://files.ballistica.net/cache/ba1/47/dd/5fbbbf4636d3f5f1b1ccdbcd7ee9", + "assets/build/ba_data/audio/ali3.ogg": "https://files.ballistica.net/cache/ba1/e7/e2/3d9421fe70a347e421817a2b7281", + "assets/build/ba_data/audio/ali4.ogg": "https://files.ballistica.net/cache/ba1/75/6d/3986f030b46a23325ffe590ae864", + "assets/build/ba_data/audio/aliDeath.ogg": "https://files.ballistica.net/cache/ba1/0d/55/3b5715fc528462a85857209bddf5", + "assets/build/ba_data/audio/aliFall.ogg": "https://files.ballistica.net/cache/ba1/9b/44/4ae14fa4e34460eff4ff79adca82", + "assets/build/ba_data/audio/aliHit1.ogg": "https://files.ballistica.net/cache/ba1/69/7f/34fddf7c9c23d5bdb88765f246f3", + "assets/build/ba_data/audio/aliHit2.ogg": "https://files.ballistica.net/cache/ba1/d3/67/871f6ee7fbe3c0b079c1c376cad4", + "assets/build/ba_data/audio/alien1.ogg": "https://files.ballistica.net/cache/ba1/8d/25/7e7e6484081f461a3c835a40466a", + "assets/build/ba_data/audio/alien2.ogg": "https://files.ballistica.net/cache/ba1/27/17/aeabc20283ce7542d5e5dc959efb", + "assets/build/ba_data/audio/alien3.ogg": "https://files.ballistica.net/cache/ba1/83/2e/46a27a8d9650cb64fd6cd2df865f", + "assets/build/ba_data/audio/alien4.ogg": "https://files.ballistica.net/cache/ba1/37/33/4f765d486286c1f998ae4b68d98e", + "assets/build/ba_data/audio/alienDeath.ogg": "https://files.ballistica.net/cache/ba1/92/99/e9fe339c6cb5d5d91d653f2a2894", + "assets/build/ba_data/audio/alienFall.ogg": "https://files.ballistica.net/cache/ba1/70/8e/8e2fb00c82452632854959c664ce", + "assets/build/ba_data/audio/alienHit1.ogg": "https://files.ballistica.net/cache/ba1/c4/9c/181dd79a43686ebb8cc05851d7ea", + "assets/build/ba_data/audio/alienHit2.ogg": "https://files.ballistica.net/cache/ba1/bb/3e/4238ca124fdf0bdbb9aac13549f8", + "assets/build/ba_data/audio/announceEight.ogg": "https://files.ballistica.net/cache/ba1/27/6a/574c3185d7c35d9480a839c8888a", + "assets/build/ba_data/audio/announceFive.ogg": "https://files.ballistica.net/cache/ba1/11/6f/072ad78bb410d30cf26d6e511d67", + "assets/build/ba_data/audio/announceFour.ogg": "https://files.ballistica.net/cache/ba1/32/f2/c02875245b900e5fbb7a384f2c17", + "assets/build/ba_data/audio/announceNine.ogg": "https://files.ballistica.net/cache/ba1/11/c0/47a7d6d8e578229db28b604932cb", + "assets/build/ba_data/audio/announceOne.ogg": "https://files.ballistica.net/cache/ba1/96/5f/5985e6a5cc5596d507d64908ecfa", + "assets/build/ba_data/audio/announceSeven.ogg": "https://files.ballistica.net/cache/ba1/3a/11/dcc1c4c6573f29852ebe55e5b549", + "assets/build/ba_data/audio/announceSix.ogg": "https://files.ballistica.net/cache/ba1/2a/22/a966bc15bab28ed56f8ff7e5bbfa", + "assets/build/ba_data/audio/announceTen.ogg": "https://files.ballistica.net/cache/ba1/e0/2e/5c614c252c2b3c24e63ae8498dbf", + "assets/build/ba_data/audio/announceThree.ogg": "https://files.ballistica.net/cache/ba1/dc/29/3172eee392826010e9d2fa9c138e", + "assets/build/ba_data/audio/announceTwo.ogg": "https://files.ballistica.net/cache/ba1/43/18/098574d833d394808a07ba36cede", + "assets/build/ba_data/audio/assassin1.ogg": "https://files.ballistica.net/cache/ba1/c3/5f/6598616f4f1f96c40413b71de9e8", + "assets/build/ba_data/audio/assassin2.ogg": "https://files.ballistica.net/cache/ba1/a4/8d/4116a1ea3715f1c4bb788819cd18", + "assets/build/ba_data/audio/assassin3.ogg": "https://files.ballistica.net/cache/ba1/4e/92/ab9b6565d11b89b73aaa265eb8f0", + "assets/build/ba_data/audio/assassin4.ogg": "https://files.ballistica.net/cache/ba1/7b/e0/a40c91b027bace02667c0fcf158c", + "assets/build/ba_data/audio/assassinDeath.ogg": "https://files.ballistica.net/cache/ba1/05/88/f550d7014923a2c6134f12628098", + "assets/build/ba_data/audio/assassinFall.ogg": "https://files.ballistica.net/cache/ba1/dd/df/94392604b6a346f8b11b696c8f1d", + "assets/build/ba_data/audio/assassinHit1.ogg": "https://files.ballistica.net/cache/ba1/c0/6f/de6f72745e850af65cf9a5dbb3a6", + "assets/build/ba_data/audio/assassinHit2.ogg": "https://files.ballistica.net/cache/ba1/9e/e2/a69db7c14065ee8d570a100a263b", + "assets/build/ba_data/audio/bear1.ogg": "https://files.ballistica.net/cache/ba1/72/49/9551e6ff43e4fdd863cca11134f4", + "assets/build/ba_data/audio/bear2.ogg": "https://files.ballistica.net/cache/ba1/d7/1f/2c830ac5e0a0c43f145a20fa2c25", + "assets/build/ba_data/audio/bear3.ogg": "https://files.ballistica.net/cache/ba1/aa/98/9f1a21aa9dac07d05085e8687068", + "assets/build/ba_data/audio/bear4.ogg": "https://files.ballistica.net/cache/ba1/c7/26/69891bac03ddbea748f9baec9f95", + "assets/build/ba_data/audio/bearDeath.ogg": "https://files.ballistica.net/cache/ba1/e9/eb/39834342979b9340776d814902bb", + "assets/build/ba_data/audio/bearFall.ogg": "https://files.ballistica.net/cache/ba1/15/6b/2be51a0c48077b44166ce9b5a133", + "assets/build/ba_data/audio/bearHit1.ogg": "https://files.ballistica.net/cache/ba1/96/22/6f56ec5c0b58ce8faf959c766a61", + "assets/build/ba_data/audio/bearHit2.ogg": "https://files.ballistica.net/cache/ba1/4f/98/5366c6a26a83e9618b8eca54780a", + "assets/build/ba_data/audio/bellHigh.ogg": "https://files.ballistica.net/cache/ba1/7c/02/4bc38047fc4301eb3c195e0539b9", + "assets/build/ba_data/audio/bellLow.ogg": "https://files.ballistica.net/cache/ba1/85/e0/6ebea452dc2a1284e6668f18e6ec", + "assets/build/ba_data/audio/bellMed.ogg": "https://files.ballistica.net/cache/ba1/a2/d0/57fc42d7e5b76024f0221b43cdfe", + "assets/build/ba_data/audio/bigImpact.ogg": "https://files.ballistica.net/cache/ba1/90/6c/07bb89e1e1d59f927c7530c88fe8", + "assets/build/ba_data/audio/bigImpact2.ogg": "https://files.ballistica.net/cache/ba1/04/81/87864481b02fecb9914e3b50e2a6", + "assets/build/ba_data/audio/blank.ogg": "https://files.ballistica.net/cache/ba1/55/70/90a49806365698031bd7c2a1e55f", + "assets/build/ba_data/audio/blip.ogg": "https://files.ballistica.net/cache/ba1/be/d9/c7bae6f1b9900727cdcffe70adad", + "assets/build/ba_data/audio/block.ogg": "https://files.ballistica.net/cache/ba1/f6/5e/e27553fb56edd40e854a8310ce6b", + "assets/build/ba_data/audio/bombDrop01.ogg": "https://files.ballistica.net/cache/ba1/1a/e8/2bd59450bb142dd8edb7fc875337", + "assets/build/ba_data/audio/bombDrop02.ogg": "https://files.ballistica.net/cache/ba1/28/f5/f7601c05201d1cb088f7b01dd244", + "assets/build/ba_data/audio/bombRoll01.ogg": "https://files.ballistica.net/cache/ba1/4b/64/e0c24177793c47547e3f57c7273b", + "assets/build/ba_data/audio/bones1.ogg": "https://files.ballistica.net/cache/ba1/66/99/fc98f957a6db4a93b5fbb5786b4e", + "assets/build/ba_data/audio/bones2.ogg": "https://files.ballistica.net/cache/ba1/a1/38/064ad0b952104f931c1bcc34d747", + "assets/build/ba_data/audio/bones3.ogg": "https://files.ballistica.net/cache/ba1/20/6e/665a3bd95dc7769c95938da89a2b", + "assets/build/ba_data/audio/bonesDeath.ogg": "https://files.ballistica.net/cache/ba1/2c/53/450b0d309913653756599fb54f25", + "assets/build/ba_data/audio/bonesFall.ogg": "https://files.ballistica.net/cache/ba1/b5/94/d157d5a2b02016caf4a3b40c358c", + "assets/build/ba_data/audio/boo.ogg": "https://files.ballistica.net/cache/ba1/9e/b6/e71d3e3cb099fd93034adc78d079", + "assets/build/ba_data/audio/boxDrop.ogg": "https://files.ballistica.net/cache/ba1/4a/b6/c9f4c108be9808134c15cf44e4b2", + "assets/build/ba_data/audio/boxingBell.ogg": "https://files.ballistica.net/cache/ba1/34/e1/05c5c1400662d2fb3a07594db5b7", + "assets/build/ba_data/audio/bunny1.ogg": "https://files.ballistica.net/cache/ba1/24/8f/bb616af82630e9dc7b98f29318a9", + "assets/build/ba_data/audio/bunny2.ogg": "https://files.ballistica.net/cache/ba1/9d/63/3b247d4a4de0a673008868342765", + "assets/build/ba_data/audio/bunny3.ogg": "https://files.ballistica.net/cache/ba1/0e/08/6490c22fe15808b214068bdc7753", + "assets/build/ba_data/audio/bunny4.ogg": "https://files.ballistica.net/cache/ba1/2a/b7/c480591a278edfe518df5e12ec6a", + "assets/build/ba_data/audio/bunnyDeath.ogg": "https://files.ballistica.net/cache/ba1/93/7d/152e5bf4fdd7880c3f0b9abf178d", + "assets/build/ba_data/audio/bunnyFall.ogg": "https://files.ballistica.net/cache/ba1/0c/31/97752e51b1ab8f581d467b453d29", + "assets/build/ba_data/audio/bunnyHit1.ogg": "https://files.ballistica.net/cache/ba1/1a/e9/7b62eeb9abb596b89bfe53c41df2", + "assets/build/ba_data/audio/bunnyHit2.ogg": "https://files.ballistica.net/cache/ba1/37/56/f44055d623b9f16a6d3ea52cf95d", + "assets/build/ba_data/audio/bunnyJump.ogg": "https://files.ballistica.net/cache/ba1/be/92/b63a629718a81effe5858530a2be", + "assets/build/ba_data/audio/cashRegister.ogg": "https://files.ballistica.net/cache/ba1/91/07/33e1d7d98479aeb0386898bc633e", + "assets/build/ba_data/audio/cashRegister2.ogg": "https://files.ballistica.net/cache/ba1/f8/12/74edab7ebda050f913428793f477", + "assets/build/ba_data/audio/charSelectMusic.ogg": "https://files.ballistica.net/cache/ba1/a7/6d/53b41cd118b34d9ab8254dbd2ff1", + "assets/build/ba_data/audio/cheer.ogg": "https://files.ballistica.net/cache/ba1/c7/ff/c962b9c39a35de2004198e9f03f1", + "assets/build/ba_data/audio/click01.ogg": "https://files.ballistica.net/cache/ba1/7e/a6/42511f8b555d460156424bc53f47", + "assets/build/ba_data/audio/corkPop.ogg": "https://files.ballistica.net/cache/ba1/68/a4/2b7c6d678fe1fa09cde1081c83ef", + "assets/build/ba_data/audio/cowboy1.ogg": "https://files.ballistica.net/cache/ba1/1b/0f/a0bea97d774aa221a3941f0e0af2", + "assets/build/ba_data/audio/cowboy2.ogg": "https://files.ballistica.net/cache/ba1/eb/da/b25db53f6a6d4871db7a7829a8b3", + "assets/build/ba_data/audio/cowboy3.ogg": "https://files.ballistica.net/cache/ba1/42/7c/8eeaec50726c9f6bbd62694bffc5", + "assets/build/ba_data/audio/cowboy4.ogg": "https://files.ballistica.net/cache/ba1/c6/f4/a0f56e61df27ced1d7f03b1dc458", + "assets/build/ba_data/audio/cowboyDeath.ogg": "https://files.ballistica.net/cache/ba1/cb/0e/abb677f438cd64b63dd6fc363d4a", + "assets/build/ba_data/audio/cowboyFall.ogg": "https://files.ballistica.net/cache/ba1/1d/af/c302b9caba1d7f736a6dd9f52268", + "assets/build/ba_data/audio/cowboyHit1.ogg": "https://files.ballistica.net/cache/ba1/71/57/0a9213ba8dea0404318893385068", + "assets/build/ba_data/audio/cowboyHit2.ogg": "https://files.ballistica.net/cache/ba1/cb/13/afa6a5a87981e947177695af64d5", + "assets/build/ba_data/audio/crowdChant.ogg": "https://files.ballistica.net/cache/ba1/f5/c0/92c75181f783dae40075d9c2b689", + "assets/build/ba_data/audio/cyborg1.ogg": "https://files.ballistica.net/cache/ba1/47/15/b4930affbf40421447247546fe99", + "assets/build/ba_data/audio/cyborg2.ogg": "https://files.ballistica.net/cache/ba1/b2/af/626e8e08ab19d5854e474b9195aa", + "assets/build/ba_data/audio/cyborg3.ogg": "https://files.ballistica.net/cache/ba1/8c/0c/b25cf168c367368689c2830361ba", + "assets/build/ba_data/audio/cyborg4.ogg": "https://files.ballistica.net/cache/ba1/38/85/714969eb77f14b8b89c1fdf4bb54", + "assets/build/ba_data/audio/cyborgDeath.ogg": "https://files.ballistica.net/cache/ba1/2f/16/437f9756452e7386a6f737e957db", + "assets/build/ba_data/audio/cyborgFall.ogg": "https://files.ballistica.net/cache/ba1/77/db/a912a8c114f815799738da41ad5f", + "assets/build/ba_data/audio/cyborgHit1.ogg": "https://files.ballistica.net/cache/ba1/86/0c/c988a0ec4cf50cadbb3617b51547", + "assets/build/ba_data/audio/cyborgHit2.ogg": "https://files.ballistica.net/cache/ba1/30/86/9a0fd20c447caa136f902c0995aa", + "assets/build/ba_data/audio/cymbal.ogg": "https://files.ballistica.net/cache/ba1/74/c6/0f51346d8bd9ca177d20c913d4bc", + "assets/build/ba_data/audio/debrisFall.ogg": "https://files.ballistica.net/cache/ba1/82/8a/cc77cccd8f885307237e3091a43f", + "assets/build/ba_data/audio/deek.ogg": "https://files.ballistica.net/cache/ba1/4c/cf/d44e49553a8f590e6044d5a29c40", + "assets/build/ba_data/audio/deek2.ogg": "https://files.ballistica.net/cache/ba1/a1/9d/6feb67617bd1d6b0e116ba8f4051", + "assets/build/ba_data/audio/ding.ogg": "https://files.ballistica.net/cache/ba1/49/44/70398a2997c7238349abd56f64e9", + "assets/build/ba_data/audio/dingSmall.ogg": "https://files.ballistica.net/cache/ba1/ce/5d/6de4581beee72fd2dbf78e884f6d", + "assets/build/ba_data/audio/dingSmallHigh.ogg": "https://files.ballistica.net/cache/ba1/d8/6c/c290d65aa888309b14172b4550f5", + "assets/build/ba_data/audio/dripity.ogg": "https://files.ballistica.net/cache/ba1/5a/c7/2012a0547b43f4fe22300ba1e435", + "assets/build/ba_data/audio/drumRoll.ogg": "https://files.ballistica.net/cache/ba1/f9/c9/eb8cdc6911207e1b9fc37c856550", + "assets/build/ba_data/audio/error.ogg": "https://files.ballistica.net/cache/ba1/f0/fb/8db7d282d17f6549439472a17443", + "assets/build/ba_data/audio/explosion01.ogg": "https://files.ballistica.net/cache/ba1/7e/5c/60d2827cf919ce3a2a742c13656d", + "assets/build/ba_data/audio/explosion02.ogg": "https://files.ballistica.net/cache/ba1/40/5b/0ad2e9b46bdbeb5117c6c35d0c06", + "assets/build/ba_data/audio/explosion03.ogg": "https://files.ballistica.net/cache/ba1/fc/55/a9abae0b44d7a38e8965dbe0e82d", + "assets/build/ba_data/audio/explosion04.ogg": "https://files.ballistica.net/cache/ba1/3e/1d/6956a0ebd528c85d928f64e986ad", + "assets/build/ba_data/audio/explosion05.ogg": "https://files.ballistica.net/cache/ba1/1f/6a/ad37d5a4a16390ff4984008c4529", + "assets/build/ba_data/audio/fanfare.ogg": "https://files.ballistica.net/cache/ba1/65/89/78fb925efb8e70a3a7b3b8e6eb22", + "assets/build/ba_data/audio/flagCatcherMusic.ogg": "https://files.ballistica.net/cache/ba1/d2/63/1214d61047ae93562e81ebb5ff31", + "assets/build/ba_data/audio/flyingMusic.ogg": "https://files.ballistica.net/cache/ba1/84/62/853c3e325b4709e59e4d08c05f71", + "assets/build/ba_data/audio/foghorn.ogg": "https://files.ballistica.net/cache/ba1/74/26/2338cc1801cfa18e1e106aeb4ae6", + "assets/build/ba_data/audio/footImpact01.ogg": "https://files.ballistica.net/cache/ba1/d2/86/b525c0f04e5118b20d55cd075b8d", + "assets/build/ba_data/audio/footImpact02.ogg": "https://files.ballistica.net/cache/ba1/cc/c9/3a00e1b3f628412877c88f1be1dd", + "assets/build/ba_data/audio/footImpact03.ogg": "https://files.ballistica.net/cache/ba1/15/43/3e555fb6ea381f384d3ac1646707", + "assets/build/ba_data/audio/forwardMarchMusic.ogg": "https://files.ballistica.net/cache/ba1/4f/bd/c9a96a8949fca5328df20bf6c160", + "assets/build/ba_data/audio/freeze.ogg": "https://files.ballistica.net/cache/ba1/02/ab/e598b181e844a065925f2bf97963", + "assets/build/ba_data/audio/frosty01.ogg": "https://files.ballistica.net/cache/ba1/ef/6d/3400f25717f7f442dd8d1419033e", + "assets/build/ba_data/audio/frosty02.ogg": "https://files.ballistica.net/cache/ba1/76/38/5854a95ec204f41e43b50d263409", + "assets/build/ba_data/audio/frosty03.ogg": "https://files.ballistica.net/cache/ba1/a8/16/60fc348f2edc081c4c338e7956e6", + "assets/build/ba_data/audio/frosty04.ogg": "https://files.ballistica.net/cache/ba1/11/f0/7860caaada9174a47251c9c66018", + "assets/build/ba_data/audio/frosty05.ogg": "https://files.ballistica.net/cache/ba1/45/8f/def4659833a1dbd76f14b13d2bff", + "assets/build/ba_data/audio/frostyDeath.ogg": "https://files.ballistica.net/cache/ba1/d4/bd/d214a161586e03503c21d859b615", + "assets/build/ba_data/audio/frostyFall.ogg": "https://files.ballistica.net/cache/ba1/e9/44/98873e7072b05ab1fda1f35ee9cf", + "assets/build/ba_data/audio/frostyHit01.ogg": "https://files.ballistica.net/cache/ba1/7d/c9/5a6686a9f625692a51845f8b1a9e", + "assets/build/ba_data/audio/frostyHit02.ogg": "https://files.ballistica.net/cache/ba1/65/d3/bd26b06bc0d3840d12971a8ff7a3", + "assets/build/ba_data/audio/frostyHit03.ogg": "https://files.ballistica.net/cache/ba1/62/b8/ff9ae4125d95afff1eabfa70e85f", + "assets/build/ba_data/audio/fuse01.ogg": "https://files.ballistica.net/cache/ba1/e0/33/05a6deab05d5fc024078294911e6", + "assets/build/ba_data/audio/gladiator1.ogg": "https://files.ballistica.net/cache/ba1/62/c9/9a1677c7ac53aa1e2d86b6a41cb8", + "assets/build/ba_data/audio/gladiator2.ogg": "https://files.ballistica.net/cache/ba1/01/03/826a4dc462a2ffde058c229563c4", + "assets/build/ba_data/audio/gladiator3.ogg": "https://files.ballistica.net/cache/ba1/75/ac/4153c1bae224e124e6a0c14f3767", + "assets/build/ba_data/audio/gladiator4.ogg": "https://files.ballistica.net/cache/ba1/41/57/9d42f96a7b4f2501516c76acd8eb", + "assets/build/ba_data/audio/gladiatorDeath.ogg": "https://files.ballistica.net/cache/ba1/0b/3f/7b823002ac4823e692f3e3772e6d", + "assets/build/ba_data/audio/gladiatorFall.ogg": "https://files.ballistica.net/cache/ba1/59/52/bd80868601bbe451ea2b8bbedd3b", + "assets/build/ba_data/audio/gladiatorHit1.ogg": "https://files.ballistica.net/cache/ba1/d5/f1/eec7713ca5613b27827f2cecd23e", + "assets/build/ba_data/audio/gladiatorHit2.ogg": "https://files.ballistica.net/cache/ba1/8d/f6/65d8116517cedabd94498fad52f5", + "assets/build/ba_data/audio/gong.ogg": "https://files.ballistica.net/cache/ba1/22/74/cbebc4aea2e05e0b04acc6505247", + "assets/build/ba_data/audio/grandRompMusic.ogg": "https://files.ballistica.net/cache/ba1/d8/8d/c58f032720cf364033eca76836db", + "assets/build/ba_data/audio/gravelSkid.ogg": "https://files.ballistica.net/cache/ba1/53/45/06c085914c1f9faef2486bb97437", + "assets/build/ba_data/audio/gunCocking.ogg": "https://files.ballistica.net/cache/ba1/d8/ce/edd7befc975296aef73d732bb663", + "assets/build/ba_data/audio/healthPowerup.ogg": "https://files.ballistica.net/cache/ba1/f0/34/72c44aef2241471debca16f03870", + "assets/build/ba_data/audio/hiss.ogg": "https://files.ballistica.net/cache/ba1/04/3a/9b820db7a76beb8271c9737558ba", + "assets/build/ba_data/audio/impactHard.ogg": "https://files.ballistica.net/cache/ba1/30/e7/9e78011593669448536cfc97cfd2", + "assets/build/ba_data/audio/impactHard2.ogg": "https://files.ballistica.net/cache/ba1/3e/5f/4da1dd1467abf87db71303958898", + "assets/build/ba_data/audio/impactHard3.ogg": "https://files.ballistica.net/cache/ba1/19/b6/3350b18401d089a06ed953b664d8", + "assets/build/ba_data/audio/impactMedium.ogg": "https://files.ballistica.net/cache/ba1/fc/50/e6d167d4c54f01a23a8a509c0033", + "assets/build/ba_data/audio/impactMedium2.ogg": "https://files.ballistica.net/cache/ba1/d9/c9/594cee989be6e1101e5b81f84e21", + "assets/build/ba_data/audio/jack01.ogg": "https://files.ballistica.net/cache/ba1/e9/1d/924768dd46f3ebba712f7c4671fd", + "assets/build/ba_data/audio/jack02.ogg": "https://files.ballistica.net/cache/ba1/bd/6b/6f1071d7151a0c2cfb58203d3b0a", + "assets/build/ba_data/audio/jack03.ogg": "https://files.ballistica.net/cache/ba1/fe/2e/ee03645ecc98b87351b36dc8bad8", + "assets/build/ba_data/audio/jack04.ogg": "https://files.ballistica.net/cache/ba1/04/eb/2b842246184c956b63e03a030eb0", + "assets/build/ba_data/audio/jack05.ogg": "https://files.ballistica.net/cache/ba1/ee/9b/e9505d780f8df0b7f52521633033", + "assets/build/ba_data/audio/jack06.ogg": "https://files.ballistica.net/cache/ba1/28/c1/fc96bb381c38fe24db32ce943d39", + "assets/build/ba_data/audio/jackDeath01.ogg": "https://files.ballistica.net/cache/ba1/10/ad/a44b04f740f29112e146f61d08dd", + "assets/build/ba_data/audio/jackFall01.ogg": "https://files.ballistica.net/cache/ba1/d8/69/8185e28dedad83a6ce42412eca0b", + "assets/build/ba_data/audio/jackHit01.ogg": "https://files.ballistica.net/cache/ba1/c9/7d/076eb7ef2e45129e8f7870d2b5fa", + "assets/build/ba_data/audio/jackHit02.ogg": "https://files.ballistica.net/cache/ba1/cc/8c/8196a164dfa4a7304753767bc806", + "assets/build/ba_data/audio/jackHit03.ogg": "https://files.ballistica.net/cache/ba1/c0/93/280556ce2e97fbb3cfd43d4cc6f8", + "assets/build/ba_data/audio/jackHit04.ogg": "https://files.ballistica.net/cache/ba1/7d/2e/59fb210c91477798962076d40bed", + "assets/build/ba_data/audio/jackHit05.ogg": "https://files.ballistica.net/cache/ba1/d9/15/8db623ab332a7adf3087c54eb439", + "assets/build/ba_data/audio/jackHit06.ogg": "https://files.ballistica.net/cache/ba1/14/25/d85c7443244ff9c4b762cfba7d45", + "assets/build/ba_data/audio/jackHit07.ogg": "https://files.ballistica.net/cache/ba1/c3/92/70e73537e642c3de7c0d1514c62c", + "assets/build/ba_data/audio/jumpsuit1.ogg": "https://files.ballistica.net/cache/ba1/1d/e6/caeb8f3d75ad8d00a896493d4981", + "assets/build/ba_data/audio/jumpsuit2.ogg": "https://files.ballistica.net/cache/ba1/9d/65/5bada79073612f81dada09cdd669", + "assets/build/ba_data/audio/jumpsuit3.ogg": "https://files.ballistica.net/cache/ba1/ec/97/1807c9196930f55ed29080374395", + "assets/build/ba_data/audio/jumpsuit4.ogg": "https://files.ballistica.net/cache/ba1/3c/84/d62da6a915e3255434a0929e4ec8", + "assets/build/ba_data/audio/jumpsuitDeath.ogg": "https://files.ballistica.net/cache/ba1/8c/b3/525216f8302f9d948095bfa9799a", + "assets/build/ba_data/audio/jumpsuitFall.ogg": "https://files.ballistica.net/cache/ba1/7f/af/6b411b9a46ad8be33e15dc9e6429", + "assets/build/ba_data/audio/jumpsuitHit1.ogg": "https://files.ballistica.net/cache/ba1/a6/29/bed67bd2fa608427b5b27703a369", + "assets/build/ba_data/audio/jumpsuitHit2.ogg": "https://files.ballistica.net/cache/ba1/de/ff/aac029f85323dfde023607bd5b98", + "assets/build/ba_data/audio/kronk1.ogg": "https://files.ballistica.net/cache/ba1/a5/25/6ffeb4f7c0b479f6ea331fad4cb0", + "assets/build/ba_data/audio/kronk10.ogg": "https://files.ballistica.net/cache/ba1/e0/72/50b27a07c338b3ea9467877fcba6", + "assets/build/ba_data/audio/kronk2.ogg": "https://files.ballistica.net/cache/ba1/d3/4a/ab1f9a3af8ec7a35dc4c84ebec93", + "assets/build/ba_data/audio/kronk3.ogg": "https://files.ballistica.net/cache/ba1/78/3e/04ed2f524aa8c9d7cc20240dd102", + "assets/build/ba_data/audio/kronk4.ogg": "https://files.ballistica.net/cache/ba1/a7/90/67fc1bcc1e29225c6560b22dc797", + "assets/build/ba_data/audio/kronk5.ogg": "https://files.ballistica.net/cache/ba1/47/73/ebadf9e3e762761b486574f92ae5", + "assets/build/ba_data/audio/kronk6.ogg": "https://files.ballistica.net/cache/ba1/d7/12/eb34c17c7eae64861019d8b9d0e4", + "assets/build/ba_data/audio/kronk7.ogg": "https://files.ballistica.net/cache/ba1/50/12/4bbf79acb96de2891d0c04793dd8", + "assets/build/ba_data/audio/kronk8.ogg": "https://files.ballistica.net/cache/ba1/fb/3d/cf3678af97b1e9453b2a5ccf6556", + "assets/build/ba_data/audio/kronk9.ogg": "https://files.ballistica.net/cache/ba1/2b/5d/80ac256b9a0395ce0c1df07198b7", + "assets/build/ba_data/audio/kronkDeath.ogg": "https://files.ballistica.net/cache/ba1/a8/86/adb0bcf982f41aef1266bfef4ac3", + "assets/build/ba_data/audio/kronkFall.ogg": "https://files.ballistica.net/cache/ba1/01/bc/933e24668420f71aa5a7f405166e", + "assets/build/ba_data/audio/laser.ogg": "https://files.ballistica.net/cache/ba1/9e/ef/c95d203792e7c2410cf48b8e6242", + "assets/build/ba_data/audio/laserReverse.ogg": "https://files.ballistica.net/cache/ba1/ee/de/e4e5513a1e0b45bd7c21802a0680", + "assets/build/ba_data/audio/mel01.ogg": "https://files.ballistica.net/cache/ba1/df/e6/9597698cb9abe30ceade8ab682e1", + "assets/build/ba_data/audio/mel02.ogg": "https://files.ballistica.net/cache/ba1/28/0e/41a16319712fc1c0d7999d439dff", + "assets/build/ba_data/audio/mel03.ogg": "https://files.ballistica.net/cache/ba1/bf/b0/5ae8a0a1c92664a078869125aa33", + "assets/build/ba_data/audio/mel04.ogg": "https://files.ballistica.net/cache/ba1/62/8d/30104cf07b07d7f8044324587f8b", + "assets/build/ba_data/audio/mel05.ogg": "https://files.ballistica.net/cache/ba1/a3/ba/7e268b1bf136ab431ed8aa600c92", + "assets/build/ba_data/audio/mel06.ogg": "https://files.ballistica.net/cache/ba1/18/e1/f9a292341b7ae940dcdfc9af6dde", + "assets/build/ba_data/audio/mel07.ogg": "https://files.ballistica.net/cache/ba1/4e/42/c512f97edc448246a89e4c92f9c8", + "assets/build/ba_data/audio/mel08.ogg": "https://files.ballistica.net/cache/ba1/73/52/3930c7eb099dfe89fbd09c90309c", + "assets/build/ba_data/audio/mel09.ogg": "https://files.ballistica.net/cache/ba1/22/79/82f9d313915592a142e8cf0c6e99", + "assets/build/ba_data/audio/mel10.ogg": "https://files.ballistica.net/cache/ba1/a0/3a/067da88e50b7fb576cb30441065e", + "assets/build/ba_data/audio/melDeath01.ogg": "https://files.ballistica.net/cache/ba1/cd/e1/b3a3cf043eba71e1f6fdecb010f2", + "assets/build/ba_data/audio/melFall01.ogg": "https://files.ballistica.net/cache/ba1/fd/48/d9903063f4a5cd445f140280faba", + "assets/build/ba_data/audio/menuMusic.ogg": "https://files.ballistica.net/cache/ba1/61/25/949add05fbdc5d6d163192a5bf96", + "assets/build/ba_data/audio/metalHit.ogg": "https://files.ballistica.net/cache/ba1/ee/80/b0305bfb666556e8931ec5729088", + "assets/build/ba_data/audio/metalSkid.ogg": "https://files.ballistica.net/cache/ba1/de/81/6d1597d6bb6ae20d6715c52b8757", + "assets/build/ba_data/audio/ninjaAttack1.ogg": "https://files.ballistica.net/cache/ba1/b0/ec/7e6ea6898010fc117fe7ab3cfd14", + "assets/build/ba_data/audio/ninjaAttack2.ogg": "https://files.ballistica.net/cache/ba1/b9/2a/1b3045380c083e67252cade17f60", + "assets/build/ba_data/audio/ninjaAttack3.ogg": "https://files.ballistica.net/cache/ba1/83/fe/6854cffa06c237e8ba11aa1c3811", + "assets/build/ba_data/audio/ninjaAttack4.ogg": "https://files.ballistica.net/cache/ba1/09/f7/5b3de6c0c466c3fc6d2f6b19102c", + "assets/build/ba_data/audio/ninjaAttack5.ogg": "https://files.ballistica.net/cache/ba1/ec/42/e0784271bec8a82dfb54201c2e1c", + "assets/build/ba_data/audio/ninjaAttack6.ogg": "https://files.ballistica.net/cache/ba1/b2/e6/20743d838354bbc70b0eab0942e6", + "assets/build/ba_data/audio/ninjaAttack7.ogg": "https://files.ballistica.net/cache/ba1/9e/bb/e7002c6810d6a66d1a9779091364", + "assets/build/ba_data/audio/ninjaDeath1.ogg": "https://files.ballistica.net/cache/ba1/b8/62/c9f0b5aed52a44cda7c1d874f096", + "assets/build/ba_data/audio/ninjaFall1.ogg": "https://files.ballistica.net/cache/ba1/45/f8/461537290f94f4e93e6d127e73eb", + "assets/build/ba_data/audio/ninjaHit1.ogg": "https://files.ballistica.net/cache/ba1/b5/4d/0acb8fe85d7c67ec8afe3005ae2a", + "assets/build/ba_data/audio/ninjaHit2.ogg": "https://files.ballistica.net/cache/ba1/41/7b/bc492022c86f91cd38a203a7dbc8", + "assets/build/ba_data/audio/ninjaHit3.ogg": "https://files.ballistica.net/cache/ba1/21/a9/4bf5331435ab7f0118a769efc82e", + "assets/build/ba_data/audio/ninjaHit4.ogg": "https://files.ballistica.net/cache/ba1/90/9a/6a012a5e6782726a5e2d6fe91f44", + "assets/build/ba_data/audio/ninjaHit5.ogg": "https://files.ballistica.net/cache/ba1/30/ef/7d13306f36cb7827273062c3f2a4", + "assets/build/ba_data/audio/ninjaHit6.ogg": "https://files.ballistica.net/cache/ba1/5f/fe/fb2532d2e6de096a9feeab7f6c17", + "assets/build/ba_data/audio/ninjaHit7.ogg": "https://files.ballistica.net/cache/ba1/57/56/0ba4ab0f1233ef72108ccda9ccfa", + "assets/build/ba_data/audio/ninjaHit8.ogg": "https://files.ballistica.net/cache/ba1/d2/d9/b1fbfc0a864161fc879785b544c5", + "assets/build/ba_data/audio/oldLady1.ogg": "https://files.ballistica.net/cache/ba1/27/9c/4ae89ba2d90c5491a05a9098dfb7", + "assets/build/ba_data/audio/oldLady2.ogg": "https://files.ballistica.net/cache/ba1/6d/55/0f3a7a838905dde023bd93775ebb", + "assets/build/ba_data/audio/oldLady3.ogg": "https://files.ballistica.net/cache/ba1/d8/77/08e31296569e99eaea6e3335dac3", + "assets/build/ba_data/audio/oldLady4.ogg": "https://files.ballistica.net/cache/ba1/b7/96/5f7dd93a643a3ab1f5d6a0a4e8c3", + "assets/build/ba_data/audio/oldLadyDeath.ogg": "https://files.ballistica.net/cache/ba1/71/f0/ee089bbd54bb57734d09477cc2d9", + "assets/build/ba_data/audio/oldLadyFall.ogg": "https://files.ballistica.net/cache/ba1/b3/4b/a3dc06498650caee6290e364f2d6", + "assets/build/ba_data/audio/oldLadyHit1.ogg": "https://files.ballistica.net/cache/ba1/4a/66/358ad6790d13b4b2edcfc3e0f271", + "assets/build/ba_data/audio/oldLadyHit2.ogg": "https://files.ballistica.net/cache/ba1/18/cb/d7c3037b62cd77781fe4f12691fa", + "assets/build/ba_data/audio/ooh.ogg": "https://files.ballistica.net/cache/ba1/b7/28/6cefdb25ff8d908cc3feae409db3", + "assets/build/ba_data/audio/operaSinger1.ogg": "https://files.ballistica.net/cache/ba1/1f/ae/192442b203a9ea76ede63f8c6703", + "assets/build/ba_data/audio/operaSinger2.ogg": "https://files.ballistica.net/cache/ba1/ec/bd/5f82598f65e996cd38808750d31e", + "assets/build/ba_data/audio/operaSinger3.ogg": "https://files.ballistica.net/cache/ba1/6f/05/650ce355834ff955bd92e826bf61", + "assets/build/ba_data/audio/operaSinger4.ogg": "https://files.ballistica.net/cache/ba1/d9/7b/912192363ea7bdefad644d581031", + "assets/build/ba_data/audio/operaSingerDeath.ogg": "https://files.ballistica.net/cache/ba1/80/3b/9f46ff5e3935ef65a5fc241f6f69", + "assets/build/ba_data/audio/operaSingerFall.ogg": "https://files.ballistica.net/cache/ba1/31/87/7a3b7d9a0f30b97ea4c9465b1ed6", + "assets/build/ba_data/audio/operaSingerHit1.ogg": "https://files.ballistica.net/cache/ba1/af/f5/eed5e1c078a8ebb42da718d8eb2c", + "assets/build/ba_data/audio/operaSingerHit2.ogg": "https://files.ballistica.net/cache/ba1/81/9d/d2d943aec38c910aec3cd37ca8ce", + "assets/build/ba_data/audio/orchestraHit.ogg": "https://files.ballistica.net/cache/ba1/10/52/c067809e0e67ada9f51b7df4f905", + "assets/build/ba_data/audio/orchestraHit2.ogg": "https://files.ballistica.net/cache/ba1/cf/c5/f176dba87e6b8e9d8b23f79b6875", + "assets/build/ba_data/audio/orchestraHit3.ogg": "https://files.ballistica.net/cache/ba1/22/db/069cd352d268b36532fe44863a2c", + "assets/build/ba_data/audio/orchestraHit4.ogg": "https://files.ballistica.net/cache/ba1/0d/ca/e27abfc328e28c6ef394d7ae8820", + "assets/build/ba_data/audio/orchestraHitBig1.ogg": "https://files.ballistica.net/cache/ba1/b6/8f/310a8e3b4584274806ec4a623a37", + "assets/build/ba_data/audio/orchestraHitBig2.ogg": "https://files.ballistica.net/cache/ba1/36/7f/4d6affb3c51d5ab2d1f2c8161fbf", + "assets/build/ba_data/audio/penguin1.ogg": "https://files.ballistica.net/cache/ba1/05/e8/6a85b96b711a24d6b3ed85754de6", + "assets/build/ba_data/audio/penguin2.ogg": "https://files.ballistica.net/cache/ba1/a6/1c/684a4571e1e99b214ca21d600e41", + "assets/build/ba_data/audio/penguin3.ogg": "https://files.ballistica.net/cache/ba1/79/13/d728dd568a344cc7383a88a0f05a", + "assets/build/ba_data/audio/penguin4.ogg": "https://files.ballistica.net/cache/ba1/2d/f2/5b11c310268ef32a62b2ba4dcea2", + "assets/build/ba_data/audio/penguinDeath.ogg": "https://files.ballistica.net/cache/ba1/df/68/cd8363872bcef0b18d509685e3d0", + "assets/build/ba_data/audio/penguinFall.ogg": "https://files.ballistica.net/cache/ba1/a3/bb/28be81b10af2e47443e55e114878", + "assets/build/ba_data/audio/penguinHit1.ogg": "https://files.ballistica.net/cache/ba1/11/3a/9cd37ea4d2d61015c395d0e33815", + "assets/build/ba_data/audio/penguinHit2.ogg": "https://files.ballistica.net/cache/ba1/d2/5f/115f8eb45fff640967df5749383c", + "assets/build/ba_data/audio/pixie1.ogg": "https://files.ballistica.net/cache/ba1/f6/d6/8a1395d4d7305e8633f6e1caf0fb", + "assets/build/ba_data/audio/pixie2.ogg": "https://files.ballistica.net/cache/ba1/c0/5b/d0d2547b0887b7d7bbd81500b89a", + "assets/build/ba_data/audio/pixie3.ogg": "https://files.ballistica.net/cache/ba1/95/23/77e22310dd9377bb7a3444ac2bd7", + "assets/build/ba_data/audio/pixie4.ogg": "https://files.ballistica.net/cache/ba1/05/8b/81cf7b359746d76c762e2fd6004d", + "assets/build/ba_data/audio/pixieDeath.ogg": "https://files.ballistica.net/cache/ba1/e7/be/8a191fa33b425029a7e13625fa91", + "assets/build/ba_data/audio/pixieFall.ogg": "https://files.ballistica.net/cache/ba1/d5/64/34231aa7e9d336fa462cfaaec999", + "assets/build/ba_data/audio/pixieHit1.ogg": "https://files.ballistica.net/cache/ba1/e3/05/08b1c6f7e5906e6cb992dfbe514b", + "assets/build/ba_data/audio/pixieHit2.ogg": "https://files.ballistica.net/cache/ba1/ec/3f/c663c857d7530f216052ce814e97", + "assets/build/ba_data/audio/playerDeath.ogg": "https://files.ballistica.net/cache/ba1/96/a2/1e632a728ef300bcae2ff2d717a6", + "assets/build/ba_data/audio/playerLeft.ogg": "https://files.ballistica.net/cache/ba1/79/d8/7713140a3ede3b65e3bcdcba7d26", + "assets/build/ba_data/audio/pop01.ogg": "https://files.ballistica.net/cache/ba1/cc/48/4c7972a8ec6e7dbecc50debf05c9", + "assets/build/ba_data/audio/powerdown01.ogg": "https://files.ballistica.net/cache/ba1/a8/6d/9302b1a73bcbd9764f41875d7380", + "assets/build/ba_data/audio/powerup01.ogg": "https://files.ballistica.net/cache/ba1/fb/d4/deac2edc909c60ca651080a53794", + "assets/build/ba_data/audio/punch01.ogg": "https://files.ballistica.net/cache/ba1/55/4c/c31706350cfbb2a86af697848dab", + "assets/build/ba_data/audio/punchStrong01.ogg": "https://files.ballistica.net/cache/ba1/0d/7a/f1da7cbbd0597e5854a66efc2a88", + "assets/build/ba_data/audio/punchStrong02.ogg": "https://files.ballistica.net/cache/ba1/4e/c0/e100a891c673a56deeee605602b3", + "assets/build/ba_data/audio/punchSwish.ogg": "https://files.ballistica.net/cache/ba1/11/0c/d80e4d0842595fdc0923c4195ceb", + "assets/build/ba_data/audio/punchWeak01.ogg": "https://files.ballistica.net/cache/ba1/20/d3/08715bb8a195bc632c477469aed1", + "assets/build/ba_data/audio/raceBeep1.ogg": "https://files.ballistica.net/cache/ba1/53/5d/c54ae886ee8f56d3bb060fb0dfcb", + "assets/build/ba_data/audio/raceBeep2.ogg": "https://files.ballistica.net/cache/ba1/96/bc/455cf8d28acb205d13f01d4900bc", + "assets/build/ba_data/audio/refWhistle.ogg": "https://files.ballistica.net/cache/ba1/87/77/008ed6d8eac37f8b5aeabd8879c7", + "assets/build/ba_data/audio/robot1.ogg": "https://files.ballistica.net/cache/ba1/18/86/1ff23c315df417652e854b440c34", + "assets/build/ba_data/audio/robot2.ogg": "https://files.ballistica.net/cache/ba1/88/85/9f0ccaf6facb14a0a17d5ec89160", + "assets/build/ba_data/audio/robot3.ogg": "https://files.ballistica.net/cache/ba1/ac/92/647c8b99c83c1230d0709a27107b", + "assets/build/ba_data/audio/robot4.ogg": "https://files.ballistica.net/cache/ba1/ac/1e/6d1decef47d1fe68c36373f44cb4", + "assets/build/ba_data/audio/robotDeath.ogg": "https://files.ballistica.net/cache/ba1/0e/89/8e8dc3869dfa1349cfe6f400bd82", + "assets/build/ba_data/audio/robotFall.ogg": "https://files.ballistica.net/cache/ba1/02/d9/60eddc36b7ee6fbb02ae1ddb6b9e", + "assets/build/ba_data/audio/robotHit1.ogg": "https://files.ballistica.net/cache/ba1/eb/e2/f7f1492bd1ef17599b4253dea8e1", + "assets/build/ba_data/audio/robotHit2.ogg": "https://files.ballistica.net/cache/ba1/72/c3/3c9343953f884808f5452e6c7a1e", + "assets/build/ba_data/audio/runAwayMusic.ogg": "https://files.ballistica.net/cache/ba1/5a/d2/8dd3ec953d5a99a454250cee0cf2", + "assets/build/ba_data/audio/santa01.ogg": "https://files.ballistica.net/cache/ba1/f4/a4/18b599e1a8d2030e5ac71f57caad", + "assets/build/ba_data/audio/santa02.ogg": "https://files.ballistica.net/cache/ba1/c2/68/5bf7fc6c40706a830fa8feafd76d", + "assets/build/ba_data/audio/santa03.ogg": "https://files.ballistica.net/cache/ba1/0f/79/5ba921fe0af18aadc66b56443cd1", + "assets/build/ba_data/audio/santa04.ogg": "https://files.ballistica.net/cache/ba1/c7/7c/99c0b38cd9b457eafcc933efe0c4", + "assets/build/ba_data/audio/santa05.ogg": "https://files.ballistica.net/cache/ba1/e3/2f/03b8d771be498553d76dc3e1ca77", + "assets/build/ba_data/audio/santaDeath.ogg": "https://files.ballistica.net/cache/ba1/af/d2/17ef3bd225d342711fdaeaa13292", + "assets/build/ba_data/audio/santaFall.ogg": "https://files.ballistica.net/cache/ba1/3a/35/e7fd2c83bfa02fb4ef12226093bc", + "assets/build/ba_data/audio/santaHit01.ogg": "https://files.ballistica.net/cache/ba1/e5/a3/8212320d1f05b0abc8219f15283f", + "assets/build/ba_data/audio/santaHit02.ogg": "https://files.ballistica.net/cache/ba1/3f/56/d4f4afae2fe9f7d47fa57b2234c4", + "assets/build/ba_data/audio/santaHit03.ogg": "https://files.ballistica.net/cache/ba1/1d/63/5ba4653014fbc2885db708afd1ae", + "assets/build/ba_data/audio/santaHit04.ogg": "https://files.ballistica.net/cache/ba1/9c/fe/f0a5d119bf94ecd4547e81f12d7d", + "assets/build/ba_data/audio/scamper01.ogg": "https://files.ballistica.net/cache/ba1/b0/c0/77de611e53981f058e85d9d747b3", + "assets/build/ba_data/audio/scaryMusic.ogg": "https://files.ballistica.net/cache/ba1/62/a4/3f9af814e9a4796e994bde555a8f", + "assets/build/ba_data/audio/score.ogg": "https://files.ballistica.net/cache/ba1/5e/94/05dc50f166c99202a4aa2d106fff", + "assets/build/ba_data/audio/scoreHit01.ogg": "https://files.ballistica.net/cache/ba1/81/97/4ffd5ba4357e44df8f3ec37d75ed", + "assets/build/ba_data/audio/scoreHit02.ogg": "https://files.ballistica.net/cache/ba1/74/eb/220feb610faafde1e4601ff1dc65", + "assets/build/ba_data/audio/scoreIncrease.ogg": "https://files.ballistica.net/cache/ba1/cd/31/7ea93db05ec08d109bc53ff27114", + "assets/build/ba_data/audio/scoresEpicMusic.ogg": "https://files.ballistica.net/cache/ba1/16/63/0f6f47b8335573ae995d48671761", + "assets/build/ba_data/audio/shatter.ogg": "https://files.ballistica.net/cache/ba1/8c/10/27917e07d416be160445fbc51b30", + "assets/build/ba_data/audio/shieldDown.ogg": "https://files.ballistica.net/cache/ba1/f3/d8/039af57511dcf0c6a357a8607e31", + "assets/build/ba_data/audio/shieldHit.ogg": "https://files.ballistica.net/cache/ba1/ac/d8/191e528070dcfae914b1cd3a9ac3", + "assets/build/ba_data/audio/shieldUp.ogg": "https://files.ballistica.net/cache/ba1/eb/26/0d5329d330ee90542e8f7827ae9f", + "assets/build/ba_data/audio/skid01.ogg": "https://files.ballistica.net/cache/ba1/4f/0b/e12f1bd0b6e6b6246d5367ba492b", + "assets/build/ba_data/audio/slowEpicMusic.ogg": "https://files.ballistica.net/cache/ba1/5c/2e/7aa87fc4557c43009247e89d1a7e", + "assets/build/ba_data/audio/sparkle01.ogg": "https://files.ballistica.net/cache/ba1/06/97/865ba23d8393f0a6856e5ff9fa9f", + "assets/build/ba_data/audio/sparkle02.ogg": "https://files.ballistica.net/cache/ba1/e9/34/c7306677c23abe96b25005c4b227", + "assets/build/ba_data/audio/sparkle03.ogg": "https://files.ballistica.net/cache/ba1/fc/40/5883d06dc893f796276288494cda", + "assets/build/ba_data/audio/spawn.ogg": "https://files.ballistica.net/cache/ba1/1c/ad/832c7ca8efbd1933d05994b7f97c", + "assets/build/ba_data/audio/spazAttack01.ogg": "https://files.ballistica.net/cache/ba1/d0/af/5bba53f113f3ddd418da226a6383", + "assets/build/ba_data/audio/spazAttack02.ogg": "https://files.ballistica.net/cache/ba1/5c/99/cc38e0ef3afdce2e8957af33b100", + "assets/build/ba_data/audio/spazAttack03.ogg": "https://files.ballistica.net/cache/ba1/3c/1d/8c2d8fb2481e760da082cb976b40", + "assets/build/ba_data/audio/spazAttack04.ogg": "https://files.ballistica.net/cache/ba1/18/7c/d502771339dd6e0ac3425325ef7c", + "assets/build/ba_data/audio/spazDeath01.ogg": "https://files.ballistica.net/cache/ba1/41/96/bef46473014670f54ef9ea16df16", + "assets/build/ba_data/audio/spazEff.ogg": "https://files.ballistica.net/cache/ba1/70/72/d84808938005033bba5ca6955fef", + "assets/build/ba_data/audio/spazFall01.ogg": "https://files.ballistica.net/cache/ba1/aa/76/a7b3444ea49ff74f509108a22a66", + "assets/build/ba_data/audio/spazImpact01.ogg": "https://files.ballistica.net/cache/ba1/47/f1/58a6e673edfee76a535959ac574b", + "assets/build/ba_data/audio/spazImpact02.ogg": "https://files.ballistica.net/cache/ba1/1f/ca/ceb0cfe82f3269ecb595647d01f5", + "assets/build/ba_data/audio/spazImpact03.ogg": "https://files.ballistica.net/cache/ba1/7d/8a/6b5cb7d301808eb014a37e9b6d8f", + "assets/build/ba_data/audio/spazImpact04.ogg": "https://files.ballistica.net/cache/ba1/ad/32/6a3f980d5336cee41807efe6a9d6", + "assets/build/ba_data/audio/spazJump01.ogg": "https://files.ballistica.net/cache/ba1/77/b1/1478ab4c054f555d83f1a49d64b2", + "assets/build/ba_data/audio/spazJump02.ogg": "https://files.ballistica.net/cache/ba1/c3/70/f0acbf2c0916b2ac67b821c91372", + "assets/build/ba_data/audio/spazJump03.ogg": "https://files.ballistica.net/cache/ba1/cc/2c/66a30feb9b4781c8fbde12010ef5", + "assets/build/ba_data/audio/spazJump04.ogg": "https://files.ballistica.net/cache/ba1/91/83/cdcc15feadbd08dd4d899534ecf7", + "assets/build/ba_data/audio/spazOw.ogg": "https://files.ballistica.net/cache/ba1/1e/81/dc0302757a2d0ce8efbed226ce9e", + "assets/build/ba_data/audio/spazPickup01.ogg": "https://files.ballistica.net/cache/ba1/93/bf/c9b53b241bbec978c772c7e14caa", + "assets/build/ba_data/audio/spazScream01.ogg": "https://files.ballistica.net/cache/ba1/79/20/eb98e70397b0cd98149952753ef1", + "assets/build/ba_data/audio/splatter.ogg": "https://files.ballistica.net/cache/ba1/be/05/35059cebfb5658f7d434d32c94d1", + "assets/build/ba_data/audio/sportsMusic.ogg": "https://files.ballistica.net/cache/ba1/ff/cc/ba30edcc58ecc75ad4cf9f13e987", + "assets/build/ba_data/audio/stickyImpact.ogg": "https://files.ballistica.net/cache/ba1/5a/1c/bcfb5574c3ba2b8aec3d04d5937b", + "assets/build/ba_data/audio/superPunch.ogg": "https://files.ballistica.net/cache/ba1/ab/05/7ccdbb7ec4dc2da7e519644b7ab1", + "assets/build/ba_data/audio/superhero1.ogg": "https://files.ballistica.net/cache/ba1/2d/4b/d07a04dba349620a7b4f22e2340c", + "assets/build/ba_data/audio/superhero2.ogg": "https://files.ballistica.net/cache/ba1/35/b3/cf4479013786a22f2d378a998a15", + "assets/build/ba_data/audio/superhero3.ogg": "https://files.ballistica.net/cache/ba1/09/24/9aaf558d4eefad33845179b001f1", + "assets/build/ba_data/audio/superhero4.ogg": "https://files.ballistica.net/cache/ba1/3f/8e/219bab660637500a61f5be205b99", + "assets/build/ba_data/audio/superheroDeath.ogg": "https://files.ballistica.net/cache/ba1/d8/65/a0c7dc72b3a900ee3e9fc3a6c703", + "assets/build/ba_data/audio/superheroFall.ogg": "https://files.ballistica.net/cache/ba1/ba/21/c92b72275739cf682fe687fff10a", + "assets/build/ba_data/audio/superheroHit1.ogg": "https://files.ballistica.net/cache/ba1/fc/23/e15bb8d3e6daf77b4e393123d6f7", + "assets/build/ba_data/audio/superheroHit2.ogg": "https://files.ballistica.net/cache/ba1/f4/05/e2719c56ac77f3db1be03a0feac8", + "assets/build/ba_data/audio/survivalMusic.ogg": "https://files.ballistica.net/cache/ba1/69/45/5993fb4a9b6caba465feae60e3aa", + "assets/build/ba_data/audio/swip.ogg": "https://files.ballistica.net/cache/ba1/b2/fe/1a0796807eeb42160aeed59622f7", + "assets/build/ba_data/audio/swip2.ogg": "https://files.ballistica.net/cache/ba1/08/3d/12d4291235d240dd7e44dbe7f283", + "assets/build/ba_data/audio/swish.ogg": "https://files.ballistica.net/cache/ba1/33/41/3648e08fa50e2cf876f6ffa7fb3e", + "assets/build/ba_data/audio/swish2.ogg": "https://files.ballistica.net/cache/ba1/cc/67/8294681a9e9a88d055f33022a41f", + "assets/build/ba_data/audio/swish3.ogg": "https://files.ballistica.net/cache/ba1/06/35/7e03c8300a493d9c6ec4185b62fb", + "assets/build/ba_data/audio/tap.ogg": "https://files.ballistica.net/cache/ba1/30/7f/9f2a2aabfc63dfdb3e93106f3835", + "assets/build/ba_data/audio/technoHit01.ogg": "https://files.ballistica.net/cache/ba1/61/8a/d322dc58f7f41f34f2937a3879cf", + "assets/build/ba_data/audio/tick.ogg": "https://files.ballistica.net/cache/ba1/f5/cf/722bc46de90a550cab9ca11dd076", + "assets/build/ba_data/audio/ticking.ogg": "https://files.ballistica.net/cache/ba1/fb/55/55e5508fc180a67b2730d731856b", + "assets/build/ba_data/audio/tickingCrazy.ogg": "https://files.ballistica.net/cache/ba1/75/1c/43cea75988866fe0674883d70e08", + "assets/build/ba_data/audio/toTheDeathMusic.ogg": "https://files.ballistica.net/cache/ba1/ee/9a/9d2459da2a3fa0fbc977c639c5c6", + "assets/build/ba_data/audio/trashRummage.ogg": "https://files.ballistica.net/cache/ba1/ce/93/0e1b7d2155bcaccb585b3bcbf8b6", + "assets/build/ba_data/audio/victoryMusic.ogg": "https://files.ballistica.net/cache/ba1/6a/a7/0cf20971661de58dd3ee118856dc", + "assets/build/ba_data/audio/warnBeep.ogg": "https://files.ballistica.net/cache/ba1/51/ab/710c0882ab078f155ee574e124f4", + "assets/build/ba_data/audio/warnBeeps.ogg": "https://files.ballistica.net/cache/ba1/bc/b4/fed2b34f7ec47465b637b49e69fa", + "assets/build/ba_data/audio/warrior1.ogg": "https://files.ballistica.net/cache/ba1/fc/29/a88557dabe502eaa1f4e61e66050", + "assets/build/ba_data/audio/warrior2.ogg": "https://files.ballistica.net/cache/ba1/f1/37/cb391e6b920f278c5b007b381388", + "assets/build/ba_data/audio/warrior3.ogg": "https://files.ballistica.net/cache/ba1/8c/2e/d7c4c7a599a3a368f2d95f247127", + "assets/build/ba_data/audio/warrior4.ogg": "https://files.ballistica.net/cache/ba1/07/51/4796e3f9f9de9c5566740e951222", + "assets/build/ba_data/audio/warriorDeath.ogg": "https://files.ballistica.net/cache/ba1/d9/b6/c2e7f4a83928534e285f7ce1c922", + "assets/build/ba_data/audio/warriorFall.ogg": "https://files.ballistica.net/cache/ba1/2d/c5/ba39d507aa20f054feda013a9f21", + "assets/build/ba_data/audio/warriorHit1.ogg": "https://files.ballistica.net/cache/ba1/4f/83/1cbd4d2fb3e94e5e25979ed097ca", + "assets/build/ba_data/audio/warriorHit2.ogg": "https://files.ballistica.net/cache/ba1/be/ac/36bf2226134a7d319fd12fd6b28a", + "assets/build/ba_data/audio/whenJohnnyComesMarchingHomeMusic.ogg": "https://files.ballistica.net/cache/ba1/08/b1/21ee18cb2db336861c5a04d86f45", + "assets/build/ba_data/audio/witch1.ogg": "https://files.ballistica.net/cache/ba1/67/4e/05132bdb446fbdc1e1915089763b", + "assets/build/ba_data/audio/witch2.ogg": "https://files.ballistica.net/cache/ba1/57/a2/141d27861ab6a6177337d422e428", + "assets/build/ba_data/audio/witch3.ogg": "https://files.ballistica.net/cache/ba1/41/13/88fe3efdbc6b300ea74b8db0c816", + "assets/build/ba_data/audio/witch4.ogg": "https://files.ballistica.net/cache/ba1/1e/6a/67aaa75635a97116ca7bb5761051", + "assets/build/ba_data/audio/witchDeath.ogg": "https://files.ballistica.net/cache/ba1/22/33/2c7098263df931564f14815be5e8", + "assets/build/ba_data/audio/witchFall.ogg": "https://files.ballistica.net/cache/ba1/54/1c/d2de34a6985d56b469f10b7560ef", + "assets/build/ba_data/audio/witchHit1.ogg": "https://files.ballistica.net/cache/ba1/ae/24/430389e6bafba567a096b55228e6", + "assets/build/ba_data/audio/witchHit2.ogg": "https://files.ballistica.net/cache/ba1/c1/56/89955e8ab2fabaa5ff989bdf299e", + "assets/build/ba_data/audio/wizard1.ogg": "https://files.ballistica.net/cache/ba1/ff/6a/f81dc1a4656c6dffd1a36216d1b8", + "assets/build/ba_data/audio/wizard2.ogg": "https://files.ballistica.net/cache/ba1/52/43/f0e9af1d49b8d20bf561f8f9d3a9", + "assets/build/ba_data/audio/wizard3.ogg": "https://files.ballistica.net/cache/ba1/50/ba/716520f2f0137d8f86410a6089fb", + "assets/build/ba_data/audio/wizard4.ogg": "https://files.ballistica.net/cache/ba1/50/cc/2d239102cdc2ace02e79d8b0879c", + "assets/build/ba_data/audio/wizardDeath.ogg": "https://files.ballistica.net/cache/ba1/bb/4c/5e4dc54df830187c63a2bc7922b6", + "assets/build/ba_data/audio/wizardFall.ogg": "https://files.ballistica.net/cache/ba1/25/a5/21d69464843cb9f067541383468d", + "assets/build/ba_data/audio/wizardHit1.ogg": "https://files.ballistica.net/cache/ba1/10/47/be3966c620333be4ca9c30e1a2c4", + "assets/build/ba_data/audio/wizardHit2.ogg": "https://files.ballistica.net/cache/ba1/40/9a/0aed7b1bff3e69c257099ac26c1d", + "assets/build/ba_data/audio/woodDebrisFall.ogg": "https://files.ballistica.net/cache/ba1/94/03/59046559bc61e1e4b01078e778dd", + "assets/build/ba_data/audio/wrestler1.ogg": "https://files.ballistica.net/cache/ba1/52/71/c84d34f895c64d2fb38d880c737e", + "assets/build/ba_data/audio/wrestler2.ogg": "https://files.ballistica.net/cache/ba1/81/1f/c93c1b89d8d434fe84985d7d1af0", + "assets/build/ba_data/audio/wrestler3.ogg": "https://files.ballistica.net/cache/ba1/d8/2e/af82c6b47d77e9fa91b431ae03d1", + "assets/build/ba_data/audio/wrestler4.ogg": "https://files.ballistica.net/cache/ba1/7b/28/3aab8e16de76fc7453ed1e0886a8", + "assets/build/ba_data/audio/wrestlerDeath.ogg": "https://files.ballistica.net/cache/ba1/ae/b3/090c2525c3f697450a142458f6dc", + "assets/build/ba_data/audio/wrestlerFall.ogg": "https://files.ballistica.net/cache/ba1/1f/15/15fb12bb80fa7363b2ba88a4dce3", + "assets/build/ba_data/audio/wrestlerHit1.ogg": "https://files.ballistica.net/cache/ba1/90/b6/403ede16b60bdf089ce92079ef65", + "assets/build/ba_data/audio/wrestlerHit2.ogg": "https://files.ballistica.net/cache/ba1/d8/f7/4b4104842d9a408a9bb757cebabf", + "assets/build/ba_data/audio/zoeAttack01.ogg": "https://files.ballistica.net/cache/ba1/22/66/786bb399ac6bfc406f8fb0f6b3b4", + "assets/build/ba_data/audio/zoeAttack02.ogg": "https://files.ballistica.net/cache/ba1/37/42/60be96146c62bb29b10efae99fbe", + "assets/build/ba_data/audio/zoeAttack03.ogg": "https://files.ballistica.net/cache/ba1/0d/1f/9a71c8ce2aa31ffc2bdaa3341aed", + "assets/build/ba_data/audio/zoeAttack04.ogg": "https://files.ballistica.net/cache/ba1/52/e2/97d0299a564d2b7454fb742d5aab", + "assets/build/ba_data/audio/zoeDeath01.ogg": "https://files.ballistica.net/cache/ba1/fa/aa/f622e55e348e145955e27a4c3e57", + "assets/build/ba_data/audio/zoeEff.ogg": "https://files.ballistica.net/cache/ba1/42/c3/0bf8991471b650a1d2cd320c5ce3", + "assets/build/ba_data/audio/zoeFall01.ogg": "https://files.ballistica.net/cache/ba1/9e/12/ce19febfcbf2b43eb733dbd1626b", + "assets/build/ba_data/audio/zoeImpact01.ogg": "https://files.ballistica.net/cache/ba1/01/8c/90ab117e9c73fc33d556d18b079a", + "assets/build/ba_data/audio/zoeImpact02.ogg": "https://files.ballistica.net/cache/ba1/01/69/21c09400f109285b9d8cb8814d69", + "assets/build/ba_data/audio/zoeImpact03.ogg": "https://files.ballistica.net/cache/ba1/61/72/5bf11492feba95994f75040e36ce", + "assets/build/ba_data/audio/zoeImpact04.ogg": "https://files.ballistica.net/cache/ba1/c1/b1/a1159e8caeb1f5b80fcff55e8244", + "assets/build/ba_data/audio/zoeJump01.ogg": "https://files.ballistica.net/cache/ba1/b1/f0/5220fdb723a42e9177a99f9f5bdc", + "assets/build/ba_data/audio/zoeJump02.ogg": "https://files.ballistica.net/cache/ba1/71/01/4b2e5d9e2fcdfba254290c71a002", + "assets/build/ba_data/audio/zoeJump03.ogg": "https://files.ballistica.net/cache/ba1/66/3b/8ffff9c3d0280b7d1a15c92dfa94", + "assets/build/ba_data/audio/zoeOw.ogg": "https://files.ballistica.net/cache/ba1/60/ad/38269b7f1c7dc20cb9a506cd0681", + "assets/build/ba_data/audio/zoePickup01.ogg": "https://files.ballistica.net/cache/ba1/72/85/d6fc4d16b7081d91fba2850b5b10", + "assets/build/ba_data/audio/zoeScream01.ogg": "https://files.ballistica.net/cache/ba1/e9/ae/1d674d0c086eaa0bd1c3b1db0505", "assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/df/d4/b9814c484722df1380894b9f8661", "assets/build/ba_data/data/languages/arabic.json": "https://files.ballistica.net/cache/ba1/c5/81/e386a592e4fdf702b9089f106610", "assets/build/ba_data/data/languages/belarussian.json": "https://files.ballistica.net/cache/ba1/61/03/89070ca765e06da3a419a579f503", @@ -1073,7 +1073,7 @@ "assets/build/ba_data/textures/actionHeroColor.dds": "https://files.ballistica.net/cache/ba1/62/91/355fa26219c26750e46ad358dbc7", "assets/build/ba_data/textures/actionHeroColor.ktx": "https://files.ballistica.net/cache/ba1/01/ce/95415b6b29f60015900b2f33db42", "assets/build/ba_data/textures/actionHeroColor.pvr": "https://files.ballistica.net/cache/ba1/0d/03/832309d85531d4be991b6f7a9107", - "assets/build/ba_data/textures/actionHeroColorMask.dds": "https://files.ballistica.net/cache/ba1/7d/8d/5b94b6e589f7f67ecc310e2cfa3c", + "assets/build/ba_data/textures/actionHeroColorMask.dds": "https://files.ballistica.net/cache/ba1/5c/c0/7f52de795a1f08ffa72030cf9178", "assets/build/ba_data/textures/actionHeroColorMask.ktx": "https://files.ballistica.net/cache/ba1/07/ed/6791e01ac69bb61cdffade59808f", "assets/build/ba_data/textures/actionHeroColorMask.pvr": "https://files.ballistica.net/cache/ba1/22/40/d50cbe4fa13a3294638bb1b42c72", "assets/build/ba_data/textures/actionHeroColorMask_preview.png": "https://files.ballistica.net/cache/ba1/83/2f/9a009e8f2cc9b956043511db105c", @@ -1090,15 +1090,15 @@ "assets/build/ba_data/textures/advancedIcon.ktx": "https://files.ballistica.net/cache/ba1/87/6d/1758aaf14120f6c418e2ecdb410f", "assets/build/ba_data/textures/advancedIcon.pvr": "https://files.ballistica.net/cache/ba1/39/00/237c07cd4a239ca69f90ba571e07", "assets/build/ba_data/textures/advancedIcon_preview.png": "https://files.ballistica.net/cache/ba1/21/d5/3a3a834112b84befe910c15df2b6", - "assets/build/ba_data/textures/agentColor.dds": "https://files.ballistica.net/cache/ba1/17/c2/2a9cc0d3c88e048cce4e75880328", + "assets/build/ba_data/textures/agentColor.dds": "https://files.ballistica.net/cache/ba1/05/19/15d35284e062e8d037dfece71af5", "assets/build/ba_data/textures/agentColor.ktx": "https://files.ballistica.net/cache/ba1/ff/8a/3e375971f932cba1e4c8800129e8", "assets/build/ba_data/textures/agentColor.pvr": "https://files.ballistica.net/cache/ba1/f8/3a/438fae77e7ad607345ff883c272d", - "assets/build/ba_data/textures/agentColorMask.dds": "https://files.ballistica.net/cache/ba1/4f/ab/db5c3baed96dbec309c33ca13258", + "assets/build/ba_data/textures/agentColorMask.dds": "https://files.ballistica.net/cache/ba1/dc/b1/a5a98e27864377a91452abcfba66", "assets/build/ba_data/textures/agentColorMask.ktx": "https://files.ballistica.net/cache/ba1/64/9a/255eeabf2f4a5626d478b41f2268", "assets/build/ba_data/textures/agentColorMask.pvr": "https://files.ballistica.net/cache/ba1/6a/d2/7a311a8525c02f7c8edb974e9651", "assets/build/ba_data/textures/agentColorMask_preview.png": "https://files.ballistica.net/cache/ba1/78/ec/c4ddf22b95d893fa467412334ff5", "assets/build/ba_data/textures/agentColor_preview.png": "https://files.ballistica.net/cache/ba1/9f/1b/1c128a69900d438c220ca7885dc7", - "assets/build/ba_data/textures/agentIcon.dds": "https://files.ballistica.net/cache/ba1/64/37/c020b7e02cf7a7b90eec2e094395", + "assets/build/ba_data/textures/agentIcon.dds": "https://files.ballistica.net/cache/ba1/b4/ea/bc2ed456f6536711e03d292121fa", "assets/build/ba_data/textures/agentIcon.ktx": "https://files.ballistica.net/cache/ba1/eb/1e/e73199f7c33e9002e92fe363a23b", "assets/build/ba_data/textures/agentIcon.pvr": "https://files.ballistica.net/cache/ba1/5e/2d/e18e2133517fdcc8cb7ac28b31a8", "assets/build/ba_data/textures/agentIconColorMask.dds": "https://files.ballistica.net/cache/ba1/b1/9a/ecb2300afababd460ca4bae36d96", @@ -1106,11 +1106,11 @@ "assets/build/ba_data/textures/agentIconColorMask.pvr": "https://files.ballistica.net/cache/ba1/22/24/8aadc852761e3f2c0fbf9d2f025a", "assets/build/ba_data/textures/agentIconColorMask_preview.png": "https://files.ballistica.net/cache/ba1/e2/02/85032b1257accbb85ad1904018ef", "assets/build/ba_data/textures/agentIcon_preview.png": "https://files.ballistica.net/cache/ba1/49/70/68d243aeff2de4e474e9a22ee6ef", - "assets/build/ba_data/textures/aliBSRemoteIOSQR.dds": "https://files.ballistica.net/cache/ba1/32/c7/d95e248a28236f7495f285a9e65f", + "assets/build/ba_data/textures/aliBSRemoteIOSQR.dds": "https://files.ballistica.net/cache/ba1/b7/69/9c4a96ceb3f84c6670355cac136d", "assets/build/ba_data/textures/aliBSRemoteIOSQR.ktx": "https://files.ballistica.net/cache/ba1/10/a6/2cc21c0bae6eb45208974d8b1f60", "assets/build/ba_data/textures/aliBSRemoteIOSQR.pvr": "https://files.ballistica.net/cache/ba1/56/8f/3f31426a93b70d4c1c7c54050473", "assets/build/ba_data/textures/aliBSRemoteIOSQR_preview.png": "https://files.ballistica.net/cache/ba1/96/d8/d37b845efc618616a8e1fd0dd04b", - "assets/build/ba_data/textures/aliColor.dds": "https://files.ballistica.net/cache/ba1/d8/6d/edff4cac631ca75db279ccfb1399", + "assets/build/ba_data/textures/aliColor.dds": "https://files.ballistica.net/cache/ba1/54/17/1d3b7c4d9577908ed773ad11dad2", "assets/build/ba_data/textures/aliColor.ktx": "https://files.ballistica.net/cache/ba1/ed/f3/3005b276e2b231be8170102c1cd7", "assets/build/ba_data/textures/aliColor.pvr": "https://files.ballistica.net/cache/ba1/f3/bd/2c82648f6ef242ca4b34fd278629", "assets/build/ba_data/textures/aliColorMask.dds": "https://files.ballistica.net/cache/ba1/68/bb/c7db9f1886a6d3fd5cdb308f3cef", @@ -1118,14 +1118,14 @@ "assets/build/ba_data/textures/aliColorMask.pvr": "https://files.ballistica.net/cache/ba1/31/2a/ddb2a68bdfb3b175be2d3d6bcade", "assets/build/ba_data/textures/aliColorMask_preview.png": "https://files.ballistica.net/cache/ba1/3b/05/0dd47cdf3a3ac437e5e276f5fd86", "assets/build/ba_data/textures/aliColor_preview.png": "https://files.ballistica.net/cache/ba1/cb/93/d9230bee0324b2eec4bb8519dae3", - "assets/build/ba_data/textures/aliControllerQR.dds": "https://files.ballistica.net/cache/ba1/68/f4/742194ee422ce66e9c0c4c7a2c66", + "assets/build/ba_data/textures/aliControllerQR.dds": "https://files.ballistica.net/cache/ba1/55/0a/44ecb9f5cf4e5c02b83089d0d13b", "assets/build/ba_data/textures/aliControllerQR.ktx": "https://files.ballistica.net/cache/ba1/56/50/6d84e5b788b25b4e7275d20ce635", "assets/build/ba_data/textures/aliControllerQR.pvr": "https://files.ballistica.net/cache/ba1/22/8d/34c3d66662866cc806c81ee13517", "assets/build/ba_data/textures/aliControllerQR_preview.png": "https://files.ballistica.net/cache/ba1/59/83/a2dce8f9ec55f87cf450813a31c1", - "assets/build/ba_data/textures/aliIcon.dds": "https://files.ballistica.net/cache/ba1/a0/a6/f4fc06a5e3967f1cfc35eb627706", + "assets/build/ba_data/textures/aliIcon.dds": "https://files.ballistica.net/cache/ba1/bf/c9/ad39ef333825bbd5d6f5462d1a11", "assets/build/ba_data/textures/aliIcon.ktx": "https://files.ballistica.net/cache/ba1/d1/ee/7c1c37d57cdb70d854ecdfb235ed", "assets/build/ba_data/textures/aliIcon.pvr": "https://files.ballistica.net/cache/ba1/b6/04/931fbed4b2a9c75ae7745a88ed40", - "assets/build/ba_data/textures/aliIconColorMask.dds": "https://files.ballistica.net/cache/ba1/64/09/2fdf334c8cb3661bdbecdd2d2dd4", + "assets/build/ba_data/textures/aliIconColorMask.dds": "https://files.ballistica.net/cache/ba1/58/bc/04f52451d42f051acb8409ab965b", "assets/build/ba_data/textures/aliIconColorMask.ktx": "https://files.ballistica.net/cache/ba1/78/89/c3e95a7c3794e4c86ece540aa3a3", "assets/build/ba_data/textures/aliIconColorMask.pvr": "https://files.ballistica.net/cache/ba1/7a/81/d269ece740203c2e1a9a3c9523af", "assets/build/ba_data/textures/aliIconColorMask_preview.png": "https://files.ballistica.net/cache/ba1/0f/8d/203f6ec0ff5a8dd380330a0f3853", @@ -1137,7 +1137,7 @@ "assets/build/ba_data/textures/alienColor.dds": "https://files.ballistica.net/cache/ba1/b3/63/1ec79e210306f871f4d24b7a005e", "assets/build/ba_data/textures/alienColor.ktx": "https://files.ballistica.net/cache/ba1/97/fe/96c9ab440866a08d2510109eaaff", "assets/build/ba_data/textures/alienColor.pvr": "https://files.ballistica.net/cache/ba1/39/dc/bb457bc12cd61482e2c7edfa457c", - "assets/build/ba_data/textures/alienColorMask.dds": "https://files.ballistica.net/cache/ba1/12/8c/4b32a6cb77e2d4b840b7fd19ec8a", + "assets/build/ba_data/textures/alienColorMask.dds": "https://files.ballistica.net/cache/ba1/ce/51/a41c4af1205bd33dc8647898e4b6", "assets/build/ba_data/textures/alienColorMask.ktx": "https://files.ballistica.net/cache/ba1/a7/3e/7759a1566e2dacd35c0a23304fc7", "assets/build/ba_data/textures/alienColorMask.pvr": "https://files.ballistica.net/cache/ba1/70/70/49e327a70992f6f2cd57a69e182b", "assets/build/ba_data/textures/alienColorMask_preview.png": "https://files.ballistica.net/cache/ba1/6a/7c/7e2fe077f46778b639b58d533ef8", @@ -1150,15 +1150,15 @@ "assets/build/ba_data/textures/alienIconColorMask.pvr": "https://files.ballistica.net/cache/ba1/0b/8a/54fa4a11a7d066ff0cbc6c741451", "assets/build/ba_data/textures/alienIconColorMask_preview.png": "https://files.ballistica.net/cache/ba1/55/bc/686e349c8557f232c6404bc22371", "assets/build/ba_data/textures/alienIcon_preview.png": "https://files.ballistica.net/cache/ba1/4c/c9/12ab7e3cf9f1af93c608ce1bcefb", - "assets/build/ba_data/textures/alwaysLandBGColor.dds": "https://files.ballistica.net/cache/ba1/3e/1e/ee38b7626761d3ead1f2fec82070", + "assets/build/ba_data/textures/alwaysLandBGColor.dds": "https://files.ballistica.net/cache/ba1/88/d6/3afdd31b573a08eb0cf3771f86bb", "assets/build/ba_data/textures/alwaysLandBGColor.ktx": "https://files.ballistica.net/cache/ba1/5a/80/c2ff48e9f0f3e549f105e926dd3d", "assets/build/ba_data/textures/alwaysLandBGColor.pvr": "https://files.ballistica.net/cache/ba1/2d/c0/c236df146c22606a3d290139e5b3", "assets/build/ba_data/textures/alwaysLandBGColor_preview.png": "https://files.ballistica.net/cache/ba1/59/9c/933c8322bf93c02968e6f440ae59", - "assets/build/ba_data/textures/alwaysLandLevelColor.dds": "https://files.ballistica.net/cache/ba1/8a/5e/a2d2c01be327dd3fc34e46706b43", + "assets/build/ba_data/textures/alwaysLandLevelColor.dds": "https://files.ballistica.net/cache/ba1/1e/da/7e0f8f4f82a9728a9996fe4b76bc", "assets/build/ba_data/textures/alwaysLandLevelColor.ktx": "https://files.ballistica.net/cache/ba1/13/bd/5458fc8068b06a20ec00d2e35c2e", "assets/build/ba_data/textures/alwaysLandLevelColor.pvr": "https://files.ballistica.net/cache/ba1/29/12/7c1b247f977a20c2d70069f95787", "assets/build/ba_data/textures/alwaysLandLevelColor_preview.png": "https://files.ballistica.net/cache/ba1/4a/61/15580dd303e1682c7c2f63e890da", - "assets/build/ba_data/textures/alwaysLandPreview.dds": "https://files.ballistica.net/cache/ba1/36/6c/c1c4fcc4464359de5403244d3e30", + "assets/build/ba_data/textures/alwaysLandPreview.dds": "https://files.ballistica.net/cache/ba1/de/5e/62854d25f37a4f2151716dcbb5e0", "assets/build/ba_data/textures/alwaysLandPreview.ktx": "https://files.ballistica.net/cache/ba1/44/1b/8985da2a7c0670089ec086237de2", "assets/build/ba_data/textures/alwaysLandPreview.pvr": "https://files.ballistica.net/cache/ba1/8b/bb/db84d43e0acd251940d39ad52622", "assets/build/ba_data/textures/alwaysLandPreview_preview.png": "https://files.ballistica.net/cache/ba1/c7/6d/d633bbe5ad1fb1478a49cc51f702", @@ -1173,7 +1173,7 @@ "assets/build/ba_data/textures/assassinColor.dds": "https://files.ballistica.net/cache/ba1/74/4c/15d8400e13ddef0e6712bf52dd6e", "assets/build/ba_data/textures/assassinColor.ktx": "https://files.ballistica.net/cache/ba1/77/1e/340bae7b1759427c0cf4ef6f200a", "assets/build/ba_data/textures/assassinColor.pvr": "https://files.ballistica.net/cache/ba1/88/27/2a6734a37b350a8fe9d4313169ae", - "assets/build/ba_data/textures/assassinColorMask.dds": "https://files.ballistica.net/cache/ba1/e2/e5/dc0bcae56faf7203eda79a9397d0", + "assets/build/ba_data/textures/assassinColorMask.dds": "https://files.ballistica.net/cache/ba1/b9/72/87c5ff1b72de68f5751140508d0e", "assets/build/ba_data/textures/assassinColorMask.ktx": "https://files.ballistica.net/cache/ba1/52/6b/126ba01cd6e6f883e0a6695aec9c", "assets/build/ba_data/textures/assassinColorMask.pvr": "https://files.ballistica.net/cache/ba1/c0/2c/5b137a905b0719022101f82f581d", "assets/build/ba_data/textures/assassinColorMask_preview.png": "https://files.ballistica.net/cache/ba1/b0/c5/cb9321a0aca799d83159479d602c", @@ -1198,7 +1198,7 @@ "assets/build/ba_data/textures/bar.ktx": "https://files.ballistica.net/cache/ba1/69/25/7c811b9c7e77e6c7d1df1a047991", "assets/build/ba_data/textures/bar.pvr": "https://files.ballistica.net/cache/ba1/1c/b7/605cdb8193d4190f3a90a173cc90", "assets/build/ba_data/textures/bar_preview.png": "https://files.ballistica.net/cache/ba1/b6/63/94b82a98ae1305b0f6b57fe32e8b", - "assets/build/ba_data/textures/bearColor.dds": "https://files.ballistica.net/cache/ba1/8d/13/f83d6f1249673ad7ba10996d0ac8", + "assets/build/ba_data/textures/bearColor.dds": "https://files.ballistica.net/cache/ba1/e3/9a/f6b129a0fe2933fb23643e71d9ef", "assets/build/ba_data/textures/bearColor.ktx": "https://files.ballistica.net/cache/ba1/62/fc/be9341da4cfa66a8ce63807a3a8e", "assets/build/ba_data/textures/bearColor.pvr": "https://files.ballistica.net/cache/ba1/c3/f7/1773a5033ab0a6689d01e0683a63", "assets/build/ba_data/textures/bearColorMask.dds": "https://files.ballistica.net/cache/ba1/38/04/166ea3d73ed0af9b285db1b7e6c0", @@ -1209,19 +1209,19 @@ "assets/build/ba_data/textures/bearIcon.dds": "https://files.ballistica.net/cache/ba1/cd/80/163ac24028fd5d8ce484040d4176", "assets/build/ba_data/textures/bearIcon.ktx": "https://files.ballistica.net/cache/ba1/01/f7/c2ef1c82862e74f74386c6341cb8", "assets/build/ba_data/textures/bearIcon.pvr": "https://files.ballistica.net/cache/ba1/87/83/c856c8fb48ba9d7a7fd9869746f2", - "assets/build/ba_data/textures/bearIconColorMask.dds": "https://files.ballistica.net/cache/ba1/60/b8/634304bf7f29d239d63dd89ce96b", + "assets/build/ba_data/textures/bearIconColorMask.dds": "https://files.ballistica.net/cache/ba1/78/c9/123f72ce037631bb8f1906b8fd92", "assets/build/ba_data/textures/bearIconColorMask.ktx": "https://files.ballistica.net/cache/ba1/ad/75/804e6901f09e75348f1d480c5ae8", "assets/build/ba_data/textures/bearIconColorMask.pvr": "https://files.ballistica.net/cache/ba1/ce/23/1fd7ce03b72db0dc6b3903d8146f", "assets/build/ba_data/textures/bearIconColorMask_preview.png": "https://files.ballistica.net/cache/ba1/72/1c/9775c5e7acec13a491299b998703", "assets/build/ba_data/textures/bearIcon_preview.png": "https://files.ballistica.net/cache/ba1/d9/d2/b74a4de7ca068c378d78c745331b", - "assets/build/ba_data/textures/bg.dds": "https://files.ballistica.net/cache/ba1/2e/60/a4e78e526ace713727738e3a5587", + "assets/build/ba_data/textures/bg.dds": "https://files.ballistica.net/cache/ba1/92/e3/7beb6a9b50408b92e02a94965664", "assets/build/ba_data/textures/bg.ktx": "https://files.ballistica.net/cache/ba1/97/6c/b965850bfa25cf9db805b921d291", "assets/build/ba_data/textures/bg.pvr": "https://files.ballistica.net/cache/ba1/11/84/be878cc8fbe77a3ffdb4cd4ce125", "assets/build/ba_data/textures/bg_preview.png": "https://files.ballistica.net/cache/ba1/6a/77/7613140be4610b02dcb0372111ed", - "assets/build/ba_data/textures/bigG.dds": "https://files.ballistica.net/cache/ba1/2e/74/5d1c4fe9f920a291846c62c7d65e", + "assets/build/ba_data/textures/bigG.dds": "https://files.ballistica.net/cache/ba1/49/34/fe6162a12af04927e4c3489dcfff", "assets/build/ba_data/textures/bigG.ktx": "https://files.ballistica.net/cache/ba1/df/1c/526de060409ebbd5235592943e94", "assets/build/ba_data/textures/bigG.pvr": "https://files.ballistica.net/cache/ba1/41/82/532ef83baefbde887504c11ce140", - "assets/build/ba_data/textures/bigGPreview.dds": "https://files.ballistica.net/cache/ba1/93/0e/842e2e3a11f71802c81a5de450a6", + "assets/build/ba_data/textures/bigGPreview.dds": "https://files.ballistica.net/cache/ba1/2b/1c/8fb6a40e7e08419473d22e23cfcc", "assets/build/ba_data/textures/bigGPreview.ktx": "https://files.ballistica.net/cache/ba1/4a/28/d3c6f8ad9f0c65cd7a422d9177dd", "assets/build/ba_data/textures/bigGPreview.pvr": "https://files.ballistica.net/cache/ba1/4f/b4/9b4069351815040b2af7c4c9b498", "assets/build/ba_data/textures/bigGPreview_preview.png": "https://files.ballistica.net/cache/ba1/4b/24/f4b442bc8ed68d6f3f740ffb19fd", @@ -1237,16 +1237,16 @@ "assets/build/ba_data/textures/bombColor.dds": "https://files.ballistica.net/cache/ba1/5e/2b/492e68d77e6be9d6399e49435a8d", "assets/build/ba_data/textures/bombColor.ktx": "https://files.ballistica.net/cache/ba1/bc/9f/c7a76334cf56bb0bb93d1f720b40", "assets/build/ba_data/textures/bombColor.pvr": "https://files.ballistica.net/cache/ba1/c7/bb/89159008de3b624bcb90b3c25568", - "assets/build/ba_data/textures/bombColorIce.dds": "https://files.ballistica.net/cache/ba1/27/d6/7790056abb3e73e7ffd01920dfb8", + "assets/build/ba_data/textures/bombColorIce.dds": "https://files.ballistica.net/cache/ba1/ab/ed/3f5a8f9f2fb8d1e60f34f1f1701b", "assets/build/ba_data/textures/bombColorIce.ktx": "https://files.ballistica.net/cache/ba1/4b/2d/c8cfa1990fa1f211de36679a3665", "assets/build/ba_data/textures/bombColorIce.pvr": "https://files.ballistica.net/cache/ba1/71/aa/3127d32782835de9fa0fab8c7395", "assets/build/ba_data/textures/bombColorIce_preview.png": "https://files.ballistica.net/cache/ba1/ec/3a/96b5191c5e7662be273c311fa826", "assets/build/ba_data/textures/bombColor_preview.png": "https://files.ballistica.net/cache/ba1/a5/65/878c8aa7876031426f5adf3aeb79", - "assets/build/ba_data/textures/bombStickyColor.dds": "https://files.ballistica.net/cache/ba1/b9/54/8e1dc631ecdb5a045441e96ea2e9", + "assets/build/ba_data/textures/bombStickyColor.dds": "https://files.ballistica.net/cache/ba1/c2/2d/cf8b630173546f03926c56258724", "assets/build/ba_data/textures/bombStickyColor.ktx": "https://files.ballistica.net/cache/ba1/be/83/f3b7ca04ca377e2df7359784d6cf", "assets/build/ba_data/textures/bombStickyColor.pvr": "https://files.ballistica.net/cache/ba1/14/a3/90a633e9edd9f826d89d2f610a0d", "assets/build/ba_data/textures/bombStickyColor_preview.png": "https://files.ballistica.net/cache/ba1/c0/98/05587d954ce791ba5caa41af943f", - "assets/build/ba_data/textures/bonesColor.dds": "https://files.ballistica.net/cache/ba1/31/d5/90d0088aa8435ff2eb9c3b79ebc0", + "assets/build/ba_data/textures/bonesColor.dds": "https://files.ballistica.net/cache/ba1/02/23/f9f6293644faaff5d3fe2f49408f", "assets/build/ba_data/textures/bonesColor.ktx": "https://files.ballistica.net/cache/ba1/51/24/beed81e702c15d04b4f94388a328", "assets/build/ba_data/textures/bonesColor.pvr": "https://files.ballistica.net/cache/ba1/84/85/d3822cbf93732d312b64dd0d2b26", "assets/build/ba_data/textures/bonesColorMask.dds": "https://files.ballistica.net/cache/ba1/9e/57/bc0c41cf259d94e11814170d0137", @@ -1266,7 +1266,7 @@ "assets/build/ba_data/textures/boxingGlovesColor.ktx": "https://files.ballistica.net/cache/ba1/9c/c1/fcb445a18de7bb2adb9c93644840", "assets/build/ba_data/textures/boxingGlovesColor.pvr": "https://files.ballistica.net/cache/ba1/93/a9/c6d48979dc6c72c70f5c39ccabff", "assets/build/ba_data/textures/boxingGlovesColor_preview.png": "https://files.ballistica.net/cache/ba1/75/d2/6056b445e3c8da206f4d7574c623", - "assets/build/ba_data/textures/bridgitLevelColor.dds": "https://files.ballistica.net/cache/ba1/04/af/6c34a515c1e52a5f9c4303683853", + "assets/build/ba_data/textures/bridgitLevelColor.dds": "https://files.ballistica.net/cache/ba1/91/ab/184a0bbeba1c1bb79d28168709be", "assets/build/ba_data/textures/bridgitLevelColor.ktx": "https://files.ballistica.net/cache/ba1/30/08/4f5fec91381abc98c3382763cad9", "assets/build/ba_data/textures/bridgitLevelColor.pvr": "https://files.ballistica.net/cache/ba1/6f/89/65a75daf364c9f3aec77c73bc343", "assets/build/ba_data/textures/bridgitLevelColor_preview.png": "https://files.ballistica.net/cache/ba1/c9/fd/7e9daa40ebce9e08d2daf07aef49", @@ -1274,7 +1274,7 @@ "assets/build/ba_data/textures/bridgitPreview.ktx": "https://files.ballistica.net/cache/ba1/d4/d9/6f936f48e988e335ee1949c2219d", "assets/build/ba_data/textures/bridgitPreview.pvr": "https://files.ballistica.net/cache/ba1/51/18/4716016fd0d40a0bb94cdac9c627", "assets/build/ba_data/textures/bridgitPreview_preview.png": "https://files.ballistica.net/cache/ba1/c8/77/01fcaf507ca7c4575a76bff62ff0", - "assets/build/ba_data/textures/bunnyColor.dds": "https://files.ballistica.net/cache/ba1/9e/30/d07e0031093130e6cbc23a135e45", + "assets/build/ba_data/textures/bunnyColor.dds": "https://files.ballistica.net/cache/ba1/fc/32/5452de45237f804355667a2584ba", "assets/build/ba_data/textures/bunnyColor.ktx": "https://files.ballistica.net/cache/ba1/52/88/9b31fa2ce14ef7b98631cb36e769", "assets/build/ba_data/textures/bunnyColor.pvr": "https://files.ballistica.net/cache/ba1/6b/33/e48393656bbbf7a146d4e246fdc9", "assets/build/ba_data/textures/bunnyColorMask.dds": "https://files.ballistica.net/cache/ba1/b8/f2/7570c919e1f06c66c7236524d53f", @@ -1282,7 +1282,7 @@ "assets/build/ba_data/textures/bunnyColorMask.pvr": "https://files.ballistica.net/cache/ba1/db/91/d3ad07cabd17cffa0d9591532477", "assets/build/ba_data/textures/bunnyColorMask_preview.png": "https://files.ballistica.net/cache/ba1/72/b8/27c36d27c73d19f496f955fa50e2", "assets/build/ba_data/textures/bunnyColor_preview.png": "https://files.ballistica.net/cache/ba1/cb/f2/861b06f9154cd59a8e20802a0875", - "assets/build/ba_data/textures/bunnyIcon.dds": "https://files.ballistica.net/cache/ba1/3a/8c/c4615ce15d075e64da5768272ee7", + "assets/build/ba_data/textures/bunnyIcon.dds": "https://files.ballistica.net/cache/ba1/ca/2e/0352302668a840b50cf83b7d69b3", "assets/build/ba_data/textures/bunnyIcon.ktx": "https://files.ballistica.net/cache/ba1/da/92/e1ce1ba464ffc9ce57bfe87dd792", "assets/build/ba_data/textures/bunnyIcon.pvr": "https://files.ballistica.net/cache/ba1/6e/03/4848e2435ac4f9938a98a7adaf25", "assets/build/ba_data/textures/bunnyIconColorMask.dds": "https://files.ballistica.net/cache/ba1/d2/5d/7427e249e21960ab7f5e738f833d", @@ -1353,14 +1353,14 @@ "assets/build/ba_data/textures/circle.dds": "https://files.ballistica.net/cache/ba1/88/a6/c2e3db7c1c6aab2ad9b05d7074b4", "assets/build/ba_data/textures/circle.ktx": "https://files.ballistica.net/cache/ba1/85/cd/0d9bd306a8f91a9ed661f99529b2", "assets/build/ba_data/textures/circle.pvr": "https://files.ballistica.net/cache/ba1/3a/a2/d61927bc0770e37848ddd6712876", - "assets/build/ba_data/textures/circleNoAlpha.dds": "https://files.ballistica.net/cache/ba1/e9/c1/6af34d954867f725dbb7c63026f1", + "assets/build/ba_data/textures/circleNoAlpha.dds": "https://files.ballistica.net/cache/ba1/90/8b/7c1942e8bd58a3f2f20fc4be7173", "assets/build/ba_data/textures/circleNoAlpha.ktx": "https://files.ballistica.net/cache/ba1/e4/83/17f847e9f832201929a30f1ea535", "assets/build/ba_data/textures/circleNoAlpha.pvr": "https://files.ballistica.net/cache/ba1/23/d1/6d053de8f4ab7871c3275920cf18", "assets/build/ba_data/textures/circleNoAlpha_preview.png": "https://files.ballistica.net/cache/ba1/5c/9d/0ffc70edd5440cea9d5b22810aa2", "assets/build/ba_data/textures/circleOutline.dds": "https://files.ballistica.net/cache/ba1/a4/c2/e0a5bf011be78509dbef899b8f28", "assets/build/ba_data/textures/circleOutline.ktx": "https://files.ballistica.net/cache/ba1/ce/91/5fe4f6f2ade655564632f78ddb32", "assets/build/ba_data/textures/circleOutline.pvr": "https://files.ballistica.net/cache/ba1/df/7a/6de156c06892d833f7ebd264e772", - "assets/build/ba_data/textures/circleOutlineNoAlpha.dds": "https://files.ballistica.net/cache/ba1/86/32/c8fe0fbf2003b7883216b19984fa", + "assets/build/ba_data/textures/circleOutlineNoAlpha.dds": "https://files.ballistica.net/cache/ba1/60/0e/c7d019fe5cd651e26967c97c4969", "assets/build/ba_data/textures/circleOutlineNoAlpha.ktx": "https://files.ballistica.net/cache/ba1/3d/19/19c290ceb02d8d41740c864e7793", "assets/build/ba_data/textures/circleOutlineNoAlpha.pvr": "https://files.ballistica.net/cache/ba1/b0/56/02950e983c0fb55e9bc491b8860c", "assets/build/ba_data/textures/circleOutlineNoAlpha_preview.png": "https://files.ballistica.net/cache/ba1/fc/b5/7d4368c1ff5655ecd7b22234cf54", @@ -1382,18 +1382,18 @@ "assets/build/ba_data/textures/controllerIcon.ktx": "https://files.ballistica.net/cache/ba1/14/16/a15ad29481944559f81f54fdfe20", "assets/build/ba_data/textures/controllerIcon.pvr": "https://files.ballistica.net/cache/ba1/fe/01/befdbde27b052c35d3b12d80e80f", "assets/build/ba_data/textures/controllerIcon_preview.png": "https://files.ballistica.net/cache/ba1/59/a5/1465197ee1267ba0e0b25c43d80f", - "assets/build/ba_data/textures/courtyardLevelColor.dds": "https://files.ballistica.net/cache/ba1/46/f5/b4e9bdd3e30776884339293408eb", + "assets/build/ba_data/textures/courtyardLevelColor.dds": "https://files.ballistica.net/cache/ba1/b2/e1/fb40e54fac2969cbaa71682af9ce", "assets/build/ba_data/textures/courtyardLevelColor.ktx": "https://files.ballistica.net/cache/ba1/bd/56/4b6d7c0144fc37f99f35c52ab009", "assets/build/ba_data/textures/courtyardLevelColor.pvr": "https://files.ballistica.net/cache/ba1/77/97/bf195499e7e18777f02bb87061d7", "assets/build/ba_data/textures/courtyardLevelColor_preview.png": "https://files.ballistica.net/cache/ba1/91/bf/617c0d77529aa079200fdf75173d", - "assets/build/ba_data/textures/courtyardPreview.dds": "https://files.ballistica.net/cache/ba1/52/e5/cfdaab9a05d3f5706c7e5be114a1", + "assets/build/ba_data/textures/courtyardPreview.dds": "https://files.ballistica.net/cache/ba1/cf/c7/5e5a25f7b6b1c0840d66d203e030", "assets/build/ba_data/textures/courtyardPreview.ktx": "https://files.ballistica.net/cache/ba1/58/1c/ceeccf17dd5f3f1beb9af1ab720a", "assets/build/ba_data/textures/courtyardPreview.pvr": "https://files.ballistica.net/cache/ba1/a4/e8/9f1afe13ee2ebb9f6754a5f00f26", "assets/build/ba_data/textures/courtyardPreview_preview.png": "https://files.ballistica.net/cache/ba1/cb/40/06faf314dd35177a6d0e2a041bb7", "assets/build/ba_data/textures/cowboyColor.dds": "https://files.ballistica.net/cache/ba1/a4/49/f004e03fe36543d89dd8d1a6ed7f", "assets/build/ba_data/textures/cowboyColor.ktx": "https://files.ballistica.net/cache/ba1/00/30/f2ae84970bd0697725b821f2f152", "assets/build/ba_data/textures/cowboyColor.pvr": "https://files.ballistica.net/cache/ba1/45/1a/5bbcf702a33fd48e2b9a7016323f", - "assets/build/ba_data/textures/cowboyColorMask.dds": "https://files.ballistica.net/cache/ba1/bd/6a/6158fd65af4641bcd936045005a2", + "assets/build/ba_data/textures/cowboyColorMask.dds": "https://files.ballistica.net/cache/ba1/52/2f/874896a060d55f6498656cb8ba1d", "assets/build/ba_data/textures/cowboyColorMask.ktx": "https://files.ballistica.net/cache/ba1/51/68/9145727dc989afded72318e673c7", "assets/build/ba_data/textures/cowboyColorMask.pvr": "https://files.ballistica.net/cache/ba1/69/44/41ab993ebfc0a1aa32e431582fb4", "assets/build/ba_data/textures/cowboyColorMask_preview.png": "https://files.ballistica.net/cache/ba1/93/43/7bb7d6df6b89daa507ead29d4f2a", @@ -1406,11 +1406,11 @@ "assets/build/ba_data/textures/cowboyIconColorMask.pvr": "https://files.ballistica.net/cache/ba1/b9/bf/be1704729e7714781060d58d65c2", "assets/build/ba_data/textures/cowboyIconColorMask_preview.png": "https://files.ballistica.net/cache/ba1/ca/e7/0bc54a6b3fd60923c951fc97d790", "assets/build/ba_data/textures/cowboyIcon_preview.png": "https://files.ballistica.net/cache/ba1/1c/67/f2c47c042d89c220e78e7ebce5ed", - "assets/build/ba_data/textures/cragCastleLevelColor.dds": "https://files.ballistica.net/cache/ba1/89/88/9723a3035d39ef69cf3f3c7bda03", + "assets/build/ba_data/textures/cragCastleLevelColor.dds": "https://files.ballistica.net/cache/ba1/fe/9a/3d8efc6b02fe3f071b832d41dacb", "assets/build/ba_data/textures/cragCastleLevelColor.ktx": "https://files.ballistica.net/cache/ba1/ea/44/3b99b25e09c05fc6e85583866694", "assets/build/ba_data/textures/cragCastleLevelColor.pvr": "https://files.ballistica.net/cache/ba1/1e/9a/9b5125e165f5ebaecc8f1934a2c1", "assets/build/ba_data/textures/cragCastleLevelColor_preview.png": "https://files.ballistica.net/cache/ba1/b4/6c/6b8f525be822459dd4bd6548b2a8", - "assets/build/ba_data/textures/cragCastlePreview.dds": "https://files.ballistica.net/cache/ba1/87/12/9abc61fcd67f230597f166220d60", + "assets/build/ba_data/textures/cragCastlePreview.dds": "https://files.ballistica.net/cache/ba1/fb/22/e6c8a874a13b94a688ba5421141a", "assets/build/ba_data/textures/cragCastlePreview.ktx": "https://files.ballistica.net/cache/ba1/0c/b2/890cb8167c41cd2c220daa3db7a9", "assets/build/ba_data/textures/cragCastlePreview.pvr": "https://files.ballistica.net/cache/ba1/c9/61/1c57e31b464b26c5e6c125d38944", "assets/build/ba_data/textures/cragCastlePreview_preview.png": "https://files.ballistica.net/cache/ba1/b1/b2/d49537dbba63c3cbc25b3989a2e2", @@ -1430,18 +1430,18 @@ "assets/build/ba_data/textures/cuteSpaz.ktx": "https://files.ballistica.net/cache/ba1/9a/65/5bfc1d1ef2bb7ac9b767e70d6015", "assets/build/ba_data/textures/cuteSpaz.pvr": "https://files.ballistica.net/cache/ba1/ff/ec/9172f64f96803393de8da58f7566", "assets/build/ba_data/textures/cuteSpaz_preview.png": "https://files.ballistica.net/cache/ba1/e9/74/364547fef623e7bbbbc8a92a9efa", - "assets/build/ba_data/textures/cyborgColor.dds": "https://files.ballistica.net/cache/ba1/35/94/7e5c288cb0f17bd904f3a66ee6f7", + "assets/build/ba_data/textures/cyborgColor.dds": "https://files.ballistica.net/cache/ba1/93/d4/75c140eff1c3cc45e1766fc0e95c", "assets/build/ba_data/textures/cyborgColor.ktx": "https://files.ballistica.net/cache/ba1/d0/d6/e611760948207bebc5cec40721ee", "assets/build/ba_data/textures/cyborgColor.pvr": "https://files.ballistica.net/cache/ba1/3b/b4/14499682862c916ba7e6df183445", - "assets/build/ba_data/textures/cyborgColorMask.dds": "https://files.ballistica.net/cache/ba1/28/57/0bd64f9f7d5573a9e1fd1c5f422d", + "assets/build/ba_data/textures/cyborgColorMask.dds": "https://files.ballistica.net/cache/ba1/34/e0/24881a8cabf3b48f1e68635b0096", "assets/build/ba_data/textures/cyborgColorMask.ktx": "https://files.ballistica.net/cache/ba1/09/49/64a4b4bd11d7f43ee3e3b4557ccb", "assets/build/ba_data/textures/cyborgColorMask.pvr": "https://files.ballistica.net/cache/ba1/aa/8f/2017c219d46766b0a8a58b12ef80", "assets/build/ba_data/textures/cyborgColorMask_preview.png": "https://files.ballistica.net/cache/ba1/b2/c8/1ca1bb73d93dd93169977aef26eb", "assets/build/ba_data/textures/cyborgColor_preview.png": "https://files.ballistica.net/cache/ba1/23/68/de2999bc4db759030c77dd372e23", - "assets/build/ba_data/textures/cyborgIcon.dds": "https://files.ballistica.net/cache/ba1/99/c3/8eed2f236f66aef901d452cdb98b", + "assets/build/ba_data/textures/cyborgIcon.dds": "https://files.ballistica.net/cache/ba1/5a/55/c63bdf0b63c76da7b387b4bebecb", "assets/build/ba_data/textures/cyborgIcon.ktx": "https://files.ballistica.net/cache/ba1/de/ab/4d5b2163047d3fb9b05d43c9183d", "assets/build/ba_data/textures/cyborgIcon.pvr": "https://files.ballistica.net/cache/ba1/0c/7b/b47a4bfbbfd8607ea06375963485", - "assets/build/ba_data/textures/cyborgIconColorMask.dds": "https://files.ballistica.net/cache/ba1/9d/2a/1852d636d06de05bff2ffac52d9c", + "assets/build/ba_data/textures/cyborgIconColorMask.dds": "https://files.ballistica.net/cache/ba1/ad/20/71a5de426d081b99c1abe672474a", "assets/build/ba_data/textures/cyborgIconColorMask.ktx": "https://files.ballistica.net/cache/ba1/20/95/85096b550149fb17500c673a9589", "assets/build/ba_data/textures/cyborgIconColorMask.pvr": "https://files.ballistica.net/cache/ba1/1f/70/35e302e1a91d78ab23cb3e936bde", "assets/build/ba_data/textures/cyborgIconColorMask_preview.png": "https://files.ballistica.net/cache/ba1/09/bb/e6563f614b2cda0ca5da89b80b2a", @@ -1450,15 +1450,15 @@ "assets/build/ba_data/textures/discordLogo.ktx": "https://files.ballistica.net/cache/ba1/a2/ad/24c11330f25cd763640872fbd16e", "assets/build/ba_data/textures/discordLogo.pvr": "https://files.ballistica.net/cache/ba1/2b/41/7b2e332fbfe4c74cc8c76be16fd0", "assets/build/ba_data/textures/discordLogo_preview.png": "https://files.ballistica.net/cache/ba1/ad/88/2fc2f22f8ee9925df99dbc47d315", - "assets/build/ba_data/textures/doomShroomBGColor.dds": "https://files.ballistica.net/cache/ba1/12/cc/3fa62b5809176403776958657571", + "assets/build/ba_data/textures/doomShroomBGColor.dds": "https://files.ballistica.net/cache/ba1/5c/2b/88deea7de0cf4b7e3250ca76bcc1", "assets/build/ba_data/textures/doomShroomBGColor.ktx": "https://files.ballistica.net/cache/ba1/db/35/7f5884df9de36467179b45e8e241", "assets/build/ba_data/textures/doomShroomBGColor.pvr": "https://files.ballistica.net/cache/ba1/65/5d/fc508d48f3703e91cfbfce0187ed", "assets/build/ba_data/textures/doomShroomBGColor_preview.png": "https://files.ballistica.net/cache/ba1/b5/7e/995e3c648eb68d4c72c4e50be7e6", - "assets/build/ba_data/textures/doomShroomLevelColor.dds": "https://files.ballistica.net/cache/ba1/ac/a4/03513b905d7379ee44e6e686056d", + "assets/build/ba_data/textures/doomShroomLevelColor.dds": "https://files.ballistica.net/cache/ba1/cd/1e/f297f1c37249810e7aaffca591a4", "assets/build/ba_data/textures/doomShroomLevelColor.ktx": "https://files.ballistica.net/cache/ba1/6c/96/d887b3d3cf79d2264ad2e601193d", "assets/build/ba_data/textures/doomShroomLevelColor.pvr": "https://files.ballistica.net/cache/ba1/e2/15/8303117a33a96a61376dad6f5e9d", "assets/build/ba_data/textures/doomShroomLevelColor_preview.png": "https://files.ballistica.net/cache/ba1/61/cf/327dd838ebab6875b92ee28c3bcd", - "assets/build/ba_data/textures/doomShroomPreview.dds": "https://files.ballistica.net/cache/ba1/f5/68/bd828096f33579d65a44c5357933", + "assets/build/ba_data/textures/doomShroomPreview.dds": "https://files.ballistica.net/cache/ba1/d7/c7/888bb15afe907f3a37006e76b3af", "assets/build/ba_data/textures/doomShroomPreview.ktx": "https://files.ballistica.net/cache/ba1/f6/3c/20abd773a8502a0954d62c0917c7", "assets/build/ba_data/textures/doomShroomPreview.pvr": "https://files.ballistica.net/cache/ba1/d3/92/aca35e87cb29f4da683e88859a21", "assets/build/ba_data/textures/doomShroomPreview_preview.png": "https://files.ballistica.net/cache/ba1/19/85/7ec1b3b28c5bc564fd0a106d2423", @@ -1498,7 +1498,7 @@ "assets/build/ba_data/textures/empty.ktx": "https://files.ballistica.net/cache/ba1/1c/1a/c944b4615540bebbd2337f37a36e", "assets/build/ba_data/textures/empty.pvr": "https://files.ballistica.net/cache/ba1/e1/85/0e5d594e57336cf14b4914ebb37c", "assets/build/ba_data/textures/empty_preview.png": "https://files.ballistica.net/cache/ba1/27/1d/936488a18c78f387f2f4ec562545", - "assets/build/ba_data/textures/explosion.dds": "https://files.ballistica.net/cache/ba1/da/1f/fac45c02f2f889b62335f3f85d77", + "assets/build/ba_data/textures/explosion.dds": "https://files.ballistica.net/cache/ba1/e7/95/a6d20541c8ffff02583799ab77ba", "assets/build/ba_data/textures/explosion.ktx": "https://files.ballistica.net/cache/ba1/72/e7/7db06c8ab6f0dd8dfc48162824b1", "assets/build/ba_data/textures/explosion.pvr": "https://files.ballistica.net/cache/ba1/38/42/e4de72086e36187dcb5e4005f4e9", "assets/build/ba_data/textures/explosion_preview.png": "https://files.ballistica.net/cache/ba1/6f/01/8a6cf54d2e9b24c87c00ea2ca9c3", @@ -1514,11 +1514,11 @@ "assets/build/ba_data/textures/file.ktx": "https://files.ballistica.net/cache/ba1/d5/f6/a80ff58c84435b33a05a1e61016e", "assets/build/ba_data/textures/file.pvr": "https://files.ballistica.net/cache/ba1/5f/25/e6079cc54364d95d6101fc74bdba", "assets/build/ba_data/textures/file_preview.png": "https://files.ballistica.net/cache/ba1/ef/c6/71a8f503449908b15a40ce3b5b03", - "assets/build/ba_data/textures/flagColor.dds": "https://files.ballistica.net/cache/ba1/ee/84/655bd471f8265bc7d61f95beda16", + "assets/build/ba_data/textures/flagColor.dds": "https://files.ballistica.net/cache/ba1/4a/ce/2682d3720bff14ec43bdfcaca346", "assets/build/ba_data/textures/flagColor.ktx": "https://files.ballistica.net/cache/ba1/81/3c/f16914e9d68d64ce59a1f7681bff", "assets/build/ba_data/textures/flagColor.pvr": "https://files.ballistica.net/cache/ba1/e0/b0/06fd752a0f3563252d6dee64dcb3", "assets/build/ba_data/textures/flagColor_preview.png": "https://files.ballistica.net/cache/ba1/0b/33/50db4a9487b0ef8d65f2628776e5", - "assets/build/ba_data/textures/flagPoleColor.dds": "https://files.ballistica.net/cache/ba1/ba/7a/25e2cd1d33d4f323682716489099", + "assets/build/ba_data/textures/flagPoleColor.dds": "https://files.ballistica.net/cache/ba1/22/e0/43555f1a8a4bff7088c33ccd179e", "assets/build/ba_data/textures/flagPoleColor.ktx": "https://files.ballistica.net/cache/ba1/0f/56/7d16d9b2af848d004da2012c2cf7", "assets/build/ba_data/textures/flagPoleColor.pvr": "https://files.ballistica.net/cache/ba1/7b/63/e163c96ff68bb242e8b9ef339711", "assets/build/ba_data/textures/flagPoleColor_preview.png": "https://files.ballistica.net/cache/ba1/e0/e4/6c41b0bfd6796344ba60d0bdf189", @@ -1578,10 +1578,10 @@ "assets/build/ba_data/textures/fontSmall7.ktx": "https://files.ballistica.net/cache/ba1/14/d0/23e59a31103533757dea7ffae94e", "assets/build/ba_data/textures/fontSmall7.pvr": "https://files.ballistica.net/cache/ba1/48/b5/26321b2643219162a713170ab9b8", "assets/build/ba_data/textures/fontSmall7_preview.png": "https://files.ballistica.net/cache/ba1/70/56/13b940fb6d0ba48023e7fac6f184", - "assets/build/ba_data/textures/footballStadium.dds": "https://files.ballistica.net/cache/ba1/37/98/82cd29605606ef50ec7f7f1a2b38", + "assets/build/ba_data/textures/footballStadium.dds": "https://files.ballistica.net/cache/ba1/c6/f3/1906912b8e4d923a0ec975de5e8f", "assets/build/ba_data/textures/footballStadium.ktx": "https://files.ballistica.net/cache/ba1/00/bf/6b8e37071ad1d6e33f30f1998bed", "assets/build/ba_data/textures/footballStadium.pvr": "https://files.ballistica.net/cache/ba1/92/69/f2c5577a1de103343ddcb01d6104", - "assets/build/ba_data/textures/footballStadiumPreview.dds": "https://files.ballistica.net/cache/ba1/f6/f3/032deefbd09bdb75806d9ed813c2", + "assets/build/ba_data/textures/footballStadiumPreview.dds": "https://files.ballistica.net/cache/ba1/d9/7f/b42a16567ea5ae5a85faa027e4ce", "assets/build/ba_data/textures/footballStadiumPreview.ktx": "https://files.ballistica.net/cache/ba1/96/f2/6cf9b95e27aeca2d8be08feedaef", "assets/build/ba_data/textures/footballStadiumPreview.pvr": "https://files.ballistica.net/cache/ba1/3f/1b/ce5faa6a8678c3b7d0a461c9509b", "assets/build/ba_data/textures/footballStadiumPreview_preview.png": "https://files.ballistica.net/cache/ba1/a7/c8/393d085e92e185e6c43ab28cd5ee", @@ -1590,15 +1590,15 @@ "assets/build/ba_data/textures/frameInset.ktx": "https://files.ballistica.net/cache/ba1/61/d7/264cfcdd0d07d67ac90827969caa", "assets/build/ba_data/textures/frameInset.pvr": "https://files.ballistica.net/cache/ba1/d1/ef/b0dd66aab3c8cf21933dc53f0c8f", "assets/build/ba_data/textures/frameInset_preview.png": "https://files.ballistica.net/cache/ba1/51/2f/a18329872f0d0b71f0a333c0db81", - "assets/build/ba_data/textures/frostyColor.dds": "https://files.ballistica.net/cache/ba1/8c/ae/6ca51f72866944ce9691c8a1a7d5", + "assets/build/ba_data/textures/frostyColor.dds": "https://files.ballistica.net/cache/ba1/6d/c6/2a49a0ec7810e7431c35752d3d37", "assets/build/ba_data/textures/frostyColor.ktx": "https://files.ballistica.net/cache/ba1/17/6c/fe178ee04831b332ff771bade627", "assets/build/ba_data/textures/frostyColor.pvr": "https://files.ballistica.net/cache/ba1/f8/fb/83779ec75b8113a47b9368ad6992", - "assets/build/ba_data/textures/frostyColorMask.dds": "https://files.ballistica.net/cache/ba1/f0/aa/0c7c2dfc831bb96d76b2c1719597", + "assets/build/ba_data/textures/frostyColorMask.dds": "https://files.ballistica.net/cache/ba1/7c/a3/3cd619ea33d9e222af6da8ce7ccc", "assets/build/ba_data/textures/frostyColorMask.ktx": "https://files.ballistica.net/cache/ba1/5d/ff/5a82bf1855c957357d277dec18c7", "assets/build/ba_data/textures/frostyColorMask.pvr": "https://files.ballistica.net/cache/ba1/d2/e3/5ccf3bc21b48180ef890cfd1ebab", "assets/build/ba_data/textures/frostyColorMask_preview.png": "https://files.ballistica.net/cache/ba1/44/6f/795803f91fbf1628e708a6a293a4", "assets/build/ba_data/textures/frostyColor_preview.png": "https://files.ballistica.net/cache/ba1/cd/3c/f7e49e7cf8164f754c2384f35e55", - "assets/build/ba_data/textures/frostyIcon.dds": "https://files.ballistica.net/cache/ba1/52/39/1044bf10f62219a9c804efec91ea", + "assets/build/ba_data/textures/frostyIcon.dds": "https://files.ballistica.net/cache/ba1/17/76/45c5a0a3d416259aab598bad0303", "assets/build/ba_data/textures/frostyIcon.ktx": "https://files.ballistica.net/cache/ba1/74/b4/d498eb65a6a3b562e9eb6195131b", "assets/build/ba_data/textures/frostyIcon.pvr": "https://files.ballistica.net/cache/ba1/a2/a6/589107d7ab94e8ba9dec5895ba6d", "assets/build/ba_data/textures/frostyIconColorMask.dds": "https://files.ballistica.net/cache/ba1/af/d5/5421823e52ef7bb86d1e24a610c4", @@ -1606,7 +1606,7 @@ "assets/build/ba_data/textures/frostyIconColorMask.pvr": "https://files.ballistica.net/cache/ba1/8e/98/89e07ef5493074a2c4cbb7aa1592", "assets/build/ba_data/textures/frostyIconColorMask_preview.png": "https://files.ballistica.net/cache/ba1/ef/77/6b17bc9b8d8d3fa37760ed4d96ac", "assets/build/ba_data/textures/frostyIcon_preview.png": "https://files.ballistica.net/cache/ba1/3e/dd/9cc6d8f3f494b586237b050a4e06", - "assets/build/ba_data/textures/fuse.dds": "https://files.ballistica.net/cache/ba1/4b/72/e7709195c5903f968c33209dc1ed", + "assets/build/ba_data/textures/fuse.dds": "https://files.ballistica.net/cache/ba1/9a/72/5eb4b3235d38ec3f69c61fdb0445", "assets/build/ba_data/textures/fuse.ktx": "https://files.ballistica.net/cache/ba1/49/ea/71c5c7dcbdcb213c036460d59117", "assets/build/ba_data/textures/fuse.pvr": "https://files.ballistica.net/cache/ba1/48/3a/710945756ee605974820d4c98e49", "assets/build/ba_data/textures/fuse_preview.png": "https://files.ballistica.net/cache/ba1/f1/69/975f7d19d7db9a01d78ecb33bfe2", @@ -1625,7 +1625,7 @@ "assets/build/ba_data/textures/gladiatorColor.dds": "https://files.ballistica.net/cache/ba1/a8/6a/2b8eb1e0f4c15993e98be5395e4c", "assets/build/ba_data/textures/gladiatorColor.ktx": "https://files.ballistica.net/cache/ba1/20/13/e491823b8cc38a52400f9d74a209", "assets/build/ba_data/textures/gladiatorColor.pvr": "https://files.ballistica.net/cache/ba1/14/60/1d4a45b0036538368348613ad01f", - "assets/build/ba_data/textures/gladiatorColorMask.dds": "https://files.ballistica.net/cache/ba1/05/7f/ee686ec23643b388502639d98879", + "assets/build/ba_data/textures/gladiatorColorMask.dds": "https://files.ballistica.net/cache/ba1/d2/ac/02d7c9a4320ed6a8b416d48f2665", "assets/build/ba_data/textures/gladiatorColorMask.ktx": "https://files.ballistica.net/cache/ba1/1e/ae/f91222e92e938c0fc8be66103cb5", "assets/build/ba_data/textures/gladiatorColorMask.pvr": "https://files.ballistica.net/cache/ba1/46/18/4ad8171ff791a86b03160648afcf", "assets/build/ba_data/textures/gladiatorColorMask_preview.png": "https://files.ballistica.net/cache/ba1/87/45/0621a7a40782a938a8f66f8985ae", @@ -1670,10 +1670,10 @@ "assets/build/ba_data/textures/heart.ktx": "https://files.ballistica.net/cache/ba1/b7/b1/8db1d5e585578b16ad0e7dac922e", "assets/build/ba_data/textures/heart.pvr": "https://files.ballistica.net/cache/ba1/b1/78/46eb38e941aa94b7a8c654c1ef38", "assets/build/ba_data/textures/heart_preview.png": "https://files.ballistica.net/cache/ba1/3c/d8/bc7b73e6920382202f1bf27b7b40", - "assets/build/ba_data/textures/hockeyStadium.dds": "https://files.ballistica.net/cache/ba1/8e/19/703679fb5ac0e07d577d2727ab27", + "assets/build/ba_data/textures/hockeyStadium.dds": "https://files.ballistica.net/cache/ba1/bc/a0/0ddbb1707aab5481582f40b5042c", "assets/build/ba_data/textures/hockeyStadium.ktx": "https://files.ballistica.net/cache/ba1/57/14/4a768367b5a3ada80b8b866320ae", "assets/build/ba_data/textures/hockeyStadium.pvr": "https://files.ballistica.net/cache/ba1/f4/e4/65792658b9ef354781472d5f82ba", - "assets/build/ba_data/textures/hockeyStadiumPreview.dds": "https://files.ballistica.net/cache/ba1/e0/84/38b2f0294f016bf122dcbfa226d2", + "assets/build/ba_data/textures/hockeyStadiumPreview.dds": "https://files.ballistica.net/cache/ba1/3c/d6/a0f39559e614781ef7590cf98826", "assets/build/ba_data/textures/hockeyStadiumPreview.ktx": "https://files.ballistica.net/cache/ba1/af/05/69b7f2c83e332b6ec410163a59fd", "assets/build/ba_data/textures/hockeyStadiumPreview.pvr": "https://files.ballistica.net/cache/ba1/4c/fb/7bcd3e1d5f830558cd01206c57e6", "assets/build/ba_data/textures/hockeyStadiumPreview_preview.png": "https://files.ballistica.net/cache/ba1/d8/99/5d6922a337009674a13b647e06c5", @@ -1690,7 +1690,7 @@ "assets/build/ba_data/textures/iircadeLogo.ktx": "https://files.ballistica.net/cache/ba1/58/b9/848fbac7a1c7ad6a9b2efd758ff1", "assets/build/ba_data/textures/iircadeLogo.pvr": "https://files.ballistica.net/cache/ba1/19/ba/66f832c978d9cf46f991e4811401", "assets/build/ba_data/textures/iircadeLogo_preview.png": "https://files.ballistica.net/cache/ba1/c7/d6/0740136951cbc17907f6192357b2", - "assets/build/ba_data/textures/impactBombColor.dds": "https://files.ballistica.net/cache/ba1/59/f6/810262f238679951f7702f2ed1a5", + "assets/build/ba_data/textures/impactBombColor.dds": "https://files.ballistica.net/cache/ba1/a6/70/8486c52fb904e18e9b13f4850b5e", "assets/build/ba_data/textures/impactBombColor.ktx": "https://files.ballistica.net/cache/ba1/fc/3b/e1051061b1ed03bcbfdc6b9f8c79", "assets/build/ba_data/textures/impactBombColor.pvr": "https://files.ballistica.net/cache/ba1/d6/d9/0f81193db5aa44780ee8bb0943b9", "assets/build/ba_data/textures/impactBombColorLit.dds": "https://files.ballistica.net/cache/ba1/fe/65/a55aba9c983239516c96f28fd4b2", @@ -1702,15 +1702,15 @@ "assets/build/ba_data/textures/inventoryIcon.ktx": "https://files.ballistica.net/cache/ba1/3c/ca/1a61ddc33fbae07060b3ffe24531", "assets/build/ba_data/textures/inventoryIcon.pvr": "https://files.ballistica.net/cache/ba1/a7/e3/6fe1d29dd307067b5b42aa1e78ca", "assets/build/ba_data/textures/inventoryIcon_preview.png": "https://files.ballistica.net/cache/ba1/5d/95/fc2f9cf29120f6e5714a82b49762", - "assets/build/ba_data/textures/jackColor.dds": "https://files.ballistica.net/cache/ba1/3e/bb/562defe30cd5860a6648aa8c3127", + "assets/build/ba_data/textures/jackColor.dds": "https://files.ballistica.net/cache/ba1/9c/16/c4c568eec16b4ac15110e2213107", "assets/build/ba_data/textures/jackColor.ktx": "https://files.ballistica.net/cache/ba1/b4/92/c66d4bd99efdd17578c1ab40eb38", "assets/build/ba_data/textures/jackColor.pvr": "https://files.ballistica.net/cache/ba1/93/f0/b67389b8a52446f9d60119b4e4b0", - "assets/build/ba_data/textures/jackColorMask.dds": "https://files.ballistica.net/cache/ba1/74/c3/18ed606a334e8096ab0f9a6b6045", + "assets/build/ba_data/textures/jackColorMask.dds": "https://files.ballistica.net/cache/ba1/33/86/4e8b48b1274373302fed850899f3", "assets/build/ba_data/textures/jackColorMask.ktx": "https://files.ballistica.net/cache/ba1/c9/40/a44ca36c9fcb3ca51fb61dbaa2cf", "assets/build/ba_data/textures/jackColorMask.pvr": "https://files.ballistica.net/cache/ba1/32/89/9243f17fdd9d8c3d7c9cc8a26191", "assets/build/ba_data/textures/jackColorMask_preview.png": "https://files.ballistica.net/cache/ba1/71/92/54cc17903955e0b923f64bb746a7", "assets/build/ba_data/textures/jackColor_preview.png": "https://files.ballistica.net/cache/ba1/83/f8/daf0dc5014e0220a8e4bc8d1113a", - "assets/build/ba_data/textures/jackIcon.dds": "https://files.ballistica.net/cache/ba1/0c/1f/ec2d1e00f2b409df11b485667334", + "assets/build/ba_data/textures/jackIcon.dds": "https://files.ballistica.net/cache/ba1/42/a1/c6f5a537e23a509a22a13870470f", "assets/build/ba_data/textures/jackIcon.ktx": "https://files.ballistica.net/cache/ba1/e8/5d/e5e222130b790f5239089333fd92", "assets/build/ba_data/textures/jackIcon.pvr": "https://files.ballistica.net/cache/ba1/da/f9/29d46bb6b052d5aad5a81efa994e", "assets/build/ba_data/textures/jackIconColorMask.dds": "https://files.ballistica.net/cache/ba1/1e/8e/395cb09dbe9ca002ad0d5532f6bd", @@ -1721,7 +1721,7 @@ "assets/build/ba_data/textures/jumpsuitColor.dds": "https://files.ballistica.net/cache/ba1/5b/9c/4761afb2e6fc3e0f8ef028d317be", "assets/build/ba_data/textures/jumpsuitColor.ktx": "https://files.ballistica.net/cache/ba1/45/25/6084698fbdd038fbd750fc72dd28", "assets/build/ba_data/textures/jumpsuitColor.pvr": "https://files.ballistica.net/cache/ba1/6c/77/39fe91748b79f2aabc640f38fd2a", - "assets/build/ba_data/textures/jumpsuitColorMask.dds": "https://files.ballistica.net/cache/ba1/c3/3c/5ad8f955187c9825ea9871fa3c3c", + "assets/build/ba_data/textures/jumpsuitColorMask.dds": "https://files.ballistica.net/cache/ba1/04/00/8fbe70c2d5bc499f842e76b6a71d", "assets/build/ba_data/textures/jumpsuitColorMask.ktx": "https://files.ballistica.net/cache/ba1/50/c2/79341c7081f28d70de09cb6db116", "assets/build/ba_data/textures/jumpsuitColorMask.pvr": "https://files.ballistica.net/cache/ba1/51/1e/5f4580d17068abebb0f8d2609c3c", "assets/build/ba_data/textures/jumpsuitColorMask_preview.png": "https://files.ballistica.net/cache/ba1/6f/05/15f3184259761adc208e2dd659ca", @@ -1734,26 +1734,26 @@ "assets/build/ba_data/textures/jumpsuitIconColorMask.pvr": "https://files.ballistica.net/cache/ba1/77/e0/1326a95629aec5d0a447f4694dc8", "assets/build/ba_data/textures/jumpsuitIconColorMask_preview.png": "https://files.ballistica.net/cache/ba1/d0/81/c975a77166d8bac47d63340960b4", "assets/build/ba_data/textures/jumpsuitIcon_preview.png": "https://files.ballistica.net/cache/ba1/06/1f/0f16b73da3b140ae91a645ad3920", - "assets/build/ba_data/textures/kronk.dds": "https://files.ballistica.net/cache/ba1/41/b3/1173def9511feb2ebc516e070ed6", + "assets/build/ba_data/textures/kronk.dds": "https://files.ballistica.net/cache/ba1/79/99/217e4d40c7107337bf4ff402e020", "assets/build/ba_data/textures/kronk.ktx": "https://files.ballistica.net/cache/ba1/80/d7/0f40cc83961456cca52f50d87657", "assets/build/ba_data/textures/kronk.pvr": "https://files.ballistica.net/cache/ba1/4d/74/fb56c0df66aa36551ae4ac73a141", - "assets/build/ba_data/textures/kronkColorMask.dds": "https://files.ballistica.net/cache/ba1/fa/9c/bba4cffffd4d7e7bdc53bd27819b", + "assets/build/ba_data/textures/kronkColorMask.dds": "https://files.ballistica.net/cache/ba1/f7/e2/92c6c2179b0ea3dcaa85f357e3d7", "assets/build/ba_data/textures/kronkColorMask.ktx": "https://files.ballistica.net/cache/ba1/de/23/7ab48fef2af0a1253b2eb6a083ab", "assets/build/ba_data/textures/kronkColorMask.pvr": "https://files.ballistica.net/cache/ba1/d4/ab/0df43e24f6aa11608a2f9b2bda6d", "assets/build/ba_data/textures/kronkColorMask_preview.png": "https://files.ballistica.net/cache/ba1/5c/14/80f2148210e89e8ca6b3b03b6e10", "assets/build/ba_data/textures/kronkIcon.dds": "https://files.ballistica.net/cache/ba1/d2/66/367fb5a09d45419be710683f0b8a", "assets/build/ba_data/textures/kronkIcon.ktx": "https://files.ballistica.net/cache/ba1/0b/23/ca03de39efd26cc2ca53a46f70b4", "assets/build/ba_data/textures/kronkIcon.pvr": "https://files.ballistica.net/cache/ba1/d7/2c/17a833f010265c66243ec90fcf09", - "assets/build/ba_data/textures/kronkIconColorMask.dds": "https://files.ballistica.net/cache/ba1/8b/b1/d2f52c09816856963fa41e1e8b83", + "assets/build/ba_data/textures/kronkIconColorMask.dds": "https://files.ballistica.net/cache/ba1/ec/4f/d9c86c700f2feaf28767f666a836", "assets/build/ba_data/textures/kronkIconColorMask.ktx": "https://files.ballistica.net/cache/ba1/41/41/5c76cd5af36248308d96cf1b4bcd", "assets/build/ba_data/textures/kronkIconColorMask.pvr": "https://files.ballistica.net/cache/ba1/4c/0c/41d95110ecda25e0e66a3876cce4", "assets/build/ba_data/textures/kronkIconColorMask_preview.png": "https://files.ballistica.net/cache/ba1/a3/24/7b66c17a8bae4ef0f9f3ca4a95ca", "assets/build/ba_data/textures/kronkIcon_preview.png": "https://files.ballistica.net/cache/ba1/5f/28/4ca750d54dcb57ad82f3bbacd2e5", "assets/build/ba_data/textures/kronk_preview.png": "https://files.ballistica.net/cache/ba1/0b/2e/083f0a0c74bec4b4f629e2bdd2a0", - "assets/build/ba_data/textures/lakeFrigid.dds": "https://files.ballistica.net/cache/ba1/52/fb/3df33cd21b7e6cfa4e4f9b03add5", + "assets/build/ba_data/textures/lakeFrigid.dds": "https://files.ballistica.net/cache/ba1/de/16/41f8895b19d81123ab48ad72f38d", "assets/build/ba_data/textures/lakeFrigid.ktx": "https://files.ballistica.net/cache/ba1/d2/ad/c28e092d9eeea2c5643d1d89613f", "assets/build/ba_data/textures/lakeFrigid.pvr": "https://files.ballistica.net/cache/ba1/f8/c0/53f0c6ec9f5ec37514b07d0c3506", - "assets/build/ba_data/textures/lakeFrigidPreview.dds": "https://files.ballistica.net/cache/ba1/23/9b/b65965dc2da90a77737df299527f", + "assets/build/ba_data/textures/lakeFrigidPreview.dds": "https://files.ballistica.net/cache/ba1/eb/fd/9d832e847a72de6f62a02403abc5", "assets/build/ba_data/textures/lakeFrigidPreview.ktx": "https://files.ballistica.net/cache/ba1/8f/d5/185af314124e8ca312475205704e", "assets/build/ba_data/textures/lakeFrigidPreview.pvr": "https://files.ballistica.net/cache/ba1/9b/2d/8b05ecb7e85b4dd42613e3e0ff89", "assets/build/ba_data/textures/lakeFrigidPreview_preview.png": "https://files.ballistica.net/cache/ba1/80/ef/8283d6c6c7f144b1dd187262b661", @@ -1830,10 +1830,10 @@ "assets/build/ba_data/textures/medalSilver.ktx": "https://files.ballistica.net/cache/ba1/68/84/934ab97c1014e98ffd6bbb24ad89", "assets/build/ba_data/textures/medalSilver.pvr": "https://files.ballistica.net/cache/ba1/37/e8/0f2d99b80e98d8388cbb1fb81aed", "assets/build/ba_data/textures/medalSilver_preview.png": "https://files.ballistica.net/cache/ba1/1c/38/7e840a4f3b6f7c15e21b22628603", - "assets/build/ba_data/textures/melColor.dds": "https://files.ballistica.net/cache/ba1/bd/29/6743f3197828fb39a9f424788023", + "assets/build/ba_data/textures/melColor.dds": "https://files.ballistica.net/cache/ba1/c6/f1/ef8f3740635ec2b601f73afe0424", "assets/build/ba_data/textures/melColor.ktx": "https://files.ballistica.net/cache/ba1/fa/a1/645eb759ffd7b046fe91ff4f9f8b", "assets/build/ba_data/textures/melColor.pvr": "https://files.ballistica.net/cache/ba1/b1/90/45696ef2a4717ce5f3e1838e31f1", - "assets/build/ba_data/textures/melColorMask.dds": "https://files.ballistica.net/cache/ba1/0c/95/4cce7a44347eef0356dd96dbae60", + "assets/build/ba_data/textures/melColorMask.dds": "https://files.ballistica.net/cache/ba1/b7/64/9ae23dc4897fd612952d3193c023", "assets/build/ba_data/textures/melColorMask.ktx": "https://files.ballistica.net/cache/ba1/bb/ed/2e666f6e2d647b45874645084028", "assets/build/ba_data/textures/melColorMask.pvr": "https://files.ballistica.net/cache/ba1/af/a4/002bc32b803774a668ce8953014e", "assets/build/ba_data/textures/melColorMask_preview.png": "https://files.ballistica.net/cache/ba1/58/ee/347860a4fc2faf37f1fa3013ce18", @@ -1841,12 +1841,12 @@ "assets/build/ba_data/textures/melIcon.dds": "https://files.ballistica.net/cache/ba1/0e/b2/683438456569eacf65b24f18b66f", "assets/build/ba_data/textures/melIcon.ktx": "https://files.ballistica.net/cache/ba1/a6/fb/e0f4945bea0edf83729dadf52f24", "assets/build/ba_data/textures/melIcon.pvr": "https://files.ballistica.net/cache/ba1/b6/ec/ed46dda142a62f35c28720878c8f", - "assets/build/ba_data/textures/melIconColorMask.dds": "https://files.ballistica.net/cache/ba1/5a/db/4439edcfbbef9ea932fb7d56e26a", + "assets/build/ba_data/textures/melIconColorMask.dds": "https://files.ballistica.net/cache/ba1/61/b4/637cf663cd1df1d6adacfcbc148c", "assets/build/ba_data/textures/melIconColorMask.ktx": "https://files.ballistica.net/cache/ba1/64/e0/2f0de4aca98350b0cecbaea53cda", "assets/build/ba_data/textures/melIconColorMask.pvr": "https://files.ballistica.net/cache/ba1/ba/94/c1955a495fcb9156ef4415105fa3", "assets/build/ba_data/textures/melIconColorMask_preview.png": "https://files.ballistica.net/cache/ba1/60/9b/38b259d63b5b8c17e0e8f4a09682", "assets/build/ba_data/textures/melIcon_preview.png": "https://files.ballistica.net/cache/ba1/cf/1d/5fd4405703e177ab90cc331e2809", - "assets/build/ba_data/textures/menuBG.dds": "https://files.ballistica.net/cache/ba1/7c/60/840dbf0ae2e0273c5553a81a9613", + "assets/build/ba_data/textures/menuBG.dds": "https://files.ballistica.net/cache/ba1/66/38/e19d5d26e0c3b7750ad612288f51", "assets/build/ba_data/textures/menuBG.ktx": "https://files.ballistica.net/cache/ba1/f9/f7/a09f825ab514e1a57fcf67149798", "assets/build/ba_data/textures/menuBG.pvr": "https://files.ballistica.net/cache/ba1/2e/8a/11960533b874cb081c384a521710", "assets/build/ba_data/textures/menuBG_preview.png": "https://files.ballistica.net/cache/ba1/03/1c/9a07cf577bdf39e58effdbc2e242", @@ -1862,11 +1862,11 @@ "assets/build/ba_data/textures/meter.ktx": "https://files.ballistica.net/cache/ba1/b5/e7/3ba3d4c7c7e05081eb033ae5da8f", "assets/build/ba_data/textures/meter.pvr": "https://files.ballistica.net/cache/ba1/58/de/ab83ad9e0d9b434ca42811030ef9", "assets/build/ba_data/textures/meter_preview.png": "https://files.ballistica.net/cache/ba1/09/b7/40a1a187d7b057defa6f32c6b372", - "assets/build/ba_data/textures/monkeyFaceLevelColor.dds": "https://files.ballistica.net/cache/ba1/c6/29/e07d5663f90bec057f4c0a175baa", + "assets/build/ba_data/textures/monkeyFaceLevelColor.dds": "https://files.ballistica.net/cache/ba1/e8/41/cfcdc67b1adbf50621ae9ebdafef", "assets/build/ba_data/textures/monkeyFaceLevelColor.ktx": "https://files.ballistica.net/cache/ba1/33/d0/e2600748ebab847b7a146350a3c9", "assets/build/ba_data/textures/monkeyFaceLevelColor.pvr": "https://files.ballistica.net/cache/ba1/09/98/9491294da842980b75739e8d1c59", "assets/build/ba_data/textures/monkeyFaceLevelColor_preview.png": "https://files.ballistica.net/cache/ba1/2f/84/fd142ba957ead4acb7b4081a3771", - "assets/build/ba_data/textures/monkeyFacePreview.dds": "https://files.ballistica.net/cache/ba1/3d/14/795c5ec8cf2e1b5c49e1dba05341", + "assets/build/ba_data/textures/monkeyFacePreview.dds": "https://files.ballistica.net/cache/ba1/7d/53/6c90a28662f70e03ae967a63151c", "assets/build/ba_data/textures/monkeyFacePreview.ktx": "https://files.ballistica.net/cache/ba1/ff/83/d340f1495861ebb97bd7f766ccbb", "assets/build/ba_data/textures/monkeyFacePreview.pvr": "https://files.ballistica.net/cache/ba1/85/e7/807edc04137ee1a3b7767e90d692", "assets/build/ba_data/textures/monkeyFacePreview_preview.png": "https://files.ballistica.net/cache/ba1/5c/62/929429eb7fd47b21edf6dd8d8f63", @@ -1874,19 +1874,19 @@ "assets/build/ba_data/textures/multiplayerExamples.ktx": "https://files.ballistica.net/cache/ba1/48/2c/081cf255b138824720c0b49d2e1e", "assets/build/ba_data/textures/multiplayerExamples.pvr": "https://files.ballistica.net/cache/ba1/d1/db/8902cdbf501bf919e5f9f0ada2b4", "assets/build/ba_data/textures/multiplayerExamples_preview.png": "https://files.ballistica.net/cache/ba1/ea/7c/acf4240ca1fa313126060a8258f0", - "assets/build/ba_data/textures/natureBackgroundColor.dds": "https://files.ballistica.net/cache/ba1/78/ff/45c52ff0f98ffabcd472e68e3a04", + "assets/build/ba_data/textures/natureBackgroundColor.dds": "https://files.ballistica.net/cache/ba1/41/5a/2821b371bfb514531fd617be39cd", "assets/build/ba_data/textures/natureBackgroundColor.ktx": "https://files.ballistica.net/cache/ba1/60/09/50676eca6d0599eabf895f18aa21", "assets/build/ba_data/textures/natureBackgroundColor.pvr": "https://files.ballistica.net/cache/ba1/1f/37/b4950cf37311fc39f53235adb190", "assets/build/ba_data/textures/natureBackgroundColor_preview.png": "https://files.ballistica.net/cache/ba1/61/91/2af689aba61ee35bc281a8c2fc88", - "assets/build/ba_data/textures/neoSpazColor.dds": "https://files.ballistica.net/cache/ba1/91/44/f06dba5c1cb7fda6d62e2c0c5484", + "assets/build/ba_data/textures/neoSpazColor.dds": "https://files.ballistica.net/cache/ba1/e7/77/ba83d0d9a1472d495d3ebaa182c4", "assets/build/ba_data/textures/neoSpazColor.ktx": "https://files.ballistica.net/cache/ba1/d1/d7/797152df3d1260338405ea0ea59f", "assets/build/ba_data/textures/neoSpazColor.pvr": "https://files.ballistica.net/cache/ba1/8b/68/60b1e0bc0c6295fba84e493c313d", - "assets/build/ba_data/textures/neoSpazColorMask.dds": "https://files.ballistica.net/cache/ba1/72/05/774cf76faed583a54d1658e17402", + "assets/build/ba_data/textures/neoSpazColorMask.dds": "https://files.ballistica.net/cache/ba1/05/ff/08bba0e201d0eea3ead5746ca96f", "assets/build/ba_data/textures/neoSpazColorMask.ktx": "https://files.ballistica.net/cache/ba1/ef/f6/84779b7eb27ccbbcdb77f3b6f2fb", "assets/build/ba_data/textures/neoSpazColorMask.pvr": "https://files.ballistica.net/cache/ba1/a2/a8/4aa145599bd4b8c53d87624553e2", "assets/build/ba_data/textures/neoSpazColorMask_preview.png": "https://files.ballistica.net/cache/ba1/62/88/1239b81fe081de88c08ac7434bc3", "assets/build/ba_data/textures/neoSpazColor_preview.png": "https://files.ballistica.net/cache/ba1/23/2c/b541bf04f85d1aa5de3b475b82d2", - "assets/build/ba_data/textures/neoSpazIcon.dds": "https://files.ballistica.net/cache/ba1/d9/ef/2e3e5cb4151c3ac209c0774dea79", + "assets/build/ba_data/textures/neoSpazIcon.dds": "https://files.ballistica.net/cache/ba1/e0/6e/59525196623212ac76d96d9cd3bb", "assets/build/ba_data/textures/neoSpazIcon.ktx": "https://files.ballistica.net/cache/ba1/d2/b5/f7c3badf697bc9dd82cffd17352c", "assets/build/ba_data/textures/neoSpazIcon.pvr": "https://files.ballistica.net/cache/ba1/47/c1/5ee2e1475e142aa8468b2d50c752", "assets/build/ba_data/textures/neoSpazIconColorMask.dds": "https://files.ballistica.net/cache/ba1/60/46/4e61726cb5e2c81b0e0af5a7cd5e", @@ -1898,15 +1898,15 @@ "assets/build/ba_data/textures/nextLevelIcon.ktx": "https://files.ballistica.net/cache/ba1/b2/84/0bb105ab76cc15c66f52ecbefcf7", "assets/build/ba_data/textures/nextLevelIcon.pvr": "https://files.ballistica.net/cache/ba1/0b/8d/087ad0de136250c54e42f4dca92f", "assets/build/ba_data/textures/nextLevelIcon_preview.png": "https://files.ballistica.net/cache/ba1/76/5f/ffae5ff97775780301b96a1a3f52", - "assets/build/ba_data/textures/ninjaColor.dds": "https://files.ballistica.net/cache/ba1/d3/5c/67af280eab6793195bb039488ce1", + "assets/build/ba_data/textures/ninjaColor.dds": "https://files.ballistica.net/cache/ba1/e7/25/60195fddd30365324328f09e1230", "assets/build/ba_data/textures/ninjaColor.ktx": "https://files.ballistica.net/cache/ba1/2a/a1/22d137826995da608c2e3898083e", "assets/build/ba_data/textures/ninjaColor.pvr": "https://files.ballistica.net/cache/ba1/2d/0c/6a9364e38112591a5f77de741ca2", - "assets/build/ba_data/textures/ninjaColorMask.dds": "https://files.ballistica.net/cache/ba1/02/06/3c07252b18ba88964bba62b8a656", + "assets/build/ba_data/textures/ninjaColorMask.dds": "https://files.ballistica.net/cache/ba1/db/da/51021e6f1482e5664af808b29b00", "assets/build/ba_data/textures/ninjaColorMask.ktx": "https://files.ballistica.net/cache/ba1/1d/68/ee8c4f656d583b49638f3cb40b4e", "assets/build/ba_data/textures/ninjaColorMask.pvr": "https://files.ballistica.net/cache/ba1/06/0a/58e0e29f5b9f503afcfc1a93f052", "assets/build/ba_data/textures/ninjaColorMask_preview.png": "https://files.ballistica.net/cache/ba1/8c/22/0103111a22390dd49615eaf2a4c3", "assets/build/ba_data/textures/ninjaColor_preview.png": "https://files.ballistica.net/cache/ba1/d9/d9/52cf79858329ee664417fa86325a", - "assets/build/ba_data/textures/ninjaIcon.dds": "https://files.ballistica.net/cache/ba1/38/30/a7b91f95d0d38b8d31558ca83680", + "assets/build/ba_data/textures/ninjaIcon.dds": "https://files.ballistica.net/cache/ba1/a4/34/ac0523aa0d224b5668966a1ce6cd", "assets/build/ba_data/textures/ninjaIcon.ktx": "https://files.ballistica.net/cache/ba1/fb/be/7acdbf4b9e212c3a20bf7b7ffe1a", "assets/build/ba_data/textures/ninjaIcon.pvr": "https://files.ballistica.net/cache/ba1/1a/c3/a5843f74115717fcbeb44cb792df", "assets/build/ba_data/textures/ninjaIconColorMask.dds": "https://files.ballistica.net/cache/ba1/b8/eb/6b4811f664e79059a8604db820d6", @@ -1925,7 +1925,7 @@ "assets/build/ba_data/textures/oldLadyColor.dds": "https://files.ballistica.net/cache/ba1/9c/9a/7b82b343061f5b2f8f2b281abf07", "assets/build/ba_data/textures/oldLadyColor.ktx": "https://files.ballistica.net/cache/ba1/e9/a6/b2c434cba993f176a1fbce5e017c", "assets/build/ba_data/textures/oldLadyColor.pvr": "https://files.ballistica.net/cache/ba1/49/6e/5d95e58db32fafff298781d3c379", - "assets/build/ba_data/textures/oldLadyColorMask.dds": "https://files.ballistica.net/cache/ba1/e3/9e/dc76d3799d4e1900d605745f71e6", + "assets/build/ba_data/textures/oldLadyColorMask.dds": "https://files.ballistica.net/cache/ba1/e5/91/354e94e932df33f458ee0bf6e1a0", "assets/build/ba_data/textures/oldLadyColorMask.ktx": "https://files.ballistica.net/cache/ba1/81/da/80cd97c5f4c228ea585d4c6b1906", "assets/build/ba_data/textures/oldLadyColorMask.pvr": "https://files.ballistica.net/cache/ba1/b7/fc/328a89dfc0578184d0cd9be05e5f", "assets/build/ba_data/textures/oldLadyColorMask_preview.png": "https://files.ballistica.net/cache/ba1/f7/23/f290703d2c69f7f115151907afdd", @@ -1941,7 +1941,7 @@ "assets/build/ba_data/textures/operaSingerColor.dds": "https://files.ballistica.net/cache/ba1/06/40/1d46db18bbf308f1e8e88ed25c7d", "assets/build/ba_data/textures/operaSingerColor.ktx": "https://files.ballistica.net/cache/ba1/a9/34/bac2cb5bfa5cfac1b5a209e77a36", "assets/build/ba_data/textures/operaSingerColor.pvr": "https://files.ballistica.net/cache/ba1/1b/e3/4a871e36791bf302c0ecb68426a7", - "assets/build/ba_data/textures/operaSingerColorMask.dds": "https://files.ballistica.net/cache/ba1/e4/57/7f6534987c17b43ac14da7aa15cc", + "assets/build/ba_data/textures/operaSingerColorMask.dds": "https://files.ballistica.net/cache/ba1/a6/c8/eb903a977a1c83792b5a9485357a", "assets/build/ba_data/textures/operaSingerColorMask.ktx": "https://files.ballistica.net/cache/ba1/ad/76/24839951a638bcdbd2f399e26b96", "assets/build/ba_data/textures/operaSingerColorMask.pvr": "https://files.ballistica.net/cache/ba1/1e/56/ce51acda0e9f77cf8450c4871503", "assets/build/ba_data/textures/operaSingerColorMask_preview.png": "https://files.ballistica.net/cache/ba1/99/5e/a20ff9e112ae711dff9d9b0602c0", @@ -1974,34 +1974,34 @@ "assets/build/ba_data/textures/ouyaYButton.ktx": "https://files.ballistica.net/cache/ba1/dd/99/0a8364d55243d59174e449445c40", "assets/build/ba_data/textures/ouyaYButton.pvr": "https://files.ballistica.net/cache/ba1/2d/f8/ebd32f8ca2f65f450641eda0e4b3", "assets/build/ba_data/textures/ouyaYButton_preview.png": "https://files.ballistica.net/cache/ba1/a0/39/27eb09f33ca04d133a2c86d30f87", - "assets/build/ba_data/textures/penguinColor.dds": "https://files.ballistica.net/cache/ba1/b0/90/b5e0f65db8428e7f58a677fc8712", + "assets/build/ba_data/textures/penguinColor.dds": "https://files.ballistica.net/cache/ba1/46/06/98a0d4e3a61c17eabca8a5addac9", "assets/build/ba_data/textures/penguinColor.ktx": "https://files.ballistica.net/cache/ba1/e8/a4/4bebf5671504129dd5daa25a8eaf", "assets/build/ba_data/textures/penguinColor.pvr": "https://files.ballistica.net/cache/ba1/5c/7b/af36d581b9c5e920609861c4fab0", - "assets/build/ba_data/textures/penguinColorMask.dds": "https://files.ballistica.net/cache/ba1/70/9c/9b96ade9b7231f07ae0580e4f60f", + "assets/build/ba_data/textures/penguinColorMask.dds": "https://files.ballistica.net/cache/ba1/ea/71/c0d2e8b03f5e02a17e884c332691", "assets/build/ba_data/textures/penguinColorMask.ktx": "https://files.ballistica.net/cache/ba1/8a/10/60999fce550b8de1444f1d05f263", "assets/build/ba_data/textures/penguinColorMask.pvr": "https://files.ballistica.net/cache/ba1/46/27/d3978fdfac00e02373d9298e755f", "assets/build/ba_data/textures/penguinColorMask_preview.png": "https://files.ballistica.net/cache/ba1/a9/f6/99954cafdabea10227ac0943a206", "assets/build/ba_data/textures/penguinColor_preview.png": "https://files.ballistica.net/cache/ba1/d5/4d/bb509ed353b4dd0e1e5231ddb59d", - "assets/build/ba_data/textures/penguinIcon.dds": "https://files.ballistica.net/cache/ba1/2c/07/d519ac490eec7432713ce7b85473", + "assets/build/ba_data/textures/penguinIcon.dds": "https://files.ballistica.net/cache/ba1/8b/01/d805bef78053a8bc2980fa9e987d", "assets/build/ba_data/textures/penguinIcon.ktx": "https://files.ballistica.net/cache/ba1/5a/d8/daadfc2654dd77d31caf4e0796d0", "assets/build/ba_data/textures/penguinIcon.pvr": "https://files.ballistica.net/cache/ba1/87/1c/dcbc92cc2fe862c43e81d587b1fe", - "assets/build/ba_data/textures/penguinIconColorMask.dds": "https://files.ballistica.net/cache/ba1/b7/be/a11bb4ae3d7535c43ca02afd0ee3", + "assets/build/ba_data/textures/penguinIconColorMask.dds": "https://files.ballistica.net/cache/ba1/f0/0d/71a45142684d98ec7004eab7cfcd", "assets/build/ba_data/textures/penguinIconColorMask.ktx": "https://files.ballistica.net/cache/ba1/b2/10/73b6efac0d2df908570c53ded344", "assets/build/ba_data/textures/penguinIconColorMask.pvr": "https://files.ballistica.net/cache/ba1/25/26/0551afc2a52c6a6426ff3c21e4f4", "assets/build/ba_data/textures/penguinIconColorMask_preview.png": "https://files.ballistica.net/cache/ba1/7c/0e/7df9e0157fd40450e0b5935cdc41", "assets/build/ba_data/textures/penguinIcon_preview.png": "https://files.ballistica.net/cache/ba1/db/bf/98796d0f0d33bc200c896ba82109", - "assets/build/ba_data/textures/pixieColor.dds": "https://files.ballistica.net/cache/ba1/f0/f6/90a78ac8b17c8b3b6cb258f078ed", + "assets/build/ba_data/textures/pixieColor.dds": "https://files.ballistica.net/cache/ba1/75/cc/389a63b73cfcbae4aed11b8b710a", "assets/build/ba_data/textures/pixieColor.ktx": "https://files.ballistica.net/cache/ba1/23/90/c836828f9342e6bd21612ff78938", "assets/build/ba_data/textures/pixieColor.pvr": "https://files.ballistica.net/cache/ba1/3d/ce/acca60b5cde2111bd62d90adc41e", - "assets/build/ba_data/textures/pixieColorMask.dds": "https://files.ballistica.net/cache/ba1/7f/8f/4eaddebfa9dfb7909c7cdad4b576", + "assets/build/ba_data/textures/pixieColorMask.dds": "https://files.ballistica.net/cache/ba1/82/27/8c1fe9eec5b984f42fca3d3e9381", "assets/build/ba_data/textures/pixieColorMask.ktx": "https://files.ballistica.net/cache/ba1/59/fe/138ccc612be62ef4a30b9adfbcf9", "assets/build/ba_data/textures/pixieColorMask.pvr": "https://files.ballistica.net/cache/ba1/57/84/72b8fc64aad487d406fc876b1b42", "assets/build/ba_data/textures/pixieColorMask_preview.png": "https://files.ballistica.net/cache/ba1/8a/7e/51ba798eac9278727df8a804ba35", "assets/build/ba_data/textures/pixieColor_preview.png": "https://files.ballistica.net/cache/ba1/07/86/d9bab7a777b2e38107403edfcd50", - "assets/build/ba_data/textures/pixieIcon.dds": "https://files.ballistica.net/cache/ba1/b7/f4/fd43b64dacef89608c5ab6db0377", + "assets/build/ba_data/textures/pixieIcon.dds": "https://files.ballistica.net/cache/ba1/68/32/7d731f50bf51e633df18254034a3", "assets/build/ba_data/textures/pixieIcon.ktx": "https://files.ballistica.net/cache/ba1/e8/25/576bf3a4e9e2dba964c5f18b6622", "assets/build/ba_data/textures/pixieIcon.pvr": "https://files.ballistica.net/cache/ba1/21/72/ba1ca96c4f017c11cffaec11d788", - "assets/build/ba_data/textures/pixieIconColorMask.dds": "https://files.ballistica.net/cache/ba1/1d/8c/bcfcc534447ae4a5eb33effa157c", + "assets/build/ba_data/textures/pixieIconColorMask.dds": "https://files.ballistica.net/cache/ba1/3c/25/1f57bdf36447463ad1065a614c7f", "assets/build/ba_data/textures/pixieIconColorMask.ktx": "https://files.ballistica.net/cache/ba1/76/3f/caf7f06633052fa327db6eaa39d6", "assets/build/ba_data/textures/pixieIconColorMask.pvr": "https://files.ballistica.net/cache/ba1/1f/1e/da8a3c0f1a42acbe09140e29609d", "assets/build/ba_data/textures/pixieIconColorMask_preview.png": "https://files.ballistica.net/cache/ba1/18/f4/e96160f142153a37f9e0919c883e", @@ -2014,7 +2014,7 @@ "assets/build/ba_data/textures/powerupBomb.ktx": "https://files.ballistica.net/cache/ba1/1b/bc/5bf3f52c9f880476221d63a41ee1", "assets/build/ba_data/textures/powerupBomb.pvr": "https://files.ballistica.net/cache/ba1/99/05/7144537430a306d45efbd75f733f", "assets/build/ba_data/textures/powerupBomb_preview.png": "https://files.ballistica.net/cache/ba1/75/17/31e7f1997e0f3304b597a062efa7", - "assets/build/ba_data/textures/powerupCurse.dds": "https://files.ballistica.net/cache/ba1/2e/ff/9c66e6f7c1a973155e68ab5560a8", + "assets/build/ba_data/textures/powerupCurse.dds": "https://files.ballistica.net/cache/ba1/6f/cd/50c78074de3f655afe1d029ffce8", "assets/build/ba_data/textures/powerupCurse.ktx": "https://files.ballistica.net/cache/ba1/40/4f/0648e5b36ad56442fdba6e07ce6c", "assets/build/ba_data/textures/powerupCurse.pvr": "https://files.ballistica.net/cache/ba1/31/2b/01f49d263a0915691651ae6b8196", "assets/build/ba_data/textures/powerupCurse_preview.png": "https://files.ballistica.net/cache/ba1/07/21/962169962af41bec8c43cf3d01a1", @@ -2022,7 +2022,7 @@ "assets/build/ba_data/textures/powerupHealth.ktx": "https://files.ballistica.net/cache/ba1/be/3e/5bd4f2ac8d7bf972571f89992264", "assets/build/ba_data/textures/powerupHealth.pvr": "https://files.ballistica.net/cache/ba1/64/ec/f1507c9ed94d0bd4b0c9ab8569da", "assets/build/ba_data/textures/powerupHealth_preview.png": "https://files.ballistica.net/cache/ba1/42/11/e09c9daf2dadf44be3b9249e3fa4", - "assets/build/ba_data/textures/powerupIceBombs.dds": "https://files.ballistica.net/cache/ba1/03/8e/96c1d4ef593ea45528f2dda9853c", + "assets/build/ba_data/textures/powerupIceBombs.dds": "https://files.ballistica.net/cache/ba1/9f/4d/af9b3707142271e4b6090c19f330", "assets/build/ba_data/textures/powerupIceBombs.ktx": "https://files.ballistica.net/cache/ba1/27/6e/3b2b5fa2e68a073db9ed5c67da39", "assets/build/ba_data/textures/powerupIceBombs.pvr": "https://files.ballistica.net/cache/ba1/b3/32/b9c0df53502d4402b36b8bdba951", "assets/build/ba_data/textures/powerupIceBombs_preview.png": "https://files.ballistica.net/cache/ba1/61/8b/7f43a09b4ca30edef5099cecbbb1", @@ -2030,7 +2030,7 @@ "assets/build/ba_data/textures/powerupImpactBombs.ktx": "https://files.ballistica.net/cache/ba1/49/0c/df4b313585f897592ccee9d5c542", "assets/build/ba_data/textures/powerupImpactBombs.pvr": "https://files.ballistica.net/cache/ba1/f2/1b/8b6c447613d2bbec20cff630b1f1", "assets/build/ba_data/textures/powerupImpactBombs_preview.png": "https://files.ballistica.net/cache/ba1/0c/33/5d041471446792bb5da31291b869", - "assets/build/ba_data/textures/powerupLandMines.dds": "https://files.ballistica.net/cache/ba1/8b/96/2731079019cf1688415831619c76", + "assets/build/ba_data/textures/powerupLandMines.dds": "https://files.ballistica.net/cache/ba1/99/f8/ea06e3d99018797fe82841988cce", "assets/build/ba_data/textures/powerupLandMines.ktx": "https://files.ballistica.net/cache/ba1/79/ac/333130d040444c03fbcf7302e35b", "assets/build/ba_data/textures/powerupLandMines.pvr": "https://files.ballistica.net/cache/ba1/2b/7a/4ac9f04cfa3a59e19fd3ddd72b2e", "assets/build/ba_data/textures/powerupLandMines_preview.png": "https://files.ballistica.net/cache/ba1/21/bc/b619e59db015ed4cc8020972a336", @@ -2046,31 +2046,31 @@ "assets/build/ba_data/textures/powerupSpeed.ktx": "https://files.ballistica.net/cache/ba1/2e/fc/63e2a260e55d0d33ed0dc4400cb0", "assets/build/ba_data/textures/powerupSpeed.pvr": "https://files.ballistica.net/cache/ba1/35/c1/657cc9772d575786c21d2575034d", "assets/build/ba_data/textures/powerupSpeed_preview.png": "https://files.ballistica.net/cache/ba1/f1/2a/278da1921f939809afad254fbb03", - "assets/build/ba_data/textures/powerupStickyBombs.dds": "https://files.ballistica.net/cache/ba1/eb/e0/0191d68d9daf896e9d2298c57941", + "assets/build/ba_data/textures/powerupStickyBombs.dds": "https://files.ballistica.net/cache/ba1/02/93/92f9be86367f44404b8257bdbf6c", "assets/build/ba_data/textures/powerupStickyBombs.ktx": "https://files.ballistica.net/cache/ba1/fd/1b/0a64a4e0149e6c9acc3bd5710283", "assets/build/ba_data/textures/powerupStickyBombs.pvr": "https://files.ballistica.net/cache/ba1/f5/44/ea00c858e1fdd2c73ae953b6fbe5", "assets/build/ba_data/textures/powerupStickyBombs_preview.png": "https://files.ballistica.net/cache/ba1/76/67/7e11feb9a7f94a68be36128e9afd", - "assets/build/ba_data/textures/puckColor.dds": "https://files.ballistica.net/cache/ba1/55/0f/0ad93b23a0a4d86ce4799135b26d", + "assets/build/ba_data/textures/puckColor.dds": "https://files.ballistica.net/cache/ba1/14/5f/893c54c1ccb320272450c24d232b", "assets/build/ba_data/textures/puckColor.ktx": "https://files.ballistica.net/cache/ba1/91/a8/49adfe0386637b17fd0d5df798d5", "assets/build/ba_data/textures/puckColor.pvr": "https://files.ballistica.net/cache/ba1/00/54/b9d50d210bfba69387909e6e91de", "assets/build/ba_data/textures/puckColor_preview.png": "https://files.ballistica.net/cache/ba1/bd/c4/4a3a3dcb8c1084a34479d43dcaed", - "assets/build/ba_data/textures/rampageBGColor.dds": "https://files.ballistica.net/cache/ba1/34/2b/e98df914e71d6789e771ea70a264", + "assets/build/ba_data/textures/rampageBGColor.dds": "https://files.ballistica.net/cache/ba1/37/a1/a11281d3002afc84c3d28db58395", "assets/build/ba_data/textures/rampageBGColor.ktx": "https://files.ballistica.net/cache/ba1/b0/39/acaf74037621c74a29a72576ee20", "assets/build/ba_data/textures/rampageBGColor.pvr": "https://files.ballistica.net/cache/ba1/6b/9d/54521c22a5e2de98eabfb985fa85", - "assets/build/ba_data/textures/rampageBGColor2.dds": "https://files.ballistica.net/cache/ba1/22/94/8c49d6e549a2f08076d48417fb40", + "assets/build/ba_data/textures/rampageBGColor2.dds": "https://files.ballistica.net/cache/ba1/08/35/b2aca6e05626aaf870cceb35ba8e", "assets/build/ba_data/textures/rampageBGColor2.ktx": "https://files.ballistica.net/cache/ba1/60/23/d866c382fc22fdea03bf2527d147", "assets/build/ba_data/textures/rampageBGColor2.pvr": "https://files.ballistica.net/cache/ba1/3e/69/d3c1a9d7f8910199598f010efd8a", "assets/build/ba_data/textures/rampageBGColor2_preview.png": "https://files.ballistica.net/cache/ba1/79/f6/068a9185d32b580a4e73806d8d12", "assets/build/ba_data/textures/rampageBGColor_preview.png": "https://files.ballistica.net/cache/ba1/38/39/0a2366c421eacc7c5a051c430e15", - "assets/build/ba_data/textures/rampageLevelColor.dds": "https://files.ballistica.net/cache/ba1/81/69/f4b28c3c4713d96e3cb208bcfbce", + "assets/build/ba_data/textures/rampageLevelColor.dds": "https://files.ballistica.net/cache/ba1/fe/40/41c878b5db3ebe47686d8a605cf6", "assets/build/ba_data/textures/rampageLevelColor.ktx": "https://files.ballistica.net/cache/ba1/ef/06/d2ac2ec0f775180b62e341a5890f", "assets/build/ba_data/textures/rampageLevelColor.pvr": "https://files.ballistica.net/cache/ba1/8a/74/ff813c81875c81cd8ccd345c5a27", "assets/build/ba_data/textures/rampageLevelColor_preview.png": "https://files.ballistica.net/cache/ba1/b9/db/0920892160b677dac33844acb9e3", - "assets/build/ba_data/textures/rampagePreview.dds": "https://files.ballistica.net/cache/ba1/09/56/67a073d1abfec5e861e3412bca94", + "assets/build/ba_data/textures/rampagePreview.dds": "https://files.ballistica.net/cache/ba1/15/af/3089f17f4e969b3780c92ef1ba58", "assets/build/ba_data/textures/rampagePreview.ktx": "https://files.ballistica.net/cache/ba1/b3/80/783d2507b45af55ebe7d9e4aa7b1", "assets/build/ba_data/textures/rampagePreview.pvr": "https://files.ballistica.net/cache/ba1/97/d2/99028f0da86ef4d61a70da709c29", "assets/build/ba_data/textures/rampagePreview_preview.png": "https://files.ballistica.net/cache/ba1/4f/64/6469bc8cfe52cdd9590c1edbc89c", - "assets/build/ba_data/textures/reflectionChar_+x.dds": "https://files.ballistica.net/cache/ba1/2c/ec/82270cbcd6f3fc72aa1c69036163", + "assets/build/ba_data/textures/reflectionChar_+x.dds": "https://files.ballistica.net/cache/ba1/5b/6d/76948a60ad687d91d4db8696ff35", "assets/build/ba_data/textures/reflectionChar_+x.ktx": "https://files.ballistica.net/cache/ba1/d2/31/6eb2af3d54a5a9b194f5fd5a0cd7", "assets/build/ba_data/textures/reflectionChar_+x.pvr": "https://files.ballistica.net/cache/ba1/45/72/1bf60fc63ee6024e2c62026e1d13", "assets/build/ba_data/textures/reflectionChar_+x_preview.png": "https://files.ballistica.net/cache/ba1/3e/19/1545732b54357b959468baeadb05", @@ -2086,7 +2086,7 @@ "assets/build/ba_data/textures/reflectionChar_-x.ktx": "https://files.ballistica.net/cache/ba1/7b/a7/6592e876e7c31687e11e019a305d", "assets/build/ba_data/textures/reflectionChar_-x.pvr": "https://files.ballistica.net/cache/ba1/88/fb/372bde1b68e238da396a7576088f", "assets/build/ba_data/textures/reflectionChar_-x_preview.png": "https://files.ballistica.net/cache/ba1/81/8f/422c1c54b3021abc70a4aa64b3fd", - "assets/build/ba_data/textures/reflectionChar_-y.dds": "https://files.ballistica.net/cache/ba1/45/c3/d1f2ffdb624d2236eb41e93b79cc", + "assets/build/ba_data/textures/reflectionChar_-y.dds": "https://files.ballistica.net/cache/ba1/25/03/628a5da0305261041300f75ef756", "assets/build/ba_data/textures/reflectionChar_-y.ktx": "https://files.ballistica.net/cache/ba1/25/1f/4e5b9240dcf6ea6639fb81f3579a", "assets/build/ba_data/textures/reflectionChar_-y.pvr": "https://files.ballistica.net/cache/ba1/4e/ee/7cdca1ae6b1458a443262c5a4e9c", "assets/build/ba_data/textures/reflectionChar_-y_preview.png": "https://files.ballistica.net/cache/ba1/ba/70/f2f188b95e2735467e823c94504a", @@ -2094,7 +2094,7 @@ "assets/build/ba_data/textures/reflectionChar_-z.ktx": "https://files.ballistica.net/cache/ba1/96/56/0f9aef42c876c3d2832ba570de79", "assets/build/ba_data/textures/reflectionChar_-z.pvr": "https://files.ballistica.net/cache/ba1/60/68/cb7fefc89119f14265c58200afde", "assets/build/ba_data/textures/reflectionChar_-z_preview.png": "https://files.ballistica.net/cache/ba1/b5/10/70b59c9cd551b44f8422867a38c2", - "assets/build/ba_data/textures/reflectionPowerup_+x.dds": "https://files.ballistica.net/cache/ba1/aa/16/e46748f64851d1f0fd6c3b0bab9a", + "assets/build/ba_data/textures/reflectionPowerup_+x.dds": "https://files.ballistica.net/cache/ba1/4b/3d/76538e3f18edb2a373bb3b591314", "assets/build/ba_data/textures/reflectionPowerup_+x.ktx": "https://files.ballistica.net/cache/ba1/a6/9b/682e676c993ae660475b4467fa6a", "assets/build/ba_data/textures/reflectionPowerup_+x.pvr": "https://files.ballistica.net/cache/ba1/f9/45/2b58be3bf14314607a25143fb477", "assets/build/ba_data/textures/reflectionPowerup_+x_preview.png": "https://files.ballistica.net/cache/ba1/66/cc/5021c0239527286f8c8f63aad21a", @@ -2126,11 +2126,11 @@ "assets/build/ba_data/textures/reflectionSharp_+y.ktx": "https://files.ballistica.net/cache/ba1/2c/a5/141e266b590226ee4a3474ac874e", "assets/build/ba_data/textures/reflectionSharp_+y.pvr": "https://files.ballistica.net/cache/ba1/a5/10/cdd96a99404584f090032ca60e62", "assets/build/ba_data/textures/reflectionSharp_+y_preview.png": "https://files.ballistica.net/cache/ba1/0f/58/f04fac2b705b92c8b0e11036a8ff", - "assets/build/ba_data/textures/reflectionSharp_+z.dds": "https://files.ballistica.net/cache/ba1/ac/4b/db6e2bf52594a0cb882d17579bec", + "assets/build/ba_data/textures/reflectionSharp_+z.dds": "https://files.ballistica.net/cache/ba1/2a/be/a4ec2fb348452797276aa8a7ea52", "assets/build/ba_data/textures/reflectionSharp_+z.ktx": "https://files.ballistica.net/cache/ba1/21/2c/51df5254932dac26b7068bc1e044", "assets/build/ba_data/textures/reflectionSharp_+z.pvr": "https://files.ballistica.net/cache/ba1/e4/87/2eaf17f6a15512b4326c7a2ae395", "assets/build/ba_data/textures/reflectionSharp_+z_preview.png": "https://files.ballistica.net/cache/ba1/1f/14/cd9fa509c22fea0f73a5eb76ac54", - "assets/build/ba_data/textures/reflectionSharp_-x.dds": "https://files.ballistica.net/cache/ba1/d7/b4/19de232b288604ffd66e48b182cf", + "assets/build/ba_data/textures/reflectionSharp_-x.dds": "https://files.ballistica.net/cache/ba1/8f/2f/def7cd6049055701946f6ba7efcb", "assets/build/ba_data/textures/reflectionSharp_-x.ktx": "https://files.ballistica.net/cache/ba1/04/cf/03b8b252c6d0a14b4a74df1697b2", "assets/build/ba_data/textures/reflectionSharp_-x.pvr": "https://files.ballistica.net/cache/ba1/f3/5b/36f37a9ca99d555c8950524ca118", "assets/build/ba_data/textures/reflectionSharp_-x_preview.png": "https://files.ballistica.net/cache/ba1/80/18/f2f8c9ce1f0dc8f297e0b29def1b", @@ -2142,7 +2142,7 @@ "assets/build/ba_data/textures/reflectionSharp_-z.ktx": "https://files.ballistica.net/cache/ba1/09/79/7c34e93c1453fa653098644dc902", "assets/build/ba_data/textures/reflectionSharp_-z.pvr": "https://files.ballistica.net/cache/ba1/08/d2/fa84664b3558ce68269581d52ab3", "assets/build/ba_data/textures/reflectionSharp_-z_preview.png": "https://files.ballistica.net/cache/ba1/e0/6e/de9a4cfdcb483bf92a63ac64e435", - "assets/build/ba_data/textures/reflectionSharper_+x.dds": "https://files.ballistica.net/cache/ba1/86/21/0ed2cff91343e7d697e3fdbc9d15", + "assets/build/ba_data/textures/reflectionSharper_+x.dds": "https://files.ballistica.net/cache/ba1/ed/05/68ad6e013833ba230bee61037591", "assets/build/ba_data/textures/reflectionSharper_+x.ktx": "https://files.ballistica.net/cache/ba1/ab/9b/243e80e52d6f837f206472054489", "assets/build/ba_data/textures/reflectionSharper_+x.pvr": "https://files.ballistica.net/cache/ba1/70/29/f1847b9d9c4892e3d383c8136b28", "assets/build/ba_data/textures/reflectionSharper_+x_preview.png": "https://files.ballistica.net/cache/ba1/22/db/1afb62440951a98fcf57663d5884", @@ -2210,7 +2210,7 @@ "assets/build/ba_data/textures/reflectionSoft_-y.ktx": "https://files.ballistica.net/cache/ba1/c7/af/7e09853ae6f0487e3a4122ac31d5", "assets/build/ba_data/textures/reflectionSoft_-y.pvr": "https://files.ballistica.net/cache/ba1/80/81/e5428d62dd5a31f708a68b258366", "assets/build/ba_data/textures/reflectionSoft_-y_preview.png": "https://files.ballistica.net/cache/ba1/2f/e1/b0cee0f161188752abcba04c9291", - "assets/build/ba_data/textures/reflectionSoft_-z.dds": "https://files.ballistica.net/cache/ba1/35/65/f84fc0c302b96ffde8d816c118c4", + "assets/build/ba_data/textures/reflectionSoft_-z.dds": "https://files.ballistica.net/cache/ba1/14/be/6bab80deb23a5105dd1ddd57740b", "assets/build/ba_data/textures/reflectionSoft_-z.ktx": "https://files.ballistica.net/cache/ba1/55/b2/45ec181ec07cd28be1a089b6bb79", "assets/build/ba_data/textures/reflectionSoft_-z.pvr": "https://files.ballistica.net/cache/ba1/67/6e/271b323497b797718b7d9bd3f939", "assets/build/ba_data/textures/reflectionSoft_-z_preview.png": "https://files.ballistica.net/cache/ba1/6f/38/dce6d5c26bc45005b9355b030c94", @@ -2229,7 +2229,7 @@ "assets/build/ba_data/textures/robotColor.dds": "https://files.ballistica.net/cache/ba1/a3/c0/2f7089d363c3e22b4ab10cd1c589", "assets/build/ba_data/textures/robotColor.ktx": "https://files.ballistica.net/cache/ba1/9a/9d/dbdec15776fd014e03eb1808ad28", "assets/build/ba_data/textures/robotColor.pvr": "https://files.ballistica.net/cache/ba1/9d/24/cc381a8ff6e80947618a97d36107", - "assets/build/ba_data/textures/robotColorMask.dds": "https://files.ballistica.net/cache/ba1/9f/89/248c558b1f019a7e37c24c6f2c74", + "assets/build/ba_data/textures/robotColorMask.dds": "https://files.ballistica.net/cache/ba1/ec/0e/d1b4b152415679464cd0bf773b94", "assets/build/ba_data/textures/robotColorMask.ktx": "https://files.ballistica.net/cache/ba1/19/4e/6bf15a0ac4ba4ad3bedd5eb3a3f3", "assets/build/ba_data/textures/robotColorMask.pvr": "https://files.ballistica.net/cache/ba1/ee/88/47d89b21335c4ba8916ff4eb11fd", "assets/build/ba_data/textures/robotColorMask_preview.png": "https://files.ballistica.net/cache/ba1/03/fd/c13045e5beed778e19f9a70f81ea", @@ -2242,18 +2242,18 @@ "assets/build/ba_data/textures/robotIconColorMask.pvr": "https://files.ballistica.net/cache/ba1/b8/65/40642024959c225ce4704b954f8f", "assets/build/ba_data/textures/robotIconColorMask_preview.png": "https://files.ballistica.net/cache/ba1/3a/c2/771b5f4aa159f61383b8bbefa291", "assets/build/ba_data/textures/robotIcon_preview.png": "https://files.ballistica.net/cache/ba1/7a/b8/1dad64c97fa4655f70490004cedc", - "assets/build/ba_data/textures/roundaboutLevelColor.dds": "https://files.ballistica.net/cache/ba1/b6/df/cc3d90cdccfc1e07c99a4a5a5851", + "assets/build/ba_data/textures/roundaboutLevelColor.dds": "https://files.ballistica.net/cache/ba1/69/bd/5a0e33f022abb454eebf4b9668ab", "assets/build/ba_data/textures/roundaboutLevelColor.ktx": "https://files.ballistica.net/cache/ba1/19/f8/d8ea41097c6dfe7bec255d85ea0a", "assets/build/ba_data/textures/roundaboutLevelColor.pvr": "https://files.ballistica.net/cache/ba1/0a/5a/19e1f33492b7ae2a9f100cf26fff", "assets/build/ba_data/textures/roundaboutLevelColor_preview.png": "https://files.ballistica.net/cache/ba1/18/c7/7dbe95a06d9e877fbe848f415141", - "assets/build/ba_data/textures/roundaboutPreview.dds": "https://files.ballistica.net/cache/ba1/c5/62/00e8ad165d2350b7136784bc0dc7", + "assets/build/ba_data/textures/roundaboutPreview.dds": "https://files.ballistica.net/cache/ba1/a8/c2/d800722b8b7e172fcf19227abf05", "assets/build/ba_data/textures/roundaboutPreview.ktx": "https://files.ballistica.net/cache/ba1/1f/63/e4776ec44e00a0d736aec31f1dfb", "assets/build/ba_data/textures/roundaboutPreview.pvr": "https://files.ballistica.net/cache/ba1/65/1a/019c03931b513047b9a5fcb7e8af", "assets/build/ba_data/textures/roundaboutPreview_preview.png": "https://files.ballistica.net/cache/ba1/d4/df/d26e050aac7285a6f453185f0046", - "assets/build/ba_data/textures/santaColor.dds": "https://files.ballistica.net/cache/ba1/26/e6/febe3c69537cb30d8f1988cd405d", + "assets/build/ba_data/textures/santaColor.dds": "https://files.ballistica.net/cache/ba1/5f/a1/91e228dda47c28f430ec2ff226b8", "assets/build/ba_data/textures/santaColor.ktx": "https://files.ballistica.net/cache/ba1/cc/f4/de2aaaf8cc855afaaceb1e618409", "assets/build/ba_data/textures/santaColor.pvr": "https://files.ballistica.net/cache/ba1/b6/22/85dfce13ccc2a531a42a91d4dd89", - "assets/build/ba_data/textures/santaColorMask.dds": "https://files.ballistica.net/cache/ba1/5e/5f/6c47e8aa0cdfc92d06bfd3a23b6d", + "assets/build/ba_data/textures/santaColorMask.dds": "https://files.ballistica.net/cache/ba1/8a/9c/db332211cdc1deb5d60ce035d5a8", "assets/build/ba_data/textures/santaColorMask.ktx": "https://files.ballistica.net/cache/ba1/b7/b0/9ebd903f0d9e491fa6a65181de19", "assets/build/ba_data/textures/santaColorMask.pvr": "https://files.ballistica.net/cache/ba1/a8/8c/6ab8ad9a2ea2e907635286163e57", "assets/build/ba_data/textures/santaColorMask_preview.png": "https://files.ballistica.net/cache/ba1/01/c4/436aca37ae86e73db9b7c856056a", @@ -2261,7 +2261,7 @@ "assets/build/ba_data/textures/santaIcon.dds": "https://files.ballistica.net/cache/ba1/50/10/67dc3f02df57883342cc345cf72e", "assets/build/ba_data/textures/santaIcon.ktx": "https://files.ballistica.net/cache/ba1/b7/6c/f22cde80b89403aeb4e950d8e2d2", "assets/build/ba_data/textures/santaIcon.pvr": "https://files.ballistica.net/cache/ba1/a0/4c/24e260da5e86b10a86049503b986", - "assets/build/ba_data/textures/santaIconColorMask.dds": "https://files.ballistica.net/cache/ba1/6c/54/c155cd9278a8411441fe9f68f09b", + "assets/build/ba_data/textures/santaIconColorMask.dds": "https://files.ballistica.net/cache/ba1/9e/36/dbeba27f8008aa3404864070f5bc", "assets/build/ba_data/textures/santaIconColorMask.ktx": "https://files.ballistica.net/cache/ba1/32/7a/c2d2cc16c7be82dbcff72a376f70", "assets/build/ba_data/textures/santaIconColorMask.pvr": "https://files.ballistica.net/cache/ba1/25/db/3dfff995ae0b87511a6bb7cc8b79", "assets/build/ba_data/textures/santaIconColorMask_preview.png": "https://files.ballistica.net/cache/ba1/ca/f2/a9f44952811c708bd50525d4da30", @@ -2310,7 +2310,7 @@ "assets/build/ba_data/textures/slash.ktx": "https://files.ballistica.net/cache/ba1/54/cb/a35780a274f021fc1044b45daf99", "assets/build/ba_data/textures/slash.pvr": "https://files.ballistica.net/cache/ba1/b6/d2/fa0617f78a81fc0eacb962484729", "assets/build/ba_data/textures/slash_preview.png": "https://files.ballistica.net/cache/ba1/33/2f/060dad5afdba8162d7a3ad082df0", - "assets/build/ba_data/textures/smoke.dds": "https://files.ballistica.net/cache/ba1/66/a6/714c50394e08e6709f9470f2f02d", + "assets/build/ba_data/textures/smoke.dds": "https://files.ballistica.net/cache/ba1/c1/b5/f1c19535edd6f9abc74b85a9673a", "assets/build/ba_data/textures/smoke.ktx": "https://files.ballistica.net/cache/ba1/8c/d8/74ac19c7930bbd695f533ec09fa3", "assets/build/ba_data/textures/smoke.pvr": "https://files.ballistica.net/cache/ba1/d7/a5/014c007053212e96096b545626ea", "assets/build/ba_data/textures/smoke_preview.png": "https://files.ballistica.net/cache/ba1/b1/c6/52443210c0229920389219868dcc", @@ -2326,7 +2326,7 @@ "assets/build/ba_data/textures/softRectVertical.pvr": "https://files.ballistica.net/cache/ba1/4d/19/857d457d9b5a0279a80dceea2cd3", "assets/build/ba_data/textures/softRectVertical_preview.png": "https://files.ballistica.net/cache/ba1/56/0f/524a88de51160a96224fb40249c1", "assets/build/ba_data/textures/softRect_preview.png": "https://files.ballistica.net/cache/ba1/5e/31/512ca0d886a0d866f194f875c3db", - "assets/build/ba_data/textures/sparks.dds": "https://files.ballistica.net/cache/ba1/0a/c4/0514ac00c5978979f65fbdf1b56e", + "assets/build/ba_data/textures/sparks.dds": "https://files.ballistica.net/cache/ba1/89/77/00c8ba51a9cf06bfc0a0a427efc3", "assets/build/ba_data/textures/sparks.ktx": "https://files.ballistica.net/cache/ba1/3d/6d/beee025480e5711ecd52bc5f6b07", "assets/build/ba_data/textures/sparks.pvr": "https://files.ballistica.net/cache/ba1/39/af/5b9e1081c0973f5e853c11fa06bc", "assets/build/ba_data/textures/sparks_preview.png": "https://files.ballistica.net/cache/ba1/19/fc/4a53d76b56ea0f0c3d5eaeed93b4", @@ -2338,11 +2338,11 @@ "assets/build/ba_data/textures/startButton.ktx": "https://files.ballistica.net/cache/ba1/ef/9a/9323a447cb7cf8fa119bbeadbf7c", "assets/build/ba_data/textures/startButton.pvr": "https://files.ballistica.net/cache/ba1/a8/25/74bd9ee857764fba362a0ecdc9b3", "assets/build/ba_data/textures/startButton_preview.png": "https://files.ballistica.net/cache/ba1/ba/d5/48858f0b1a1e0e4043762d4b0216", - "assets/build/ba_data/textures/stepRightUpLevelColor.dds": "https://files.ballistica.net/cache/ba1/58/51/eec340a570c3797198bcd9c7c205", + "assets/build/ba_data/textures/stepRightUpLevelColor.dds": "https://files.ballistica.net/cache/ba1/aa/27/277f7741294d367810f01ef150f8", "assets/build/ba_data/textures/stepRightUpLevelColor.ktx": "https://files.ballistica.net/cache/ba1/6f/35/3380ac50585bce22311666d28782", "assets/build/ba_data/textures/stepRightUpLevelColor.pvr": "https://files.ballistica.net/cache/ba1/8b/fb/eba3c0faa304123c784c888d0c65", "assets/build/ba_data/textures/stepRightUpLevelColor_preview.png": "https://files.ballistica.net/cache/ba1/5d/b9/bcdca38ad1d808b541b8008d5555", - "assets/build/ba_data/textures/stepRightUpPreview.dds": "https://files.ballistica.net/cache/ba1/26/45/d61d7173f3875fb5a8e7a748b2df", + "assets/build/ba_data/textures/stepRightUpPreview.dds": "https://files.ballistica.net/cache/ba1/ce/8f/8843ebbc561cf5dd44eb657b797d", "assets/build/ba_data/textures/stepRightUpPreview.ktx": "https://files.ballistica.net/cache/ba1/bd/75/7b19bfb14c8a73ae9a42156d70f2", "assets/build/ba_data/textures/stepRightUpPreview.pvr": "https://files.ballistica.net/cache/ba1/fe/44/e09c5a523cb3e8576709256c79a9", "assets/build/ba_data/textures/stepRightUpPreview_preview.png": "https://files.ballistica.net/cache/ba1/ad/ff/086bca9f87fdc17bae4bd55e904f", @@ -2365,7 +2365,7 @@ "assets/build/ba_data/textures/superheroColor.dds": "https://files.ballistica.net/cache/ba1/20/22/1e1f70c67cdbf49ce120b454f76a", "assets/build/ba_data/textures/superheroColor.ktx": "https://files.ballistica.net/cache/ba1/6d/7c/bc6c4f9b237301fefea90f27f9a0", "assets/build/ba_data/textures/superheroColor.pvr": "https://files.ballistica.net/cache/ba1/48/12/34feeaf8bb9724e3d084b96cda3b", - "assets/build/ba_data/textures/superheroColorMask.dds": "https://files.ballistica.net/cache/ba1/3b/2f/c7890bc048477e15698c7663b3d4", + "assets/build/ba_data/textures/superheroColorMask.dds": "https://files.ballistica.net/cache/ba1/68/a5/b09635c375edc462cf4b102c3236", "assets/build/ba_data/textures/superheroColorMask.ktx": "https://files.ballistica.net/cache/ba1/a5/19/f7169d492c759f9f3416887df9d5", "assets/build/ba_data/textures/superheroColorMask.pvr": "https://files.ballistica.net/cache/ba1/39/dc/256d7b9203f90032bbe21cec3a03", "assets/build/ba_data/textures/superheroColorMask_preview.png": "https://files.ballistica.net/cache/ba1/7d/f0/d05466477b420b25ff7dd881c87b", @@ -2382,11 +2382,11 @@ "assets/build/ba_data/textures/textClearButton.ktx": "https://files.ballistica.net/cache/ba1/05/60/2ae6636eb10907f2973342229949", "assets/build/ba_data/textures/textClearButton.pvr": "https://files.ballistica.net/cache/ba1/b1/32/dc45a735786df68c442b16a62a57", "assets/build/ba_data/textures/textClearButton_preview.png": "https://files.ballistica.net/cache/ba1/12/64/67e74f9e5d77ba1230304ea40497", - "assets/build/ba_data/textures/thePadLevelColor.dds": "https://files.ballistica.net/cache/ba1/7c/0d/09d84d8de458a7bcc7343b65ab9f", + "assets/build/ba_data/textures/thePadLevelColor.dds": "https://files.ballistica.net/cache/ba1/61/17/6fb9d7fef2499c9ef5e3eb7ac928", "assets/build/ba_data/textures/thePadLevelColor.ktx": "https://files.ballistica.net/cache/ba1/4e/34/bf0d6a8b0e64cf7fef14b1ec9da5", "assets/build/ba_data/textures/thePadLevelColor.pvr": "https://files.ballistica.net/cache/ba1/27/ad/471ab1086db8d6669040fc48742a", "assets/build/ba_data/textures/thePadLevelColor_preview.png": "https://files.ballistica.net/cache/ba1/88/1d/42616ff95265cb0d0db6c353a044", - "assets/build/ba_data/textures/thePadPreview.dds": "https://files.ballistica.net/cache/ba1/cd/ee/a4e2f05ada77eab50013534e46fc", + "assets/build/ba_data/textures/thePadPreview.dds": "https://files.ballistica.net/cache/ba1/12/67/c64f2c3a5726712453400859e0f3", "assets/build/ba_data/textures/thePadPreview.ktx": "https://files.ballistica.net/cache/ba1/5e/11/ff9caf9657a7c439b2e0fab39049", "assets/build/ba_data/textures/thePadPreview.pvr": "https://files.ballistica.net/cache/ba1/5a/8f/4061a1deafca6ba331738f6c9db8", "assets/build/ba_data/textures/thePadPreview_preview.png": "https://files.ballistica.net/cache/ba1/94/12/ec4cc8f0378cf62f811122e6faec", @@ -2410,11 +2410,11 @@ "assets/build/ba_data/textures/ticketsMore.pvr": "https://files.ballistica.net/cache/ba1/59/1a/73c4109d96e85316c2c46ff2c025", "assets/build/ba_data/textures/ticketsMore_preview.png": "https://files.ballistica.net/cache/ba1/24/01/32ba85edd6394dd56562f64eee09", "assets/build/ba_data/textures/tickets_preview.png": "https://files.ballistica.net/cache/ba1/90/ce/b693dd116e50d1b0eff488cfdd98", - "assets/build/ba_data/textures/tipTopBGColor.dds": "https://files.ballistica.net/cache/ba1/ac/31/d9009e21104f4131117610ba03a0", + "assets/build/ba_data/textures/tipTopBGColor.dds": "https://files.ballistica.net/cache/ba1/19/bf/258c624e1b3e3e3efabeefe3dd20", "assets/build/ba_data/textures/tipTopBGColor.ktx": "https://files.ballistica.net/cache/ba1/39/8c/a9f1ba489b23f5d899bb3f9941b1", "assets/build/ba_data/textures/tipTopBGColor.pvr": "https://files.ballistica.net/cache/ba1/1b/0d/89ecc99bc58aa985f00f7097177a", "assets/build/ba_data/textures/tipTopBGColor_preview.png": "https://files.ballistica.net/cache/ba1/54/0b/9978639a58e703cece49de6523b7", - "assets/build/ba_data/textures/tipTopLevelColor.dds": "https://files.ballistica.net/cache/ba1/5f/d8/d29d224f0fcdcbf04ce625945baf", + "assets/build/ba_data/textures/tipTopLevelColor.dds": "https://files.ballistica.net/cache/ba1/d9/9d/5887220819a9bceaf547349cc1f3", "assets/build/ba_data/textures/tipTopLevelColor.ktx": "https://files.ballistica.net/cache/ba1/4f/77/17f60fceaa239805af2bb7a169be", "assets/build/ba_data/textures/tipTopLevelColor.pvr": "https://files.ballistica.net/cache/ba1/8b/20/240ddac5158fb481ce41c50a86ce", "assets/build/ba_data/textures/tipTopLevelColor_preview.png": "https://files.ballistica.net/cache/ba1/75/88/019f15db873f836c5651b1b12130", @@ -2434,15 +2434,15 @@ "assets/build/ba_data/textures/touchArrowsActions.pvr": "https://files.ballistica.net/cache/ba1/74/1b/7642cfb899d1337073b10855d01d", "assets/build/ba_data/textures/touchArrowsActions_preview.png": "https://files.ballistica.net/cache/ba1/3c/21/1933b01847e20ed77164097aaea5", "assets/build/ba_data/textures/touchArrows_preview.png": "https://files.ballistica.net/cache/ba1/14/bd/595019a7e3b87bd844f8a60bf04c", - "assets/build/ba_data/textures/towerDLevelColor.dds": "https://files.ballistica.net/cache/ba1/08/c1/8925800c38503c077829f7b3fa96", + "assets/build/ba_data/textures/towerDLevelColor.dds": "https://files.ballistica.net/cache/ba1/8a/1f/997dafb004fe5b2122c66ae66302", "assets/build/ba_data/textures/towerDLevelColor.ktx": "https://files.ballistica.net/cache/ba1/8d/42/47252953095838210efdf6abc37d", "assets/build/ba_data/textures/towerDLevelColor.pvr": "https://files.ballistica.net/cache/ba1/9f/18/de2d35f9737871b3a1a914561428", "assets/build/ba_data/textures/towerDLevelColor_preview.png": "https://files.ballistica.net/cache/ba1/d4/e2/96ed47c7c856cf772a74f7385fab", - "assets/build/ba_data/textures/towerDPreview.dds": "https://files.ballistica.net/cache/ba1/de/cc/3810b38d96b849375c4d9a416665", + "assets/build/ba_data/textures/towerDPreview.dds": "https://files.ballistica.net/cache/ba1/4f/91/7de86add4cdc30060477c93e2aa6", "assets/build/ba_data/textures/towerDPreview.ktx": "https://files.ballistica.net/cache/ba1/e9/3a/d62eb672f3f26757b59f4d6d9e48", "assets/build/ba_data/textures/towerDPreview.pvr": "https://files.ballistica.net/cache/ba1/be/40/cc2ad06c0c08a1b937a2165f3bdb", "assets/build/ba_data/textures/towerDPreview_preview.png": "https://files.ballistica.net/cache/ba1/20/80/2314d36626f44f2ded99773ce267", - "assets/build/ba_data/textures/treesColor.dds": "https://files.ballistica.net/cache/ba1/ff/c9/f24bda9787c79435fea19b8ff647", + "assets/build/ba_data/textures/treesColor.dds": "https://files.ballistica.net/cache/ba1/a9/c6/e78e8aecedb379288c5a2d6e41f0", "assets/build/ba_data/textures/treesColor.ktx": "https://files.ballistica.net/cache/ba1/e7/19/2b8b0c8cfd26839ebd1d514354b7", "assets/build/ba_data/textures/treesColor.pvr": "https://files.ballistica.net/cache/ba1/03/b2/159518817084766a2cc464ba0a1b", "assets/build/ba_data/textures/treesColor_preview.png": "https://files.ballistica.net/cache/ba1/72/2b/7addb4861a6a8cd09748248e4de4", @@ -2470,14 +2470,14 @@ "assets/build/ba_data/textures/usersButton.ktx": "https://files.ballistica.net/cache/ba1/5b/e6/34fb5d6f905c30b3a2b9aa9e5734", "assets/build/ba_data/textures/usersButton.pvr": "https://files.ballistica.net/cache/ba1/0a/de/0f45f12e34557fb1141d7a266a0d", "assets/build/ba_data/textures/usersButton_preview.png": "https://files.ballistica.net/cache/ba1/1a/fc/7d74541cd06ad5db3de119418f81", - "assets/build/ba_data/textures/vrFillMound.dds": "https://files.ballistica.net/cache/ba1/03/2e/06c7ee248c6adef3fde077f4e4e1", + "assets/build/ba_data/textures/vrFillMound.dds": "https://files.ballistica.net/cache/ba1/bc/b3/8e14500bb766cf3639ea003cd9af", "assets/build/ba_data/textures/vrFillMound.ktx": "https://files.ballistica.net/cache/ba1/5d/1e/e86c34fd33355e21955d3d48bfe6", "assets/build/ba_data/textures/vrFillMound.pvr": "https://files.ballistica.net/cache/ba1/e8/da/46ed26badb88b6fd10abc37f35f6", "assets/build/ba_data/textures/vrFillMound_preview.png": "https://files.ballistica.net/cache/ba1/fd/33/4f817cfe06d2f8a04c395a9dc960", "assets/build/ba_data/textures/warriorColor.dds": "https://files.ballistica.net/cache/ba1/f2/51/d42750c9df1f55f39c134c925c7f", "assets/build/ba_data/textures/warriorColor.ktx": "https://files.ballistica.net/cache/ba1/e7/72/6f9a3314300c12b5ffd99a4d0000", "assets/build/ba_data/textures/warriorColor.pvr": "https://files.ballistica.net/cache/ba1/f2/63/d8bf3ba74b47932b4465847ef133", - "assets/build/ba_data/textures/warriorColorMask.dds": "https://files.ballistica.net/cache/ba1/9f/d5/4787b04a7004e2b830f37cea8f2d", + "assets/build/ba_data/textures/warriorColorMask.dds": "https://files.ballistica.net/cache/ba1/e4/4c/e0ccd356704be279c55ad5d7bc68", "assets/build/ba_data/textures/warriorColorMask.ktx": "https://files.ballistica.net/cache/ba1/d4/22/c8c01a12e9ec10f214659ce9faa4", "assets/build/ba_data/textures/warriorColorMask.pvr": "https://files.ballistica.net/cache/ba1/17/c5/87586c89935377cb8d4336713094", "assets/build/ba_data/textures/warriorColorMask_preview.png": "https://files.ballistica.net/cache/ba1/d9/97/16b01e9e4bf3bdc8c57672526158", @@ -2509,7 +2509,7 @@ "assets/build/ba_data/textures/witchColor.dds": "https://files.ballistica.net/cache/ba1/41/36/4b562ef0323d0b3ad88fea31bec8", "assets/build/ba_data/textures/witchColor.ktx": "https://files.ballistica.net/cache/ba1/f2/32/d61ee331287b1c4e508a1f6ea317", "assets/build/ba_data/textures/witchColor.pvr": "https://files.ballistica.net/cache/ba1/e5/f4/1ae61921f42efa27ed72120337a1", - "assets/build/ba_data/textures/witchColorMask.dds": "https://files.ballistica.net/cache/ba1/39/b4/db14abde641fa3b63447936f2f9b", + "assets/build/ba_data/textures/witchColorMask.dds": "https://files.ballistica.net/cache/ba1/85/13/5d498983b93a3b27565525e60e03", "assets/build/ba_data/textures/witchColorMask.ktx": "https://files.ballistica.net/cache/ba1/e0/23/4fb45223a969626489041af0de9f", "assets/build/ba_data/textures/witchColorMask.pvr": "https://files.ballistica.net/cache/ba1/ab/d9/d03a2366b07854e7c82cd0e1e443", "assets/build/ba_data/textures/witchColorMask_preview.png": "https://files.ballistica.net/cache/ba1/49/7f/61faa30b3b091c142c1212a85019", @@ -2522,18 +2522,18 @@ "assets/build/ba_data/textures/witchIconColorMask.pvr": "https://files.ballistica.net/cache/ba1/2e/76/a2b8bfd7868a47c11b2c5fd1660b", "assets/build/ba_data/textures/witchIconColorMask_preview.png": "https://files.ballistica.net/cache/ba1/49/bc/8479175256d1e62e607b2c392f2d", "assets/build/ba_data/textures/witchIcon_preview.png": "https://files.ballistica.net/cache/ba1/5f/96/cb2eb1c3a9fb0240f5748c5c1da5", - "assets/build/ba_data/textures/wizardColor.dds": "https://files.ballistica.net/cache/ba1/91/1b/af0d8cd18532d766b4b129317ed4", + "assets/build/ba_data/textures/wizardColor.dds": "https://files.ballistica.net/cache/ba1/ec/e9/fcbc0fc4d1fc397f8ec5b498337f", "assets/build/ba_data/textures/wizardColor.ktx": "https://files.ballistica.net/cache/ba1/50/da/d0569142ec7924ca40eccf82a930", "assets/build/ba_data/textures/wizardColor.pvr": "https://files.ballistica.net/cache/ba1/11/dc/b7f4a083ef2a93d7834b3d841443", - "assets/build/ba_data/textures/wizardColorMask.dds": "https://files.ballistica.net/cache/ba1/ad/cc/a104746ef03fa4a788e118424fc4", + "assets/build/ba_data/textures/wizardColorMask.dds": "https://files.ballistica.net/cache/ba1/b4/32/3d46d2e5920e7530b384d7626617", "assets/build/ba_data/textures/wizardColorMask.ktx": "https://files.ballistica.net/cache/ba1/0d/0d/80e2b947ebd3dbde1330682f62a4", "assets/build/ba_data/textures/wizardColorMask.pvr": "https://files.ballistica.net/cache/ba1/5a/7c/9933e396902aca69b786468d1c38", "assets/build/ba_data/textures/wizardColorMask_preview.png": "https://files.ballistica.net/cache/ba1/44/93/65a9e806485cd757e6a05655916a", "assets/build/ba_data/textures/wizardColor_preview.png": "https://files.ballistica.net/cache/ba1/cf/3c/3db3b3f5b6dab73f8b8a5353fe1a", - "assets/build/ba_data/textures/wizardIcon.dds": "https://files.ballistica.net/cache/ba1/0a/79/2ccd8ee9c225bf6a969f8f29d5d9", + "assets/build/ba_data/textures/wizardIcon.dds": "https://files.ballistica.net/cache/ba1/e6/2f/74df3fe2e97c960ff1ca64aed588", "assets/build/ba_data/textures/wizardIcon.ktx": "https://files.ballistica.net/cache/ba1/b9/3d/2c10de406177de22b8e89c9cb3b3", "assets/build/ba_data/textures/wizardIcon.pvr": "https://files.ballistica.net/cache/ba1/e3/c0/7d62f35ec06d5c4442a92b175cc0", - "assets/build/ba_data/textures/wizardIconColorMask.dds": "https://files.ballistica.net/cache/ba1/f1/aa/65c24f94a227616f5ef7d1f77bb8", + "assets/build/ba_data/textures/wizardIconColorMask.dds": "https://files.ballistica.net/cache/ba1/b5/16/7f556e4b852a94400388b4c96db4", "assets/build/ba_data/textures/wizardIconColorMask.ktx": "https://files.ballistica.net/cache/ba1/91/17/307bfa8af7dc435aa92dd38158f6", "assets/build/ba_data/textures/wizardIconColorMask.pvr": "https://files.ballistica.net/cache/ba1/3e/31/19cb4995ec02f1884bd35b29a464", "assets/build/ba_data/textures/wizardIconColorMask_preview.png": "https://files.ballistica.net/cache/ba1/20/24/700221546a08f3bc9c31e751ebcc", @@ -2541,7 +2541,7 @@ "assets/build/ba_data/textures/wrestlerColor.dds": "https://files.ballistica.net/cache/ba1/1f/d5/d21adac8982ad713b0bbdbb7ee6c", "assets/build/ba_data/textures/wrestlerColor.ktx": "https://files.ballistica.net/cache/ba1/d7/22/bf15886b227531620eec6462be2d", "assets/build/ba_data/textures/wrestlerColor.pvr": "https://files.ballistica.net/cache/ba1/ab/76/9f573919ed6b9e635f4a014584ba", - "assets/build/ba_data/textures/wrestlerColorMask.dds": "https://files.ballistica.net/cache/ba1/9f/98/98d3c41b83875f850abc3b2c31df", + "assets/build/ba_data/textures/wrestlerColorMask.dds": "https://files.ballistica.net/cache/ba1/fb/a5/472ae89a40a52d189c9337c179fa", "assets/build/ba_data/textures/wrestlerColorMask.ktx": "https://files.ballistica.net/cache/ba1/21/1f/eebe5e1fe740412aad15026d21b5", "assets/build/ba_data/textures/wrestlerColorMask.pvr": "https://files.ballistica.net/cache/ba1/36/43/ef6da6107379ac3f74204a34c529", "assets/build/ba_data/textures/wrestlerColorMask_preview.png": "https://files.ballistica.net/cache/ba1/0c/5f/8619903636053dc0ff1858bf3451", @@ -2554,26 +2554,26 @@ "assets/build/ba_data/textures/wrestlerIconColorMask.pvr": "https://files.ballistica.net/cache/ba1/7b/5d/83a1a0f4d7b06303d5da137e5847", "assets/build/ba_data/textures/wrestlerIconColorMask_preview.png": "https://files.ballistica.net/cache/ba1/b5/74/774b56f03e583df47388c552c63e", "assets/build/ba_data/textures/wrestlerIcon_preview.png": "https://files.ballistica.net/cache/ba1/38/71/8b5f4d69dde24101ce0d69747486", - "assets/build/ba_data/textures/zigZagLevelColor.dds": "https://files.ballistica.net/cache/ba1/ea/cf/a59f7ca3b2f0d7a08e3ad42d83ab", + "assets/build/ba_data/textures/zigZagLevelColor.dds": "https://files.ballistica.net/cache/ba1/df/17/9994816ad67f481800bae16f2db2", "assets/build/ba_data/textures/zigZagLevelColor.ktx": "https://files.ballistica.net/cache/ba1/c1/1e/82884d1423ce4a7d641003e84bfb", "assets/build/ba_data/textures/zigZagLevelColor.pvr": "https://files.ballistica.net/cache/ba1/56/df/c53d264147677138e47799ea990e", "assets/build/ba_data/textures/zigZagLevelColor_preview.png": "https://files.ballistica.net/cache/ba1/cd/d7/b45e95db0117c4fe5d957136b4bb", - "assets/build/ba_data/textures/zigzagPreview.dds": "https://files.ballistica.net/cache/ba1/00/3b/3a7f2ab4aed12f4d911e94093002", + "assets/build/ba_data/textures/zigzagPreview.dds": "https://files.ballistica.net/cache/ba1/6c/13/64e4a3570343f8a8965b8c6bb318", "assets/build/ba_data/textures/zigzagPreview.ktx": "https://files.ballistica.net/cache/ba1/33/ca/b022d38b1306d8382c2ecdb270b9", "assets/build/ba_data/textures/zigzagPreview.pvr": "https://files.ballistica.net/cache/ba1/0e/21/4f296b4440f8467c904221d18400", "assets/build/ba_data/textures/zigzagPreview_preview.png": "https://files.ballistica.net/cache/ba1/f4/32/1f69e507893d054aca0371c31248", - "assets/build/ba_data/textures/zoeColor.dds": "https://files.ballistica.net/cache/ba1/82/6e/c531db13a3eff5a2e37c32af79c1", + "assets/build/ba_data/textures/zoeColor.dds": "https://files.ballistica.net/cache/ba1/05/e4/93016a653b2bb3433138594c9c0e", "assets/build/ba_data/textures/zoeColor.ktx": "https://files.ballistica.net/cache/ba1/8d/80/906fb08660e1fcde3f5997108abf", "assets/build/ba_data/textures/zoeColor.pvr": "https://files.ballistica.net/cache/ba1/4a/74/8ca47effb87502b7334398e967be", - "assets/build/ba_data/textures/zoeColorMask.dds": "https://files.ballistica.net/cache/ba1/eb/a5/a71bc5739b02d7101dbd29e6b81b", + "assets/build/ba_data/textures/zoeColorMask.dds": "https://files.ballistica.net/cache/ba1/b6/06/e4086e65b697d7de1c8864f49029", "assets/build/ba_data/textures/zoeColorMask.ktx": "https://files.ballistica.net/cache/ba1/b9/32/91c389da7403df50125cddc37575", "assets/build/ba_data/textures/zoeColorMask.pvr": "https://files.ballistica.net/cache/ba1/f4/6a/4cbdbcf47abdb7f8fdc8d283451e", "assets/build/ba_data/textures/zoeColorMask_preview.png": "https://files.ballistica.net/cache/ba1/ca/0e/66481610316607e9adcb456467d1", "assets/build/ba_data/textures/zoeColor_preview.png": "https://files.ballistica.net/cache/ba1/3b/3e/91abd548d271a97df63b327a1f82", - "assets/build/ba_data/textures/zoeIcon.dds": "https://files.ballistica.net/cache/ba1/23/d4/d1b9a5a9fd790beb494b823f7a35", + "assets/build/ba_data/textures/zoeIcon.dds": "https://files.ballistica.net/cache/ba1/da/63/063fc70b4a22b7a0f32ca8e9f8b4", "assets/build/ba_data/textures/zoeIcon.ktx": "https://files.ballistica.net/cache/ba1/fd/75/88d1a4355980906272cf904bd722", "assets/build/ba_data/textures/zoeIcon.pvr": "https://files.ballistica.net/cache/ba1/7c/66/7959cdfaa884068bdb11db1ef330", - "assets/build/ba_data/textures/zoeIconColorMask.dds": "https://files.ballistica.net/cache/ba1/0b/61/f5e3848c72b5359e129ed7fd9ee0", + "assets/build/ba_data/textures/zoeIconColorMask.dds": "https://files.ballistica.net/cache/ba1/75/06/c186a1ad6e54ba6d8862b23c2136", "assets/build/ba_data/textures/zoeIconColorMask.ktx": "https://files.ballistica.net/cache/ba1/bd/eb/deb5899cffa81a665248e3062363", "assets/build/ba_data/textures/zoeIconColorMask.pvr": "https://files.ballistica.net/cache/ba1/2b/dc/22df1ef245a7f368060d2eecb839", "assets/build/ba_data/textures/zoeIconColorMask_preview.png": "https://files.ballistica.net/cache/ba1/d5/08/7d5e28abf51591fb4923892f43dd", @@ -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/72/15/a3419621532792868f14916bd34a", - "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/18/ac/ee5f88a1c29b499ffa41a69cdf38", - "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/ac/47/e5ec1b1a7a8b9c84e2f2f2b8300e", - "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/60/7f/59e5077df04a756b7afc627a4c7b", - "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/db/2d/49a6bbb0d77513f30a07687f051c", - "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/f0/7b/dcaeb5c6221bf5257e45581e926b", - "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/56/3e/f81e23d9b0bf3f4c6359f6428801", - "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/1f/9a/5afb53b0a127144f92203e40c25b", - "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/61/e0/a4ba0178462217007cf112667c13", - "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/c6/c2/4b35be76f242ba55a9344476abd7", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/e8/9a/efc48010be9a619bb7b634027075", - "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/21/ee/92682d84a0db7135e8f408489cce", - "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/7a/32/230627534f1fcace63c79d0bd8d5", - "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/2f/96/1df9bb9cdac82d644faf3c13b4cd", - "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/64/55/aab8e044fd15398a88d31c9fb51b", - "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/6c/9c/49105190245fbcab5cd93005ab81", - "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/fb/49/9e0f204242ae3b8d24341674325d", - "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/22/b6/219dd7ff36d458f41dcedb01c212", - "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/7d/c3/b10f13471461e58a36e44a342788", - "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/4e/eb/508149422a89e63891d110a9ab81", - "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/28/9d/ecf9b1e3f0cc39c627007a6625ec", + "build/prefab/full/linux_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/71/7a/0bb7d72ca8ac1fe10fe008127880", + "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/53/0f/d0d74f0bcf19e8a610768a8a42a2", + "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/f4/be/f713686f27fe0b1967aff72653ba", + "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/97/62/9fb7f250d52fa2e1455a6c537953", + "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/f5/e8/8cfeae03ad4bc04074a7e86d493d", + "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/d2/b2/846f62ef4e25589959a8f9f98505", + "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/06/ba/42366d10fe88573efd60b5baaf7b", + "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/8e/43/daae498beeca536d8e550d20b79f", + "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/c8/8e/5dfece7c0d71431f1d58d7af6d25", + "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/4d/53/1ca6da109d06a45e4ff02d2e85c9", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/d8/fd/e2bb0454640569545eb2cb44832c", + "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/4c/f9/3c3049396ee7f171b4515ce5607e", + "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/af/b6/95902f975a47d4b02c6142e05b12", + "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/1d/02/8556f4f657a0079f8b04459bdc85", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/ad/99/c6430c6f0574d8a9161970c80095", + "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/10/41/2d7167ae6b0e1923d6d70f12111d", + "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/57/f8/a2d6941211c9a0a621307490cfcd", + "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/21/df/bb23493a7e2a12052b3270f909b3", + "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/a4/4a/4238ebba5f5e3e5fcd5499192b48", + "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/fe/cf/84b8059cfacd0261e9c2943cdaca", + "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a2/9d/285cd73953e62fdb7945c09fb83c", "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/22/2d/3df4908dfdcdebe772bf3df0daee", - "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/76/a1/1487a3b3320bbaf56f966294f1e6", + "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/2a/74/763faee36da963364e94996429d5", "build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/87/9f/4408f47d293436f420ff9338dca6", - "build/prefab/lib/linux_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/b1/e2/cb8a3c638ea0ae97bd7ad843d65c", + "build/prefab/lib/linux_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/4f/e8/2518fd177b5c51f89ef0795b1264", "build/prefab/lib/linux_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/77/b1/41befd66869830590f00bff7ba97", - "build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/58/58/64ca6d95f17cc2c0f3dd622e726c", + "build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/92/a2/8d6f01537d722803aab60cb67e6d", "build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/fc/be/0e1af48000395cdbe72179dba90a", "build/prefab/lib/mac_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/20/7a/b31ec8c47d67b7fd23ed2510aae7", "build/prefab/lib/mac_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a0/b5/b4ffd9769f3b703226e744423a58", "build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/3b/02/9e8f15c68ca328a7549846d53a8f", "build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a0/74/b61b74ada26b41f421563b535dd0", - "build/prefab/lib/mac_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/cb/76/6be6a4353ba029f0926d44a2bc38", + "build/prefab/lib/mac_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ec/5c/08c171db06bd4492a2b414c77488", "build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/2f/8a/0384cc905ba23bd45afdfcacb882", - "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/55/ea/ac29558ce9735f704fc1fc32d769", + "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/63/6f/e6ba3560e0a8e404bb592405de27", "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/6e/14/c4f70a74e2111e3adb096dfbd215", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/b9/e0/02fdc0a225e6ec118ed7f5244b58", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/d1/43/754722685a834ab3779850af54af", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/79/2d/b37cf8c48d05b6a7313552506c4a", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/df/ef/849dacb5977c53749d8516ec4a85", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/bd/ee/c751ff7a69e4174eef5040d07b2e", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/00/9d/25c03c0cfc21ab1a619806a3e300", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/5f/e7/338348603f27430ea5adb4089d0b", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/c6/6e/1126f1605e6e46a822e89a2147b9", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/64/34/4fb57218d72dd96ebd773d038b9e", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/e9/85/fce0278db5f65c6eebe538bc6e8a", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/e7/94/9a9303c4dcdc9f19aa6d14fde9b4", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/94/15/0f51426585729738fb6bcec10dcc", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/fe/db/eacb9929f586fa69c952eff0e710", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/ab/c8/478b908fbc91f09eee627c54b402", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/b8/69/26e9d56eb7379cb60e6d62c0922e", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/c9/b7/c083c6dbd82bf50b81ba2eb676e3", "src/ballistica/generated/python_embedded/binding.inc": "https://files.ballistica.net/cache/ba1/25/77/8093dfffddaa80cd513ddaa61867", "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/CHANGELOG.md b/CHANGELOG.md index 4095fb1f..4cf8ba9b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -### 1.7.16 (build 20961, api 7, 2022-12-06) +### 1.7.16 (build 20962, api 7, 2022-12-07) - Fixed a bug where profile names encased in curly brackets could cause harmless error messages. - Android will no longer log errors on ba.open_url() calls if a browser is not available (it still just falls back to the in-app dialog in that case). - The 'Upgrade' button for device accounts now signs you out and closes the upgrade window to hopefully make it more clear that you need to sign in with your newly created/upgraded BombSquad account. diff --git a/assets/src/ba_data/python/ba/_bootstrap.py b/assets/src/ba_data/python/ba/_bootstrap.py index ba6ab50d..801e6fd9 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 = 20961 + expected_build = 20962 running_build: int = env['build_number'] if running_build != expected_build: print( diff --git a/src/ballistica/ballistica.cc b/src/ballistica/ballistica.cc index 310acbd1..99e5ccbe 100644 --- a/src/ballistica/ballistica.cc +++ b/src/ballistica/ballistica.cc @@ -32,7 +32,7 @@ namespace ballistica { // These are set automatically via script; don't modify them here. -const int kAppBuildNumber = 20961; +const int kAppBuildNumber = 20962; const char* kAppVersion = "1.7.16"; // Our standalone globals. From 46a18171c62ae4a965dd898c23e1f104dcadbe45 Mon Sep 17 00:00:00 2001 From: Eric Date: Thu, 8 Dec 2022 14:36:00 -0800 Subject: [PATCH 10/26] fix for early bsremote connection bug --- .efrocachemap | 44 +++++++++---------- .idea/dictionaries/ericf.xml | 1 + CHANGELOG.md | 3 +- assets/src/ba_data/python/ba/_bootstrap.py | 2 +- .../.idea/dictionaries/ericf.xml | 1 + src/ballistica/ballistica.cc | 2 +- src/ballistica/input/remote_app.cc | 6 ++- 7 files changed, 32 insertions(+), 27 deletions(-) diff --git a/.efrocachemap b/.efrocachemap index a12af0c5..8e4e0f44 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -420,7 +420,7 @@ "assets/build/ba_data/audio/zoeOw.ogg": "https://files.ballistica.net/cache/ba1/60/ad/38269b7f1c7dc20cb9a506cd0681", "assets/build/ba_data/audio/zoePickup01.ogg": "https://files.ballistica.net/cache/ba1/72/85/d6fc4d16b7081d91fba2850b5b10", "assets/build/ba_data/audio/zoeScream01.ogg": "https://files.ballistica.net/cache/ba1/e9/ae/1d674d0c086eaa0bd1c3b1db0505", - "assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/df/d4/b9814c484722df1380894b9f8661", + "assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/82/b0/714f4683c01a746f516710612b6e", "assets/build/ba_data/data/languages/arabic.json": "https://files.ballistica.net/cache/ba1/c5/81/e386a592e4fdf702b9089f106610", "assets/build/ba_data/data/languages/belarussian.json": "https://files.ballistica.net/cache/ba1/61/03/89070ca765e06da3a419a579f503", "assets/build/ba_data/data/languages/chinese.json": "https://files.ballistica.net/cache/ba1/d3/84/5e7df03070af059070ad1bd93cee", @@ -432,7 +432,7 @@ "assets/build/ba_data/data/languages/english.json": "https://files.ballistica.net/cache/ba1/91/8c/67fb1ca2b8f256f133950b41ba2c", "assets/build/ba_data/data/languages/esperanto.json": "https://files.ballistica.net/cache/ba1/ac/f5/c0922a99e40dfc9f5e026d43b533", "assets/build/ba_data/data/languages/filipino.json": "https://files.ballistica.net/cache/ba1/86/26/060476f46994c035ae0d52640657", - "assets/build/ba_data/data/languages/french.json": "https://files.ballistica.net/cache/ba1/c7/cf/35a6ebc876c7476b72547a914d07", + "assets/build/ba_data/data/languages/french.json": "https://files.ballistica.net/cache/ba1/5d/2a/a5363cbe713fd67ea0baaa44403a", "assets/build/ba_data/data/languages/german.json": "https://files.ballistica.net/cache/ba1/06/58/071d6f7bbb5e93a3e074dbd323ae", "assets/build/ba_data/data/languages/gibberish.json": "https://files.ballistica.net/cache/ba1/45/e1/32cc8660b71d3d6b5fe1faff694d", "assets/build/ba_data/data/languages/greek.json": "https://files.ballistica.net/cache/ba1/8a/82/392f2a4e0e6e5a5e367f19e49538", @@ -4003,26 +4003,26 @@ "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/71/7a/0bb7d72ca8ac1fe10fe008127880", - "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/53/0f/d0d74f0bcf19e8a610768a8a42a2", - "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/f4/be/f713686f27fe0b1967aff72653ba", - "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/97/62/9fb7f250d52fa2e1455a6c537953", - "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/f5/e8/8cfeae03ad4bc04074a7e86d493d", - "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/d2/b2/846f62ef4e25589959a8f9f98505", - "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/06/ba/42366d10fe88573efd60b5baaf7b", - "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/8e/43/daae498beeca536d8e550d20b79f", - "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/c8/8e/5dfece7c0d71431f1d58d7af6d25", - "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/4d/53/1ca6da109d06a45e4ff02d2e85c9", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/d8/fd/e2bb0454640569545eb2cb44832c", - "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/4c/f9/3c3049396ee7f171b4515ce5607e", - "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/af/b6/95902f975a47d4b02c6142e05b12", - "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/1d/02/8556f4f657a0079f8b04459bdc85", - "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/ad/99/c6430c6f0574d8a9161970c80095", - "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/10/41/2d7167ae6b0e1923d6d70f12111d", - "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/57/f8/a2d6941211c9a0a621307490cfcd", - "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/21/df/bb23493a7e2a12052b3270f909b3", - "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/a4/4a/4238ebba5f5e3e5fcd5499192b48", - "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/fe/cf/84b8059cfacd0261e9c2943cdaca", + "build/prefab/full/linux_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/02/50/7fd361fc7503bd6511dafe947737", + "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/cd/f1/fc3ad4cb576876298e3da037baed", + "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/5d/f4/c7c37b0ed8386fc204d5321e0ab9", + "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/a7/a8/4768f13ef21d2d3b384e806f06f6", + "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/63/38/bef42b4c6a1f742f0c9e63a9b16d", + "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/9c/f3/b3b46212ab0b146938a20990d800", + "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/1b/29/79f4ebdcb096ad83aaf752fb3701", + "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/02/f8/23419184457a183af712403a1352", + "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/b3/dc/892643ac9d8ec706229f866bbb6e", + "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/03/9e/8144ef6cd3db9fc5e71ee75371e5", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/f4/29/de145f02e7b8636995132c7b73b1", + "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/d3/1e/f9ef9e2189ca84d24df7322ca220", + "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/10/dd/1e10c03dd72a683d8cd281f514d4", + "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/aa/91/e421baaab4757358888ad44828b9", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/6d/84/c6675d46d85ebb2160c0de08d0c6", + "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/da/13/7bed9b02db2bd5983612694c5184", + "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/5d/c9/3e74ab03a580875a5cb032f7b0a2", + "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/ab/88/ca7e637cc7df91a9795ed4908446", + "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/26/3c/89b35d14dd9f6b703508d6bca998", + "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/2d/89/f67a14b5fc94c31767a2c9eb6d53", "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a2/9d/285cd73953e62fdb7945c09fb83c", "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/22/2d/3df4908dfdcdebe772bf3df0daee", "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/2a/74/763faee36da963364e94996429d5", diff --git a/.idea/dictionaries/ericf.xml b/.idea/dictionaries/ericf.xml index 32534d60..ccea1e37 100644 --- a/.idea/dictionaries/ericf.xml +++ b/.idea/dictionaries/ericf.xml @@ -679,6 +679,7 @@ dosomething dostar dostuff + downcasting downmix dpad dpath diff --git a/CHANGELOG.md b/CHANGELOG.md index 4cf8ba9b..4bf94ffa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,8 @@ -### 1.7.16 (build 20962, api 7, 2022-12-07) +### 1.7.16 (build 20963, api 7, 2022-12-08) - Fixed a bug where profile names encased in curly brackets could cause harmless error messages. - Android will no longer log errors on ba.open_url() calls if a browser is not available (it still just falls back to the in-app dialog in that case). - The 'Upgrade' button for device accounts now signs you out and closes the upgrade window to hopefully make it more clear that you need to sign in with your newly created/upgraded BombSquad account. +- Fixed a bug where the remote app could not connect for the first 5 seconds after launching the app. ### 1.7.15 (build 20960, api 7, 2022-12-04) - The cancel button on the 'Sign in with a Bombsquad Account' popup no longer respond to system cancel buttons (escape key, android back button, etc). Turns out some Android people were pressing back repeatedly to come back from a browser after signing in and immediately canceling their sign in attempts in the game before they completed. Hopefully this will avoid some frustration. diff --git a/assets/src/ba_data/python/ba/_bootstrap.py b/assets/src/ba_data/python/ba/_bootstrap.py index 801e6fd9..0f5821ec 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 = 20962 + expected_build = 20963 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 de0fbb15..d584d5dc 100644 --- a/ballisticacore-cmake/.idea/dictionaries/ericf.xml +++ b/ballisticacore-cmake/.idea/dictionaries/ericf.xml @@ -369,6 +369,7 @@ doraise dosomething dout + downcasting downsample dpad dpads diff --git a/src/ballistica/ballistica.cc b/src/ballistica/ballistica.cc index 99e5ccbe..6455dac7 100644 --- a/src/ballistica/ballistica.cc +++ b/src/ballistica/ballistica.cc @@ -32,7 +32,7 @@ namespace ballistica { // These are set automatically via script; don't modify them here. -const int kAppBuildNumber = 20962; +const int kAppBuildNumber = 20963; const char* kAppVersion = "1.7.16"; // Our standalone globals. diff --git a/src/ballistica/input/remote_app.cc b/src/ballistica/input/remote_app.cc index 43c3549a..09320c24 100644 --- a/src/ballistica/input/remote_app.cc +++ b/src/ballistica/input/remote_app.cc @@ -377,12 +377,14 @@ auto RemoteAppServer::GetClient(int request_id, struct sockaddr* addr, } } - // Don't reuse a slot for 5 seconds. + // Don't reuse a slot for 5 seconds (if its been heard from since this time). millisecs_t cooldown_time = GetRealTime() - 5000; // Ok, not there already.. now look for a non-taken one and return that. for (int i = 0; i < kMaxRemoteAppClients; i++) { - if (!clients_[i].in_use && clients_[i].last_contact_time < cooldown_time) { + if (!clients_[i].in_use + && (clients_[i].last_contact_time == 0 + || clients_[i].last_contact_time < cooldown_time)) { // Ok lets fill out the client. clients_[i].in_use = true; clients_[i].next_state_id = 0; From f5eda68e325b0dd76ed1e285ce260142f3c59af8 Mon Sep 17 00:00:00 2001 From: Eric Date: Sat, 10 Dec 2022 10:56:44 -0800 Subject: [PATCH 11/26] languages and tidying --- .efrocachemap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.efrocachemap b/.efrocachemap index 8e4e0f44..92108362 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -433,7 +433,7 @@ "assets/build/ba_data/data/languages/esperanto.json": "https://files.ballistica.net/cache/ba1/ac/f5/c0922a99e40dfc9f5e026d43b533", "assets/build/ba_data/data/languages/filipino.json": "https://files.ballistica.net/cache/ba1/86/26/060476f46994c035ae0d52640657", "assets/build/ba_data/data/languages/french.json": "https://files.ballistica.net/cache/ba1/5d/2a/a5363cbe713fd67ea0baaa44403a", - "assets/build/ba_data/data/languages/german.json": "https://files.ballistica.net/cache/ba1/06/58/071d6f7bbb5e93a3e074dbd323ae", + "assets/build/ba_data/data/languages/german.json": "https://files.ballistica.net/cache/ba1/58/40/5315a0f4ebbd58c6cb3390907f9a", "assets/build/ba_data/data/languages/gibberish.json": "https://files.ballistica.net/cache/ba1/45/e1/32cc8660b71d3d6b5fe1faff694d", "assets/build/ba_data/data/languages/greek.json": "https://files.ballistica.net/cache/ba1/8a/82/392f2a4e0e6e5a5e367f19e49538", "assets/build/ba_data/data/languages/hindi.json": "https://files.ballistica.net/cache/ba1/9f/df/469e166c6a0d42bca4baae3a6cb6", From 8e39622bab496def9939119c7e1ae5077372141b Mon Sep 17 00:00:00 2001 From: Eric Date: Sun, 11 Dec 2022 09:51:53 -0800 Subject: [PATCH 12/26] added malay language and other lang updates --- .efrocachemap | 47 +++++++++---------- CHANGELOG.md | 1 + assets/.asset_manifest_private.json | 1 + assets/Makefile | 1 + assets/src/ba_data/python/ba/_language.py | 55 ++++++++++++----------- 5 files changed, 55 insertions(+), 50 deletions(-) diff --git a/.efrocachemap b/.efrocachemap index 92108362..dcae0fe6 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -420,7 +420,7 @@ "assets/build/ba_data/audio/zoeOw.ogg": "https://files.ballistica.net/cache/ba1/60/ad/38269b7f1c7dc20cb9a506cd0681", "assets/build/ba_data/audio/zoePickup01.ogg": "https://files.ballistica.net/cache/ba1/72/85/d6fc4d16b7081d91fba2850b5b10", "assets/build/ba_data/audio/zoeScream01.ogg": "https://files.ballistica.net/cache/ba1/e9/ae/1d674d0c086eaa0bd1c3b1db0505", - "assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/82/b0/714f4683c01a746f516710612b6e", + "assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/f0/2d/dbe45794f17260f2961831c88a36", "assets/build/ba_data/data/languages/arabic.json": "https://files.ballistica.net/cache/ba1/c5/81/e386a592e4fdf702b9089f106610", "assets/build/ba_data/data/languages/belarussian.json": "https://files.ballistica.net/cache/ba1/61/03/89070ca765e06da3a419a579f503", "assets/build/ba_data/data/languages/chinese.json": "https://files.ballistica.net/cache/ba1/d3/84/5e7df03070af059070ad1bd93cee", @@ -429,18 +429,19 @@ "assets/build/ba_data/data/languages/czech.json": "https://files.ballistica.net/cache/ba1/cb/df/f2d54d3146a159c678a47d3ff01b", "assets/build/ba_data/data/languages/danish.json": "https://files.ballistica.net/cache/ba1/6a/fa/fcf4a804beaff927b0f12c179eaa", "assets/build/ba_data/data/languages/dutch.json": "https://files.ballistica.net/cache/ba1/68/93/da8e9874f41a786edf52ba4ccaad", - "assets/build/ba_data/data/languages/english.json": "https://files.ballistica.net/cache/ba1/91/8c/67fb1ca2b8f256f133950b41ba2c", + "assets/build/ba_data/data/languages/english.json": "https://files.ballistica.net/cache/ba1/1f/55/bd97a0f23f4deba2a72ad9ab549e", "assets/build/ba_data/data/languages/esperanto.json": "https://files.ballistica.net/cache/ba1/ac/f5/c0922a99e40dfc9f5e026d43b533", - "assets/build/ba_data/data/languages/filipino.json": "https://files.ballistica.net/cache/ba1/86/26/060476f46994c035ae0d52640657", + "assets/build/ba_data/data/languages/filipino.json": "https://files.ballistica.net/cache/ba1/22/5e/6ef2e291465bfb12998f0e23616a", "assets/build/ba_data/data/languages/french.json": "https://files.ballistica.net/cache/ba1/5d/2a/a5363cbe713fd67ea0baaa44403a", "assets/build/ba_data/data/languages/german.json": "https://files.ballistica.net/cache/ba1/58/40/5315a0f4ebbd58c6cb3390907f9a", - "assets/build/ba_data/data/languages/gibberish.json": "https://files.ballistica.net/cache/ba1/45/e1/32cc8660b71d3d6b5fe1faff694d", + "assets/build/ba_data/data/languages/gibberish.json": "https://files.ballistica.net/cache/ba1/d5/65/40add8ed982fb1abb8f120651a1d", "assets/build/ba_data/data/languages/greek.json": "https://files.ballistica.net/cache/ba1/8a/82/392f2a4e0e6e5a5e367f19e49538", - "assets/build/ba_data/data/languages/hindi.json": "https://files.ballistica.net/cache/ba1/9f/df/469e166c6a0d42bca4baae3a6cb6", + "assets/build/ba_data/data/languages/hindi.json": "https://files.ballistica.net/cache/ba1/2e/d1/b506ddf3d27af7be1ae6159531a3", "assets/build/ba_data/data/languages/hungarian.json": "https://files.ballistica.net/cache/ba1/b2/81/53c8cd7617d649403e539c3a6171", "assets/build/ba_data/data/languages/indonesian.json": "https://files.ballistica.net/cache/ba1/38/74/88d1ed374207750c9a834cddb809", "assets/build/ba_data/data/languages/italian.json": "https://files.ballistica.net/cache/ba1/ce/09/20c87e343b41ec5dc43138ce071e", "assets/build/ba_data/data/languages/korean.json": "https://files.ballistica.net/cache/ba1/7c/38/d4a44c481757d355836f292ede48", + "assets/build/ba_data/data/languages/malay.json": "https://files.ballistica.net/cache/ba1/66/32/92ae734c4358397d2e90c1c85325", "assets/build/ba_data/data/languages/persian.json": "https://files.ballistica.net/cache/ba1/db/14/2f441ccb65023775dc8139a63f3f", "assets/build/ba_data/data/languages/polish.json": "https://files.ballistica.net/cache/ba1/67/93/372c2a2428a830056e9ba22bbf95", "assets/build/ba_data/data/languages/portuguese.json": "https://files.ballistica.net/cache/ba1/03/14/6b767289325368be52e24ed3a58a", @@ -4011,18 +4012,18 @@ "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/9c/f3/b3b46212ab0b146938a20990d800", "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/1b/29/79f4ebdcb096ad83aaf752fb3701", "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/02/f8/23419184457a183af712403a1352", - "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/b3/dc/892643ac9d8ec706229f866bbb6e", + "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/f8/e7/fdb608da459208f4e6fc8372106b", "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/03/9e/8144ef6cd3db9fc5e71ee75371e5", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/f4/29/de145f02e7b8636995132c7b73b1", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/9b/a9/57eda2e68544bd0c36fa13cffd2b", "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/d3/1e/f9ef9e2189ca84d24df7322ca220", - "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/10/dd/1e10c03dd72a683d8cd281f514d4", - "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/aa/91/e421baaab4757358888ad44828b9", - "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/6d/84/c6675d46d85ebb2160c0de08d0c6", - "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/da/13/7bed9b02db2bd5983612694c5184", - "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/5d/c9/3e74ab03a580875a5cb032f7b0a2", - "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/ab/88/ca7e637cc7df91a9795ed4908446", - "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/26/3c/89b35d14dd9f6b703508d6bca998", - "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/2d/89/f67a14b5fc94c31767a2c9eb6d53", + "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/50/6e/aefb6451ab6f7fa2851297011cba", + "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/a1/c9/6d07587d3b2e8c1862dccfef4e94", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/ab/4e/91d2d27cf15792c17829549580ca", + "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/a1/f9/12bf33e3b52202e6853adacba2a7", + "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/e7/44/52c8c2ab2abd417b568ccab82898", + "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/18/37/f7817784360e6c7b093c296a60b6", + "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/13/db/2af6ebf94790575c036a051c5b20", + "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/42/c3/cbeba6007e0a326abd9731bcb9fe", "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a2/9d/285cd73953e62fdb7945c09fb83c", "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/22/2d/3df4908dfdcdebe772bf3df0daee", "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/2a/74/763faee36da963364e94996429d5", @@ -4039,14 +4040,14 @@ "build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/2f/8a/0384cc905ba23bd45afdfcacb882", "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/63/6f/e6ba3560e0a8e404bb592405de27", "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/6e/14/c4f70a74e2111e3adb096dfbd215", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/64/34/4fb57218d72dd96ebd773d038b9e", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/e9/85/fce0278db5f65c6eebe538bc6e8a", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/e7/94/9a9303c4dcdc9f19aa6d14fde9b4", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/94/15/0f51426585729738fb6bcec10dcc", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/fe/db/eacb9929f586fa69c952eff0e710", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/ab/c8/478b908fbc91f09eee627c54b402", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/b8/69/26e9d56eb7379cb60e6d62c0922e", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/c9/b7/c083c6dbd82bf50b81ba2eb676e3", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/7c/1c/09d20642216c867d8a0adfddff95", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/a7/ff/e4d363b28c753ed796fff546b9fb", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/77/e9/f62f482ec7efe2b758b2f541b841", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/5e/fb/52723ebc5ba87a95ae3342826d2c", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/11/be/7dcecaa97f8eac0183307c5b0e7d", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/50/79/eb8f282ab42ca5fc6c9c088d87a6", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/74/08/8f1403844c6a9562ae076a4451a3", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/96/52/846ce7853177655441ec7085113c", "src/ballistica/generated/python_embedded/binding.inc": "https://files.ballistica.net/cache/ba1/25/77/8093dfffddaa80cd513ddaa61867", "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/CHANGELOG.md b/CHANGELOG.md index 4bf94ffa..fe05359f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ - Android will no longer log errors on ba.open_url() calls if a browser is not available (it still just falls back to the in-app dialog in that case). - The 'Upgrade' button for device accounts now signs you out and closes the upgrade window to hopefully make it more clear that you need to sign in with your newly created/upgraded BombSquad account. - Fixed a bug where the remote app could not connect for the first 5 seconds after launching the app. +- Added Malay language. Ick; apparently its been sitting done for a while and I hadn't realized it wasn't added to the game yet. Apologies!. And thanks to all contributors! ### 1.7.15 (build 20960, api 7, 2022-12-04) - The cancel button on the 'Sign in with a Bombsquad Account' popup no longer respond to system cancel buttons (escape key, android back button, etc). Turns out some Android people were pressing back repeatedly to come back from a browser after signing in and immediately canceling their sign in attempts in the game before they completed. Hopefully this will avoid some frustration. diff --git a/assets/.asset_manifest_private.json b/assets/.asset_manifest_private.json index 68e5523f..9fd06197 100644 --- a/assets/.asset_manifest_private.json +++ b/assets/.asset_manifest_private.json @@ -441,6 +441,7 @@ "ba_data/data/languages/indonesian.json", "ba_data/data/languages/italian.json", "ba_data/data/languages/korean.json", + "ba_data/data/languages/malay.json", "ba_data/data/languages/persian.json", "ba_data/data/languages/polish.json", "ba_data/data/languages/portuguese.json", diff --git a/assets/Makefile b/assets/Makefile index e764adfc..6734f2fb 100644 --- a/assets/Makefile +++ b/assets/Makefile @@ -4917,6 +4917,7 @@ DATA_TARGETS = \ build/ba_data/data/languages/indonesian.json \ build/ba_data/data/languages/italian.json \ build/ba_data/data/languages/korean.json \ + build/ba_data/data/languages/malay.json \ build/ba_data/data/languages/persian.json \ build/ba_data/data/languages/polish.json \ build/ba_data/data/languages/portuguese.json \ diff --git a/assets/src/ba_data/python/ba/_language.py b/assets/src/ba_data/python/ba/_language.py index 9d1fbecc..812f1ec9 100644 --- a/assets/src/ba_data/python/ba/_language.py +++ b/assets/src/ba_data/python/ba/_language.py @@ -67,38 +67,39 @@ class LanguageSubsystem: def _get_default_language(self) -> str: languages = { + 'ar': 'Arabic', + 'be': 'Belarussian', + 'zh': 'Chinese', + 'hr': 'Croatian', + 'cs': 'Czech', + 'da': 'Danish', + 'nl': 'Dutch', + 'eo': 'Esperanto', + 'fil': 'Filipino', + 'fr': 'French', 'de': 'German', + 'el': 'Greek', + 'hi': 'Hindi', + 'hu': 'Hungarian', + 'id': 'Indonesian', + 'it': 'Italian', + 'ko': 'Korean', + 'ms': 'Malay', + 'fa': 'Persian', + 'pl': 'Polish', + 'pt': 'Portuguese', + 'ro': 'Romanian', + 'ru': 'Russian', + 'sr': 'Serbian', 'es': 'Spanish', 'sk': 'Slovak', - 'it': 'Italian', - 'nl': 'Dutch', - 'da': 'Danish', - 'pt': 'Portuguese', - 'fr': 'French', - 'el': 'Greek', - 'ru': 'Russian', - 'pl': 'Polish', 'sv': 'Swedish', - 'eo': 'Esperanto', - 'cs': 'Czech', - 'hr': 'Croatian', - 'hu': 'Hungarian', - 'be': 'Belarussian', - 'ro': 'Romanian', - 'ko': 'Korean', - 'fa': 'Persian', - 'ar': 'Arabic', - 'zh': 'Chinese', - 'tr': 'Turkish', - 'th': 'Thai', - 'id': 'Indonesian', - 'sr': 'Serbian', - 'uk': 'Ukrainian', - 'vi': 'Vietnamese', - 'vec': 'Venetian', - 'hi': 'Hindi', 'ta': 'Tamil', - 'fil': 'Filipino', + 'th': 'Thai', + 'tr': 'Turkish', + 'uk': 'Ukrainian', + 'vec': 'Venetian', + 'vi': 'Vietnamese', } # Special case for Chinese: map specific variations to traditional. From 0901fa1b21c311cc04824cbe6694a60c5df3aa13 Mon Sep 17 00:00:00 2001 From: Eric Date: Thu, 15 Dec 2022 17:24:17 -0800 Subject: [PATCH 13/26] server join queue can now be disabled --- .efrocachemap | 88 +++++++++---------- CHANGELOG.md | 4 +- assets/src/ba_data/python/._ba_sources_hash | 2 +- assets/src/ba_data/python/_ba.py | 6 ++ assets/src/ba_data/python/ba/_bootstrap.py | 2 +- assets/src/ba_data/python/ba/_servermode.py | 1 + assets/src/ba_data/python/ba/internal.py | 2 + .../python/bastd/ui/account/settings.py | 7 +- .../python/bastd/ui/gather/publictab.py | 1 - src/ballistica/ballistica.cc | 2 +- src/ballistica/logic/logic.cc | 14 +++ src/ballistica/logic/logic.h | 5 ++ .../methods/python_methods_networking.cc | 22 +++++ tools/bacommon/servermanager.py | 5 ++ tools/efro/call.py | 38 ++++++++ tools/efro/util.py | 1 + 16 files changed, 147 insertions(+), 53 deletions(-) diff --git a/.efrocachemap b/.efrocachemap index dcae0fe6..1f4b457e 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -4004,50 +4004,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/02/50/7fd361fc7503bd6511dafe947737", - "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/cd/f1/fc3ad4cb576876298e3da037baed", - "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/5d/f4/c7c37b0ed8386fc204d5321e0ab9", - "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/a7/a8/4768f13ef21d2d3b384e806f06f6", - "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/63/38/bef42b4c6a1f742f0c9e63a9b16d", - "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/9c/f3/b3b46212ab0b146938a20990d800", - "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/1b/29/79f4ebdcb096ad83aaf752fb3701", - "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/02/f8/23419184457a183af712403a1352", - "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/f8/e7/fdb608da459208f4e6fc8372106b", - "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/03/9e/8144ef6cd3db9fc5e71ee75371e5", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/9b/a9/57eda2e68544bd0c36fa13cffd2b", - "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/d3/1e/f9ef9e2189ca84d24df7322ca220", - "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/50/6e/aefb6451ab6f7fa2851297011cba", - "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/a1/c9/6d07587d3b2e8c1862dccfef4e94", - "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/ab/4e/91d2d27cf15792c17829549580ca", - "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/a1/f9/12bf33e3b52202e6853adacba2a7", - "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/e7/44/52c8c2ab2abd417b568ccab82898", - "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/18/37/f7817784360e6c7b093c296a60b6", - "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/13/db/2af6ebf94790575c036a051c5b20", - "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/42/c3/cbeba6007e0a326abd9731bcb9fe", - "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a2/9d/285cd73953e62fdb7945c09fb83c", - "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/22/2d/3df4908dfdcdebe772bf3df0daee", - "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/2a/74/763faee36da963364e94996429d5", - "build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/87/9f/4408f47d293436f420ff9338dca6", - "build/prefab/lib/linux_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/4f/e8/2518fd177b5c51f89ef0795b1264", - "build/prefab/lib/linux_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/77/b1/41befd66869830590f00bff7ba97", - "build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/92/a2/8d6f01537d722803aab60cb67e6d", - "build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/fc/be/0e1af48000395cdbe72179dba90a", - "build/prefab/lib/mac_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/20/7a/b31ec8c47d67b7fd23ed2510aae7", - "build/prefab/lib/mac_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a0/b5/b4ffd9769f3b703226e744423a58", - "build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/3b/02/9e8f15c68ca328a7549846d53a8f", - "build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a0/74/b61b74ada26b41f421563b535dd0", - "build/prefab/lib/mac_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ec/5c/08c171db06bd4492a2b414c77488", - "build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/2f/8a/0384cc905ba23bd45afdfcacb882", - "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/63/6f/e6ba3560e0a8e404bb592405de27", - "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/6e/14/c4f70a74e2111e3adb096dfbd215", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/7c/1c/09d20642216c867d8a0adfddff95", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/a7/ff/e4d363b28c753ed796fff546b9fb", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/77/e9/f62f482ec7efe2b758b2f541b841", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/5e/fb/52723ebc5ba87a95ae3342826d2c", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/11/be/7dcecaa97f8eac0183307c5b0e7d", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/50/79/eb8f282ab42ca5fc6c9c088d87a6", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/74/08/8f1403844c6a9562ae076a4451a3", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/96/52/846ce7853177655441ec7085113c", + "build/prefab/full/linux_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/1c/91/7ae1b68a23982fea887522f1c190", + "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/0a/85/df9814b9bf896f4abea28768e92b", + "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/b4/a1/7f03feb7a85d24245f1f6684032e", + "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/9c/6a/8653f666ea158628c486ea54e4e2", + "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/d6/e2/ca77c216625adc6b4e8af0d388b1", + "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/d4/bb/a88afebc39bf026b31abaf08d9d4", + "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/01/a0/1a3b24b2a41563594b26eb4fb948", + "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/74/57/115e41be4d58896035abf97ce344", + "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/73/16/fc91ce4346f1f47f6f2ca7851c74", + "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/29/d5/b4104b2bdcd5313599442f67422b", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/ec/73/9d05a319bcc76428d29e3449b9cc", + "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/ea/f7/f86d1d668e67254333b774b2d8c1", + "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/f7/75/ee906782bf6cda84349bd2a12ede", + "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/50/0b/f57762d8bb07d039441f6f4d05c2", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/a2/17/d025c0947448310b4efbf6553bca", + "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/c0/a7/febd382d01d7a6671f50b45cf7b7", + "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/36/6b/6a1baa6b91487ab4f156a720e875", + "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/ff/e7/63d4866736010ebeb01ded394cac", + "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/72/6a/d6e87def1a6e663f0eed36a05779", + "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/09/ac/34a441b000c510d46c4fda7036fb", + "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/1b/47/d6384f65f8b4a3fc1c63c69a1c8c", + "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/b6/4c/14bc1088021461969748f0555d64", + "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ef/08/deb368b8fa5f12eaadc63b1388dc", + "build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/30/78/1069cc823a81fad93339bc791a11", + "build/prefab/lib/linux_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/e3/9f/2fd0cdf791782b9cf887fdee5eee", + "build/prefab/lib/linux_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/d2/24/459b6854f0a8fae959b9ff37ed4c", + "build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ce/27/104a5dca1fa570cd41faedf6973e", + "build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/93/1c/259af37062fb8fe2a50bcaad8c1a", + "build/prefab/lib/mac_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/7b/63/2430e689d0e1980c3f40d113db6e", + "build/prefab/lib/mac_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/34/a7/484b831c51c83c692e8c59dcd11c", + "build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/8b/ce/8136e2adf01ee38b1d419553464f", + "build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/0d/90/2c695a05575e73c42969917f2d3a", + "build/prefab/lib/mac_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/d2/fd/ceb1eb357d0b36852d88899356e8", + "build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/09/15/a8daaff2ebe63f85987937692152", + "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/23/f9/ab5c5f9b0bb754034881ab82afe5", + "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/34/16/dbc9386010f6074dc548a081e7cd", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/b7/06/ce8858ccf49e1ccdb71e15d25ead", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/b2/25/2203b80ba9adea38dbb152bc665e", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/4a/29/908997a9aa377f2a13053e591c16", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/27/c9/46e170eb44a7cccb92cfd6b382a2", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/6c/29/06e3a7db44446f381ffcf4f79c99", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/02/9b/66ce0f85f69e71549b2aab5b4fca", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/23/7d/15c3fe7a60284323da4d4f199845", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/32/e5/faff7cbc87f94743f2176bd7efef", "src/ballistica/generated/python_embedded/binding.inc": "https://files.ballistica.net/cache/ba1/25/77/8093dfffddaa80cd513ddaa61867", "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/CHANGELOG.md b/CHANGELOG.md index fe05359f..9d6d6d87 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,11 @@ -### 1.7.16 (build 20963, api 7, 2022-12-08) +### 1.7.16 (build 20966, api 7, 2022-12-15) - Fixed a bug where profile names encased in curly brackets could cause harmless error messages. - Android will no longer log errors on ba.open_url() calls if a browser is not available (it still just falls back to the in-app dialog in that case). - The 'Upgrade' button for device accounts now signs you out and closes the upgrade window to hopefully make it more clear that you need to sign in with your newly created/upgraded BombSquad account. - Fixed a bug where the remote app could not connect for the first 5 seconds after launching the app. - Added Malay language. Ick; apparently its been sitting done for a while and I hadn't realized it wasn't added to the game yet. Apologies!. And thanks to all contributors! +- Added 'enable_queue' server config setting. This defaults to True but can be turned off as a workaround for server owners targeted by queue spam attacks. +- The public party list no longer sorts servers without queues at the end of the list. This sorting was put there long ago to prioritize fancy new queue-supporting servers but now it would just make the few that opt out of queues hard to find. Doh. So opting out of queues is probably not a great idea until this build is widespread. ### 1.7.15 (build 20960, api 7, 2022-12-04) - The cancel button on the 'Sign in with a Bombsquad Account' popup no longer respond to system cancel buttons (escape key, android back button, etc). Turns out some Android people were pressing back repeatedly to come back from a browser after signing in and immediately canceling their sign in attempts in the game before they completed. Hopefully this will avoid some frustration. diff --git a/assets/src/ba_data/python/._ba_sources_hash b/assets/src/ba_data/python/._ba_sources_hash index 121cc8c6..f3c0eaa2 100644 --- a/assets/src/ba_data/python/._ba_sources_hash +++ b/assets/src/ba_data/python/._ba_sources_hash @@ -1 +1 @@ -313825873705357186590048512620581045590 \ No newline at end of file +307626381968915875246137499583097815878 \ No newline at end of file diff --git a/assets/src/ba_data/python/_ba.py b/assets/src/ba_data/python/_ba.py index f4a79295..eb4a7c75 100644 --- a/assets/src/ba_data/python/_ba.py +++ b/assets/src/ba_data/python/_ba.py @@ -3025,6 +3025,12 @@ def set_public_party_name(name: str) -> None: return None +def set_public_party_queue_enabled(max_size: bool) -> None: + + """(internal)""" + return None + + def set_public_party_stats_url(url: str | None) -> None: """(internal)""" diff --git a/assets/src/ba_data/python/ba/_bootstrap.py b/assets/src/ba_data/python/ba/_bootstrap.py index 0f5821ec..882de6c2 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 = 20963 + expected_build = 20966 running_build: int = env['build_number'] if running_build != expected_build: print( diff --git a/assets/src/ba_data/python/ba/_servermode.py b/assets/src/ba_data/python/ba/_servermode.py index f5a40551..52f433fa 100644 --- a/assets/src/ba_data/python/ba/_servermode.py +++ b/assets/src/ba_data/python/ba/_servermode.py @@ -418,6 +418,7 @@ class ServerController: # Call set-enabled last (will push state to the cloud). _ba.set_public_party_max_size(self._config.max_party_size) + _ba.set_public_party_queue_enabled(self._config.enable_queue) _ba.set_public_party_name(self._config.party_name) _ba.set_public_party_stats_url(self._config.stats_url) _ba.set_public_party_enabled(self._config.party_is_public) diff --git a/assets/src/ba_data/python/ba/internal.py b/assets/src/ba_data/python/ba/internal.py index c688faf1..7cf9a06e 100644 --- a/assets/src/ba_data/python/ba/internal.py +++ b/assets/src/ba_data/python/ba/internal.py @@ -40,6 +40,7 @@ from _ba import ( get_public_party_max_size, set_public_party_name, set_public_party_max_size, + set_public_party_queue_enabled, set_authenticate_clients, set_public_party_enabled, reset_random_player_names, @@ -213,6 +214,7 @@ __all__ = [ 'get_public_party_max_size', 'set_public_party_name', 'set_public_party_max_size', + 'set_public_party_queue_enabled', 'set_authenticate_clients', 'set_public_party_enabled', 'reset_random_player_names', diff --git a/assets/src/ba_data/python/bastd/ui/account/settings.py b/assets/src/ba_data/python/bastd/ui/account/settings.py index 04d17a36..149e89d0 100644 --- a/assets/src/ba_data/python/bastd/ui/account/settings.py +++ b/assets/src/ba_data/python/bastd/ui/account/settings.py @@ -17,10 +17,9 @@ import ba.internal if TYPE_CHECKING: from ba.internal import LoginAdapter -# We only show v1 linking controls when directly signed in with -# V1 accounts. Generally V2 accounts should use the web ui for linking. -# However we have an escape-hatch here if someone needs to access -# V1 linking for the V1 portion of their V2 account. +# These days we're directing people to the web based account settings +# for V2 account linking and trying to get them to disconnect remaining +# V1 links, but leaving this escape hatch here in case needed. FORCE_ENABLE_V1_LINKING = False diff --git a/assets/src/ba_data/python/bastd/ui/gather/publictab.py b/assets/src/ba_data/python/bastd/ui/gather/publictab.py index fafd19b4..e874af6b 100644 --- a/assets/src/ba_data/python/bastd/ui/gather/publictab.py +++ b/assets/src/ba_data/python/bastd/ui/gather/publictab.py @@ -1094,7 +1094,6 @@ class PublicGatherTab(GatherTab): self._parties_sorted.sort( key=lambda p: ( - p[1].queue is None, # Show non-queued last. p[1].ping if p[1].ping is not None else 999999.0, p[1].index, ) diff --git a/src/ballistica/ballistica.cc b/src/ballistica/ballistica.cc index 6455dac7..fb6052c0 100644 --- a/src/ballistica/ballistica.cc +++ b/src/ballistica/ballistica.cc @@ -32,7 +32,7 @@ namespace ballistica { // These are set automatically via script; don't modify them here. -const int kAppBuildNumber = 20963; +const int kAppBuildNumber = 20966; const char* kAppVersion = "1.7.16"; // Our standalone globals. diff --git a/src/ballistica/logic/logic.cc b/src/ballistica/logic/logic.cc index 8ac784af..4ebe931d 100644 --- a/src/ballistica/logic/logic.cc +++ b/src/ballistica/logic/logic.cc @@ -2108,6 +2108,20 @@ void Logic::SetPublicPartySize(int count) { } } +auto Logic::SetPublicPartyQueueEnabled(bool enabled) -> void { + assert(InLogicThread()); + if (enabled == public_party_queue_enabled_) { + return; + } + public_party_queue_enabled_ = enabled; + + // Push our new state to the server *ONLY* if public-party is turned on + // (wasteful otherwise). + if (public_party_enabled_) { + g_app_internal->PushPublicPartyState(); + } +} + void Logic::SetPublicPartyMaxSize(int count) { assert(InLogicThread()); if (count == public_party_max_size_) { diff --git a/src/ballistica/logic/logic.h b/src/ballistica/logic/logic.h index 1baa65d0..7ba31f1d 100644 --- a/src/ballistica/logic/logic.h +++ b/src/ballistica/logic/logic.h @@ -214,6 +214,10 @@ class Logic { auto public_party_size() const { return public_party_size_; } auto SetPublicPartySize(int count) -> void; auto public_party_max_size() const { return public_party_max_size_; } + auto SetPublicPartyQueueEnabled(bool enabled) -> void; + auto public_party_queue_enabled() const { + return public_party_queue_enabled_; + } auto public_party_max_player_count() const { return public_party_max_player_count_; } @@ -322,6 +326,7 @@ class Logic { bool public_party_enabled_{}; int public_party_size_{1}; // Always count ourself (is that what we want?). int public_party_max_size_{8}; + bool public_party_queue_enabled_{true}; int public_party_player_count_{0}; int public_party_max_player_count_{8}; std::string public_party_name_; diff --git a/src/ballistica/python/methods/python_methods_networking.cc b/src/ballistica/python/methods/python_methods_networking.cc index 6c5a4d6e..bd59b102 100644 --- a/src/ballistica/python/methods/python_methods_networking.cc +++ b/src/ballistica/python/methods/python_methods_networking.cc @@ -114,6 +114,21 @@ auto PySetPublicPartyMaxSize(PyObject* self, PyObject* args, PyObject* keywds) BA_PYTHON_CATCH; } +auto PySetPublicPartyQueueEnabled(PyObject* self, PyObject* args, + PyObject* keywds) -> PyObject* { + BA_PYTHON_TRY; + int enabled; + static const char* kwlist[] = {"enabled", nullptr}; + if (!PyArg_ParseTupleAndKeywords(args, keywds, "p", + const_cast(kwlist), &enabled)) { + return nullptr; + } + assert(g_python); + g_logic->SetPublicPartyQueueEnabled(enabled); + Py_RETURN_NONE; + BA_PYTHON_CATCH; +} + auto PySetAuthenticateClients(PyObject* self, PyObject* args, PyObject* keywds) -> PyObject* { BA_PYTHON_TRY; @@ -498,6 +513,13 @@ auto PythonMethodsNetworking::GetMethods() -> std::vector { METH_VARARGS | METH_KEYWORDS, "set_public_party_max_size(max_size: int) -> None\n" "\n" + + "(internal)"}, + + {"set_public_party_queue_enabled", + (PyCFunction)PySetPublicPartyQueueEnabled, METH_VARARGS | METH_KEYWORDS, + "set_public_party_queue_enabled(max_size: bool) -> None\n" + "\n" "(internal)"}, {"get_public_party_max_size", (PyCFunction)PyGetPublicPartyMaxSize, diff --git a/tools/bacommon/servermanager.py b/tools/bacommon/servermanager.py index e21b1d1f..7c13910a 100644 --- a/tools/bacommon/servermanager.py +++ b/tools/bacommon/servermanager.py @@ -138,6 +138,11 @@ class ServerConfig: tuple[float, float, float], tuple[float, float, float] ] | None = None + # Whether to enable the queue where players can line up before entering + # your server. Disabling this can be used as a workaround to deal with + # queue spamming attacks. + enable_queue: bool = True + # (internal) stress-testing mode. stress_test_players: int | None = None diff --git a/tools/efro/call.py b/tools/efro/call.py index 7013f3dd..8e811e50 100644 --- a/tools/efro/call.py +++ b/tools/efro/call.py @@ -274,6 +274,44 @@ if TYPE_CHECKING: ) -> _CallNoArgs[OutT]: ... + # 4 arg call; 3 args bundled. + # noinspection PyPep8Naming + @overload + def Call( + call: Callable[[In1T, In2T, In3T, In4T], OutT], + arg1: In1T, + arg2: In2T, + arg3: In3T, + ) -> _Call1Arg[In4T, OutT]: + ... + + # 4 arg call; 2 args bundled. + # noinspection PyPep8Naming + @overload + def Call( + call: Callable[[In1T, In2T, In3T, In4T], OutT], + arg1: In1T, + arg2: In2T, + ) -> _Call2Args[In3T, In4T, OutT]: + ... + + # 4 arg call; 1 arg bundled. + # noinspection PyPep8Naming + @overload + def Call( + call: Callable[[In1T, In2T, In3T, In4T], OutT], + arg1: In1T, + ) -> _Call3Args[In2T, In3T, In4T, OutT]: + ... + + # 4 arg call; no args bundled. + # noinspection PyPep8Naming + @overload + def Call( + call: Callable[[In1T, In2T, In3T, In4T], OutT], + ) -> _Call4Args[In1T, In2T, In3T, In4T, OutT]: + ... + # 5 arg call; 5 args bundled. # noinspection PyPep8Naming @overload diff --git a/tools/efro/util.py b/tools/efro/util.py index 553120f0..2c0ab72a 100644 --- a/tools/efro/util.py +++ b/tools/efro/util.py @@ -39,6 +39,7 @@ class _EmptyObj: pass +# TODO: kill this and just use efro.call.tpartial if TYPE_CHECKING: Call = Call else: From 006156aef74a2ce69806b515a527b5517bf068b4 Mon Sep 17 00:00:00 2001 From: Eric Date: Fri, 16 Dec 2022 22:40:55 -0800 Subject: [PATCH 14/26] v1.7.16 --- .efrocachemap | 118 +++++++++--------- .idea/dictionaries/ericf.xml | 3 + CHANGELOG.md | 4 +- assets/.asset_manifest_private.json | 4 + assets/Makefile | 4 + assets/src/ba_data/python/ba/_bootstrap.py | 2 +- assets/src/ba_data/python/ba/_cloud.py | 6 + assets/src/ba_data/python/ba/_store.py | 16 ++- .../ba_data/python/bastd/ui/store/browser.py | 71 ++++++++++- .../src/ba_data/python/bastd/ui/store/item.py | 22 +++- .../.idea/dictionaries/ericf.xml | 3 + src/ballistica/ballistica.cc | 2 +- src/ballistica/platform/platform.cc | 11 +- tools/bacommon/cloud.py | 18 +++ 14 files changed, 210 insertions(+), 74 deletions(-) diff --git a/.efrocachemap b/.efrocachemap index 1f4b457e..19cce70e 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -420,40 +420,40 @@ "assets/build/ba_data/audio/zoeOw.ogg": "https://files.ballistica.net/cache/ba1/60/ad/38269b7f1c7dc20cb9a506cd0681", "assets/build/ba_data/audio/zoePickup01.ogg": "https://files.ballistica.net/cache/ba1/72/85/d6fc4d16b7081d91fba2850b5b10", "assets/build/ba_data/audio/zoeScream01.ogg": "https://files.ballistica.net/cache/ba1/e9/ae/1d674d0c086eaa0bd1c3b1db0505", - "assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/f0/2d/dbe45794f17260f2961831c88a36", + "assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/3c/3f/dc185a4ea8f2512770558ce0ff90", "assets/build/ba_data/data/languages/arabic.json": "https://files.ballistica.net/cache/ba1/c5/81/e386a592e4fdf702b9089f106610", "assets/build/ba_data/data/languages/belarussian.json": "https://files.ballistica.net/cache/ba1/61/03/89070ca765e06da3a419a579f503", - "assets/build/ba_data/data/languages/chinese.json": "https://files.ballistica.net/cache/ba1/d3/84/5e7df03070af059070ad1bd93cee", + "assets/build/ba_data/data/languages/chinese.json": "https://files.ballistica.net/cache/ba1/8e/4f/992f2a50dbe9514d774c1bb4fd28", "assets/build/ba_data/data/languages/chinesetraditional.json": "https://files.ballistica.net/cache/ba1/c2/a4/993d5f0f30d0670d7053466929b6", "assets/build/ba_data/data/languages/croatian.json": "https://files.ballistica.net/cache/ba1/c9/73/01a1343af814131b1ee96af0b687", "assets/build/ba_data/data/languages/czech.json": "https://files.ballistica.net/cache/ba1/cb/df/f2d54d3146a159c678a47d3ff01b", "assets/build/ba_data/data/languages/danish.json": "https://files.ballistica.net/cache/ba1/6a/fa/fcf4a804beaff927b0f12c179eaa", "assets/build/ba_data/data/languages/dutch.json": "https://files.ballistica.net/cache/ba1/68/93/da8e9874f41a786edf52ba4ccaad", - "assets/build/ba_data/data/languages/english.json": "https://files.ballistica.net/cache/ba1/1f/55/bd97a0f23f4deba2a72ad9ab549e", + "assets/build/ba_data/data/languages/english.json": "https://files.ballistica.net/cache/ba1/7e/e7/836562182c2056902a326f5c7b9d", "assets/build/ba_data/data/languages/esperanto.json": "https://files.ballistica.net/cache/ba1/ac/f5/c0922a99e40dfc9f5e026d43b533", - "assets/build/ba_data/data/languages/filipino.json": "https://files.ballistica.net/cache/ba1/22/5e/6ef2e291465bfb12998f0e23616a", + "assets/build/ba_data/data/languages/filipino.json": "https://files.ballistica.net/cache/ba1/65/3f/6f1b739feac015dc39e97675b49d", "assets/build/ba_data/data/languages/french.json": "https://files.ballistica.net/cache/ba1/5d/2a/a5363cbe713fd67ea0baaa44403a", - "assets/build/ba_data/data/languages/german.json": "https://files.ballistica.net/cache/ba1/58/40/5315a0f4ebbd58c6cb3390907f9a", - "assets/build/ba_data/data/languages/gibberish.json": "https://files.ballistica.net/cache/ba1/d5/65/40add8ed982fb1abb8f120651a1d", + "assets/build/ba_data/data/languages/german.json": "https://files.ballistica.net/cache/ba1/27/48/4cf2f4a3dd35260ef9b3b188ccde", + "assets/build/ba_data/data/languages/gibberish.json": "https://files.ballistica.net/cache/ba1/63/64/8073ab02f55940292099513d341b", "assets/build/ba_data/data/languages/greek.json": "https://files.ballistica.net/cache/ba1/8a/82/392f2a4e0e6e5a5e367f19e49538", "assets/build/ba_data/data/languages/hindi.json": "https://files.ballistica.net/cache/ba1/2e/d1/b506ddf3d27af7be1ae6159531a3", "assets/build/ba_data/data/languages/hungarian.json": "https://files.ballistica.net/cache/ba1/b2/81/53c8cd7617d649403e539c3a6171", - "assets/build/ba_data/data/languages/indonesian.json": "https://files.ballistica.net/cache/ba1/38/74/88d1ed374207750c9a834cddb809", - "assets/build/ba_data/data/languages/italian.json": "https://files.ballistica.net/cache/ba1/ce/09/20c87e343b41ec5dc43138ce071e", + "assets/build/ba_data/data/languages/indonesian.json": "https://files.ballistica.net/cache/ba1/b4/51/0f993429723480691d5289c7bc5d", + "assets/build/ba_data/data/languages/italian.json": "https://files.ballistica.net/cache/ba1/72/35/c40aee4c2f7f64fa030f83eb08d5", "assets/build/ba_data/data/languages/korean.json": "https://files.ballistica.net/cache/ba1/7c/38/d4a44c481757d355836f292ede48", "assets/build/ba_data/data/languages/malay.json": "https://files.ballistica.net/cache/ba1/66/32/92ae734c4358397d2e90c1c85325", "assets/build/ba_data/data/languages/persian.json": "https://files.ballistica.net/cache/ba1/db/14/2f441ccb65023775dc8139a63f3f", "assets/build/ba_data/data/languages/polish.json": "https://files.ballistica.net/cache/ba1/67/93/372c2a2428a830056e9ba22bbf95", - "assets/build/ba_data/data/languages/portuguese.json": "https://files.ballistica.net/cache/ba1/03/14/6b767289325368be52e24ed3a58a", + "assets/build/ba_data/data/languages/portuguese.json": "https://files.ballistica.net/cache/ba1/e6/fb/dfef0975c9c58cbcc621c022ec4b", "assets/build/ba_data/data/languages/romanian.json": "https://files.ballistica.net/cache/ba1/d7/06/9d70642d0a4d1e3b1c2149d7a17c", - "assets/build/ba_data/data/languages/russian.json": "https://files.ballistica.net/cache/ba1/34/2d/9cc17dbd2858e04d0616d1c65ffb", + "assets/build/ba_data/data/languages/russian.json": "https://files.ballistica.net/cache/ba1/a4/08/5e70701b63899cddf21733b0eea6", "assets/build/ba_data/data/languages/serbian.json": "https://files.ballistica.net/cache/ba1/4e/91/6f2a9a3ce733908e91377a6ddb9a", "assets/build/ba_data/data/languages/slovak.json": "https://files.ballistica.net/cache/ba1/20/a9/163d189884edf802636bf291e432", - "assets/build/ba_data/data/languages/spanish.json": "https://files.ballistica.net/cache/ba1/29/1e/1c9666647b48f9c37d8559d22606", + "assets/build/ba_data/data/languages/spanish.json": "https://files.ballistica.net/cache/ba1/e9/6d/62090311ae9aabaaae3918ea2d5b", "assets/build/ba_data/data/languages/swedish.json": "https://files.ballistica.net/cache/ba1/91/0a/35c4baf539d5951fc03a794c0e0b", - "assets/build/ba_data/data/languages/tamil.json": "https://files.ballistica.net/cache/ba1/ec/b2/426ec5d0bb98145dc7123766fb5c", + "assets/build/ba_data/data/languages/tamil.json": "https://files.ballistica.net/cache/ba1/48/2c/78cb542498a59e3023b4838df515", "assets/build/ba_data/data/languages/thai.json": "https://files.ballistica.net/cache/ba1/d6/16/523c643358880b03b233ed88e557", - "assets/build/ba_data/data/languages/turkish.json": "https://files.ballistica.net/cache/ba1/52/5e/385f4d430fa82b2ac206277a71d4", + "assets/build/ba_data/data/languages/turkish.json": "https://files.ballistica.net/cache/ba1/c3/d2/d075ad07ec8d8aec3616f8760534", "assets/build/ba_data/data/languages/ukrainian.json": "https://files.ballistica.net/cache/ba1/73/7b/b8822b5632a8d3c7cf134e2859cc", "assets/build/ba_data/data/languages/venetian.json": "https://files.ballistica.net/cache/ba1/a6/ed/416638d46950c9ab4f6155b9c334", "assets/build/ba_data/data/languages/vietnamese.json": "https://files.ballistica.net/cache/ba1/1f/ae/abe3f105b3c4b51f6b7942773305", @@ -1859,6 +1859,10 @@ "assets/build/ba_data/textures/menuIcon.ktx": "https://files.ballistica.net/cache/ba1/e7/8c/dde40b132e096841299505e2b665", "assets/build/ba_data/textures/menuIcon.pvr": "https://files.ballistica.net/cache/ba1/91/d3/6e3b38a70caa2bc68ddff50e3421", "assets/build/ba_data/textures/menuIcon_preview.png": "https://files.ballistica.net/cache/ba1/1f/22/69a013729949501405ea342a1a8b", + "assets/build/ba_data/textures/merch.dds": "https://files.ballistica.net/cache/ba1/da/6a/87779603f295cf30fcec2d3a4e9f", + "assets/build/ba_data/textures/merch.ktx": "https://files.ballistica.net/cache/ba1/5b/c4/2df30594a9e7c1988d92435d7bd0", + "assets/build/ba_data/textures/merch.pvr": "https://files.ballistica.net/cache/ba1/20/76/b8da7a2dded8c137c8388bcb6986", + "assets/build/ba_data/textures/merch_preview.png": "https://files.ballistica.net/cache/ba1/31/ad/9ffc829f1fcff718106d129ac062", "assets/build/ba_data/textures/meter.dds": "https://files.ballistica.net/cache/ba1/52/a8/00244236f0e6126e2e14bd1f3106", "assets/build/ba_data/textures/meter.ktx": "https://files.ballistica.net/cache/ba1/b5/e7/3ba3d4c7c7e05081eb033ae5da8f", "assets/build/ba_data/textures/meter.pvr": "https://files.ballistica.net/cache/ba1/58/de/ab83ad9e0d9b434ca42811030ef9", @@ -4004,50 +4008,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/1c/91/7ae1b68a23982fea887522f1c190", - "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/0a/85/df9814b9bf896f4abea28768e92b", - "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/b4/a1/7f03feb7a85d24245f1f6684032e", - "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/9c/6a/8653f666ea158628c486ea54e4e2", - "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/d6/e2/ca77c216625adc6b4e8af0d388b1", - "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/d4/bb/a88afebc39bf026b31abaf08d9d4", - "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/01/a0/1a3b24b2a41563594b26eb4fb948", - "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/74/57/115e41be4d58896035abf97ce344", - "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/73/16/fc91ce4346f1f47f6f2ca7851c74", - "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/29/d5/b4104b2bdcd5313599442f67422b", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/ec/73/9d05a319bcc76428d29e3449b9cc", - "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/ea/f7/f86d1d668e67254333b774b2d8c1", - "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/f7/75/ee906782bf6cda84349bd2a12ede", - "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/50/0b/f57762d8bb07d039441f6f4d05c2", - "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/a2/17/d025c0947448310b4efbf6553bca", - "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/c0/a7/febd382d01d7a6671f50b45cf7b7", - "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/36/6b/6a1baa6b91487ab4f156a720e875", - "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/ff/e7/63d4866736010ebeb01ded394cac", - "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/72/6a/d6e87def1a6e663f0eed36a05779", - "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/09/ac/34a441b000c510d46c4fda7036fb", - "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/1b/47/d6384f65f8b4a3fc1c63c69a1c8c", - "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/b6/4c/14bc1088021461969748f0555d64", - "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ef/08/deb368b8fa5f12eaadc63b1388dc", - "build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/30/78/1069cc823a81fad93339bc791a11", - "build/prefab/lib/linux_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/e3/9f/2fd0cdf791782b9cf887fdee5eee", - "build/prefab/lib/linux_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/d2/24/459b6854f0a8fae959b9ff37ed4c", - "build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ce/27/104a5dca1fa570cd41faedf6973e", - "build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/93/1c/259af37062fb8fe2a50bcaad8c1a", - "build/prefab/lib/mac_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/7b/63/2430e689d0e1980c3f40d113db6e", - "build/prefab/lib/mac_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/34/a7/484b831c51c83c692e8c59dcd11c", - "build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/8b/ce/8136e2adf01ee38b1d419553464f", - "build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/0d/90/2c695a05575e73c42969917f2d3a", - "build/prefab/lib/mac_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/d2/fd/ceb1eb357d0b36852d88899356e8", - "build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/09/15/a8daaff2ebe63f85987937692152", - "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/23/f9/ab5c5f9b0bb754034881ab82afe5", - "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/34/16/dbc9386010f6074dc548a081e7cd", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/b7/06/ce8858ccf49e1ccdb71e15d25ead", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/b2/25/2203b80ba9adea38dbb152bc665e", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/4a/29/908997a9aa377f2a13053e591c16", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/27/c9/46e170eb44a7cccb92cfd6b382a2", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/6c/29/06e3a7db44446f381ffcf4f79c99", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/02/9b/66ce0f85f69e71549b2aab5b4fca", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/23/7d/15c3fe7a60284323da4d4f199845", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/32/e5/faff7cbc87f94743f2176bd7efef", + "build/prefab/full/linux_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/6f/3c/b6d4e92dcbac32aa3093d9139b9d", + "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/a1/b8/31ad72ffe5df6bbedbd59eb3f02b", + "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/d2/d9/084996631fa94337e0a92c93b753", + "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/89/0a/4483e91a808e4724dfbc382d6f60", + "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/ec/4d/6c58d9a9c5b13837d87d3d871868", + "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/dd/12/2e3164bd4770a6c648e2e7dbc4f0", + "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/fa/41/63a57ecf884cecf7ee1c8b9b2dcf", + "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/64/2b/0ebcdfd2f61027dcfff899d8894f", + "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/8f/e7/3ca7ed13d4a03013ecbb80ecb78c", + "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/ec/e2/ebe20cc007e87d0ede6e0ec169af", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/3a/77/32299795fdb8b0c0fbc3130b7193", + "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/c2/1a/bfaeccd961429479947ea1cb2c47", + "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/43/74/b5749a746e72007f2f464b2941c6", + "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/eb/e2/f97727387a3f9707b079b7b2acd0", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/5f/da/6a048012e6b94a303e59b8dae61b", + "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/f5/11/e75118e0a8f821e030f82e79c1bc", + "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/d2/ad/4ee541d9d19b2d6fc1dab4947a26", + "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/10/2b/133d1cf611800e518d5353a10a94", + "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/85/53/fde7e925ac80da650a02ee078ad0", + "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/96/8e/c8292f6fc6967003affeb6ca32b7", + "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/28/f6/26327365481296a963bb37d58d82", + "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/6d/b6/4e4a46d553d1949c956e72a3617d", + "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/81/57/d0a2b72a86d6f7f542d07e4fba29", + "build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ac/f5/a6350f397911c2833c35fb86aa6c", + "build/prefab/lib/linux_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/91/87/78eab8de6f5bc52ff10f75e9d0b5", + "build/prefab/lib/linux_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a9/29/9cf3b260aae600ccafb535309b62", + "build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/56/c2/75943b307817b0f23807b4f36632", + "build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/93/51/6cf630d6ab82f8946569b96f01b5", + "build/prefab/lib/mac_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/e4/ba/31a54b98463bc261835ac9cc7c51", + "build/prefab/lib/mac_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/64/25/bba77bfd767e14a9df46795c93bb", + "build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/f2/17/02a1053141eac72b24c323b10003", + "build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/98/ca/dcbb87a7c32120a42ab6ca1e7194", + "build/prefab/lib/mac_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ca/dc/4a0fcdee7fc3c57960d5381a0299", + "build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/6c/a3/b70ad508a305efc2a10b5ba4508e", + "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/98/a9/1426b7eadc8be33f98f103fb12f0", + "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/38/8f/50753e457af4c626e2285c3171ac", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/fe/4d/77331e69f4fc0ef288df17377b42", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/9b/07/37e3a24a6ee588d0e5d4ba7b5335", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/0a/60/0109e5badaf8d6610cc9a4a61aa2", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/6d/e7/4e5bf2f3c16ca59770d5789c2481", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/b5/de/6914b0c6ab3142ad99547e930d88", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/3e/a4/e22b4cc12099dc6863a418d186f9", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/bd/c7/c97d29a73c75b3e699f14bcd6e37", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/44/36/de0a2f89ccd4e4728301cecd1033", "src/ballistica/generated/python_embedded/binding.inc": "https://files.ballistica.net/cache/ba1/25/77/8093dfffddaa80cd513ddaa61867", "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 ccea1e37..780866a1 100644 --- a/.idea/dictionaries/ericf.xml +++ b/.idea/dictionaries/ericf.xml @@ -851,6 +851,7 @@ fakeshake fallbacks farthestpt + faulthandler fback fbase fclose @@ -1525,6 +1526,7 @@ masterhash masterver mastervers + matchlines mathmodule mathnode mathutils @@ -2857,6 +2859,7 @@ wanttype warntype wasdead + wasn wavenum weakref weakrefs diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d6d6d87..a99f4fac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -### 1.7.16 (build 20966, api 7, 2022-12-15) +### 1.7.16 (build 20967, api 7, 2022-12-16) - Fixed a bug where profile names encased in curly brackets could cause harmless error messages. - Android will no longer log errors on ba.open_url() calls if a browser is not available (it still just falls back to the in-app dialog in that case). - The 'Upgrade' button for device accounts now signs you out and closes the upgrade window to hopefully make it more clear that you need to sign in with your newly created/upgraded BombSquad account. @@ -6,6 +6,8 @@ - Added Malay language. Ick; apparently its been sitting done for a while and I hadn't realized it wasn't added to the game yet. Apologies!. And thanks to all contributors! - Added 'enable_queue' server config setting. This defaults to True but can be turned off as a workaround for server owners targeted by queue spam attacks. - The public party list no longer sorts servers without queues at the end of the list. This sorting was put there long ago to prioritize fancy new queue-supporting servers but now it would just make the few that opt out of queues hard to find. Doh. So opting out of queues is probably not a great idea until this build is widespread. +- Public uuids now only change once every 6 months or so instead of with every version bump. This way periods of heavy development won't put added strain on server owners trying to keep ban lists up to date and whatnot. +- Added a merch button in the in-game store that goes to the ballistica.net merch page (though it only shows up in the few countries where merch is available). ### 1.7.15 (build 20960, api 7, 2022-12-04) - The cancel button on the 'Sign in with a Bombsquad Account' popup no longer respond to system cancel buttons (escape key, android back button, etc). Turns out some Android people were pressing back repeatedly to come back from a browser after signing in and immediately canceling their sign in attempts in the game before they completed. Hopefully this will avoid some frustration. diff --git a/assets/.asset_manifest_private.json b/assets/.asset_manifest_private.json index 9fd06197..6b62d1ec 100644 --- a/assets/.asset_manifest_private.json +++ b/assets/.asset_manifest_private.json @@ -1881,6 +1881,10 @@ "ba_data/textures/menuIcon.ktx", "ba_data/textures/menuIcon.pvr", "ba_data/textures/menuIcon_preview.png", + "ba_data/textures/merch.dds", + "ba_data/textures/merch.ktx", + "ba_data/textures/merch.pvr", + "ba_data/textures/merch_preview.png", "ba_data/textures/meter.dds", "ba_data/textures/meter.ktx", "ba_data/textures/meter.pvr", diff --git a/assets/Makefile b/assets/Makefile index 6734f2fb..2776b045 100644 --- a/assets/Makefile +++ b/assets/Makefile @@ -5598,6 +5598,7 @@ TEX2D_DDS_TARGETS = \ build/ba_data/textures/menuBG.dds \ build/ba_data/textures/menuButton.dds \ build/ba_data/textures/menuIcon.dds \ + build/ba_data/textures/merch.dds \ build/ba_data/textures/meter.dds \ build/ba_data/textures/monkeyFaceLevelColor.dds \ build/ba_data/textures/monkeyFacePreview.dds \ @@ -6003,6 +6004,7 @@ TEX2D_PVR_TARGETS = \ build/ba_data/textures/menuBG.pvr \ build/ba_data/textures/menuButton.pvr \ build/ba_data/textures/menuIcon.pvr \ + build/ba_data/textures/merch.pvr \ build/ba_data/textures/meter.pvr \ build/ba_data/textures/monkeyFaceLevelColor.pvr \ build/ba_data/textures/monkeyFacePreview.pvr \ @@ -6408,6 +6410,7 @@ TEX2D_KTX_TARGETS = \ build/ba_data/textures/menuBG.ktx \ build/ba_data/textures/menuButton.ktx \ build/ba_data/textures/menuIcon.ktx \ + build/ba_data/textures/merch.ktx \ build/ba_data/textures/meter.ktx \ build/ba_data/textures/monkeyFaceLevelColor.ktx \ build/ba_data/textures/monkeyFacePreview.ktx \ @@ -6813,6 +6816,7 @@ TEX2D_PREVIEW_PNG_TARGETS = \ build/ba_data/textures/menuBG_preview.png \ build/ba_data/textures/menuButton_preview.png \ build/ba_data/textures/menuIcon_preview.png \ + build/ba_data/textures/merch_preview.png \ build/ba_data/textures/meter_preview.png \ build/ba_data/textures/monkeyFaceLevelColor_preview.png \ build/ba_data/textures/monkeyFacePreview_preview.png \ diff --git a/assets/src/ba_data/python/ba/_bootstrap.py b/assets/src/ba_data/python/ba/_bootstrap.py index 882de6c2..53091f8f 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 = 20966 + expected_build = 20967 running_build: int = env['build_number'] if running_build != expected_build: print( diff --git a/assets/src/ba_data/python/ba/_cloud.py b/assets/src/ba_data/python/ba/_cloud.py index 785e68c7..e9ead0b4 100644 --- a/assets/src/ba_data/python/ba/_cloud.py +++ b/assets/src/ba_data/python/ba/_cloud.py @@ -131,6 +131,12 @@ class CloudSubsystem: ) -> bacommon.cloud.WorkspaceFetchResponse: ... + @overload + def send_message( + self, msg: bacommon.cloud.MerchAvailabilityMessage + ) -> bacommon.cloud.MerchAvailabilityResponse: + ... + @overload def send_message( self, msg: bacommon.cloud.TestMessage diff --git a/assets/src/ba_data/python/ba/_store.py b/assets/src/ba_data/python/ba/_store.py index 850a0aa0..2dfc07c1 100644 --- a/assets/src/ba_data/python/ba/_store.py +++ b/assets/src/ba_data/python/ba/_store.py @@ -30,6 +30,8 @@ def get_store_item_name_translated(item_name: str) -> ba.Lstr: return _language.Lstr( translate=('characterNames', item_info['character']) ) + if item_name in ['merch']: + return _language.Lstr(resource='merchText') if item_name in ['upgrades.pro', 'pro']: return _language.Lstr( resource='store.bombSquadProNameText', @@ -50,7 +52,7 @@ def get_store_item_display_size(item_name: str) -> tuple[float, float]: """(internal)""" if item_name.startswith('characters.'): return 340 * 0.6, 430 * 0.6 - if item_name in ['pro', 'upgrades.pro']: + if item_name in ['pro', 'upgrades.pro', 'merch']: return 650 * 0.9, 500 * 0.85 if item_name.startswith('maps.'): return 510 * 0.6, 450 * 0.6 @@ -96,6 +98,7 @@ def get_store_items() -> dict[str, dict]: 'characters.taobaomascot': {'character': 'Taobao Mascot'}, 'characters.santa': {'character': 'Santa Claus'}, 'characters.bunny': {'character': 'Easter Bunny'}, + 'merch': {}, 'pro': {}, 'maps.lake_frigid': {'map_type': maps.LakeFrigid}, 'games.ninja_fight': { @@ -193,9 +196,7 @@ def get_store_items() -> dict[str, dict]: 'icons.fireball': {'icon': _ba.charstr(SpecialChar.FIREBALL)}, 'icons.mikirog': {'icon': _ba.charstr(SpecialChar.MIKIROG)}, } - store_items = _ba.app.store_items - assert store_items is not None - return store_items + return _ba.app.store_items def get_store_layout() -> dict[str, list[dict[str, Any]]]: @@ -261,7 +262,6 @@ def get_store_layout() -> dict[str, list[dict[str, Any]]]: ], } store_layout = _ba.app.store_layout - assert store_layout is not None store_layout['characters'] = [ { 'items': [ @@ -302,6 +302,12 @@ def get_store_layout() -> dict[str, list[dict[str, Any]]]: 'items': ['games.easter_egg_hunt'], } ) + + # This will cause merch to show only if the master-server has + # given us a link (which means merch is available in our region). + store_layout['extras'] = [{'items': ['pro']}] + if _ba.app.config.get('Merch Link'): + store_layout['extras'][0]['items'].append('merch') return store_layout diff --git a/assets/src/ba_data/python/bastd/ui/store/browser.py b/assets/src/ba_data/python/bastd/ui/store/browser.py index 49a301c2..3582629f 100644 --- a/assets/src/ba_data/python/bastd/ui/store/browser.py +++ b/assets/src/ba_data/python/bastd/ui/store/browser.py @@ -4,18 +4,25 @@ # pylint: disable=too-many-lines from __future__ import annotations +import time import copy import math +import logging import weakref from enum import Enum +from threading import Thread from typing import TYPE_CHECKING +from efro.error import CommunicationError +import bacommon.cloud import ba import ba.internal if TYPE_CHECKING: from typing import Any, Callable, Sequence +MERCH_LINK_KEY = 'Merch Link' + class StoreBrowserWindow(ba.Window): """Window for browsing the store.""" @@ -593,8 +600,14 @@ class StoreBrowserWindow(ba.Window): else: self._last_buy_time = curtime - # Pro is an actual IAP; the rest are ticket purchases. - if item == 'pro': + # Merch is a special case - just a link. + if item == 'merch': + url = ba.app.config.get('Merch Link') + if isinstance(url, str): + ba.open_url(url) + + # Pro is an actual IAP, and the rest are ticket purchases. + elif item == 'pro': ba.playsound(ba.getsound('click01')) # Purchase either pro or pro_sale depending on whether @@ -681,7 +694,9 @@ class StoreBrowserWindow(ba.Window): assert self.button_infos is not None for b_type, b_info in self.button_infos.items(): - if b_type in ['upgrades.pro', 'pro']: + if b_type == 'merch': + purchased = False + elif b_type in ['upgrades.pro', 'pro']: purchased = ba.app.accounts_v1.have_pro() else: purchased = ba.internal.get_purchased(b_type) @@ -707,7 +722,11 @@ class StoreBrowserWindow(ba.Window): color = (0.4, 0.8, 0.1) extra_image_opacity = 1.0 call = b_info['call'] if 'call' in b_info else None - if b_type in ['upgrades.pro', 'pro']: + if b_type == 'merch': + price_text = '' + price_text_left = '' + price_text_right = '' + elif b_type in ['upgrades.pro', 'pro']: sale_time = get_available_sale_time('extras') if sale_time is not None: priceraw = ba.internal.get_price('pro') @@ -917,7 +936,9 @@ class StoreBrowserWindow(ba.Window): # pylint: disable=too-many-locals # pylint: disable=too-many-branches # pylint: disable=too-many-nested-blocks - from bastd.ui.store import item as storeitemui + from bastd.ui.store.item import ( + instantiate_store_item_display, + ) title_spacing = 40 button_border = 20 @@ -1102,7 +1123,7 @@ class StoreBrowserWindow(ba.Window): + (b_width + button_spacing) * col, v - b_height + boffs_v2, ) - storeitemui.instantiate_store_item_display( + instantiate_store_item_display( item_name, item, parent_widget=cnt2, @@ -1325,3 +1346,41 @@ class StoreBrowserWindow(ba.Window): ) if self._on_close_call is not None: self._on_close_call() + + +def _check_merch_availability_in_bg_thread() -> None: + # pylint: disable=cell-var-from-loop + + # Merch is available from some countries only. + # Make a reasonable check to ask the master-server about this at + # launch and store the results. + for _i in range(15): + try: + if ba.app.cloud.is_connected(): + response = ba.app.cloud.send_message( + bacommon.cloud.MerchAvailabilityMessage() + ) + + def _store_in_logic_thread() -> None: + cfg = ba.app.config + current: str | None = cfg.get(MERCH_LINK_KEY) + if not isinstance(current, str | None): + current = None + if current != response.url: + cfg[MERCH_LINK_KEY] = response.url + cfg.commit() + + # If we successfully get a response, kick it over to the + # logic thread to store and we're done. + ba.pushcall(_store_in_logic_thread, from_other_thread=True) + return + except CommunicationError: + pass + except Exception: + logging.warning( + 'Unexpected error in merch-availability-check.', exc_info=True + ) + time.sleep(1.1934) # A bit randomized to avoid aliasing. + + +Thread(target=_check_merch_availability_in_bg_thread, daemon=True).start() diff --git a/assets/src/ba_data/python/bastd/ui/store/item.py b/assets/src/ba_data/python/bastd/ui/store/item.py index 246e84e9..078f3c9c 100644 --- a/assets/src/ba_data/python/bastd/ui/store/item.py +++ b/assets/src/ba_data/python/bastd/ui/store/item.py @@ -92,6 +92,10 @@ def instantiate_store_item_display( tint_tex = character.icon_mask_texture title_v = 0.255 price_v = 0.145 + elif item_name == 'merch': + base_text_scale = 0.6 + title_v = 0.85 + price_v = 0.15 elif item_name in ['upgrades.pro', 'pro']: base_text_scale = 0.6 title_v = 0.85 @@ -165,6 +169,23 @@ def instantiate_store_item_display( tint2_color=tint2_color, ) + if item_name == 'merch': + frame_size = b_width * 0.7 + im_dim = frame_size * (100.0 / 113.0) + im_pos = ( + b_pos[0] + b_width * 0.5 - im_dim * 0.5 + b_offs_x, + b_pos[1] + b_height * 0.5 - im_dim * 0.5, + ) + ba.imagewidget( + parent=parent_widget, + position=im_pos, + size=(im_dim, im_dim), + transition_delay=delay, + draw_controller=btn, + opacity=1.0, + texture=ba.gettexture('merch'), + ) + if item_name in ['pro', 'upgrades.pro']: frame_size = b_width * 0.5 im_dim = frame_size * (100.0 / 113.0) @@ -184,7 +205,6 @@ def instantiate_store_item_display( ) txt = ba.Lstr(resource='store.bombSquadProNewDescriptionText') - # t = 'foo\nfoo\nfoo\nfoo\nfoo\nfoo' item['descriptionText'] = ba.textwidget( parent=parent_widget, text=txt, diff --git a/ballisticacore-cmake/.idea/dictionaries/ericf.xml b/ballisticacore-cmake/.idea/dictionaries/ericf.xml index d584d5dc..d5ef5e70 100644 --- a/ballisticacore-cmake/.idea/dictionaries/ericf.xml +++ b/ballisticacore-cmake/.idea/dictionaries/ericf.xml @@ -459,6 +459,7 @@ fastldlt fastlsolve fastltsolve + faulthandler fbos fcntl fdata @@ -800,6 +801,7 @@ maskuv masterver mastervers + matchlines maximus maxpathlen maxtries @@ -1507,6 +1509,7 @@ wakeups walisser wasdebug + wasn watte wdeprecated weakref diff --git a/src/ballistica/ballistica.cc b/src/ballistica/ballistica.cc index fb6052c0..51a2e010 100644 --- a/src/ballistica/ballistica.cc +++ b/src/ballistica/ballistica.cc @@ -32,7 +32,7 @@ namespace ballistica { // These are set automatically via script; don't modify them here. -const int kAppBuildNumber = 20966; +const int kAppBuildNumber = 20967; const char* kAppVersion = "1.7.16"; // Our standalone globals. diff --git a/src/ballistica/platform/platform.cc b/src/ballistica/platform/platform.cc index 0bdb8a89..f3067fdd 100644 --- a/src/ballistica/platform/platform.cc +++ b/src/ballistica/platform/platform.cc @@ -221,8 +221,15 @@ auto Platform::GetPublicDeviceUUID() -> std::string { // This UUID is supposed to change periodically, so let's plug in // some stuff to enforce that. inputs.emplace_back(GetOSVersionString()); - inputs.emplace_back(kAppVersion); - inputs.emplace_back("kerploople"); + + // This part gets shuffled periodically by my version-increment tools. + // We used to plug version in directly here, but that caused uuids to + // shuffle too rapidly during periods of rapid development. This + // keeps it more constant. + // __last_rand_uuid_component_shuffle_date__ 2022 12 17 + auto rand_uuid_component{"BMCJPHH0SC22KB0WVJ1RAYD68TPEXL58"}; + + inputs.emplace_back(rand_uuid_component); auto gil{Python::ScopedInterpreterLock()}; auto pylist{g_python->StringList(inputs)}; auto args{g_python->SingleMemberTuple(pylist)}; diff --git a/tools/bacommon/cloud.py b/tools/bacommon/cloud.py index bb36f6c1..1e680a40 100644 --- a/tools/bacommon/cloud.py +++ b/tools/bacommon/cloud.py @@ -157,6 +157,24 @@ class WorkspaceFetchResponse(Response): done: Annotated[bool, IOAttrs('d')] = False +@ioprepped +@dataclass +class MerchAvailabilityMessage(Message): + """Can we show merch link?""" + + @classmethod + def get_response_types(cls) -> list[type[Response] | None]: + return [MerchAvailabilityResponse] + + +@ioprepped +@dataclass +class MerchAvailabilityResponse(Response): + """About that merch...""" + + url: Annotated[str | None, IOAttrs('u')] + + @ioprepped @dataclass class SignInMessage(Message): From c296d965a2ced5e9cf1b48c4ec8f5d9e2689b9a0 Mon Sep 17 00:00:00 2001 From: Eric Date: Tue, 20 Dec 2022 17:56:15 -0800 Subject: [PATCH 15/26] logging and bug hunting --- .efrocachemap | 120 +++++------ .idea/dictionaries/ericf.xml | 6 + CHANGELOG.md | 8 +- assets/src/ba_data/python/ba/_app.py | 17 +- assets/src/ba_data/python/ba/_apputils.py | 200 ++++++++++++++++-- assets/src/ba_data/python/ba/_bootstrap.py | 2 +- assets/src/ba_data/python/ba/_store.py | 4 +- assets/src/ba_data/python/ba/internal.py | 8 +- .../python/bastd/ui/account/settings.py | 132 ++++++++---- .../src/ba_data/python/bastd/ui/mainmenu.py | 15 +- .../ba_data/python/bastd/ui/store/browser.py | 14 +- .../src/ba_data/python/bastd/ui/store/item.py | 12 +- .../.idea/dictionaries/ericf.xml | 6 + src/ballistica/ballistica.cc | 4 +- src/ballistica/ui/widget/container_widget.cc | 16 +- tools/efro/log.py | 20 ++ 16 files changed, 432 insertions(+), 152 deletions(-) diff --git a/.efrocachemap b/.efrocachemap index 19cce70e..b054ad5d 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -420,41 +420,41 @@ "assets/build/ba_data/audio/zoeOw.ogg": "https://files.ballistica.net/cache/ba1/60/ad/38269b7f1c7dc20cb9a506cd0681", "assets/build/ba_data/audio/zoePickup01.ogg": "https://files.ballistica.net/cache/ba1/72/85/d6fc4d16b7081d91fba2850b5b10", "assets/build/ba_data/audio/zoeScream01.ogg": "https://files.ballistica.net/cache/ba1/e9/ae/1d674d0c086eaa0bd1c3b1db0505", - "assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/3c/3f/dc185a4ea8f2512770558ce0ff90", - "assets/build/ba_data/data/languages/arabic.json": "https://files.ballistica.net/cache/ba1/c5/81/e386a592e4fdf702b9089f106610", + "assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/a8/a2/8c6816daac85d0b899a324509cf6", + "assets/build/ba_data/data/languages/arabic.json": "https://files.ballistica.net/cache/ba1/92/43/36b34307575f6d6219bdf4898e18", "assets/build/ba_data/data/languages/belarussian.json": "https://files.ballistica.net/cache/ba1/61/03/89070ca765e06da3a419a579f503", - "assets/build/ba_data/data/languages/chinese.json": "https://files.ballistica.net/cache/ba1/8e/4f/992f2a50dbe9514d774c1bb4fd28", + "assets/build/ba_data/data/languages/chinese.json": "https://files.ballistica.net/cache/ba1/aa/ed/4bd02af3cffbd4c9c4be532fb1fe", "assets/build/ba_data/data/languages/chinesetraditional.json": "https://files.ballistica.net/cache/ba1/c2/a4/993d5f0f30d0670d7053466929b6", "assets/build/ba_data/data/languages/croatian.json": "https://files.ballistica.net/cache/ba1/c9/73/01a1343af814131b1ee96af0b687", - "assets/build/ba_data/data/languages/czech.json": "https://files.ballistica.net/cache/ba1/cb/df/f2d54d3146a159c678a47d3ff01b", + "assets/build/ba_data/data/languages/czech.json": "https://files.ballistica.net/cache/ba1/4e/8c/72ddb584856a15dfb11df95f9283", "assets/build/ba_data/data/languages/danish.json": "https://files.ballistica.net/cache/ba1/6a/fa/fcf4a804beaff927b0f12c179eaa", "assets/build/ba_data/data/languages/dutch.json": "https://files.ballistica.net/cache/ba1/68/93/da8e9874f41a786edf52ba4ccaad", - "assets/build/ba_data/data/languages/english.json": "https://files.ballistica.net/cache/ba1/7e/e7/836562182c2056902a326f5c7b9d", + "assets/build/ba_data/data/languages/english.json": "https://files.ballistica.net/cache/ba1/ad/85/3caf0c981389e46835862248386a", "assets/build/ba_data/data/languages/esperanto.json": "https://files.ballistica.net/cache/ba1/ac/f5/c0922a99e40dfc9f5e026d43b533", - "assets/build/ba_data/data/languages/filipino.json": "https://files.ballistica.net/cache/ba1/65/3f/6f1b739feac015dc39e97675b49d", + "assets/build/ba_data/data/languages/filipino.json": "https://files.ballistica.net/cache/ba1/8e/90/3ba17e62e21919bc2fa7e46884be", "assets/build/ba_data/data/languages/french.json": "https://files.ballistica.net/cache/ba1/5d/2a/a5363cbe713fd67ea0baaa44403a", - "assets/build/ba_data/data/languages/german.json": "https://files.ballistica.net/cache/ba1/27/48/4cf2f4a3dd35260ef9b3b188ccde", - "assets/build/ba_data/data/languages/gibberish.json": "https://files.ballistica.net/cache/ba1/63/64/8073ab02f55940292099513d341b", + "assets/build/ba_data/data/languages/german.json": "https://files.ballistica.net/cache/ba1/cb/7b/b881356f22e5f8293a5e4b8976ae", + "assets/build/ba_data/data/languages/gibberish.json": "https://files.ballistica.net/cache/ba1/ee/fa/6eb38e7d4cfd13702c66d37b9723", "assets/build/ba_data/data/languages/greek.json": "https://files.ballistica.net/cache/ba1/8a/82/392f2a4e0e6e5a5e367f19e49538", "assets/build/ba_data/data/languages/hindi.json": "https://files.ballistica.net/cache/ba1/2e/d1/b506ddf3d27af7be1ae6159531a3", "assets/build/ba_data/data/languages/hungarian.json": "https://files.ballistica.net/cache/ba1/b2/81/53c8cd7617d649403e539c3a6171", - "assets/build/ba_data/data/languages/indonesian.json": "https://files.ballistica.net/cache/ba1/b4/51/0f993429723480691d5289c7bc5d", + "assets/build/ba_data/data/languages/indonesian.json": "https://files.ballistica.net/cache/ba1/30/91/9dc870d35ddca657bf07d0f88a82", "assets/build/ba_data/data/languages/italian.json": "https://files.ballistica.net/cache/ba1/72/35/c40aee4c2f7f64fa030f83eb08d5", - "assets/build/ba_data/data/languages/korean.json": "https://files.ballistica.net/cache/ba1/7c/38/d4a44c481757d355836f292ede48", + "assets/build/ba_data/data/languages/korean.json": "https://files.ballistica.net/cache/ba1/32/97/4c61425d7c200a5c4c9ae3a94a0e", "assets/build/ba_data/data/languages/malay.json": "https://files.ballistica.net/cache/ba1/66/32/92ae734c4358397d2e90c1c85325", "assets/build/ba_data/data/languages/persian.json": "https://files.ballistica.net/cache/ba1/db/14/2f441ccb65023775dc8139a63f3f", "assets/build/ba_data/data/languages/polish.json": "https://files.ballistica.net/cache/ba1/67/93/372c2a2428a830056e9ba22bbf95", - "assets/build/ba_data/data/languages/portuguese.json": "https://files.ballistica.net/cache/ba1/e6/fb/dfef0975c9c58cbcc621c022ec4b", + "assets/build/ba_data/data/languages/portuguese.json": "https://files.ballistica.net/cache/ba1/cb/96/86bb139f20e126593f7fdba9e9e1", "assets/build/ba_data/data/languages/romanian.json": "https://files.ballistica.net/cache/ba1/d7/06/9d70642d0a4d1e3b1c2149d7a17c", - "assets/build/ba_data/data/languages/russian.json": "https://files.ballistica.net/cache/ba1/a4/08/5e70701b63899cddf21733b0eea6", + "assets/build/ba_data/data/languages/russian.json": "https://files.ballistica.net/cache/ba1/b7/98/2523d11d09614bcfad8fa50be100", "assets/build/ba_data/data/languages/serbian.json": "https://files.ballistica.net/cache/ba1/4e/91/6f2a9a3ce733908e91377a6ddb9a", "assets/build/ba_data/data/languages/slovak.json": "https://files.ballistica.net/cache/ba1/20/a9/163d189884edf802636bf291e432", - "assets/build/ba_data/data/languages/spanish.json": "https://files.ballistica.net/cache/ba1/e9/6d/62090311ae9aabaaae3918ea2d5b", + "assets/build/ba_data/data/languages/spanish.json": "https://files.ballistica.net/cache/ba1/d8/19/21882f76375ade330ef5a6e791a4", "assets/build/ba_data/data/languages/swedish.json": "https://files.ballistica.net/cache/ba1/91/0a/35c4baf539d5951fc03a794c0e0b", - "assets/build/ba_data/data/languages/tamil.json": "https://files.ballistica.net/cache/ba1/48/2c/78cb542498a59e3023b4838df515", + "assets/build/ba_data/data/languages/tamil.json": "https://files.ballistica.net/cache/ba1/3d/83/e1bb0a664d1c14c41b1a083acf0d", "assets/build/ba_data/data/languages/thai.json": "https://files.ballistica.net/cache/ba1/d6/16/523c643358880b03b233ed88e557", - "assets/build/ba_data/data/languages/turkish.json": "https://files.ballistica.net/cache/ba1/c3/d2/d075ad07ec8d8aec3616f8760534", - "assets/build/ba_data/data/languages/ukrainian.json": "https://files.ballistica.net/cache/ba1/73/7b/b8822b5632a8d3c7cf134e2859cc", + "assets/build/ba_data/data/languages/turkish.json": "https://files.ballistica.net/cache/ba1/2a/0e/b164149e76efd0e6d591a9bf04bb", + "assets/build/ba_data/data/languages/ukrainian.json": "https://files.ballistica.net/cache/ba1/3e/b6/052f1faed0264bf7135feb5c4cc3", "assets/build/ba_data/data/languages/venetian.json": "https://files.ballistica.net/cache/ba1/a6/ed/416638d46950c9ab4f6155b9c334", "assets/build/ba_data/data/languages/vietnamese.json": "https://files.ballistica.net/cache/ba1/1f/ae/abe3f105b3c4b51f6b7942773305", "assets/build/ba_data/data/maps/big_g.json": "https://files.ballistica.net/cache/ba1/47/0a/a617cc85d927b576c4e6fc1091ed", @@ -4008,50 +4008,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/6f/3c/b6d4e92dcbac32aa3093d9139b9d", - "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/a1/b8/31ad72ffe5df6bbedbd59eb3f02b", - "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/d2/d9/084996631fa94337e0a92c93b753", - "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/89/0a/4483e91a808e4724dfbc382d6f60", - "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/ec/4d/6c58d9a9c5b13837d87d3d871868", - "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/dd/12/2e3164bd4770a6c648e2e7dbc4f0", - "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/fa/41/63a57ecf884cecf7ee1c8b9b2dcf", - "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/64/2b/0ebcdfd2f61027dcfff899d8894f", - "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/8f/e7/3ca7ed13d4a03013ecbb80ecb78c", - "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/ec/e2/ebe20cc007e87d0ede6e0ec169af", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/3a/77/32299795fdb8b0c0fbc3130b7193", - "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/c2/1a/bfaeccd961429479947ea1cb2c47", - "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/43/74/b5749a746e72007f2f464b2941c6", - "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/eb/e2/f97727387a3f9707b079b7b2acd0", - "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/5f/da/6a048012e6b94a303e59b8dae61b", - "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/f5/11/e75118e0a8f821e030f82e79c1bc", - "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/d2/ad/4ee541d9d19b2d6fc1dab4947a26", - "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/10/2b/133d1cf611800e518d5353a10a94", - "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/85/53/fde7e925ac80da650a02ee078ad0", - "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/96/8e/c8292f6fc6967003affeb6ca32b7", - "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/28/f6/26327365481296a963bb37d58d82", - "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/6d/b6/4e4a46d553d1949c956e72a3617d", - "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/81/57/d0a2b72a86d6f7f542d07e4fba29", - "build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ac/f5/a6350f397911c2833c35fb86aa6c", - "build/prefab/lib/linux_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/91/87/78eab8de6f5bc52ff10f75e9d0b5", - "build/prefab/lib/linux_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a9/29/9cf3b260aae600ccafb535309b62", - "build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/56/c2/75943b307817b0f23807b4f36632", - "build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/93/51/6cf630d6ab82f8946569b96f01b5", - "build/prefab/lib/mac_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/e4/ba/31a54b98463bc261835ac9cc7c51", - "build/prefab/lib/mac_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/64/25/bba77bfd767e14a9df46795c93bb", - "build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/f2/17/02a1053141eac72b24c323b10003", - "build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/98/ca/dcbb87a7c32120a42ab6ca1e7194", - "build/prefab/lib/mac_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ca/dc/4a0fcdee7fc3c57960d5381a0299", - "build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/6c/a3/b70ad508a305efc2a10b5ba4508e", - "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/98/a9/1426b7eadc8be33f98f103fb12f0", - "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/38/8f/50753e457af4c626e2285c3171ac", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/fe/4d/77331e69f4fc0ef288df17377b42", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/9b/07/37e3a24a6ee588d0e5d4ba7b5335", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/0a/60/0109e5badaf8d6610cc9a4a61aa2", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/6d/e7/4e5bf2f3c16ca59770d5789c2481", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/b5/de/6914b0c6ab3142ad99547e930d88", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/3e/a4/e22b4cc12099dc6863a418d186f9", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/bd/c7/c97d29a73c75b3e699f14bcd6e37", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/44/36/de0a2f89ccd4e4728301cecd1033", + "build/prefab/full/linux_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/b2/8a/31e68e8aeb4a440a98cdb37e688e", + "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/7e/c2/ed0e710cd33e9a96c7f54fdf400a", + "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/62/35/37d0f605248971a7d270914c0e61", + "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/91/a1/5da5cec236aa862f7f92f89783cd", + "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/37/bb/b6bfe02bbd14a9c2d02fb782e4a9", + "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/05/38/a9adca329b4a147d58dd81a714ac", + "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/2c/03/e562ae1a5cc7be268e1bf0ccc4c0", + "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/c9/d5/066f05c777e200dd73084f0a1c25", + "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/f7/6f/239efdb4e9e06cc0256f74da3aa8", + "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/d7/77/48d470740edb84a271bfb18c2a16", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/e1/2f/d8e39443dd972ea41fb0c241e8fd", + "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/32/9b/9d76eef13898e654b088698512d7", + "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/34/94/4abfe29e9b0443b292c53659a133", + "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/43/b1/2a8098e867f5d2a2cc086a4fb3f5", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/19/b6/0700636b968985ecc9ff1d3bd28e", + "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/db/ee/569470160da9dff657538c06ce7b", + "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/91/f9/6ec6bf4f8496ec4f71b3716db983", + "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/66/8a/7f50eede3fb6b6d7a655e4613f2e", + "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/d4/40/1121fb6089b698565347acec66f6", + "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/06/3b/0d289dd9a1170f750859e1c35b99", + "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/f5/70/38d78023e0b99fdbe6ee29edd809", + "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/35/92/f2e39484904878e7eb9f5b3aff60", + "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/6e/c5/6a81e0fc6027de9eca1c4a63143d", + "build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/88/b5/e58450cec94d586f3d824f53c580", + "build/prefab/lib/linux_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/66/af/cf144d78359363ba027f2bd98a55", + "build/prefab/lib/linux_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/9d/96/78f5d0d1e9249c71f018d84d9b24", + "build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/58/d1/0f90ecfd6631b5476da915a76c55", + "build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/7c/bc/ec9ef218fb8065b58182493c981d", + "build/prefab/lib/mac_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/4c/6b/b2a4eb26f043bb474e7e7e958470", + "build/prefab/lib/mac_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/64/e1/93f3afbc17ba6405cc970b559bb2", + "build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/79/d2/f3b45d1aca8056c6cb951adc99ba", + "build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/4b/40/2ad8e00744d0b821e86fc42fc1f6", + "build/prefab/lib/mac_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/8d/55/9876fecbe5d5076879b08d441665", + "build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/b4/f1/6c795ec50a26c24c734c5e0168b4", + "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/7d/44/03c734fb003671a15182e8446a44", + "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/7b/65/cadda8309ad9a4360a6930f05df8", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/41/a5/13590a172a2bf749bf419f67ce9f", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/76/26/0f89328b9e4554a5e656b1ead2d1", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/4b/da/b914c9e05be25d475155727046f4", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/c3/fb/78fe613f999fc6a9291c7141aeb8", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/f8/b2/cf697fd62a3f0bdbd248173551f0", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/d3/56/62b48ba16afb6023e730c9a42e75", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/4c/6e/009f37e5b619ce32e398b8039f62", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/26/03/2ee19e3130a7455efe5c9f78cd93", "src/ballistica/generated/python_embedded/binding.inc": "https://files.ballistica.net/cache/ba1/25/77/8093dfffddaa80cd513ddaa61867", "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 780866a1..7f276301 100644 --- a/.idea/dictionaries/ericf.xml +++ b/.idea/dictionaries/ericf.xml @@ -721,6 +721,7 @@ dummyret dummytoken dummyval + dumpminlog dups dval dxml @@ -1376,6 +1377,7 @@ levelmodule levelname levelno + levelnos levelstr lfull lfval @@ -1542,6 +1544,7 @@ mdiv mdocs mdocslines + mdpath mdpi megalint memfunctions @@ -1569,6 +1572,7 @@ minigame minigames miniplayer + minlog minping minusbutton minval @@ -2342,6 +2346,7 @@ shobs shortname shouldn + showbuffer showpoints showstats showsubseconds @@ -2869,6 +2874,7 @@ webpage webpages weeeird + whatarev whatevs whatisv wheee diff --git a/CHANGELOG.md b/CHANGELOG.md index a99f4fac..798e5152 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,10 @@ -### 1.7.16 (build 20967, api 7, 2022-12-16) +### 1.7.17 (build 20973, api 7, 2022-12-20) +- V2 accounts now show a 'Unlink Legacy (V1) Accounts' button in account settings if they have any old v1 links present. This can be used to clear out old links to replace them with V2 links which work correctly with V2 accounts. +- `ba.internal.dump_tracebacks()` is now `ba.internal.dump_app_state()` and `ba.internal.log_dumped_tracebacks()` is now `ba.internal.log_dumped_app_state()`. This reflects the fact that these calls may be expanded to include other app state in the future (C++ layer thread states, etc.). +- Added `ba.app.health_monitor` which will dump app state if the logic thread ever stops responding for 5+ seconds while the app is running (to help diagnose deadlock situations). +- Various extra logging and bug fixes related to V2 accounts and master server communication (trying to get this stuff working as smoothly as possible now that it is feature-complete). + +### 1.7.16 (build 20969, api 7, 2022-12-18) - Fixed a bug where profile names encased in curly brackets could cause harmless error messages. - Android will no longer log errors on ba.open_url() calls if a browser is not available (it still just falls back to the in-app dialog in that case). - The 'Upgrade' button for device accounts now signs you out and closes the upgrade window to hopefully make it more clear that you need to sign in with your newly created/upgraded BombSquad account. diff --git a/assets/src/ba_data/python/ba/_app.py b/assets/src/ba_data/python/ba/_app.py index 89a6184f..c7b09622 100644 --- a/assets/src/ba_data/python/ba/_app.py +++ b/assets/src/ba_data/python/ba/_app.py @@ -32,6 +32,7 @@ if TYPE_CHECKING: from bastd.actor import spazappearance from ba._accountv2 import AccountV2Subsystem from ba._level import Level + from ba._apputils import AppHealthMonitor class App: @@ -50,7 +51,9 @@ class App: # Implementations for these will be filled in by internal libs. accounts_v2: AccountV2Subsystem cloud: CloudSubsystem + log_handler: efro.log.LogHandler + health_monitor: AppHealthMonitor class State(Enum): """High level state the app can be in.""" @@ -346,7 +349,6 @@ class App: # pylint: disable=cyclic-import # pylint: disable=too-many-locals from ba import _asyncio - from ba import _apputils from ba import _appconfig from ba import _map from ba import _campaign @@ -354,11 +356,16 @@ class App: from bastd import maps as stdmaps from bastd.actor import spazappearance from ba._generated.enums import TimeType - from ba._apputils import log_dumped_tracebacks + from ba._apputils import ( + log_dumped_app_state, + handle_leftover_v1_cloud_log_file, + AppHealthMonitor, + ) assert _ba.in_logic_thread() self._aioloop = _asyncio.setup_asyncio() + self.health_monitor = AppHealthMonitor() cfg = self.config @@ -402,7 +409,7 @@ class App: # If there's a leftover log file, attempt to upload it to the # master-server and/or get rid of it. - _apputils.handle_leftover_v1_cloud_log_file() + handle_leftover_v1_cloud_log_file() # Only do this stuff if our config file is healthy so we don't # overwrite a broken one or whatnot and wipe out data. @@ -461,7 +468,7 @@ class App: ) # If any traceback dumps happened last run, log and clear them. - log_dumped_tracebacks() + log_dumped_app_state() self._launch_completed = True self._update_state() @@ -493,6 +500,7 @@ class App: self.cloud.on_app_pause() self.accounts_v1.on_app_pause() self.plugins.on_app_pause() + self.health_monitor.on_app_pause() else: # Leaving paused state: if self.state is self.State.PAUSED: @@ -501,6 +509,7 @@ class App: self.accounts_v1.on_app_resume() self.music.on_app_resume() self.plugins.on_app_resume() + self.health_monitor.on_app_resume() if self._initial_login_completed and self._meta_scan_completed: self.state = self.State.RUNNING diff --git a/assets/src/ba_data/python/ba/_apputils.py b/assets/src/ba_data/python/ba/_apputils.py index 9633b078..024ad189 100644 --- a/assets/src/ba_data/python/ba/_apputils.py +++ b/assets/src/ba_data/python/ba/_apputils.py @@ -6,8 +6,12 @@ from __future__ import annotations import gc import os import logging +from threading import Thread +from dataclasses import dataclass from typing import TYPE_CHECKING +from efro.log import LogLevel +from efro.dataclassio import ioprepped, dataclass_to_json, dataclass_from_json import _ba if TYPE_CHECKING: @@ -266,22 +270,67 @@ def print_corrupt_file_error() -> None: _tbfiles: list[TextIO] = [] -def dump_tracebacks(delay: float) -> None: - """Dump a traceback of all Python threads after a delay in seconds. +@ioprepped +@dataclass +class DumpedAppStateMetadata: + """High level info about a dumped app state.""" - Can be used for debugging deadlock situations. Will dump to a preset - file location in the app config dir. Will attempt to log and clear - the results after dumping. It will be done at next launch otherwise, - or can be done explicitly via log_dumped_tracebacks(). + reason: str + app_time: float + log_level: LogLevel - Do not use this call during regular operation of the app; it is only - intended for debugging as it can leak file descriptors/etc. + +def dump_app_state( + delay: float = 0.0, + reason: str = 'Unspecified', + log_level: LogLevel = LogLevel.WARNING, +) -> None: + """Dump various app state for debugging purposes. + + This includes stack traces for all Python threads (and potentially + other info in the future). + + This is intended for use debugging deadlock situations. It will dump + to preset file location(s) in the app config dir, and will attempt to + log and clear the results after dumping. If that should fail (due to + a hung app, etc.), then the results will be logged and cleared on the + next app run. + + Do not use this call during regular smooth operation of the app; it + is should only be used for debugging or in response to confirmed + problems as it can leak file descriptors, cause hitches, etc. """ # pylint: disable=consider-using-with import faulthandler from ba._generated.enums import TimeType - tbpath = os.path.join(os.path.dirname(_ba.app.config_file_path), '_tbdump') + # Dump our metadata immediately. If a delay is passed, it generally + # means we expect things to hang momentarily, so we should not delay + # writing our metadata or it will likely not happen. Though we + # should remember that metadata doesn't line up perfectly in time with + # the dump in that case. + try: + mdpath = os.path.join( + os.path.dirname(_ba.app.config_file_path), '_appstate_dump_md' + ) + with open(mdpath, 'w', encoding='utf-8') as outfile: + outfile.write( + dataclass_to_json( + DumpedAppStateMetadata( + reason=reason, + app_time=_ba.time(TimeType.REAL), + log_level=log_level, + ) + ) + ) + except Exception: + # Abandon whole dump if we can't write metadata. + logging.exception('Error writing app state dump metadata.') + return + + tbpath = os.path.join( + os.path.dirname(_ba.app.config_file_path), '_appstate_dump_tb' + ) # faulthandler needs the raw file descriptor to still be valid when # it fires, so stuff this into a global var to make sure it doesn't get @@ -289,23 +338,132 @@ def dump_tracebacks(delay: float) -> None: tbfile = open(tbpath, 'w', encoding='utf-8') _tbfiles.append(tbfile) - faulthandler.dump_traceback_later(delay, file=tbfile) + if delay > 0.0: + faulthandler.dump_traceback_later(delay, file=tbfile) + else: + faulthandler.dump_traceback(file=tbfile) # Attempt to log shortly after dumping. - with _ba.Context('ui'): - _ba.timer(delay + 1.0, log_dumped_tracebacks, timetype=TimeType.REAL) + # Allow sufficient time since we don't know how long the dump takes. + # We want this to work from any thread, so need to kick this part + # over to the logic thread so timer works. + _ba.pushcall( + lambda: _ba.timer( + delay + 1.0, log_dumped_app_state, timetype=TimeType.REAL + ), + from_other_thread=True, + suppress_other_thread_warning=True, + ) -def log_dumped_tracebacks() -> None: - """If a traceback dump exists, log it and clear it. No-op otherwise.""" +def log_dumped_app_state() -> None: + """If an app-state dump exists, log it and clear it. No-op otherwise.""" try: - tbpath = os.path.join( - os.path.dirname(_ba.app.config_file_path), '_tbdump' + out = '' + mdpath = os.path.join( + os.path.dirname(_ba.app.config_file_path), '_appstate_dump_md' ) - if os.path.exists(tbpath): - with open(tbpath, 'r', encoding='utf-8') as infile: - logging.info('Dumped tracebacks:\n%s', infile.read()) - os.unlink(tbpath) + if os.path.exists(mdpath): + with open(mdpath, 'r', encoding='utf-8') as infile: + metadata = dataclass_from_json( + DumpedAppStateMetadata, infile.read() + ) + os.unlink(mdpath) + out += ( + f'App state dump:\nReason: {metadata.reason}\n' + f'Time: {metadata.app_time:.2f}' + ) + tbpath = os.path.join( + os.path.dirname(_ba.app.config_file_path), '_appstate_dump_tb' + ) + if os.path.exists(tbpath): + with open(tbpath, 'r', encoding='utf-8') as infile: + out += '\nPython tracebacks:\n' + infile.read() + os.unlink(tbpath) + logging.log(metadata.log_level.python_logging_level, out) except Exception: - logging.exception('Error logging dumped tracebacks.') + logging.exception('Error logging dumped app state.') + + +class AppHealthMonitor: + """Logs things like app-not-responding issues.""" + + def __init__(self) -> None: + assert _ba.in_logic_thread() + self._running = True + self._thread = Thread(target=self._bg_thread_main, daemon=True) + self._thread.start() + self._response = False + self._first_check = True + + def _bg_thread_main(self) -> None: + + try: + self._monitor_app() + except Exception: + logging.exception('Error in AppHealthMonitor thread.') + + def _set_response(self) -> None: + assert _ba.in_logic_thread() + self._response = True + + def _check_running(self) -> bool: + # Workaround for the fact that mypy assumes _running + # doesn't change during the course of a function. + return self._running + + def _monitor_app(self) -> None: + import time + + while bool(True): + + # Always sleep a bit between checks. + time.sleep(1.234) + + # Do nothing while backgrounded. + while not self._running: + time.sleep(2.3456) + + # Wait for the logic thread to run something we send it. + starttime = time.monotonic() + self._response = False + _ba.pushcall(self._set_response, raw=True) + while not self._response: + + # Abort this check if we went into the background. + if not self._check_running(): + break + + # Wait a bit longer the first time through since the app + # could still be starting up; we generally don't want to + # report that. + threshold = 10 if self._first_check else 5 + + # If we've been waiting too long (and the app is running) + # dump the app state and bail. Make an exception for the + # first check though since the app could just be taking + # a while to get going; we don't want to report that. + duration = time.monotonic() - starttime + if duration > threshold: + dump_app_state( + reason=f'Logic thread unresponsive' + f' for {threshold} seconds.' + ) + + # We just do one alert for now. + return + + time.sleep(1.042) + + self._first_check = False + + def on_app_pause(self) -> None: + """Should be called when the app pauses.""" + assert _ba.in_logic_thread() + self._running = False + + def on_app_resume(self) -> None: + """Should be called when the app resumes.""" + assert _ba.in_logic_thread() + self._running = True diff --git a/assets/src/ba_data/python/ba/_bootstrap.py b/assets/src/ba_data/python/ba/_bootstrap.py index 53091f8f..d7a037be 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 = 20967 + expected_build = 20973 running_build: int = env['build_number'] if running_build != expected_build: print( diff --git a/assets/src/ba_data/python/ba/_store.py b/assets/src/ba_data/python/ba/_store.py index 2dfc07c1..d3274de5 100644 --- a/assets/src/ba_data/python/ba/_store.py +++ b/assets/src/ba_data/python/ba/_store.py @@ -53,7 +53,9 @@ def get_store_item_display_size(item_name: str) -> tuple[float, float]: if item_name.startswith('characters.'): return 340 * 0.6, 430 * 0.6 if item_name in ['pro', 'upgrades.pro', 'merch']: - return 650 * 0.9, 500 * 0.85 + return 650 * 0.9, 500 * ( + 0.72 if _ba.app.config.get('Merch Link') else 0.85 + ) if item_name.startswith('maps.'): return 510 * 0.6, 450 * 0.6 if item_name.startswith('icons.'): diff --git a/assets/src/ba_data/python/ba/internal.py b/assets/src/ba_data/python/ba/internal.py index 7cf9a06e..4b04a9a7 100644 --- a/assets/src/ba_data/python/ba/internal.py +++ b/assets/src/ba_data/python/ba/internal.py @@ -101,8 +101,8 @@ from ba._apputils import ( is_browser_likely_available, get_remote_app_name, should_submit_debug_info, - dump_tracebacks, - log_dumped_tracebacks, + dump_app_state, + log_dumped_app_state, ) from ba._benchmark import ( run_gpu_benchmark, @@ -334,6 +334,6 @@ __all__ = [ 'sign_out_v1', 'sign_in_v1', 'mark_config_dirty', - 'dump_tracebacks', - 'log_dumped_tracebacks', + 'dump_app_state', + 'log_dumped_app_state', ] diff --git a/assets/src/ba_data/python/bastd/ui/account/settings.py b/assets/src/ba_data/python/bastd/ui/account/settings.py index 149e89d0..ea43f5df 100644 --- a/assets/src/ba_data/python/bastd/ui/account/settings.py +++ b/assets/src/ba_data/python/bastd/ui/account/settings.py @@ -38,6 +38,8 @@ class AccountSettingsWindow(ba.Window): self._sign_in_v2_proxy_button: ba.Widget | None = None self._sign_in_device_button: ba.Widget | None = None + self._show_legacy_unlink_button = False + self._signing_in_adapter: LoginAdapter | None = None self._close_once_signed_in = close_once_signed_in ba.set_analytics_screen('Account Window') @@ -57,14 +59,8 @@ class AccountSettingsWindow(ba.Window): self._r = 'accountSettingsWindow' self._modal = modal self._needs_refresh = False - self._signed_in = ba.internal.get_v1_account_state() == 'signed_in' - self._account_state_num = ba.internal.get_v1_account_state_num() - self._show_linked = ( - self._signed_in - and ba.internal.get_v1_account_misc_read_val( - 'allowAccountLinking2', False - ) - ) + self._v1_signed_in = ba.internal.get_v1_account_state() == 'signed_in' + self._v1_account_state_num = ba.internal.get_v1_account_state_num() self._check_sign_in_timer = ba.Timer( 1.0, ba.WeakCall(self._update), @@ -73,12 +69,12 @@ class AccountSettingsWindow(ba.Window): ) # Currently we can only reset achievements on game-center. - account_type: str | None - if self._signed_in: - account_type = ba.internal.get_v1_account_type() + v1_account_type: str | None + if self._v1_signed_in: + v1_account_type = ba.internal.get_v1_account_type() else: - account_type = None - self._can_reset_achievements = account_type == 'Game Center' + v1_account_type = None + self._can_reset_achievements = v1_account_type == 'Game Center' app = ba.app uiscale = app.ui.uiscale @@ -190,31 +186,25 @@ class AccountSettingsWindow(ba.Window): def _update(self) -> None: # If they want us to close once we're signed in, do so. - if self._close_once_signed_in and self._signed_in: + if self._close_once_signed_in and self._v1_signed_in: self._back() return # Hmm should update this to use get_account_state_num. # Theoretically if we switch from one signed-in account to another # in the background this would break. - account_state_num = ba.internal.get_v1_account_state_num() - account_state = ba.internal.get_v1_account_state() - - show_linked = ( - self._signed_in - and ba.internal.get_v1_account_misc_read_val( - 'allowAccountLinking2', False - ) - ) + v1_account_state_num = ba.internal.get_v1_account_state_num() + v1_account_state = ba.internal.get_v1_account_state() + show_legacy_unlink_button = self._should_show_legacy_unlink_button() if ( - account_state_num != self._account_state_num - or self._show_linked != show_linked + v1_account_state_num != self._v1_account_state_num + or show_legacy_unlink_button != self._show_legacy_unlink_button or self._needs_refresh ): - self._show_linked = show_linked - self._account_state_num = account_state_num - self._signed_in = account_state == 'signed_in' + self._v1_account_state_num = v1_account_state_num + self._v1_signed_in = v1_account_state == 'signed_in' + self._show_legacy_unlink_button = show_legacy_unlink_button self._refresh() # Go ahead and refresh some individual things @@ -253,10 +243,10 @@ class AccountSettingsWindow(ba.Window): False if gpgs_adapter is None else gpgs_adapter.is_back_end_active() ) - show_signed_in_as = self._signed_in + show_signed_in_as = self._v1_signed_in signed_in_as_space = 95.0 - show_sign_in_benefits = not self._signed_in + show_sign_in_benefits = not self._v1_signed_in sign_in_benefits_space = 80.0 show_signing_in_text = ( @@ -282,17 +272,17 @@ class AccountSettingsWindow(ba.Window): sign_in_button_space = 70.0 deprecated_space = 60 - show_game_service_button = self._signed_in and v1_account_type in [ + show_game_service_button = self._v1_signed_in and v1_account_type in [ 'Game Center' ] game_service_button_space = 60.0 - show_what_is_v2 = self._signed_in and v1_account_type == 'V2' + show_what_is_v2 = self._v1_signed_in and v1_account_type == 'V2' - show_linked_accounts_text = self._signed_in + show_linked_accounts_text = self._v1_signed_in linked_accounts_text_space = 60.0 - show_achievements_button = self._signed_in and v1_account_type in ( + show_achievements_button = self._v1_signed_in and v1_account_type in ( 'Google Play', 'Local', 'V2', @@ -300,33 +290,33 @@ class AccountSettingsWindow(ba.Window): achievements_button_space = 60.0 show_achievements_text = ( - self._signed_in and not show_achievements_button + self._v1_signed_in and not show_achievements_button ) achievements_text_space = 27.0 - show_leaderboards_button = self._signed_in and is_gpgs + show_leaderboards_button = self._v1_signed_in and is_gpgs leaderboards_button_space = 60.0 - show_campaign_progress = self._signed_in + show_campaign_progress = self._v1_signed_in campaign_progress_space = 27.0 - show_tickets = self._signed_in + show_tickets = self._v1_signed_in tickets_space = 27.0 show_reset_progress_button = False reset_progress_button_space = 70.0 show_manage_v2_account_button = ( - self._signed_in and v1_account_type == 'V2' + self._v1_signed_in and v1_account_type == 'V2' ) manage_v2_account_button_space = 100.0 - show_player_profiles_button = self._signed_in + show_player_profiles_button = self._v1_signed_in player_profiles_button_space = ( 70.0 if show_manage_v2_account_button else 100.0 ) - show_link_accounts_button = self._signed_in and ( + show_link_accounts_button = self._v1_signed_in and ( primary_v2_account is None or FORCE_ENABLE_V1_LINKING ) link_accounts_button_space = 70.0 @@ -334,10 +324,12 @@ class AccountSettingsWindow(ba.Window): show_unlink_accounts_button = show_link_accounts_button unlink_accounts_button_space = 90.0 - show_v2_link_info = self._signed_in and not show_link_accounts_button + show_v2_link_info = self._v1_signed_in and not show_link_accounts_button v2_link_info_space = 70.0 - show_sign_out_button = self._signed_in and v1_account_type in [ + legacy_unlink_button_space = 120.0 + + show_sign_out_button = self._v1_signed_in and v1_account_type in [ 'Local', 'Google Play', 'V2', @@ -394,6 +386,8 @@ class AccountSettingsWindow(ba.Window): self._sub_height += unlink_accounts_button_space if show_v2_link_info: self._sub_height += v2_link_info_space + if self._show_legacy_unlink_button: + self._sub_height += legacy_unlink_button_space if show_sign_out_button: self._sub_height += sign_out_button_space if show_cancel_sign_in_button: @@ -460,7 +454,7 @@ class AccountSettingsWindow(ba.Window): v_align='center', autoselect=True, selectable=True, - on_activate_call=ba.WeakCall(self._on_what_is_v2_press), + on_activate_call=show_what_is_v2_page, click_activate=True, ) if first_selectable is None: @@ -1046,6 +1040,35 @@ class AccountSettingsWindow(ba.Window): color=(0.5, 0.45, 0.55), ) + if self._show_legacy_unlink_button: + v -= legacy_unlink_button_space + button_width_w = button_width * 1.5 + ba.textwidget( + parent=self._subcontainer, + position=(self._sub_width * 0.5 - 150.0, v + 75), + size=(300.0, 60), + text=ba.Lstr(resource='whatIsThisText'), + scale=0.8, + color=(0.3, 0.7, 0.05), + maxwidth=200.0, + h_align='center', + v_align='center', + autoselect=True, + selectable=True, + on_activate_call=show_what_is_legacy_unlinking_page, + click_activate=True, + ) + btn = ba.buttonwidget( + parent=self._subcontainer, + position=((self._sub_width - button_width_w) * 0.5, v + 25), + autoselect=True, + size=(button_width_w, 60), + label=ba.Lstr(resource=self._r + '.unlinkLegacyV1AccountsText'), + textcolor=(0.8, 0.4, 0), + color=(0.55, 0.5, 0.6), + on_activate_call=self._unlink_accounts_press, + ) + if show_sign_out_button: v -= sign_out_button_space self._sign_out_button = btn = ba.buttonwidget( @@ -1153,7 +1176,7 @@ class AccountSettingsWindow(ba.Window): timetype=ba.TimeType.REAL, ) - def _have_unlinkable_accounts(self) -> bool: + def _have_unlinkable_v1_accounts(self) -> bool: # if this is not present, we haven't had contact from the server so # let's not proceed.. if ba.internal.get_public_login_id() is None: @@ -1166,12 +1189,21 @@ class AccountSettingsWindow(ba.Window): def _update_unlink_accounts_button(self) -> None: if self._unlink_accounts_button is None: return - if self._have_unlinkable_accounts(): + if self._have_unlinkable_v1_accounts(): clr = (0.75, 0.7, 0.8, 1.0) else: clr = (1.0, 1.0, 1.0, 0.25) ba.textwidget(edit=self._unlink_accounts_button_label, color=clr) + def _should_show_legacy_unlink_button(self) -> bool: + + # Only show this when fully signed in to a v2 account. + if not self._v1_signed_in or ba.app.accounts_v2.primary is None: + return False + + out = self._have_unlinkable_v1_accounts() + return out + def _update_linked_accounts_text(self) -> None: if self._linked_accounts_text is None: return @@ -1297,7 +1329,7 @@ class AccountSettingsWindow(ba.Window): # pylint: disable=cyclic-import from bastd.ui.account import unlink - if not self._have_unlinkable_accounts(): + if not self._have_unlinkable_v1_accounts(): ba.playsound(ba.getsound('error')) return unlink.AccountUnlinkWindow(origin_widget=self._unlink_accounts_button) @@ -1499,3 +1531,9 @@ def show_what_is_v2_page() -> None: """Show the webpage describing V2 accounts.""" bamasteraddr = ba.internal.get_master_server_address(version=2) ba.open_url(f'{bamasteraddr}/whatisv2') + + +def show_what_is_legacy_unlinking_page() -> None: + """Show the webpage describing legacy unlinking.""" + bamasteraddr = ba.internal.get_master_server_address(version=2) + ba.open_url(f'{bamasteraddr}/whatarev1links') diff --git a/assets/src/ba_data/python/bastd/ui/mainmenu.py b/assets/src/ba_data/python/bastd/ui/mainmenu.py index a3d67738..b4369f0a 100644 --- a/assets/src/ba_data/python/bastd/ui/mainmenu.py +++ b/assets/src/ba_data/python/bastd/ui/mainmenu.py @@ -515,7 +515,20 @@ class MainMenuWindow(ba.Window): self._tdelay = 2.0 self._t_delay_inc = 0.02 self._t_delay_play = 1.7 - self._next_refresh_allow_time = ba.time(ba.TimeType.REAL) + 2.01 + + def _set_allow_time() -> None: + self._next_refresh_allow_time = ba.time(ba.TimeType.REAL) + 2.5 + + # Slight hack: widget transitions currently only progress when + # frames are being drawn, but this tends to get called before + # frame drawing even starts, meaning we don't know exactly how + # long we should wait before refreshing to avoid interrupting + # the transition. To make things a bit better, let's do a + # redundant set of the time in a deferred call which hopefully + # happens closer to actual frame draw times. + _set_allow_time() + ba.pushcall(_set_allow_time) + ba.app.did_menu_intro = True self._width = 400.0 self._height = 200.0 diff --git a/assets/src/ba_data/python/bastd/ui/store/browser.py b/assets/src/ba_data/python/bastd/ui/store/browser.py index 3582629f..22977e4c 100644 --- a/assets/src/ba_data/python/bastd/ui/store/browser.py +++ b/assets/src/ba_data/python/bastd/ui/store/browser.py @@ -907,7 +907,11 @@ class StoreBrowserWindow(ba.Window): dummy_name ) section['v_spacing'] = ( - -17 if self._tab == 'characters' else 0 + -25 + if self._tab == 'extras' + else -17 + if self._tab == 'characters' + else 0 ) if 'title' not in section: section['title'] = '' @@ -919,7 +923,13 @@ class StoreBrowserWindow(ba.Window): else 0 ) section['y_offs'] = ( - 55 + 20 + if ( + self._tab == 'extras' + and uiscale is ba.UIScale.SMALL + and ba.app.config.get('Merch Link') + ) + else 55 if ( self._tab == 'extras' and uiscale is ba.UIScale.SMALL diff --git a/assets/src/ba_data/python/bastd/ui/store/item.py b/assets/src/ba_data/python/bastd/ui/store/item.py index 078f3c9c..6c8b827e 100644 --- a/assets/src/ba_data/python/bastd/ui/store/item.py +++ b/assets/src/ba_data/python/bastd/ui/store/item.py @@ -45,19 +45,23 @@ def instantiate_store_item_display( item['name'] = title = get_store_item_name_translated(item_name) btn: ba.Widget | None + + # Hack; showbuffer stuff isn't working well when we're showing merch. + showbuffer = 10 if item_name in {'merch', 'pro', 'pro_sale'} else 76.0 + if button: item['button'] = btn = ba.buttonwidget( parent=parent_widget, position=b_pos, transition_delay=delay, - show_buffer_top=76.0, + show_buffer_top=showbuffer, enable_sound=False, button_type='square', size=(b_width, b_height), autoselect=True, label='', ) - ba.widget(edit=btn, show_buffer_bottom=76.0) + ba.widget(edit=btn, show_buffer_bottom=showbuffer) else: btn = None @@ -170,11 +174,11 @@ def instantiate_store_item_display( ) if item_name == 'merch': - frame_size = b_width * 0.7 + frame_size = b_width * 0.65 im_dim = frame_size * (100.0 / 113.0) im_pos = ( b_pos[0] + b_width * 0.5 - im_dim * 0.5 + b_offs_x, - b_pos[1] + b_height * 0.5 - im_dim * 0.5, + b_pos[1] + b_height * 0.47 - im_dim * 0.5, ) ba.imagewidget( parent=parent_widget, diff --git a/ballisticacore-cmake/.idea/dictionaries/ericf.xml b/ballisticacore-cmake/.idea/dictionaries/ericf.xml index d5ef5e70..45705ff7 100644 --- a/ballisticacore-cmake/.idea/dictionaries/ericf.xml +++ b/ballisticacore-cmake/.idea/dictionaries/ericf.xml @@ -388,6 +388,7 @@ dummyret dummyval dummyvalid + dumpminlog dval dxgi dynamicdata @@ -732,6 +733,7 @@ leaderboards lenval levelno + levelnos levelstr lgui lhalf @@ -807,6 +809,7 @@ maxtries maxwait maxwidth + mdpath mediump memalign memchr @@ -824,6 +827,7 @@ millisecs minelem miniplayer + minlog minping minsdl mipmapcount @@ -1245,6 +1249,7 @@ shhh shifthigh shouldnt + showbuffer shufflable signsubscale sigsetjmp @@ -1518,6 +1523,7 @@ weeeird welp whaaaaaaa + whatarev whatisv wheee wheeee diff --git a/src/ballistica/ballistica.cc b/src/ballistica/ballistica.cc index 51a2e010..7ed2cdc6 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 = 20967; -const char* kAppVersion = "1.7.16"; +const int kAppBuildNumber = 20973; +const char* kAppVersion = "1.7.17"; // Our standalone globals. // These are separated out for easy access. diff --git a/src/ballistica/ui/widget/container_widget.cc b/src/ballistica/ui/widget/container_widget.cc index 5d82083b..5cdd262e 100644 --- a/src/ballistica/ui/widget/container_widget.cc +++ b/src/ballistica/ui/widget/container_widget.cc @@ -446,7 +446,9 @@ auto ContainerWidget::HandleMessage(const WidgetMessage& m) -> bool { CheckLayout(); // Ignore mouse stuff while transitioning out. - if (transitioning_ && transitioning_out_) break; + if (transitioning_ && transitioning_out_) { + break; + } float x = m.fval1; float y = m.fval2; @@ -505,7 +507,9 @@ auto ContainerWidget::HandleMessage(const WidgetMessage& m) -> bool { CheckLayout(); // Ignore mouse stuff while transitioning. - if (transitioning_ && transitioning_out_) break; + if (transitioning_ && transitioning_out_) { + break; + } float x = m.fval1; float y = m.fval2; @@ -546,7 +550,9 @@ auto ContainerWidget::HandleMessage(const WidgetMessage& m) -> bool { CheckLayout(); // Ignore mouse stuff while transitioning. - if (transitioning_ && transitioning_out_) break; + if (transitioning_ && transitioning_out_) { + break; + } float x = m.fval1; float y = m.fval2; @@ -909,7 +915,9 @@ void ContainerWidget::Draw(RenderPass* pass, bool draw_transparent) { } // Don't draw if we've fully transitioned out. - if (transitioning_out_ && !transitioning_) return; + if (transitioning_out_ && !transitioning_) { + return; + } float l = transition_offset_x_smoothed_ + transition_scale_offset_x_; float r = l + width_; diff --git a/tools/efro/log.py b/tools/efro/log.py index 6ee2e896..b4ea9649 100644 --- a/tools/efro/log.py +++ b/tools/efro/log.py @@ -37,7 +37,27 @@ class LogLevel(Enum): ERROR = 3 CRITICAL = 4 + @property + def python_logging_level(self) -> int: + """Give the corresponding logging level.""" + return LOG_LEVEL_LEVELNOS[self] + @classmethod + def from_python_logging_level(cls, levelno: int) -> LogLevel: + """Given a Python logging level, return a LogLevel.""" + return LEVELNO_LOG_LEVELS[levelno] + + +# Python logging levels from LogLevels +LOG_LEVEL_LEVELNOS = { + LogLevel.DEBUG: logging.DEBUG, + LogLevel.INFO: logging.INFO, + LogLevel.WARNING: logging.WARNING, + LogLevel.ERROR: logging.ERROR, + LogLevel.CRITICAL: logging.CRITICAL, +} + +# LogLevels from Python logging levels LEVELNO_LOG_LEVELS = { logging.DEBUG: LogLevel.DEBUG, logging.INFO: LogLevel.INFO, From c390f336740f66fe7cb1997b8a16c18524c5d323 Mon Sep 17 00:00:00 2001 From: EraOSBeta <100019405+EraOSBeta@users.noreply.github.com> Date: Wed, 21 Dec 2022 09:21:21 +0330 Subject: [PATCH 16/26] Update spaz.py --- assets/src/ba_data/python/bastd/actor/spaz.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assets/src/ba_data/python/bastd/actor/spaz.py b/assets/src/ba_data/python/bastd/actor/spaz.py index 4d1529fe..2aa65a8c 100644 --- a/assets/src/ba_data/python/bastd/actor/spaz.py +++ b/assets/src/ba_data/python/bastd/actor/spaz.py @@ -180,6 +180,7 @@ class Spaz(ba.Actor): self._bomb_wear_off_flash_timer: ba.Timer | None = None self._multi_bomb_wear_off_timer: ba.Timer | None = None self._multi_bomb_wear_off_flash_timer: ba.Timer | None = None + self._curse_timer: ba.Timer | None = None self.bomb_count = self.default_bomb_count self._max_bomb_count = self.default_bomb_count self.bomb_type_default = self.default_bomb_type @@ -620,7 +621,7 @@ class Spaz(ba.Actor): self.node.curse_death_time = int( 1000.0 * (tval + self.curse_time) ) - ba.timer(5.0, ba.WeakCall(self.curse_explode)) + self._curse_timer = ba.Timer(5.0, ba.WeakCall(self.curse_explode)) def equip_boxing_gloves(self) -> None: """ From a5358a8c006a38abaa833455c5daa81c0f49b26a Mon Sep 17 00:00:00 2001 From: EraOSBeta <100019405+EraOSBeta@users.noreply.github.com> Date: Wed, 21 Dec 2022 09:51:15 +0330 Subject: [PATCH 17/26] Update CONTRIBUTORS.md --- CONTRIBUTORS.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 79ecd547..378c525a 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -38,4 +38,8 @@ ### Vishal332008 - Bug Fixer -- Modder \ No newline at end of file +- Modder + +### Era0S +- Fixed a single bug +- Modder From d2ca02e07ffed69272e1d7c9f822204008c68aaa Mon Sep 17 00:00:00 2001 From: Eric Date: Thu, 22 Dec 2022 21:44:54 -0800 Subject: [PATCH 18/26] latest polishing and bug hunting --- .efrocachemap | 92 +++++++++---------- CHANGELOG.md | 2 +- assets/src/ba_data/python/._ba_sources_hash | 2 +- assets/src/ba_data/python/ba/_apputils.py | 61 +++++++++++- assets/src/ba_data/python/ba/_bootstrap.py | 2 +- assets/src/ba_data/python/ba/_store.py | 9 +- .../ba_data/python/bastd/ui/store/browser.py | 5 +- src/ballistica/ballistica.cc | 2 +- src/ballistica/core/logging.cc | 6 +- src/ballistica/networking/network_reader.cc | 22 +++++ src/ballistica/networking/network_reader.h | 2 + src/ballistica/python/python.h | 1 + src/meta/bameta/python_embedded/binding.py | 1 + tools/efro/log.py | 4 +- 14 files changed, 152 insertions(+), 59 deletions(-) diff --git a/.efrocachemap b/.efrocachemap index b054ad5d..45711364 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -420,7 +420,7 @@ "assets/build/ba_data/audio/zoeOw.ogg": "https://files.ballistica.net/cache/ba1/60/ad/38269b7f1c7dc20cb9a506cd0681", "assets/build/ba_data/audio/zoePickup01.ogg": "https://files.ballistica.net/cache/ba1/72/85/d6fc4d16b7081d91fba2850b5b10", "assets/build/ba_data/audio/zoeScream01.ogg": "https://files.ballistica.net/cache/ba1/e9/ae/1d674d0c086eaa0bd1c3b1db0505", - "assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/a8/a2/8c6816daac85d0b899a324509cf6", + "assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/8c/16/c8b51005b8ed3a5046264ac667f4", "assets/build/ba_data/data/languages/arabic.json": "https://files.ballistica.net/cache/ba1/92/43/36b34307575f6d6219bdf4898e18", "assets/build/ba_data/data/languages/belarussian.json": "https://files.ballistica.net/cache/ba1/61/03/89070ca765e06da3a419a579f503", "assets/build/ba_data/data/languages/chinese.json": "https://files.ballistica.net/cache/ba1/aa/ed/4bd02af3cffbd4c9c4be532fb1fe", @@ -4008,51 +4008,51 @@ "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/b2/8a/31e68e8aeb4a440a98cdb37e688e", - "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/7e/c2/ed0e710cd33e9a96c7f54fdf400a", - "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/62/35/37d0f605248971a7d270914c0e61", - "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/91/a1/5da5cec236aa862f7f92f89783cd", - "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/37/bb/b6bfe02bbd14a9c2d02fb782e4a9", - "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/05/38/a9adca329b4a147d58dd81a714ac", - "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/2c/03/e562ae1a5cc7be268e1bf0ccc4c0", - "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/c9/d5/066f05c777e200dd73084f0a1c25", - "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/f7/6f/239efdb4e9e06cc0256f74da3aa8", - "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/d7/77/48d470740edb84a271bfb18c2a16", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/e1/2f/d8e39443dd972ea41fb0c241e8fd", - "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/32/9b/9d76eef13898e654b088698512d7", - "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/34/94/4abfe29e9b0443b292c53659a133", - "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/43/b1/2a8098e867f5d2a2cc086a4fb3f5", - "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/19/b6/0700636b968985ecc9ff1d3bd28e", - "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/db/ee/569470160da9dff657538c06ce7b", - "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/91/f9/6ec6bf4f8496ec4f71b3716db983", - "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/66/8a/7f50eede3fb6b6d7a655e4613f2e", - "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/d4/40/1121fb6089b698565347acec66f6", - "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/06/3b/0d289dd9a1170f750859e1c35b99", - "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/f5/70/38d78023e0b99fdbe6ee29edd809", - "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/35/92/f2e39484904878e7eb9f5b3aff60", - "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/6e/c5/6a81e0fc6027de9eca1c4a63143d", - "build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/88/b5/e58450cec94d586f3d824f53c580", - "build/prefab/lib/linux_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/66/af/cf144d78359363ba027f2bd98a55", - "build/prefab/lib/linux_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/9d/96/78f5d0d1e9249c71f018d84d9b24", - "build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/58/d1/0f90ecfd6631b5476da915a76c55", - "build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/7c/bc/ec9ef218fb8065b58182493c981d", - "build/prefab/lib/mac_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/4c/6b/b2a4eb26f043bb474e7e7e958470", - "build/prefab/lib/mac_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/64/e1/93f3afbc17ba6405cc970b559bb2", - "build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/79/d2/f3b45d1aca8056c6cb951adc99ba", - "build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/4b/40/2ad8e00744d0b821e86fc42fc1f6", - "build/prefab/lib/mac_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/8d/55/9876fecbe5d5076879b08d441665", - "build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/b4/f1/6c795ec50a26c24c734c5e0168b4", - "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/7d/44/03c734fb003671a15182e8446a44", - "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/7b/65/cadda8309ad9a4360a6930f05df8", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/41/a5/13590a172a2bf749bf419f67ce9f", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/76/26/0f89328b9e4554a5e656b1ead2d1", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/4b/da/b914c9e05be25d475155727046f4", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/c3/fb/78fe613f999fc6a9291c7141aeb8", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/f8/b2/cf697fd62a3f0bdbd248173551f0", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/d3/56/62b48ba16afb6023e730c9a42e75", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/4c/6e/009f37e5b619ce32e398b8039f62", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/26/03/2ee19e3130a7455efe5c9f78cd93", - "src/ballistica/generated/python_embedded/binding.inc": "https://files.ballistica.net/cache/ba1/25/77/8093dfffddaa80cd513ddaa61867", + "build/prefab/full/linux_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/76/00/aadc5cc5fa6a1b47535571f53e0c", + "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/8a/c5/e18feec0e01cef4f4e95fb0808ec", + "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/de/73/3238fef727dbe8e13fc01bacccdf", + "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/e3/16/33500fbc1be37a7ab0beb9ea1353", + "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/23/75/f18db49e8bf625a4d140cfddc0eb", + "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/13/92/649fec7372f2cc6513d81df7ac03", + "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/ba/aa/8a853018d236f1f8c70bfd6d830a", + "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/2e/36/908f74e219d570e16ce72520b0f9", + "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/75/0a/6bdecafd1f0a1d4613697e1ad71d", + "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/d1/55/18e339d10407ec858fee58fc9d5a", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/6b/d6/68df4d180d1eb83119a8a1d2cde3", + "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/b6/51/3f2217d1f0640ec63e7499641001", + "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/6a/0e/b42051f6e252b278279d2bf0ce65", + "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/8f/8d/2dcdfbc13d984ea6c62ef5e07600", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/63/32/555ad0de811a0af52f704f215309", + "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/60/39/8589f26d7619a11c53f452d4a808", + "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/99/a4/2e40eb7af11d25d889af56fa73dc", + "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/a5/b1/34cd5f68321e318a18d3bf2a6651", + "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/ec/8b/b08ad5030780c2554291c5ddf7b4", + "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/96/ae/28d1c19d92db131315fa2d42d772", + "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/e9/02/eb6c1b076dd366fcdbb69c0aa85a", + "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ff/2b/5e85ad35d9305d60adbdc53dbb6e", + "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/5b/fb/074697e51ab8a28604788be2b3bb", + "build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/0b/26/7a9c1094bb1ffea16a60424251e1", + "build/prefab/lib/linux_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/fb/89/55c61946fc5cfa6e1154450b84e8", + "build/prefab/lib/linux_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/b9/33/7d35c3ff242b7ad72257b9a132ec", + "build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/9c/5e/de343f0a5b9ada35352ba10f5598", + "build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a7/da/be3ad1176399531ce6e634f8700f", + "build/prefab/lib/mac_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/83/2e/f5710315b4a86e6dd2a3806f0b9a", + "build/prefab/lib/mac_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/bd/15/c896646cdff25290761c402d3b21", + "build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/7a/f1/e9cafcb4a0b721a48027763e6b50", + "build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/b7/ec/0ad3db1b805b6d3067893326e8d8", + "build/prefab/lib/mac_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/c3/88/22c1bff0c944447bf15cadb835a8", + "build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/62/fc/bbf70a63d29d536d8511474309c6", + "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/d2/c1/ed8083e560d9466547d1da458118", + "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/10/8a/534c2c99f6d314631046f0f2afc2", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/3f/7b/669a2a9f4785ca31c1dec187a2a5", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/36/7e/5c0a226564142afded25c4b75999", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/c1/af/624497502e114de73ebac45a9fd4", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/3c/be/2245d4a6302fd98af97362f2af64", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/0f/6d/ffd0a160ce991e724552a4bde26d", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/0c/d5/172d21269794aa7809fd1c63eec5", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/b2/d9/f3333d9e169a62ae8e1bfc12c1d9", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/d2/e7/ff5143a503539e10470b2e96e3aa", + "src/ballistica/generated/python_embedded/binding.inc": "https://files.ballistica.net/cache/ba1/23/ce/68396b1b7ec6d2f8425902148140", "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" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 798e5152..e9b96780 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -### 1.7.17 (build 20973, api 7, 2022-12-20) +### 1.7.17 (build 20982, api 7, 2022-12-22) - V2 accounts now show a 'Unlink Legacy (V1) Accounts' button in account settings if they have any old v1 links present. This can be used to clear out old links to replace them with V2 links which work correctly with V2 accounts. - `ba.internal.dump_tracebacks()` is now `ba.internal.dump_app_state()` and `ba.internal.log_dumped_tracebacks()` is now `ba.internal.log_dumped_app_state()`. This reflects the fact that these calls may be expanded to include other app state in the future (C++ layer thread states, etc.). - Added `ba.app.health_monitor` which will dump app state if the logic thread ever stops responding for 5+ seconds while the app is running (to help diagnose deadlock situations). diff --git a/assets/src/ba_data/python/._ba_sources_hash b/assets/src/ba_data/python/._ba_sources_hash index f3c0eaa2..71902207 100644 --- a/assets/src/ba_data/python/._ba_sources_hash +++ b/assets/src/ba_data/python/._ba_sources_hash @@ -1 +1 @@ -307626381968915875246137499583097815878 \ No newline at end of file +71864217068887285722858773141608052966 \ No newline at end of file diff --git a/assets/src/ba_data/python/ba/_apputils.py b/assets/src/ba_data/python/ba/_apputils.py index 024ad189..cbde13d8 100644 --- a/assets/src/ba_data/python/ba/_apputils.py +++ b/assets/src/ba_data/python/ba/_apputils.py @@ -392,12 +392,12 @@ class AppHealthMonitor: def __init__(self) -> None: assert _ba.in_logic_thread() self._running = True - self._thread = Thread(target=self._bg_thread_main, daemon=True) + self._thread = Thread(target=self._app_monitor_thread_main, daemon=True) self._thread.start() self._response = False self._first_check = True - def _bg_thread_main(self) -> None: + def _app_monitor_thread_main(self) -> None: try: self._monitor_app() @@ -467,3 +467,60 @@ class AppHealthMonitor: """Should be called when the app resumes.""" assert _ba.in_logic_thread() self._running = True + + +def on_too_many_file_descriptors() -> None: + """Called when too many file descriptors are open; trying to debug.""" + from ba._generated.enums import TimeType + + real_time = _ba.time(TimeType.REAL) + + def _do_log() -> None: + import subprocess + + pid = os.getpid() + out = f'TOO MANY FDS at {real_time}.\nWe are pid {pid}\n' + + out += ( + 'FD Count: ' + + subprocess.run( + f'ls -l /proc/{pid}/fd | wc -l', + shell=True, + check=False, + capture_output=True, + ).stdout.decode() + + '\n' + ) + + out += ( + 'lsof output:\n' + + subprocess.run( + f'lsof -p {pid}', + shell=True, + check=False, + capture_output=True, + ).stdout.decode() + + '\n' + ) + + logging.warning(out) + + Thread(target=_do_log, daemon=True).start() + + # import io + # from efro.debug import printtypes + + # with io.StringIO() as fstr: + # fstr.write('Too many FDs.\n') + # printtypes(file=fstr) + # fstr.seek(0) + # logging.warning(fstr.read()) + # import socket + + # objs: list[Any] = [] + # for obj in gc.get_objects(): + # if isinstance(obj, socket.socket): + # objs.append(obj) + # test = open('/Users/ericf/.zshrc', 'r', encoding='utf-8') + # reveal_type(test) + # print('FOUND', len(objs)) diff --git a/assets/src/ba_data/python/ba/_bootstrap.py b/assets/src/ba_data/python/ba/_bootstrap.py index d7a037be..13a6a30b 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 = 20973 + expected_build = 20982 running_build: int = env['build_number'] if running_build != expected_build: print( diff --git a/assets/src/ba_data/python/ba/_store.py b/assets/src/ba_data/python/ba/_store.py index d3274de5..ef8385d9 100644 --- a/assets/src/ba_data/python/ba/_store.py +++ b/assets/src/ba_data/python/ba/_store.py @@ -53,8 +53,15 @@ def get_store_item_display_size(item_name: str) -> tuple[float, float]: if item_name.startswith('characters.'): return 340 * 0.6, 430 * 0.6 if item_name in ['pro', 'upgrades.pro', 'merch']: + from ba._generated.enums import UIScale + return 650 * 0.9, 500 * ( - 0.72 if _ba.app.config.get('Merch Link') else 0.85 + 0.72 + if ( + _ba.app.config.get('Merch Link') + and _ba.app.ui.uiscale is UIScale.SMALL + ) + else 0.85 ) if item_name.startswith('maps.'): return 510 * 0.6, 450 * 0.6 diff --git a/assets/src/ba_data/python/bastd/ui/store/browser.py b/assets/src/ba_data/python/bastd/ui/store/browser.py index 22977e4c..45d603f8 100644 --- a/assets/src/ba_data/python/bastd/ui/store/browser.py +++ b/assets/src/ba_data/python/bastd/ui/store/browser.py @@ -908,7 +908,10 @@ class StoreBrowserWindow(ba.Window): ) section['v_spacing'] = ( -25 - if self._tab == 'extras' + if ( + self._tab == 'extras' + and uiscale is ba.UIScale.SMALL + ) else -17 if self._tab == 'characters' else 0 diff --git a/src/ballistica/ballistica.cc b/src/ballistica/ballistica.cc index 7ed2cdc6..ef2e8f52 100644 --- a/src/ballistica/ballistica.cc +++ b/src/ballistica/ballistica.cc @@ -32,7 +32,7 @@ namespace ballistica { // These are set automatically via script; don't modify them here. -const int kAppBuildNumber = 20973; +const int kAppBuildNumber = 20982; const char* kAppVersion = "1.7.17"; // Our standalone globals. diff --git a/src/ballistica/core/logging.cc b/src/ballistica/core/logging.cc index 50a66c90..f6dced95 100644 --- a/src/ballistica/core/logging.cc +++ b/src/ballistica/core/logging.cc @@ -70,11 +70,11 @@ auto Logging::V1CloudLog(const std::string& msg) -> void { std::scoped_lock lock(g_app->v1_cloud_log_mutex); if (!g_app->v1_cloud_log_full) { (g_app->v1_cloud_log) += (msg + "\n"); - if ((g_app->v1_cloud_log).size() > 10000) { + if ((g_app->v1_cloud_log).size() > 25000) { // Allow some reasonable overflow for last statement. - if ((g_app->v1_cloud_log).size() > 100000) { + if ((g_app->v1_cloud_log).size() > 250000) { // FIXME: This could potentially chop up utf-8 chars. - (g_app->v1_cloud_log).resize(100000); + (g_app->v1_cloud_log).resize(250000); } g_app->v1_cloud_log += "\n\n"; g_app->v1_cloud_log_full = true; diff --git a/src/ballistica/networking/network_reader.cc b/src/ballistica/networking/network_reader.cc index 68097bf2..dfd20e2a 100644 --- a/src/ballistica/networking/network_reader.cc +++ b/src/ballistica/networking/network_reader.cc @@ -2,6 +2,7 @@ #include "ballistica/networking/network_reader.h" +#include "ballistica/core/thread.h" #include "ballistica/generic/json.h" #include "ballistica/input/remote_app.h" #include "ballistica/logic/connection/connection_set.h" @@ -175,6 +176,25 @@ static auto HandleGameQuery(const char* buffer, size_t size, } } +auto NetworkReader::CheckFDThreshold(int val) -> void { + if (passed_fd_threshold_) { + return; + } + + // Let's trigger when we pass 2/3 of the FD limit. + if (val < FD_SETSIZE * 2 / 3) { + return; + } + + // If we pass the threshold, do a one-time dump of info + // to try and debug it. + passed_fd_threshold_ = true; + g_logic->thread()->PushCall([val] { + assert(InLogicThread()); + g_python->obj(Python::ObjID::kOnTooManyFileDescriptorsCall).Call(); + }); +} + auto NetworkReader::RunThread() -> int { if (!HeadlessMode()) { remote_server_ = std::make_unique(); @@ -202,6 +222,7 @@ auto NetworkReader::RunThread() -> int { // Try to get a clean error instead of a crash if we exceed our // open file descriptor limit (except on windows where FD_SETSIZE // is apparently a dummy value). + CheckFDThreshold(sd4_); if (sd4_ < 0 || sd4_ >= FD_SETSIZE) { FatalError("Socket/File Descriptor Overflow (sd4=" + std::to_string(sd4_) + ", FD_SETSIZE=" @@ -216,6 +237,7 @@ auto NetworkReader::RunThread() -> int { // Try to get a clean error instead of a crash if we exceed our // open file descriptor limit (except on windows where FD_SETSIZE // is apparently a dummy value). + CheckFDThreshold(sd6_); if (sd6_ < 0 || sd6_ >= FD_SETSIZE) { FatalError("Socket/File Descriptor Overflow (sd6=" + std::to_string(sd6_) + ", FD_SETSIZE=" diff --git a/src/ballistica/networking/network_reader.h b/src/ballistica/networking/network_reader.h index 7d86249b..543a84e0 100644 --- a/src/ballistica/networking/network_reader.h +++ b/src/ballistica/networking/network_reader.h @@ -32,6 +32,7 @@ class NetworkReader { auto sd6() const { return sd6_; } private: + auto CheckFDThreshold(int val) -> void; auto OpenSockets() -> void; auto PokeSelf() -> void; auto RunThread() -> int; @@ -53,6 +54,7 @@ class NetworkReader { bool paused_{}; std::mutex paused_mutex_; std::condition_variable paused_cv_; + bool passed_fd_threshold_{}; }; } // namespace ballistica diff --git a/src/ballistica/python/python.h b/src/ballistica/python/python.h index 35df1fe0..40a2abac 100644 --- a/src/ballistica/python/python.h +++ b/src/ballistica/python/python.h @@ -368,6 +368,7 @@ class Python { kImplicitSignInCall, kImplicitSignOutCall, kLoginAdapterGetSignInTokenResponseCall, + kOnTooManyFileDescriptorsCall, kLast // Sentinel; must be at end. }; diff --git a/src/meta/bameta/python_embedded/binding.py b/src/meta/bameta/python_embedded/binding.py index df969526..00436446 100644 --- a/src/meta/bameta/python_embedded/binding.py +++ b/src/meta/bameta/python_embedded/binding.py @@ -146,4 +146,5 @@ def get_binding_values() -> tuple[Any, ...]: _hooks.implicit_sign_in, # kImplicitSignInCall _hooks.implicit_sign_out, # kImplicitSignOutCall _hooks.login_adapter_get_sign_in_token_response, # kLoginAdapterGetSignInTokenResponseCall + _apputils.on_too_many_file_descriptors, # kOnTooManyFileDescriptorsCall ) # yapf: disable diff --git a/tools/efro/log.py b/tools/efro/log.py index b4ea9649..f9049b5e 100644 --- a/tools/efro/log.py +++ b/tools/efro/log.py @@ -148,7 +148,7 @@ class LogHandler(logging.Handler): self._cache_lock = Lock() self._printed_callback_error = False self._thread_bootstrapped = False - self._thread = Thread(target=self._thread_main, daemon=True) + self._thread = Thread(target=self._log_thread_main, daemon=True) self._thread.start() # Spin until our thread is up and running; otherwise we could @@ -165,7 +165,7 @@ class LogHandler(logging.Handler): with self._callbacks_lock: self._callbacks.append(call) - def _thread_main(self) -> None: + def _log_thread_main(self) -> None: self._event_loop = asyncio.new_event_loop() # NOTE: if we ever use default threadpool at all we should allow # setting it for our loop. From db1db7d2606a6552453bee9cd62b7081439efdce Mon Sep 17 00:00:00 2001 From: Eric Date: Mon, 9 Jan 2023 08:49:12 -0800 Subject: [PATCH 19/26] lint fixes, req updates, and tidying --- .efrocachemap | 56 +++++++++---------- CHANGELOG.md | 4 +- assets/src/ba_data/python/ba/_bootstrap.py | 2 +- .../python/bastd/ui/playlist/editgame.py | 1 - .../ba_data/python/bastd/ui/store/browser.py | 1 - src/ballistica/ballistica.cc | 2 +- tools/batools/build.py | 16 +++--- tools/efro/message/_receiver.py | 10 +++- tools/efrotools/pylintplugins.py | 9 ++- 9 files changed, 56 insertions(+), 45 deletions(-) diff --git a/.efrocachemap b/.efrocachemap index 45711364..5be4a959 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -4008,26 +4008,26 @@ "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/76/00/aadc5cc5fa6a1b47535571f53e0c", - "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/8a/c5/e18feec0e01cef4f4e95fb0808ec", - "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/de/73/3238fef727dbe8e13fc01bacccdf", - "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/e3/16/33500fbc1be37a7ab0beb9ea1353", - "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/23/75/f18db49e8bf625a4d140cfddc0eb", - "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/13/92/649fec7372f2cc6513d81df7ac03", - "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/ba/aa/8a853018d236f1f8c70bfd6d830a", - "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/2e/36/908f74e219d570e16ce72520b0f9", - "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/75/0a/6bdecafd1f0a1d4613697e1ad71d", - "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/d1/55/18e339d10407ec858fee58fc9d5a", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/6b/d6/68df4d180d1eb83119a8a1d2cde3", - "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/b6/51/3f2217d1f0640ec63e7499641001", - "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/6a/0e/b42051f6e252b278279d2bf0ce65", - "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/8f/8d/2dcdfbc13d984ea6c62ef5e07600", - "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/63/32/555ad0de811a0af52f704f215309", - "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/60/39/8589f26d7619a11c53f452d4a808", - "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/99/a4/2e40eb7af11d25d889af56fa73dc", - "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/a5/b1/34cd5f68321e318a18d3bf2a6651", - "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/ec/8b/b08ad5030780c2554291c5ddf7b4", - "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/96/ae/28d1c19d92db131315fa2d42d772", + "build/prefab/full/linux_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/c5/08/f608b52f5d884782374aa6578ed3", + "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/cb/cc/b74d5615a34e41f2dea0a6788a95", + "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/d2/b3/8a50c3dbfba9adbda587b6eed182", + "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/58/49/359da0ec2144ae8b67ca245fa6fd", + "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/14/06/b0a2ab347e8b4b4efe6536049c4a", + "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/04/2c/7813a927c280305cfe6aa56dfd99", + "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/82/ab/c3d7d1dc70b375c6e2680a9bd7b2", + "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/1c/46/3ac0c7f5d50d5f6a266b72966bbf", + "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/50/da/7146aafb6221668e17070029edae", + "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/f1/7b/8abca0c95379e4ab0692fa3f994f", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/ff/c5/5a5b4f20e9787463e370fd53c2de", + "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/0c/56/2a9a92ea5e3a16ca39f1fc04546b", + "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/78/63/f5d1347b7afbb15a2a0813f6ab7b", + "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/57/6c/76fa56be35a356fa1c119ade0f75", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/b0/4b/3d528c6331f6b370f11b913fea00", + "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/e3/50/a4c6df16326044ce3f42e16289de", + "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/84/b3/0ea2e8a870fa211e3789b2de56fe", + "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/7c/f7/a74ada4fb39f57721a4049973b39", + "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/c4/1d/9c65921602aadc94be03fb3444d8", + "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/b1/75/c098de6f3660aaa48fa5341e3d44", "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/e9/02/eb6c1b076dd366fcdbb69c0aa85a", "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ff/2b/5e85ad35d9305d60adbdc53dbb6e", "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/5b/fb/074697e51ab8a28604788be2b3bb", @@ -4044,14 +4044,14 @@ "build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/62/fc/bbf70a63d29d536d8511474309c6", "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/d2/c1/ed8083e560d9466547d1da458118", "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/10/8a/534c2c99f6d314631046f0f2afc2", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/3f/7b/669a2a9f4785ca31c1dec187a2a5", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/36/7e/5c0a226564142afded25c4b75999", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/c1/af/624497502e114de73ebac45a9fd4", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/3c/be/2245d4a6302fd98af97362f2af64", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/0f/6d/ffd0a160ce991e724552a4bde26d", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/0c/d5/172d21269794aa7809fd1c63eec5", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/b2/d9/f3333d9e169a62ae8e1bfc12c1d9", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/d2/e7/ff5143a503539e10470b2e96e3aa", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/91/b8/9163c5da07e10422148cab48149c", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/b9/06/a4f144e5f74ca1a4ea10327edfeb", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/9a/5c/d4623488a53931b97b79dfc32d06", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/b5/4c/f3abc65a6c0de4f07c12bda8d13b", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/06/11/a6827d90020d2c59bdee5e8e7fa2", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/c5/8e/64cd86adca08a9f5f15478fd4080", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/5e/70/104fae0f9f53d4f0dfa1b98596e0", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/81/d6/f0b5f88b8c15fa1ac8cc0de99594", "src/ballistica/generated/python_embedded/binding.inc": "https://files.ballistica.net/cache/ba1/23/ce/68396b1b7ec6d2f8425902148140", "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/CHANGELOG.md b/CHANGELOG.md index e9b96780..b5c57c7b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,5 @@ -### 1.7.17 (build 20982, api 7, 2022-12-22) -- V2 accounts now show a 'Unlink Legacy (V1) Accounts' button in account settings if they have any old v1 links present. This can be used to clear out old links to replace them with V2 links which work correctly with V2 accounts. +### 1.7.17 (build 20983, api 7, 2023-01-09) +- V2 accounts now show a 'Unlink Legacy (V1) Accounts' button in account settings if they have any old V1 links present. This can be used to clear out old links to replace them with V2 links which work correctly with V2 accounts. - `ba.internal.dump_tracebacks()` is now `ba.internal.dump_app_state()` and `ba.internal.log_dumped_tracebacks()` is now `ba.internal.log_dumped_app_state()`. This reflects the fact that these calls may be expanded to include other app state in the future (C++ layer thread states, etc.). - Added `ba.app.health_monitor` which will dump app state if the logic thread ever stops responding for 5+ seconds while the app is running (to help diagnose deadlock situations). - Various extra logging and bug fixes related to V2 accounts and master server communication (trying to get this stuff working as smoothly as possible now that it is feature-complete). diff --git a/assets/src/ba_data/python/ba/_bootstrap.py b/assets/src/ba_data/python/ba/_bootstrap.py index 13a6a30b..d150c6e8 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 = 20982 + expected_build = 20983 running_build: int = env['build_number'] if running_build != expected_build: print( diff --git a/assets/src/ba_data/python/bastd/ui/playlist/editgame.py b/assets/src/ba_data/python/bastd/ui/playlist/editgame.py index ee3a2cd5..a2483364 100644 --- a/assets/src/ba_data/python/bastd/ui/playlist/editgame.py +++ b/assets/src/ba_data/python/bastd/ui/playlist/editgame.py @@ -473,7 +473,6 @@ class PlaylistEditGameWindow(ba.Window): # Ok now wire up the column. try: - # pylint: disable=unsubscriptable-object prev_widgets: list[ba.Widget] | None = None for cwdg in widget_column: if prev_widgets is not None: diff --git a/assets/src/ba_data/python/bastd/ui/store/browser.py b/assets/src/ba_data/python/bastd/ui/store/browser.py index 45d603f8..1bc8da43 100644 --- a/assets/src/ba_data/python/bastd/ui/store/browser.py +++ b/assets/src/ba_data/python/bastd/ui/store/browser.py @@ -1155,7 +1155,6 @@ class StoreBrowserWindow(ba.Window): # Wire this button to the equivalent in the # previous row. if prev_row_buttons is not None: - # pylint: disable=unsubscriptable-object if len(prev_row_buttons) > col: ba.widget( edit=btn, diff --git a/src/ballistica/ballistica.cc b/src/ballistica/ballistica.cc index ef2e8f52..91d4ccb4 100644 --- a/src/ballistica/ballistica.cc +++ b/src/ballistica/ballistica.cc @@ -32,7 +32,7 @@ namespace ballistica { // These are set automatically via script; don't modify them here. -const int kAppBuildNumber = 20982; +const int kAppBuildNumber = 20983; const char* kAppVersion = "1.7.17"; // Our standalone globals. diff --git a/tools/batools/build.py b/tools/batools/build.py index c31586f5..dd8e6ace 100644 --- a/tools/batools/build.py +++ b/tools/batools/build.py @@ -40,22 +40,22 @@ class PyRequirement: # as manually-installed bits, pip itself must have some way to allow for # that, right?... PY_REQUIREMENTS = [ - PyRequirement(modulename='pylint', minversion=[2, 14, 5]), - PyRequirement(modulename='mypy', minversion=[0, 971]), + PyRequirement(modulename='pylint', minversion=[2, 15, 9]), + PyRequirement(modulename='mypy', minversion=[0, 991]), PyRequirement(modulename='cpplint', minversion=[1, 6, 1]), - PyRequirement(modulename='pytest', minversion=[7, 1, 2]), + PyRequirement(modulename='pytest', minversion=[7, 2, 0]), PyRequirement(modulename='pytz'), PyRequirement(modulename='ansiwrap'), PyRequirement(modulename='yaml', pipname='PyYAML'), PyRequirement(modulename='requests'), PyRequirement(modulename='pdoc'), - PyRequirement(pipname='black', minversion=[22, 10, 0]), - PyRequirement(pipname='typing_extensions', minversion=[4, 3, 0]), + PyRequirement(pipname='black', minversion=[22, 12, 0]), + PyRequirement(pipname='typing_extensions', minversion=[4, 4, 0]), PyRequirement(pipname='types-filelock', minversion=[3, 2, 7]), - PyRequirement(pipname='types-requests', minversion=[2, 28, 9]), + PyRequirement(pipname='types-requests', minversion=[2, 28, 11, 7]), PyRequirement(pipname='types-pytz', minversion=[2022, 2, 1, 0]), - PyRequirement(pipname='types-PyYAML', minversion=[6, 0, 11]), - PyRequirement(pipname='certifi', minversion=[2022, 6, 15]), + PyRequirement(pipname='types-PyYAML', minversion=[6, 0, 12, 2]), + PyRequirement(pipname='certifi', minversion=[2022, 12, 7]), PyRequirement(pipname='types-certifi', minversion=[2021, 10, 8, 3]), ] diff --git a/tools/efro/message/_receiver.py b/tools/efro/message/_receiver.py index e4c92447..7881b82e 100644 --- a/tools/efro/message/_receiver.py +++ b/tools/efro/message/_receiver.py @@ -316,6 +316,7 @@ class MessageReceiver: """ assert not self.is_async, "can't call sync handler on async receiver" msg_decoded: Message | None = None + msgtype: type[Message] | None = None try: msg_decoded = self._decode_incoming_message(bound_obj, msg) msgtype = type(msg_decoded) @@ -335,7 +336,14 @@ class MessageReceiver: bound_obj, msg_decoded, exc ) if dolog: - logging.exception('Error in efro.message handling.') + if msgtype is not None: + logging.exception( + 'Error handling %s.%s message.', + msgtype.__module__, + msgtype.__qualname__, + ) + else: + logging.exception('Error in efro.message handling.') return rstr async def handle_raw_message_async( diff --git a/tools/efrotools/pylintplugins.py b/tools/efrotools/pylintplugins.py index 325ca9ef..5583c61e 100644 --- a/tools/efrotools/pylintplugins.py +++ b/tools/efrotools/pylintplugins.py @@ -45,6 +45,10 @@ def ignore_type_check_filter(if_node: nc.NodeNG) -> nc.NodeNG: and isinstance(if_node.parent, astroid.Module) ): + # Special case: filelock contains a use-case that breaks us. + if if_node.parent.name == 'filelock': + return if_node + module_node = if_node.parent # Remove any locals getting defined under this if statement. @@ -177,7 +181,7 @@ def var_annotations_filter(node: nc.NodeNG) -> nc.NodeNG: # Future behavior: # Annotated assigns under functions are not evaluated. # Class and module vars are normally not either. However we - # do evaluate if we come across an 'ioprepped' dataclass + # *do* evaluate if we come across an 'ioprepped' dataclass # decorator. (the 'ioprepped' decorator explicitly evaluates # dataclass annotations). @@ -230,7 +234,8 @@ def var_annotations_filter(node: nc.NodeNG) -> nc.NodeNG: break fnode = fnode.parent - # If this annotation won't be eval'ed, replace it with a dummy string. + # If this annotation won't be eval'ed, replace its annotation with + # a dummy value. if not willeval: dummyval = astroid.Const(parent=node, value='dummyval') node.annotation = dummyval From fcf0632b4449d31d6ad4341f44f45b80e7f10aa3 Mon Sep 17 00:00:00 2001 From: Eric Froemling Date: Mon, 9 Jan 2023 09:37:09 -0800 Subject: [PATCH 20/26] updating github actions to latest versions to remove warnings --- .github/workflows/ci.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 955f5b44..068328e0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,9 +16,9 @@ jobs: check_linux: runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v3 - name: Set up Python - uses: actions/setup-python@v1 + uses: actions/setup-python@v4 with: python-version: '3.10' - name: Install dependencies @@ -31,9 +31,9 @@ jobs: compile_linux: runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v3 - name: Set up Python - uses: actions/setup-python@v1 + uses: actions/setup-python@v4 with: python-version: '3.10' - name: Compile binary @@ -47,9 +47,9 @@ jobs: check_and_compile_windows: runs-on: windows-2019 steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v3 - name: Set up Python - uses: actions/setup-python@v1 + uses: actions/setup-python@v4 with: python-version: '3.10' - name: Install dependencies From 206100ba3cb9b232665b62eb51571502e17ad58a Mon Sep 17 00:00:00 2001 From: Eric Date: Mon, 9 Jan 2023 17:00:42 -0800 Subject: [PATCH 21/26] language updates and tidying --- .efrocachemap | 54 ++++++++++++++++---------------- tools/efro/log.py | 19 +++++------ tools/efrotools/pylintplugins.py | 13 ++++++-- 3 files changed, 45 insertions(+), 41 deletions(-) diff --git a/.efrocachemap b/.efrocachemap index 5be4a959..42f5b5b3 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -420,37 +420,37 @@ "assets/build/ba_data/audio/zoeOw.ogg": "https://files.ballistica.net/cache/ba1/60/ad/38269b7f1c7dc20cb9a506cd0681", "assets/build/ba_data/audio/zoePickup01.ogg": "https://files.ballistica.net/cache/ba1/72/85/d6fc4d16b7081d91fba2850b5b10", "assets/build/ba_data/audio/zoeScream01.ogg": "https://files.ballistica.net/cache/ba1/e9/ae/1d674d0c086eaa0bd1c3b1db0505", - "assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/8c/16/c8b51005b8ed3a5046264ac667f4", + "assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/d7/de/c432c06ba1271f59656ed56165f9", "assets/build/ba_data/data/languages/arabic.json": "https://files.ballistica.net/cache/ba1/92/43/36b34307575f6d6219bdf4898e18", "assets/build/ba_data/data/languages/belarussian.json": "https://files.ballistica.net/cache/ba1/61/03/89070ca765e06da3a419a579f503", "assets/build/ba_data/data/languages/chinese.json": "https://files.ballistica.net/cache/ba1/aa/ed/4bd02af3cffbd4c9c4be532fb1fe", - "assets/build/ba_data/data/languages/chinesetraditional.json": "https://files.ballistica.net/cache/ba1/c2/a4/993d5f0f30d0670d7053466929b6", + "assets/build/ba_data/data/languages/chinesetraditional.json": "https://files.ballistica.net/cache/ba1/f7/b0/191439142c6d6da4a056edc98b38", "assets/build/ba_data/data/languages/croatian.json": "https://files.ballistica.net/cache/ba1/c9/73/01a1343af814131b1ee96af0b687", "assets/build/ba_data/data/languages/czech.json": "https://files.ballistica.net/cache/ba1/4e/8c/72ddb584856a15dfb11df95f9283", "assets/build/ba_data/data/languages/danish.json": "https://files.ballistica.net/cache/ba1/6a/fa/fcf4a804beaff927b0f12c179eaa", "assets/build/ba_data/data/languages/dutch.json": "https://files.ballistica.net/cache/ba1/68/93/da8e9874f41a786edf52ba4ccaad", "assets/build/ba_data/data/languages/english.json": "https://files.ballistica.net/cache/ba1/ad/85/3caf0c981389e46835862248386a", "assets/build/ba_data/data/languages/esperanto.json": "https://files.ballistica.net/cache/ba1/ac/f5/c0922a99e40dfc9f5e026d43b533", - "assets/build/ba_data/data/languages/filipino.json": "https://files.ballistica.net/cache/ba1/8e/90/3ba17e62e21919bc2fa7e46884be", - "assets/build/ba_data/data/languages/french.json": "https://files.ballistica.net/cache/ba1/5d/2a/a5363cbe713fd67ea0baaa44403a", + "assets/build/ba_data/data/languages/filipino.json": "https://files.ballistica.net/cache/ba1/dc/50/c109f475599608a7e8fdacea667c", + "assets/build/ba_data/data/languages/french.json": "https://files.ballistica.net/cache/ba1/4f/4d/b259b145a69db1d34052281bb3bb", "assets/build/ba_data/data/languages/german.json": "https://files.ballistica.net/cache/ba1/cb/7b/b881356f22e5f8293a5e4b8976ae", "assets/build/ba_data/data/languages/gibberish.json": "https://files.ballistica.net/cache/ba1/ee/fa/6eb38e7d4cfd13702c66d37b9723", "assets/build/ba_data/data/languages/greek.json": "https://files.ballistica.net/cache/ba1/8a/82/392f2a4e0e6e5a5e367f19e49538", "assets/build/ba_data/data/languages/hindi.json": "https://files.ballistica.net/cache/ba1/2e/d1/b506ddf3d27af7be1ae6159531a3", "assets/build/ba_data/data/languages/hungarian.json": "https://files.ballistica.net/cache/ba1/b2/81/53c8cd7617d649403e539c3a6171", "assets/build/ba_data/data/languages/indonesian.json": "https://files.ballistica.net/cache/ba1/30/91/9dc870d35ddca657bf07d0f88a82", - "assets/build/ba_data/data/languages/italian.json": "https://files.ballistica.net/cache/ba1/72/35/c40aee4c2f7f64fa030f83eb08d5", + "assets/build/ba_data/data/languages/italian.json": "https://files.ballistica.net/cache/ba1/dd/be/1ae65f073d563e69c0c5246d20d7", "assets/build/ba_data/data/languages/korean.json": "https://files.ballistica.net/cache/ba1/32/97/4c61425d7c200a5c4c9ae3a94a0e", - "assets/build/ba_data/data/languages/malay.json": "https://files.ballistica.net/cache/ba1/66/32/92ae734c4358397d2e90c1c85325", - "assets/build/ba_data/data/languages/persian.json": "https://files.ballistica.net/cache/ba1/db/14/2f441ccb65023775dc8139a63f3f", - "assets/build/ba_data/data/languages/polish.json": "https://files.ballistica.net/cache/ba1/67/93/372c2a2428a830056e9ba22bbf95", + "assets/build/ba_data/data/languages/malay.json": "https://files.ballistica.net/cache/ba1/b4/02/f686ce008312e74d5953a511c8b2", + "assets/build/ba_data/data/languages/persian.json": "https://files.ballistica.net/cache/ba1/c9/a8/e42e6a818ec3894fa2f8b2c50995", + "assets/build/ba_data/data/languages/polish.json": "https://files.ballistica.net/cache/ba1/38/31/fd930431c7612d0ab0e73e6bc74f", "assets/build/ba_data/data/languages/portuguese.json": "https://files.ballistica.net/cache/ba1/cb/96/86bb139f20e126593f7fdba9e9e1", "assets/build/ba_data/data/languages/romanian.json": "https://files.ballistica.net/cache/ba1/d7/06/9d70642d0a4d1e3b1c2149d7a17c", - "assets/build/ba_data/data/languages/russian.json": "https://files.ballistica.net/cache/ba1/b7/98/2523d11d09614bcfad8fa50be100", + "assets/build/ba_data/data/languages/russian.json": "https://files.ballistica.net/cache/ba1/6c/62/06869ed55a656b6e51b4d22e6fa8", "assets/build/ba_data/data/languages/serbian.json": "https://files.ballistica.net/cache/ba1/4e/91/6f2a9a3ce733908e91377a6ddb9a", "assets/build/ba_data/data/languages/slovak.json": "https://files.ballistica.net/cache/ba1/20/a9/163d189884edf802636bf291e432", - "assets/build/ba_data/data/languages/spanish.json": "https://files.ballistica.net/cache/ba1/d8/19/21882f76375ade330ef5a6e791a4", - "assets/build/ba_data/data/languages/swedish.json": "https://files.ballistica.net/cache/ba1/91/0a/35c4baf539d5951fc03a794c0e0b", + "assets/build/ba_data/data/languages/spanish.json": "https://files.ballistica.net/cache/ba1/f5/35/1dea74424ee613611ae3f7deec99", + "assets/build/ba_data/data/languages/swedish.json": "https://files.ballistica.net/cache/ba1/3b/9f/d40c1423d260784970fd7364ca30", "assets/build/ba_data/data/languages/tamil.json": "https://files.ballistica.net/cache/ba1/3d/83/e1bb0a664d1c14c41b1a083acf0d", "assets/build/ba_data/data/languages/thai.json": "https://files.ballistica.net/cache/ba1/d6/16/523c643358880b03b233ed88e557", "assets/build/ba_data/data/languages/turkish.json": "https://files.ballistica.net/cache/ba1/2a/0e/b164149e76efd0e6d591a9bf04bb", @@ -4016,18 +4016,18 @@ "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/04/2c/7813a927c280305cfe6aa56dfd99", "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/82/ab/c3d7d1dc70b375c6e2680a9bd7b2", "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/1c/46/3ac0c7f5d50d5f6a266b72966bbf", - "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/50/da/7146aafb6221668e17070029edae", + "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/30/89/495396eabe450fae4f1e8b0d76db", "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/f1/7b/8abca0c95379e4ab0692fa3f994f", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/ff/c5/5a5b4f20e9787463e370fd53c2de", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/2a/7f/129d1ef21820f132eab259a979ea", "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/0c/56/2a9a92ea5e3a16ca39f1fc04546b", - "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/78/63/f5d1347b7afbb15a2a0813f6ab7b", + "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/73/1a/cde9e42797701b0746866b3092dd", "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/57/6c/76fa56be35a356fa1c119ade0f75", - "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/b0/4b/3d528c6331f6b370f11b913fea00", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/3b/86/c9e0277d66af31d3458b80c2b3fb", "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/e3/50/a4c6df16326044ce3f42e16289de", - "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/84/b3/0ea2e8a870fa211e3789b2de56fe", - "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/7c/f7/a74ada4fb39f57721a4049973b39", - "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/c4/1d/9c65921602aadc94be03fb3444d8", - "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/b1/75/c098de6f3660aaa48fa5341e3d44", + "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/c5/4e/fb70411c80715607bba9ccf2891c", + "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/b9/3f/058f1adab37f36571d031265b817", + "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/3f/f7/7e1d600a05c160e106baa26ca54c", + "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/81/de/69347df0599cafe827bfeb3a3de2", "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/e9/02/eb6c1b076dd366fcdbb69c0aa85a", "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ff/2b/5e85ad35d9305d60adbdc53dbb6e", "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/5b/fb/074697e51ab8a28604788be2b3bb", @@ -4044,14 +4044,14 @@ "build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/62/fc/bbf70a63d29d536d8511474309c6", "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/d2/c1/ed8083e560d9466547d1da458118", "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/10/8a/534c2c99f6d314631046f0f2afc2", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/91/b8/9163c5da07e10422148cab48149c", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/b9/06/a4f144e5f74ca1a4ea10327edfeb", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/9a/5c/d4623488a53931b97b79dfc32d06", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/b5/4c/f3abc65a6c0de4f07c12bda8d13b", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/06/11/a6827d90020d2c59bdee5e8e7fa2", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/c5/8e/64cd86adca08a9f5f15478fd4080", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/5e/70/104fae0f9f53d4f0dfa1b98596e0", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/81/d6/f0b5f88b8c15fa1ac8cc0de99594", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/77/5a/df7c807d080a812fd101c6862d0b", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/5a/b8/65c65a447c27054bc26b89e959de", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/43/22/ad29dfbcc3a429d7e53858a38fb2", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/ac/8e/75d6b1c36166b2a8ecfcb1c277c9", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/18/49/a7508bebb7fb064b6f435e8571d4", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/54/61/8a95f051146f900b5eb5a6f7ee27", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/61/4f/3c28e119c49318e76f5bb072e760", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/2c/5e/e906f2d566fd87363e83013c64b6", "src/ballistica/generated/python_embedded/binding.inc": "https://files.ballistica.net/cache/ba1/23/ce/68396b1b7ec6d2f8425902148140", "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/tools/efro/log.py b/tools/efro/log.py index f9049b5e..99e5e2ab 100644 --- a/tools/efro/log.py +++ b/tools/efro/log.py @@ -192,20 +192,15 @@ class LogHandler(logging.Handler): now = utc_now() with self._cache_lock: - # Quick out: if oldest cache entry is still valid, - # don't touch anything. - if ( + # Prune the oldest entry as long as there is a first one that + # is too old. + while ( self._cache - and (now - self._cache[0][1].time) < self._cache_time_limit + 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 - ] + popped = self._cache.pop(0) + self._cache_size -= popped[0] + self._cache_index_offset += 1 def get_cached( self, start_index: int = 0, max_entries: int | None = None diff --git a/tools/efrotools/pylintplugins.py b/tools/efrotools/pylintplugins.py index 5583c61e..07b05a32 100644 --- a/tools/efrotools/pylintplugins.py +++ b/tools/efrotools/pylintplugins.py @@ -45,8 +45,17 @@ def ignore_type_check_filter(if_node: nc.NodeNG) -> nc.NodeNG: and isinstance(if_node.parent, astroid.Module) ): - # Special case: filelock contains a use-case that breaks us. - if if_node.parent.name == 'filelock': + # Special case: some third party modules are starting to contain + # code that we don't handle cleanly which results in pylint runs + # breaking. For now just ignoring them as they pop up. + # We should try to figure out how to disable this filtering + # for third party modules altogether or make our filtering more + # robust. + if if_node.parent.name in { + 'filelock', + 'aiohttp.web_app', + 'aiohttp.web_response', + }: return if_node module_node = if_node.parent From b5c11c340b024a0242eb2352f92fae4c7737872c Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 11 Jan 2023 17:37:24 -0800 Subject: [PATCH 22/26] tidying --- .efrocachemap | 92 ++++++++++++++++----------------- tools/efro/log.py | 30 +++++++++++ tools/efro/message/_receiver.py | 10 +++- tools/efro/message/_sender.py | 32 ++++++++++-- 4 files changed, 113 insertions(+), 51 deletions(-) diff --git a/.efrocachemap b/.efrocachemap index 42f5b5b3..9b0a8044 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -420,7 +420,7 @@ "assets/build/ba_data/audio/zoeOw.ogg": "https://files.ballistica.net/cache/ba1/60/ad/38269b7f1c7dc20cb9a506cd0681", "assets/build/ba_data/audio/zoePickup01.ogg": "https://files.ballistica.net/cache/ba1/72/85/d6fc4d16b7081d91fba2850b5b10", "assets/build/ba_data/audio/zoeScream01.ogg": "https://files.ballistica.net/cache/ba1/e9/ae/1d674d0c086eaa0bd1c3b1db0505", - "assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/d7/de/c432c06ba1271f59656ed56165f9", + "assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/fc/ad/a45526ccfa8945247b3a29c2c251", "assets/build/ba_data/data/languages/arabic.json": "https://files.ballistica.net/cache/ba1/92/43/36b34307575f6d6219bdf4898e18", "assets/build/ba_data/data/languages/belarussian.json": "https://files.ballistica.net/cache/ba1/61/03/89070ca765e06da3a419a579f503", "assets/build/ba_data/data/languages/chinese.json": "https://files.ballistica.net/cache/ba1/aa/ed/4bd02af3cffbd4c9c4be532fb1fe", @@ -442,7 +442,7 @@ "assets/build/ba_data/data/languages/italian.json": "https://files.ballistica.net/cache/ba1/dd/be/1ae65f073d563e69c0c5246d20d7", "assets/build/ba_data/data/languages/korean.json": "https://files.ballistica.net/cache/ba1/32/97/4c61425d7c200a5c4c9ae3a94a0e", "assets/build/ba_data/data/languages/malay.json": "https://files.ballistica.net/cache/ba1/b4/02/f686ce008312e74d5953a511c8b2", - "assets/build/ba_data/data/languages/persian.json": "https://files.ballistica.net/cache/ba1/c9/a8/e42e6a818ec3894fa2f8b2c50995", + "assets/build/ba_data/data/languages/persian.json": "https://files.ballistica.net/cache/ba1/81/c8/269052d2d21ba6971f3a151813b9", "assets/build/ba_data/data/languages/polish.json": "https://files.ballistica.net/cache/ba1/38/31/fd930431c7612d0ab0e73e6bc74f", "assets/build/ba_data/data/languages/portuguese.json": "https://files.ballistica.net/cache/ba1/cb/96/86bb139f20e126593f7fdba9e9e1", "assets/build/ba_data/data/languages/romanian.json": "https://files.ballistica.net/cache/ba1/d7/06/9d70642d0a4d1e3b1c2149d7a17c", @@ -4008,50 +4008,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/c5/08/f608b52f5d884782374aa6578ed3", - "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/cb/cc/b74d5615a34e41f2dea0a6788a95", - "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/d2/b3/8a50c3dbfba9adbda587b6eed182", - "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/58/49/359da0ec2144ae8b67ca245fa6fd", - "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/14/06/b0a2ab347e8b4b4efe6536049c4a", - "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/04/2c/7813a927c280305cfe6aa56dfd99", - "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/82/ab/c3d7d1dc70b375c6e2680a9bd7b2", - "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/1c/46/3ac0c7f5d50d5f6a266b72966bbf", - "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/30/89/495396eabe450fae4f1e8b0d76db", - "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/f1/7b/8abca0c95379e4ab0692fa3f994f", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/2a/7f/129d1ef21820f132eab259a979ea", - "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/0c/56/2a9a92ea5e3a16ca39f1fc04546b", - "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/73/1a/cde9e42797701b0746866b3092dd", - "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/57/6c/76fa56be35a356fa1c119ade0f75", - "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/3b/86/c9e0277d66af31d3458b80c2b3fb", - "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/e3/50/a4c6df16326044ce3f42e16289de", - "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/c5/4e/fb70411c80715607bba9ccf2891c", - "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/b9/3f/058f1adab37f36571d031265b817", - "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/3f/f7/7e1d600a05c160e106baa26ca54c", - "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/81/de/69347df0599cafe827bfeb3a3de2", - "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/e9/02/eb6c1b076dd366fcdbb69c0aa85a", - "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ff/2b/5e85ad35d9305d60adbdc53dbb6e", - "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/5b/fb/074697e51ab8a28604788be2b3bb", - "build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/0b/26/7a9c1094bb1ffea16a60424251e1", - "build/prefab/lib/linux_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/fb/89/55c61946fc5cfa6e1154450b84e8", - "build/prefab/lib/linux_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/b9/33/7d35c3ff242b7ad72257b9a132ec", - "build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/9c/5e/de343f0a5b9ada35352ba10f5598", - "build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a7/da/be3ad1176399531ce6e634f8700f", - "build/prefab/lib/mac_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/83/2e/f5710315b4a86e6dd2a3806f0b9a", - "build/prefab/lib/mac_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/bd/15/c896646cdff25290761c402d3b21", - "build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/7a/f1/e9cafcb4a0b721a48027763e6b50", - "build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/b7/ec/0ad3db1b805b6d3067893326e8d8", - "build/prefab/lib/mac_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/c3/88/22c1bff0c944447bf15cadb835a8", - "build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/62/fc/bbf70a63d29d536d8511474309c6", - "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/d2/c1/ed8083e560d9466547d1da458118", - "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/10/8a/534c2c99f6d314631046f0f2afc2", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/77/5a/df7c807d080a812fd101c6862d0b", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/5a/b8/65c65a447c27054bc26b89e959de", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/43/22/ad29dfbcc3a429d7e53858a38fb2", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/ac/8e/75d6b1c36166b2a8ecfcb1c277c9", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/18/49/a7508bebb7fb064b6f435e8571d4", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/54/61/8a95f051146f900b5eb5a6f7ee27", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/61/4f/3c28e119c49318e76f5bb072e760", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/2c/5e/e906f2d566fd87363e83013c64b6", + "build/prefab/full/linux_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/f0/de/a15c858f7de30960bf9bb0c62d0b", + "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/b2/21/fb3cc75f193b360fe01f192336c1", + "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/b5/e9/e65c9052619c2c1990462380cc54", + "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/02/ec/1652214167d27a6279cf1f525f47", + "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/6d/91/bcc179b4205353a17172ece5939d", + "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/56/83/8bdc611e72d8e681870176224bc3", + "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/82/ca/95b08abd3b0eeff5435979fc32b1", + "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/a6/33/67de7924fb59f8ae7e957d592a27", + "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/c6/ad/455d442d23c6e6699e578282dce8", + "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/d3/22/2e615a946352c67889dc4c0c5597", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/b7/c2/e29df979de73a7ca415735c34fc3", + "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/b2/24/43451b637f3f188e2913a02982d8", + "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/42/04/e1dc1a340a3ba859b9c417f330cd", + "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/7e/fe/70345e5263a0d456378e7a0e8661", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/a4/7f/7ad86eabef054f316814cbbd26ec", + "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/1e/cb/f003d8de353f71d08e81d82f6292", + "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/36/62/d86b02165ee596f2767ae24b505a", + "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/d6/73/37a2acd3bcd45cb8a48e4a80d547", + "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/57/62/ec832ceda26e7e7a07e4277a6d97", + "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/fd/88/724ff3645eb22af1f7755982af7b", + "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/e4/1b/a2ab5dd8c59cd90f5cd28f451884", + "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a5/48/1e25219edd0a78e40c0f3093396d", + "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/dd/5d/51313d43cafea4898cc2ca7aaf3d", + "build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/b3/ca/9a7f4019bf2e57d668171c42c876", + "build/prefab/lib/linux_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/4e/c8/478035d9e79dabc2a0cff7dc5c07", + "build/prefab/lib/linux_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/06/e3/5cac56d9f4e96a800cd424ecb01a", + "build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/2d/f2/f3afa4635c55863e2996ee110414", + "build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/52/2e/3fef9d99b533a1ae5e1be3c63e21", + "build/prefab/lib/mac_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/17/d4/3578de762544210f09f9ef6b60a4", + "build/prefab/lib/mac_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/18/44/f6a99fe7cf886f8a1b77b1878c7a", + "build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/84/3a/a7f7d3b3ee3bd7b1806bf77f2859", + "build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/e9/58/63afc99ce47eed08527f2dfc8f4d", + "build/prefab/lib/mac_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/43/ed/f49af3eb3646c69c5312ef8000dc", + "build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/e4/c5/091b0d55220c1c7a6939e00563d7", + "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/b3/f4/69436953e88c28d027b7c8004ba3", + "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/37/d3/599f3904f5ee987d540164237703", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/5b/0e/a571f0b1d167f3a0d3f07ff6e633", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/86/3e/abdb5280c7e24e145bcf4cfc73d4", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/15/b7/76299570cd56fac624ec810c575c", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/39/07/b32bb5e8a4458adc0df92dad82f6", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/28/46/700cc357d8c776c3a34dbdeb31c8", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/71/f0/d3d64e44f03a10536649e000c836", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/42/9a/961f50a8d8d7b1d704a2616d76ca", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/4a/da/85bb42cb764293be0b4c515268ad", "src/ballistica/generated/python_embedded/binding.inc": "https://files.ballistica.net/cache/ba1/23/ce/68396b1b7ec6d2f8425902148140", "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/tools/efro/log.py b/tools/efro/log.py index 99e5e2ab..752922ed 100644 --- a/tools/efro/log.py +++ b/tools/efro/log.py @@ -149,6 +149,8 @@ class LogHandler(logging.Handler): self._printed_callback_error = False self._thread_bootstrapped = False self._thread = Thread(target=self._log_thread_main, daemon=True) + if __debug__: + self._last_slow_emit_warning_time: float | None = None self._thread.start() # Spin until our thread is up and running; otherwise we could @@ -238,6 +240,9 @@ class LogHandler(logging.Handler): ) def emit(self, record: logging.LogRecord) -> None: + if __debug__: + starttime = time.monotonic() + # Called by logging to send us records. # We simply package them up and ship them to our thread. # UPDATE: turns out we CAN get log messages from this thread @@ -282,6 +287,31 @@ class LogHandler(logging.Handler): ) ) + if __debug__: + # Make noise if we're taking a significant amount of time here. + # Limit the noise to once every so often though; otherwise we + # could get a feedback loop where every log emit results in a + # warning log which results in another, etc. + now = time.monotonic() + # noinspection PyUnboundLocalVariable + duration = now - starttime + if duration > 0.05 and ( + self._last_slow_emit_warning_time is None + or now > self._last_slow_emit_warning_time + 10.0 + ): + # Logging calls from *within* a logging handler + # sounds sketchy, so let's just kick this over to + # the bg event loop thread we've already got. + self._last_slow_emit_warning_time = now + self._event_loop.call_soon_threadsafe( + tpartial( + logging.warning, + 'efro.log.LogHandler emit took too long' + ' (%.2f seconds).', + duration, + ) + ) + def _emit_in_thread( self, name: str, levelno: int, created: float, message: str ) -> None: diff --git a/tools/efro/message/_receiver.py b/tools/efro/message/_receiver.py index 7881b82e..cc35423f 100644 --- a/tools/efro/message/_receiver.py +++ b/tools/efro/message/_receiver.py @@ -355,6 +355,7 @@ class MessageReceiver: """ assert self.is_async, "can't call async handler on sync receiver" msg_decoded: Message | None = None + msgtype: type[Message] | None = None try: msg_decoded = await self._decode_incoming_message_async( bound_obj, msg @@ -376,7 +377,14 @@ class MessageReceiver: bound_obj, msg_decoded, exc ) if dolog: - logging.exception('Error in efro.message handling.') + if msgtype is not None: + logging.exception( + 'Error handling %s.%s message.', + msgtype.__module__, + msgtype.__qualname__, + ) + else: + logging.exception('Error in efro.message handling.') return rstr diff --git a/tools/efro/message/_sender.py b/tools/efro/message/_sender.py index ee439e01..8d71d584 100644 --- a/tools/efro/message/_sender.py +++ b/tools/efro/message/_sender.py @@ -44,6 +44,9 @@ class MessageSender: self._send_async_raw_message_call: Callable[ [Any, str], Awaitable[str] ] | None = None + self._send_async_raw_message_ex_call: Callable[ + [Any, str, Message], Awaitable[str] + ] | None = None self._encode_filter_call: Callable[ [Any, Message, dict], None ] | None = None @@ -80,6 +83,18 @@ class MessageSender: self._send_async_raw_message_call = call return call + def send_async_ex_method( + self, call: Callable[[Any, str, Message], Awaitable[str]] + ) -> Callable[[Any, str, Message], Awaitable[str]]: + """Function decorator for extended send-async method. + + This version of the method also is passed the original unencoded + message. + """ + assert self._send_async_raw_message_ex_call is None + self._send_async_raw_message_ex_call = call + return call + def encode_filter_method( self, call: Callable[[Any, Message, dict], None] ) -> Callable[[Any, Message, dict], None]: @@ -184,14 +199,23 @@ class MessageSender: to happen in different contexts/threads. """ - if self._send_async_raw_message_call is None: + if ( + self._send_async_raw_message_call is None + and self._send_async_raw_message_ex_call is None + ): raise RuntimeError('send_async() is unimplemented for this type.') msg_encoded = self._encode_message(bound_obj, message) try: - response_encoded = await self._send_async_raw_message_call( - bound_obj, msg_encoded - ) + if self._send_async_raw_message_ex_call is not None: + response_encoded = await self._send_async_raw_message_ex_call( + bound_obj, msg_encoded, message + ) + else: + assert self._send_async_raw_message_call is not None + response_encoded = await self._send_async_raw_message_call( + bound_obj, msg_encoded + ) except Exception as exc: response = ErrorSysResponse( error_message='Error in MessageSender @send_async_method.', From e0ea183ef49b50c4fe0dfdf280c6122fab4f14c0 Mon Sep 17 00:00:00 2001 From: Eric Date: Thu, 12 Jan 2023 12:32:39 -0800 Subject: [PATCH 23/26] version bump --- .efrocachemap | 44 +++++++++++----------- CHANGELOG.md | 2 + assets/src/ba_data/python/ba/_bootstrap.py | 2 +- src/ballistica/ballistica.cc | 4 +- 4 files changed, 27 insertions(+), 25 deletions(-) diff --git a/.efrocachemap b/.efrocachemap index 9b0a8044..d2231f71 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -420,7 +420,7 @@ "assets/build/ba_data/audio/zoeOw.ogg": "https://files.ballistica.net/cache/ba1/60/ad/38269b7f1c7dc20cb9a506cd0681", "assets/build/ba_data/audio/zoePickup01.ogg": "https://files.ballistica.net/cache/ba1/72/85/d6fc4d16b7081d91fba2850b5b10", "assets/build/ba_data/audio/zoeScream01.ogg": "https://files.ballistica.net/cache/ba1/e9/ae/1d674d0c086eaa0bd1c3b1db0505", - "assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/fc/ad/a45526ccfa8945247b3a29c2c251", + "assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/98/28/2d0235ac9ccd0b800f832ab7fbb3", "assets/build/ba_data/data/languages/arabic.json": "https://files.ballistica.net/cache/ba1/92/43/36b34307575f6d6219bdf4898e18", "assets/build/ba_data/data/languages/belarussian.json": "https://files.ballistica.net/cache/ba1/61/03/89070ca765e06da3a419a579f503", "assets/build/ba_data/data/languages/chinese.json": "https://files.ballistica.net/cache/ba1/aa/ed/4bd02af3cffbd4c9c4be532fb1fe", @@ -442,7 +442,7 @@ "assets/build/ba_data/data/languages/italian.json": "https://files.ballistica.net/cache/ba1/dd/be/1ae65f073d563e69c0c5246d20d7", "assets/build/ba_data/data/languages/korean.json": "https://files.ballistica.net/cache/ba1/32/97/4c61425d7c200a5c4c9ae3a94a0e", "assets/build/ba_data/data/languages/malay.json": "https://files.ballistica.net/cache/ba1/b4/02/f686ce008312e74d5953a511c8b2", - "assets/build/ba_data/data/languages/persian.json": "https://files.ballistica.net/cache/ba1/81/c8/269052d2d21ba6971f3a151813b9", + "assets/build/ba_data/data/languages/persian.json": "https://files.ballistica.net/cache/ba1/70/07/7864c07c7177dd751780ccc85b34", "assets/build/ba_data/data/languages/polish.json": "https://files.ballistica.net/cache/ba1/38/31/fd930431c7612d0ab0e73e6bc74f", "assets/build/ba_data/data/languages/portuguese.json": "https://files.ballistica.net/cache/ba1/cb/96/86bb139f20e126593f7fdba9e9e1", "assets/build/ba_data/data/languages/romanian.json": "https://files.ballistica.net/cache/ba1/d7/06/9d70642d0a4d1e3b1c2149d7a17c", @@ -4008,26 +4008,26 @@ "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/f0/de/a15c858f7de30960bf9bb0c62d0b", - "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/b2/21/fb3cc75f193b360fe01f192336c1", - "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/b5/e9/e65c9052619c2c1990462380cc54", - "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/02/ec/1652214167d27a6279cf1f525f47", - "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/6d/91/bcc179b4205353a17172ece5939d", - "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/56/83/8bdc611e72d8e681870176224bc3", - "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/82/ca/95b08abd3b0eeff5435979fc32b1", - "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/a6/33/67de7924fb59f8ae7e957d592a27", - "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/c6/ad/455d442d23c6e6699e578282dce8", - "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/d3/22/2e615a946352c67889dc4c0c5597", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/b7/c2/e29df979de73a7ca415735c34fc3", - "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/b2/24/43451b637f3f188e2913a02982d8", - "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/42/04/e1dc1a340a3ba859b9c417f330cd", - "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/7e/fe/70345e5263a0d456378e7a0e8661", - "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/a4/7f/7ad86eabef054f316814cbbd26ec", - "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/1e/cb/f003d8de353f71d08e81d82f6292", - "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/36/62/d86b02165ee596f2767ae24b505a", - "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/d6/73/37a2acd3bcd45cb8a48e4a80d547", - "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/57/62/ec832ceda26e7e7a07e4277a6d97", - "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/fd/88/724ff3645eb22af1f7755982af7b", + "build/prefab/full/linux_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/a0/31/79276810bb7e7a63b16a813762ed", + "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/8b/ff/ffe14193d7ecc7be7bd4b8f0c1df", + "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/1b/35/085b6877ca6132f22363935c556f", + "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/ea/6d/812e4be178b1bfac568dfbef1cd5", + "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/01/81/44c58651a270c66621fac233af03", + "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/bc/7f/fcb81a65171d668c02b43ad8a0ca", + "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/97/d3/a39c9949110c3258662e37a01218", + "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/34/c6/b9f70ebc862ea8c0824c20c21a8c", + "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/d4/1d/5fce150d3ffb8286eccc3c932070", + "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/7d/22/88ba10738a5fa80022fd4e43cd63", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/14/01/f113a6e70aa0f69753513c890d2e", + "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/4c/16/0a6993916d2b486cf1e3a96b5855", + "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/8d/54/7a2f804e29e8c43de5d17f3fb303", + "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/98/aa/4decee9932b26500b9db74f68115", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/e7/e2/8b1ec39a67b0ac7c23c76ea2b71d", + "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/59/ab/2756b60a87a798b89450d4ead9c6", + "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/43/f4/5289b9660fed0381c1d98626c0a6", + "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/7f/9a/fde700fa2c7a32cd9c3695fe8e8d", + "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/ba/9a/81f247b9f980e7907b28633605e1", + "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/c1/83/499a6c6d1cf150ce0370680db482", "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/e4/1b/a2ab5dd8c59cd90f5cd28f451884", "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a5/48/1e25219edd0a78e40c0f3093396d", "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/dd/5d/51313d43cafea4898cc2ca7aaf3d", diff --git a/CHANGELOG.md b/CHANGELOG.md index b5c57c7b..6825bcd4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ +### 1.7.18 (build 20984, api 7, 2023-01-12) + ### 1.7.17 (build 20983, api 7, 2023-01-09) - V2 accounts now show a 'Unlink Legacy (V1) Accounts' button in account settings if they have any old V1 links present. This can be used to clear out old links to replace them with V2 links which work correctly with V2 accounts. - `ba.internal.dump_tracebacks()` is now `ba.internal.dump_app_state()` and `ba.internal.log_dumped_tracebacks()` is now `ba.internal.log_dumped_app_state()`. This reflects the fact that these calls may be expanded to include other app state in the future (C++ layer thread states, etc.). diff --git a/assets/src/ba_data/python/ba/_bootstrap.py b/assets/src/ba_data/python/ba/_bootstrap.py index d150c6e8..63dec743 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 = 20983 + expected_build = 20984 running_build: int = env['build_number'] if running_build != expected_build: print( diff --git a/src/ballistica/ballistica.cc b/src/ballistica/ballistica.cc index 91d4ccb4..5e500c56 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 = 20983; -const char* kAppVersion = "1.7.17"; +const int kAppBuildNumber = 20984; +const char* kAppVersion = "1.7.18"; // Our standalone globals. // These are separated out for easy access. From 70946e019edbfa0caea64ea6a5e5a15835402171 Mon Sep 17 00:00:00 2001 From: EraOSBeta <100019405+EraOSBeta@users.noreply.github.com> Date: Fri, 13 Jan 2023 21:01:34 +0330 Subject: [PATCH 24/26] small change should comply with black now --- assets/src/ba_data/python/bastd/actor/spaz.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assets/src/ba_data/python/bastd/actor/spaz.py b/assets/src/ba_data/python/bastd/actor/spaz.py index 2aa65a8c..038ba00d 100644 --- a/assets/src/ba_data/python/bastd/actor/spaz.py +++ b/assets/src/ba_data/python/bastd/actor/spaz.py @@ -621,7 +621,8 @@ class Spaz(ba.Actor): self.node.curse_death_time = int( 1000.0 * (tval + self.curse_time) ) - self._curse_timer = ba.Timer(5.0, ba.WeakCall(self.curse_explode)) + self._curse_timer = ba.Timer(5.0, + ba.WeakCall(self.curse_explode)) def equip_boxing_gloves(self) -> None: """ From 667da7eef2982b0f2b7dd05f8592fe9688009e1a Mon Sep 17 00:00:00 2001 From: Eric Date: Tue, 17 Jan 2023 13:32:28 -0800 Subject: [PATCH 25/26] version bump --- .efrocachemap | 96 ++++++------- .idea/dictionaries/ericf.xml | 3 + CHANGELOG.md | 4 +- assets/src/ba_data/python/ba/_accountv2.py | 43 +++--- assets/src/ba_data/python/ba/_app.py | 10 +- assets/src/ba_data/python/ba/_apputils.py | 35 ++--- assets/src/ba_data/python/ba/_bootstrap.py | 2 +- assets/src/ba_data/python/ba/_hooks.py | 44 +++++- assets/src/ba_data/python/ba/_login.py | 44 +++++- .../python/bastd/ui/account/settings.py | 3 +- .../.idea/dictionaries/ericf.xml | 3 + src/ballistica/ballistica.cc | 2 +- tests/test_efro/test_message.py | 14 +- tools/bacommon/cloud.py | 4 + tools/efro/log.py | 14 +- tools/efro/message/_protocol.py | 58 +++++--- tools/efro/message/_receiver.py | 133 +++++++++--------- tools/efro/message/_sender.py | 102 +++++++++++--- tools/efro/rpc.py | 50 +++++-- 19 files changed, 427 insertions(+), 237 deletions(-) diff --git a/.efrocachemap b/.efrocachemap index d2231f71..49d8de4a 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -420,10 +420,10 @@ "assets/build/ba_data/audio/zoeOw.ogg": "https://files.ballistica.net/cache/ba1/60/ad/38269b7f1c7dc20cb9a506cd0681", "assets/build/ba_data/audio/zoePickup01.ogg": "https://files.ballistica.net/cache/ba1/72/85/d6fc4d16b7081d91fba2850b5b10", "assets/build/ba_data/audio/zoeScream01.ogg": "https://files.ballistica.net/cache/ba1/e9/ae/1d674d0c086eaa0bd1c3b1db0505", - "assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/98/28/2d0235ac9ccd0b800f832ab7fbb3", + "assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/9b/ec/d11f3e0238ff648bce3657fe5d50", "assets/build/ba_data/data/languages/arabic.json": "https://files.ballistica.net/cache/ba1/92/43/36b34307575f6d6219bdf4898e18", "assets/build/ba_data/data/languages/belarussian.json": "https://files.ballistica.net/cache/ba1/61/03/89070ca765e06da3a419a579f503", - "assets/build/ba_data/data/languages/chinese.json": "https://files.ballistica.net/cache/ba1/aa/ed/4bd02af3cffbd4c9c4be532fb1fe", + "assets/build/ba_data/data/languages/chinese.json": "https://files.ballistica.net/cache/ba1/96/96/1390940b8457b477113194acbb41", "assets/build/ba_data/data/languages/chinesetraditional.json": "https://files.ballistica.net/cache/ba1/f7/b0/191439142c6d6da4a056edc98b38", "assets/build/ba_data/data/languages/croatian.json": "https://files.ballistica.net/cache/ba1/c9/73/01a1343af814131b1ee96af0b687", "assets/build/ba_data/data/languages/czech.json": "https://files.ballistica.net/cache/ba1/4e/8c/72ddb584856a15dfb11df95f9283", @@ -449,11 +449,11 @@ "assets/build/ba_data/data/languages/russian.json": "https://files.ballistica.net/cache/ba1/6c/62/06869ed55a656b6e51b4d22e6fa8", "assets/build/ba_data/data/languages/serbian.json": "https://files.ballistica.net/cache/ba1/4e/91/6f2a9a3ce733908e91377a6ddb9a", "assets/build/ba_data/data/languages/slovak.json": "https://files.ballistica.net/cache/ba1/20/a9/163d189884edf802636bf291e432", - "assets/build/ba_data/data/languages/spanish.json": "https://files.ballistica.net/cache/ba1/f5/35/1dea74424ee613611ae3f7deec99", + "assets/build/ba_data/data/languages/spanish.json": "https://files.ballistica.net/cache/ba1/0b/21/a4d09ca1fea8bbf347ed7091c8a2", "assets/build/ba_data/data/languages/swedish.json": "https://files.ballistica.net/cache/ba1/3b/9f/d40c1423d260784970fd7364ca30", "assets/build/ba_data/data/languages/tamil.json": "https://files.ballistica.net/cache/ba1/3d/83/e1bb0a664d1c14c41b1a083acf0d", "assets/build/ba_data/data/languages/thai.json": "https://files.ballistica.net/cache/ba1/d6/16/523c643358880b03b233ed88e557", - "assets/build/ba_data/data/languages/turkish.json": "https://files.ballistica.net/cache/ba1/2a/0e/b164149e76efd0e6d591a9bf04bb", + "assets/build/ba_data/data/languages/turkish.json": "https://files.ballistica.net/cache/ba1/63/c8/6cfbfd6702c80aa9df490e4629d7", "assets/build/ba_data/data/languages/ukrainian.json": "https://files.ballistica.net/cache/ba1/3e/b6/052f1faed0264bf7135feb5c4cc3", "assets/build/ba_data/data/languages/venetian.json": "https://files.ballistica.net/cache/ba1/a6/ed/416638d46950c9ab4f6155b9c334", "assets/build/ba_data/data/languages/vietnamese.json": "https://files.ballistica.net/cache/ba1/1f/ae/abe3f105b3c4b51f6b7942773305", @@ -4008,50 +4008,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/a0/31/79276810bb7e7a63b16a813762ed", - "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/8b/ff/ffe14193d7ecc7be7bd4b8f0c1df", - "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/1b/35/085b6877ca6132f22363935c556f", - "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/ea/6d/812e4be178b1bfac568dfbef1cd5", - "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/01/81/44c58651a270c66621fac233af03", - "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/bc/7f/fcb81a65171d668c02b43ad8a0ca", - "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/97/d3/a39c9949110c3258662e37a01218", - "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/34/c6/b9f70ebc862ea8c0824c20c21a8c", - "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/d4/1d/5fce150d3ffb8286eccc3c932070", - "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/7d/22/88ba10738a5fa80022fd4e43cd63", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/14/01/f113a6e70aa0f69753513c890d2e", - "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/4c/16/0a6993916d2b486cf1e3a96b5855", - "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/8d/54/7a2f804e29e8c43de5d17f3fb303", - "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/98/aa/4decee9932b26500b9db74f68115", - "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/e7/e2/8b1ec39a67b0ac7c23c76ea2b71d", - "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/59/ab/2756b60a87a798b89450d4ead9c6", - "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/43/f4/5289b9660fed0381c1d98626c0a6", - "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/7f/9a/fde700fa2c7a32cd9c3695fe8e8d", - "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/ba/9a/81f247b9f980e7907b28633605e1", - "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/c1/83/499a6c6d1cf150ce0370680db482", - "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/e4/1b/a2ab5dd8c59cd90f5cd28f451884", - "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a5/48/1e25219edd0a78e40c0f3093396d", - "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/dd/5d/51313d43cafea4898cc2ca7aaf3d", - "build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/b3/ca/9a7f4019bf2e57d668171c42c876", - "build/prefab/lib/linux_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/4e/c8/478035d9e79dabc2a0cff7dc5c07", - "build/prefab/lib/linux_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/06/e3/5cac56d9f4e96a800cd424ecb01a", - "build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/2d/f2/f3afa4635c55863e2996ee110414", - "build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/52/2e/3fef9d99b533a1ae5e1be3c63e21", - "build/prefab/lib/mac_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/17/d4/3578de762544210f09f9ef6b60a4", - "build/prefab/lib/mac_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/18/44/f6a99fe7cf886f8a1b77b1878c7a", - "build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/84/3a/a7f7d3b3ee3bd7b1806bf77f2859", - "build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/e9/58/63afc99ce47eed08527f2dfc8f4d", - "build/prefab/lib/mac_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/43/ed/f49af3eb3646c69c5312ef8000dc", - "build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/e4/c5/091b0d55220c1c7a6939e00563d7", - "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/b3/f4/69436953e88c28d027b7c8004ba3", - "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/37/d3/599f3904f5ee987d540164237703", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/5b/0e/a571f0b1d167f3a0d3f07ff6e633", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/86/3e/abdb5280c7e24e145bcf4cfc73d4", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/15/b7/76299570cd56fac624ec810c575c", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/39/07/b32bb5e8a4458adc0df92dad82f6", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/28/46/700cc357d8c776c3a34dbdeb31c8", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/71/f0/d3d64e44f03a10536649e000c836", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/42/9a/961f50a8d8d7b1d704a2616d76ca", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/4a/da/85bb42cb764293be0b4c515268ad", + "build/prefab/full/linux_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/93/f0/feed13859ce5e9ea067b0e0529ff", + "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/0d/88/056f8877eb83cfa87fb581d09a52", + "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/f3/1f/14bf78a27530eec8d30e54392788", + "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/d5/f9/9acf2f6b0a04f122d937b671337b", + "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/21/b5/65486e588021c5a551a7faf60490", + "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/4f/3f/39a86bf3e6556628bac7e038eb51", + "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/6c/6f/7efeb16dffd3f1e205feb2ce99fa", + "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/21/e5/6e5bcfbf995ae8579638fc5d1488", + "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/a0/7c/7a09ecb3beedfa91cde84e964bb9", + "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/5a/fa/8491b8dac79d172c33747862e77f", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/4c/8f/90292472906d259c86c8a38bcbc7", + "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/18/c3/92d5a2465283e17bcf7af2bf26e8", + "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/f2/4a/222725049d0619e8c8d97e60d079", + "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/60/e4/d6798a2d698da031a1f97b2fd008", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/4e/96/d35f6076e1e01b7a959df4379b76", + "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/f9/56/d0f8e1eb5f17c33a99ee032a42ff", + "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/e6/fc/95cab0bca71d81826a30b7621852", + "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/99/93/23154000c5d940cd943deed2692f", + "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/ae/5b/3ccd55688d48429a7d2a4bd32919", + "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/ac/ef/5ed349d3c42d58a98a79c94404b0", + "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/cb/3b/83e6150eebf4fa7b5e8a7b863219", + "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/44/70/2878a73f2d55849cd6a75e401575", + "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/24/49/4baca475df5c7f87e6ed17d46696", + "build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/b9/46/1c6b679ef9db6807100bc0bba261", + "build/prefab/lib/linux_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/da/b9/427dfd7ae8efbe6009964fe34beb", + "build/prefab/lib/linux_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ac/2c/fc0a576c3d957896bfd3de792af6", + "build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/39/08/4033ab823798c48b3446c032a72c", + "build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/3a/c6/189744027136a7411d5dfa5c5cf4", + "build/prefab/lib/mac_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/7a/c6/bb533c59368fdf45d65812f37a27", + "build/prefab/lib/mac_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/3c/6e/88180b8e905df7453e0f989da027", + "build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/2c/99/e35a71c9c410da4035a0456314b6", + "build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/47/b2/bb092304cd5e5f3bdb6e085197de", + "build/prefab/lib/mac_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/9c/ce/523a32e2dce1174df21373ab5765", + "build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/b2/ee/b908410d85c763d5bca09a3bc893", + "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/fd/24/8c51e5752064d4b487dff42a7ffa", + "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/93/c6/40e9e47dd33c88646510212ff321", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/a1/25/ca39d9309b63ed38bee3be1f9e67", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/b3/ef/a6240c67194508ac7bd58ba73391", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/c2/cc/b081c59aa873304086d2e44c1f30", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/d3/cb/8c1ed9ee3e8f1b0d866160257506", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/f0/f8/fb0aa403b29d5c5a9ebb5aec66fb", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/0b/03/ed35c58e80013f47b57c838c12d4", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/18/1d/cfc42a4939904783c897322207aa", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/68/82/c02d830bdb12f57ae976c5acc4fb", "src/ballistica/generated/python_embedded/binding.inc": "https://files.ballistica.net/cache/ba1/23/ce/68396b1b7ec6d2f8425902148140", "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 7f276301..4b9e6319 100644 --- a/.idea/dictionaries/ericf.xml +++ b/.idea/dictionaries/ericf.xml @@ -185,6 +185,7 @@ availplug aval awaitable + awaitables axismotion bacfg backgrounded @@ -863,6 +864,7 @@ fcontents fcount fdata + fdcount fdesc fdict fdout @@ -1276,6 +1278,7 @@ iprof isatty iscale + iscoroutinefunction iserverget iserverput ispunch diff --git a/CHANGELOG.md b/CHANGELOG.md index 6825bcd4..f86ca1d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,6 @@ -### 1.7.18 (build 20984, api 7, 2023-01-12) +### 1.7.18 (build 20991, api 7, 2023-01-17) +- Reworked some low level asynchronous messaging functionality in efro.message and efro.rpc. Previously these were a little *too* asynchronous which could lead to messages being received in a different order than they were sent, which is not desirable. +- Added a way to suppress 'Your build is outdated' messages at launch (see `ba._hooks.show_client_too_old_error()`). ### 1.7.17 (build 20983, api 7, 2023-01-09) - V2 accounts now show a 'Unlink Legacy (V1) Accounts' button in account settings if they have any old V1 links present. This can be used to clear out old links to replace them with V2 links which work correctly with V2 accounts. diff --git a/assets/src/ba_data/python/ba/_accountv2.py b/assets/src/ba_data/python/ba/_accountv2.py index f5fee480..5e676230 100644 --- a/assets/src/ba_data/python/ba/_accountv2.py +++ b/assets/src/ba_data/python/ba/_accountv2.py @@ -36,7 +36,7 @@ class AccountV2Subsystem: # (or lack thereof) has completed. This includes things like # workspace syncing. Completion of this is what flips the app # into 'running' state. - self._initial_login_completed = False + self._initial_sign_in_completed = False self._kicked_off_workspace_load = False @@ -98,7 +98,7 @@ class AccountV2Subsystem: if account.workspaceid is not None: assert account.workspacename is not None if ( - not self._initial_login_completed + not self._initial_sign_in_completed and not self._kicked_off_workspace_load ): self._kicked_off_workspace_load = True @@ -121,9 +121,9 @@ class AccountV2Subsystem: return # Ok; no workspace to worry about; carry on. - if not self._initial_login_completed: - self._initial_login_completed = True - _ba.app.on_initial_login_completed() + if not self._initial_sign_in_completed: + self._initial_sign_in_completed = True + _ba.app.on_initial_sign_in_completed() def on_active_logins_changed(self, logins: dict[LoginType, str]) -> None: """Should be called when logins for the active account change.""" @@ -156,9 +156,9 @@ class AccountV2Subsystem: within a few seconds of app launch; the app can move forward with the startup sequence at that point. """ - if not self._initial_login_completed: - self._initial_login_completed = True - _ba.app.on_initial_login_completed() + if not self._initial_sign_in_completed: + self._initial_sign_in_completed = True + _ba.app.on_initial_sign_in_completed() @staticmethod def _hashstr(val: str) -> str: @@ -271,7 +271,7 @@ class AccountV2Subsystem: self._implicit_state_changed = False # Once we've made a move here we don't want to - # do any more automatic ones. + # do any more automatic stuff. self._can_do_auto_sign_in = False else: @@ -290,22 +290,23 @@ class AccountV2Subsystem: ' of implicit state change...', ) self._implicit_signed_in_adapter.sign_in( - self._on_explicit_sign_in_completed + self._on_explicit_sign_in_completed, + description='implicit state change', ) self._implicit_state_changed = False # Once we've made a move here we don't want to - # do any more automatic ones. + # do any more automatic stuff. self._can_do_auto_sign_in = False if not self._can_do_auto_sign_in: return # If we're not currently signed in, we have connectivity, and - # we have an available implicit login, auto-sign-in with it. + # we have an available implicit login, auto-sign-in with it once. # The implicit-state-change logic above should keep things - # mostly in-sync, but due to connectivity or other issues that - # might not always be the case. We prefer to keep people signed + # mostly in-sync, but that might not always be the case due to + # connectivity or other issues. We prefer to keep people signed # in as a rule, even if there are corner cases where this might # not be what they want (A user signing out and then restarting # may be auto-signed back in). @@ -324,7 +325,7 @@ class AccountV2Subsystem: ) self._can_do_auto_sign_in = False # Only ATTEMPT once self._implicit_signed_in_adapter.sign_in( - self._on_implicit_sign_in_completed + self._on_implicit_sign_in_completed, description='auto-sign-in' ) def _on_explicit_sign_in_completed( @@ -337,8 +338,8 @@ class AccountV2Subsystem: del adapter # Unused. - # Make some noise on errors since the user knows - # a sign-in attempt is happening in this case. + # Make some noise on errors since the user knows a + # sign-in attempt is happening in this case (the 'explicit' part). if isinstance(result, Exception): # We expect the occasional communication errors; # Log a full exception for anything else though. @@ -347,6 +348,8 @@ class AccountV2Subsystem: 'Error on explicit accountv2 sign in attempt.', exc_info=result, ) + + # For now just show 'error'. Should do better than this. with _ba.Context('ui'): _ba.screenmessage( Lstr(resource='internal.signInErrorText'), @@ -395,9 +398,9 @@ class AccountV2Subsystem: _ba.app.accounts_v2.set_primary_credentials(result.credentials) def _on_set_active_workspace_completed(self) -> None: - if not self._initial_login_completed: - self._initial_login_completed = True - _ba.app.on_initial_login_completed() + if not self._initial_sign_in_completed: + self._initial_sign_in_completed = True + _ba.app.on_initial_sign_in_completed() class AccountV2Handle: diff --git a/assets/src/ba_data/python/ba/_app.py b/assets/src/ba_data/python/ba/_app.py index c7b09622..9c44d333 100644 --- a/assets/src/ba_data/python/ba/_app.py +++ b/assets/src/ba_data/python/ba/_app.py @@ -235,7 +235,7 @@ class App: self.state = self.State.LAUNCHING self._launch_completed = False - self._initial_login_completed = False + self._initial_sign_in_completed = False self._meta_scan_completed = False self._called_on_app_running = False self._app_paused = False @@ -511,7 +511,7 @@ class App: self.plugins.on_app_resume() self.health_monitor.on_app_resume() - if self._initial_login_completed and self._meta_scan_completed: + if self._initial_sign_in_completed and self._meta_scan_completed: self.state = self.State.RUNNING if not self._called_on_app_running: self._called_on_app_running = True @@ -724,8 +724,8 @@ class App: _ba.screenmessage(Lstr(resource='errorText'), color=(1, 0, 0)) _ba.playsound(_ba.getsound('error')) - def on_initial_login_completed(self) -> None: - """Callback to be run after initial login process (or lack thereof). + def on_initial_sign_in_completed(self) -> None: + """Callback to be run after initial sign-in (or lack thereof). This period includes things such as syncing account workspaces or other data so it may take a substantial amount of time. @@ -736,5 +736,5 @@ class App: # (account workspaces). self.meta.start_extra_scan() - self._initial_login_completed = True + self._initial_sign_in_completed = True self._update_state() diff --git a/assets/src/ba_data/python/ba/_apputils.py b/assets/src/ba_data/python/ba/_apputils.py index cbde13d8..af4a7769 100644 --- a/assets/src/ba_data/python/ba/_apputils.py +++ b/assets/src/ba_data/python/ba/_apputils.py @@ -476,35 +476,18 @@ def on_too_many_file_descriptors() -> None: real_time = _ba.time(TimeType.REAL) def _do_log() -> None: - import subprocess - pid = os.getpid() - out = f'TOO MANY FDS at {real_time}.\nWe are pid {pid}\n' - - out += ( - 'FD Count: ' - + subprocess.run( - f'ls -l /proc/{pid}/fd | wc -l', - shell=True, - check=False, - capture_output=True, - ).stdout.decode() - + '\n' + try: + fdcount: int | str = len(os.listdir(f'/proc/{pid}/fd')) + except Exception as exc: + fdcount = f'? ({exc})' + logging.warning( + 'TOO MANY FDS at %.2f. We are pid %d. FDCount is %s.', + real_time, + pid, + fdcount, ) - out += ( - 'lsof output:\n' - + subprocess.run( - f'lsof -p {pid}', - shell=True, - check=False, - capture_output=True, - ).stdout.decode() - + '\n' - ) - - logging.warning(out) - Thread(target=_do_log, daemon=True).start() # import io diff --git a/assets/src/ba_data/python/ba/_bootstrap.py b/assets/src/ba_data/python/ba/_bootstrap.py index 63dec743..4d616449 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 = 20984 + expected_build = 20991 running_build: int = env['build_number'] if running_build != expected_build: print( diff --git a/assets/src/ba_data/python/ba/_hooks.py b/assets/src/ba_data/python/ba/_hooks.py index 9d020aa6..f7d0e471 100644 --- a/assets/src/ba_data/python/ba/_hooks.py +++ b/assets/src/ba_data/python/ba/_hooks.py @@ -1,13 +1,13 @@ # Released under the MIT License. See LICENSE for details. # -"""Snippets of code for use by the internal C++ layer. +"""Snippets of code for use by the internal layer. -History: originally I would dynamically compile/eval bits of Python text -from within C++ code, but the major downside there was that none of that was -type-checked so if names or arguments changed I would never catch code breakage -until the code was next run. By defining all snippets I use here and then -capturing references to them all at launch I can immediately verify everything -I'm looking for exists and pylint/mypy can do their magic on this file. +History: originally the engine would dynamically compile/eval various Python +code from within C++ code, but the major downside there was that none of it +was type-checked so if names or arguments changed it would go unnoticed +until it broke at runtime. By instead defining such snippets here and then +capturing references to them all at launch it is possible to allow linting +and type-checking magic to happen and most issues will be caught immediately. """ # (most of these are self-explanatory) # pylint: disable=missing-function-docstring @@ -470,3 +470,33 @@ def login_adapter_get_sign_in_token_response( adapter = _ba.app.accounts_v2.login_adapters[login_type] assert isinstance(adapter, LoginAdapterNative) adapter.on_sign_in_complete(attempt_id=attempt_id, result=result) + + +def show_client_too_old_error() -> None: + """Called at launch if the server tells us we're too old to talk to it.""" + from ba._language import Lstr + + # If you are using an old build of the app and would like to stop + # seeing this error at launch, do: + # ba.app.config['SuppressClientTooOldErrorForBuild'] = ba.app.build_number + # ba.app.config.commit() + # Note that you will have to do that again later if you update to + # a newer build. + if ( + _ba.app.config.get('SuppressClientTooOldErrorForBuild') + == _ba.app.build_number + ): + return + + _ba.playsound(_ba.getsound('error')) + _ba.screenmessage( + Lstr( + translate=( + 'serverResponses', + 'Server functionality is no longer supported' + ' in this version of the game;\n' + 'Please update to a newer version.', + ) + ), + color=(1, 0, 0), + ) diff --git a/assets/src/ba_data/python/ba/_login.py b/assets/src/ba_data/python/ba/_login.py index 0ca4098e..49541bd5 100644 --- a/assets/src/ba_data/python/ba/_login.py +++ b/assets/src/ba_data/python/ba/_login.py @@ -4,6 +4,7 @@ from __future__ import annotations +import time import logging from dataclasses import dataclass from typing import TYPE_CHECKING, final @@ -57,6 +58,9 @@ class LoginAdapter: # current active primary account. self._active_login_id: str | None = None + self._last_sign_in_time: float | None = None + self._last_sign_in_desc: str | None = None + def on_app_launch(self) -> None: """Should be called for each adapter in on_app_launch.""" @@ -142,6 +146,7 @@ class LoginAdapter: def sign_in( self, result_cb: Callable[[LoginAdapter, SignInResult | Exception], None], + description: str, ) -> None: """Attempt an explicit sign in via this adapter. @@ -151,6 +156,38 @@ class LoginAdapter: """ assert _ba.in_logic_thread() from ba._general import Call + from ba._generated.enums import TimeType + + # Have been seeing multiple sign-in attempts come through + # nearly simultaneously which can be problematic server-side. + # Let's error if a sign-in attempt is made within a few seconds + # of the last one to address this. + now = time.monotonic() + appnow = _ba.time(TimeType.REAL) + if self._last_sign_in_time is not None: + since_last = now - self._last_sign_in_time + if since_last < 1.0: + logging.warning( + 'LoginAdapter: %s adapter sign_in() called too soon' + ' (%.2fs) after last; this-desc="%s", last-desc="%s",' + ' ba-real-time=%.2f.', + self.login_type.name, + since_last, + description, + self._last_sign_in_desc, + appnow, + ) + _ba.pushcall( + Call( + result_cb, + self, + RuntimeError('sign_in called too soon after last.'), + ) + ) + return + + self._last_sign_in_desc = description + self._last_sign_in_time = now if DEBUG_LOG: logging.debug( @@ -223,7 +260,12 @@ class LoginAdapter: _ba.pushcall(Call(result_cb, self, result2)) _ba.app.cloud.send_message_cb( - bacommon.cloud.SignInMessage(self.login_type, result), + bacommon.cloud.SignInMessage( + self.login_type, + result, + description=description, + apptime=appnow, + ), on_response=_got_sign_in_response, ) diff --git a/assets/src/ba_data/python/bastd/ui/account/settings.py b/assets/src/ba_data/python/bastd/ui/account/settings.py index ea43f5df..214f8c92 100644 --- a/assets/src/ba_data/python/bastd/ui/account/settings.py +++ b/assets/src/ba_data/python/bastd/ui/account/settings.py @@ -1403,7 +1403,8 @@ class AccountSettingsWindow(ba.Window): if adapter is not None: self._signing_in_adapter = adapter adapter.sign_in( - result_cb=ba.WeakCall(self._on_adapter_sign_in_result) + result_cb=ba.WeakCall(self._on_adapter_sign_in_result), + description='account settings button', ) # Will get 'Signing in...' to show. self._needs_refresh = True diff --git a/ballisticacore-cmake/.idea/dictionaries/ericf.xml b/ballisticacore-cmake/.idea/dictionaries/ericf.xml index 45705ff7..2e0ef135 100644 --- a/ballisticacore-cmake/.idea/dictionaries/ericf.xml +++ b/ballisticacore-cmake/.idea/dictionaries/ericf.xml @@ -94,6 +94,7 @@ avel avels awaitable + awaitables axismotion backgrounded backgrounding @@ -464,6 +465,7 @@ fbos fcntl fdata + fdcount fdirx fdiry fdirz @@ -672,6 +674,7 @@ ioprepped ioprepping ioreg + iscoroutinefunction iserverget iserverput isinst diff --git a/src/ballistica/ballistica.cc b/src/ballistica/ballistica.cc index 5e500c56..757e253f 100644 --- a/src/ballistica/ballistica.cc +++ b/src/ballistica/ballistica.cc @@ -32,7 +32,7 @@ namespace ballistica { // These are set automatically via script; don't modify them here. -const int kAppBuildNumber = 20984; +const int kAppBuildNumber = 20991; const char* kAppVersion = "1.7.18"; // Our standalone globals. diff --git a/tests/test_efro/test_message.py b/tests/test_efro/test_message.py index 9916bf3a..1a944041 100644 --- a/tests/test_efro/test_message.py +++ b/tests/test_efro/test_message.py @@ -198,9 +198,9 @@ class _BoundTestMessageSenderAsync(BoundMessageSender): async def send_async(self, message: _TMsg3) -> None: ... - async def send_async(self, message: Message) -> Response | None: + def send_async(self, message: Message) -> Awaitable[Response | None]: """Send a message asynchronously.""" - return await self._sender.send_async(self._obj, message) + return self._sender.send_async(self._obj, message) # SEND_ASYNC_CODE_TEST_END @@ -261,9 +261,9 @@ class _BoundTestMessageSenderBBoth(BoundMessageSender): async def send_async(self, message: _TMsg4) -> None: ... - async def send_async(self, message: Message) -> Response | None: + def send_async(self, message: Message) -> Awaitable[Response | None]: """Send a message asynchronously.""" - return await self._sender.send_async(self._obj, message) + return self._sender.send_async(self._obj, message) # SEND_BOTH_CODE_TEST_END @@ -424,11 +424,11 @@ class _TestAsyncMessageReceiver(MessageReceiver): class _BoundTestAsyncMessageReceiver(BoundMessageReceiver): """Protocol-specific bound receiver.""" - async def handle_raw_message( + def handle_raw_message( self, message: str, raise_unregistered: bool = False - ) -> str: + ) -> Awaitable[str]: """Asynchronously handle a raw incoming message.""" - return await self._receiver.handle_raw_message_async( + return self._receiver.handle_raw_message_async( self._obj, message, raise_unregistered ) diff --git a/tools/bacommon/cloud.py b/tools/bacommon/cloud.py index 1e680a40..df621b09 100644 --- a/tools/bacommon/cloud.py +++ b/tools/bacommon/cloud.py @@ -183,6 +183,10 @@ class SignInMessage(Message): login_type: Annotated[LoginType, IOAttrs('l')] sign_in_token: Annotated[str, IOAttrs('t')] + # For debugging. Can remove soft_default once build 20988+ is ubiquitous. + description: Annotated[str, IOAttrs('d', soft_default='-')] + apptime: Annotated[float, IOAttrs('at', soft_default=-1.0)] + @classmethod def get_response_types(cls) -> list[type[Response] | None]: return [SignInResponse] diff --git a/tools/efro/log.py b/tools/efro/log.py index 752922ed..02afc2a0 100644 --- a/tools/efro/log.py +++ b/tools/efro/log.py @@ -266,6 +266,9 @@ class LogHandler(logging.Handler): # didn't expect to be stringified. msg = self.format(record) + if __debug__: + formattime = time.monotonic() + # Also immediately print pretty colored output to our echo file # (generally stderr). We do this part here instead of in our bg # thread because the delay can throw off command line prompts or @@ -277,6 +280,9 @@ class LogHandler(logging.Handler): else: self._echofile.write(f'{msg}\n') + if __debug__: + echotime = time.monotonic() + self._event_loop.call_soon_threadsafe( tpartial( self._emit_in_thread, @@ -295,6 +301,10 @@ class LogHandler(logging.Handler): now = time.monotonic() # noinspection PyUnboundLocalVariable duration = now - starttime + # noinspection PyUnboundLocalVariable + format_duration = formattime - starttime + # noinspection PyUnboundLocalVariable + echo_duration = echotime - formattime if duration > 0.05 and ( self._last_slow_emit_warning_time is None or now > self._last_slow_emit_warning_time + 10.0 @@ -307,8 +317,10 @@ class LogHandler(logging.Handler): tpartial( logging.warning, 'efro.log.LogHandler emit took too long' - ' (%.2f seconds).', + ' (%.2fs total; %.2fs format, %.2fs echo).', duration, + format_duration, + echo_duration, ) ) diff --git a/tools/efro/message/_protocol.py b/tools/efro/message/_protocol.py index 3c24c5b0..ce86d39b 100644 --- a/tools/efro/message/_protocol.py +++ b/tools/efro/message/_protocol.py @@ -282,10 +282,13 @@ class MessageProtocol: def _get_module_header( self, part: Literal['sender', 'receiver'], - extra_import_code: str | None = None, + extra_import_code: str | None, + enable_async_sends: bool, ) -> str: """Return common parts of generated modules.""" - # pylint: disable=too-many-locals, too-many-branches + # pylint: disable=too-many-locals + # pylint: disable=too-many-branches + # pylint: disable=too-many-statements import textwrap tpimports: dict[str, list[str]] = {} @@ -342,7 +345,7 @@ class MessageProtocol: if part == 'sender': import_lines += ( - 'from efro.message import MessageSender,' ' BoundMessageSender' + 'from efro.message import MessageSender, BoundMessageSender' ) tpimport_typing_extras = '' else: @@ -362,11 +365,18 @@ class MessageProtocol: import_lines += f'\n{extra_import_code}\n' ovld = ', overload' if not single_message_type else '' + ovld2 = ( + ', cast, Awaitable' + if (single_message_type and part == 'sender' and enable_async_sends) + else '' + ) tpimport_lines = textwrap.indent(tpimport_lines, ' ') baseimps = ['Any'] if part == 'receiver': baseimps.append('Callable') + if part == 'sender' and enable_async_sends: + baseimps.append('Awaitable') baseimps_s = ', '.join(baseimps) out = ( '# Released under the MIT License. See LICENSE for details.\n' @@ -375,7 +385,7 @@ class MessageProtocol: f'\n' f'from __future__ import annotations\n' f'\n' - f'from typing import TYPE_CHECKING{ovld}\n' + f'from typing import TYPE_CHECKING{ovld}{ovld2}\n' f'\n' f'{import_lines}\n' f'\n' @@ -399,13 +409,16 @@ class MessageProtocol: ) -> str: """Used by create_sender_module(); do not call directly.""" # pylint: disable=too-many-locals + # pylint: disable=too-many-branches import textwrap msgtypes = list(self.message_ids_by_type.keys()) ppre = '_' if private else '' out = self._get_module_header( - 'sender', extra_import_code=protocol_module_level_import_code + 'sender', + extra_import_code=protocol_module_level_import_code, + enable_async_sends=enable_async_sends, ) ccind = textwrap.indent(protocol_create_code, ' ') out += ( @@ -438,7 +451,8 @@ class MessageProtocol: continue pfx = 'async ' if async_pass else '' sfx = '_async' if async_pass else '' - awt = 'await ' if async_pass else '' + # awt = 'await ' if async_pass else '' + awt = '' how = 'asynchronously' if async_pass else 'synchronously' if len(msgtypes) == 1: @@ -451,22 +465,29 @@ class MessageProtocol: rtypevar = ' | '.join(_filt_tp_name(t) for t in rtypes) else: rtypevar = _filt_tp_name(rtypes[0]) + if async_pass: + rtypevar = f'Awaitable[{rtypevar}]' out += ( f'\n' - f' {pfx}def send{sfx}(self,' + f' def send{sfx}(self,' f' message: {msgtypevar})' f' -> {rtypevar}:\n' f' """Send a message {how}."""\n' f' out = {awt}self._sender.' f'send{sfx}(self._obj, message)\n' - f' assert isinstance(out, {rtypevar})\n' - f' return out\n' ) + if not async_pass: + out += ( + f' assert isinstance(out, {rtypevar})\n' + ' return out\n' + ) + else: + out += f' return cast({rtypevar}, out)\n' + else: for msgtype in msgtypes: msgtypevar = msgtype.__name__ - # rtypes = msgtype.get_response_types() rtypes = msgtype.get_response_types() if len(rtypes) > 1: rtypevar = ' | '.join( @@ -482,10 +503,13 @@ class MessageProtocol: f' -> {rtypevar}:\n' f' ...\n' ) + rtypevar = 'Response | None' + if async_pass: + rtypevar = f'Awaitable[{rtypevar}]' out += ( f'\n' - f' {pfx}def send{sfx}(self, message: Message)' - f' -> Response | None:\n' + f' def send{sfx}(self, message: Message)' + f' -> {rtypevar}:\n' f' """Send a message {how}."""\n' f' return {awt}self._sender.' f'send{sfx}(self._obj, message)\n' @@ -509,7 +533,9 @@ class MessageProtocol: ppre = '_' if private else '' msgtypes = list(self.message_ids_by_type.keys()) out = self._get_module_header( - 'receiver', extra_import_code=protocol_module_level_import_code + 'receiver', + extra_import_code=protocol_module_level_import_code, + enable_async_sends=False, ) ccind = textwrap.indent(protocol_create_code, ' ') out += ( @@ -602,11 +628,11 @@ class MessageProtocol: if is_async: out += ( '\n' - ' async def handle_raw_message(\n' + ' def handle_raw_message(\n' ' self, message: str, raise_unregistered: bool = False\n' - ' ) -> str:\n' + ' ) -> Awaitable[str]:\n' ' """Asynchronously handle a raw incoming message."""\n' - ' return await self._receiver.' + ' return self._receiver.' 'handle_raw_message_async(\n' ' self._obj, message, raise_unregistered\n' ' )\n' diff --git a/tools/efro/message/_receiver.py b/tools/efro/message/_receiver.py index cc35423f..3d8477c3 100644 --- a/tools/efro/message/_receiver.py +++ b/tools/efro/message/_receiver.py @@ -62,12 +62,6 @@ class MessageReceiver: [Any, Message | None, Response | SysResponse, dict], None ] | None = None - # TODO: don't currently have async encode equivalent - # or either for sender; can add as needed. - self._decode_filter_async_call: Callable[ - [Any, dict, Message], Awaitable[None] - ] | None = None - # noinspection PyProtectedMember def register_handler( self, call: Callable[[Any, Message], Response | None] @@ -96,14 +90,17 @@ class MessageReceiver: # Make sure we are only given async methods if we are an async handler # and sync ones otherwise. - is_async = inspect.iscoroutinefunction(call) - if self.is_async != is_async: - msg = ( - 'Expected a sync method; found an async one.' - if is_async - else 'Expected an async method; found a sync one.' - ) - raise ValueError(msg) + # UPDATE - can't do this anymore since we now sometimes use + # regular functions which return awaitables instead of having + # the entire function be async. + # is_async = inspect.iscoroutinefunction(call) + # if self.is_async != is_async: + # msg = ( + # 'Expected a sync method; found an async one.' + # if is_async + # else 'Expected an async method; found a sync one.' + # ) + # raise ValueError(msg) # Check annotation types to determine what message types we handle. # Return-type annotation can be a Union, but we probably don't @@ -189,19 +186,6 @@ class MessageReceiver: self._decode_filter_call = call return call - def decode_filter_async_method( - self, call: Callable[[Any, dict, Message], Awaitable[None]] - ) -> Callable[[Any, dict, Message], Awaitable[None]]: - """Function decorator for defining a decode filter. - - Decode filters can be used to extract extra data from incoming - message dicts. Note that this version will only work with - handle_raw_message_async(). - """ - assert self._decode_filter_async_call is None - self._decode_filter_async_call = call - return call - def encode_filter_method( self, call: Callable[ @@ -247,24 +231,6 @@ class MessageReceiver: bound_obj, _msg_dict, msg_decoded = self._decode_incoming_message_base( bound_obj=bound_obj, msg=msg ) - - # If they've set an async filter but are calling sync - # handle_raw_message() its likely a bug. - assert self._decode_filter_async_call is None - - return msg_decoded - - async def _decode_incoming_message_async( - self, bound_obj: Any, msg: str - ) -> Message: - bound_obj, msg_dict, msg_decoded = self._decode_incoming_message_base( - bound_obj=bound_obj, msg=msg - ) - - if self._decode_filter_async_call is not None: - await self._decode_filter_async_call( - bound_obj, msg_dict, msg_decoded - ) return msg_decoded def encode_user_response( @@ -346,46 +312,83 @@ class MessageReceiver: logging.exception('Error in efro.message handling.') return rstr - async def handle_raw_message_async( + def handle_raw_message_async( self, bound_obj: Any, msg: str, raise_unregistered: bool = False - ) -> str: + ) -> Awaitable[str]: """Should be called when the receiver gets a message. The return value is the raw response to the message. """ + + # Note: This call is synchronous so that the first part of it can + # happen synchronously. If the whole call were async we wouldn't be + # able to guarantee that messages handlers would be called in the + # order the messages were received. + assert self.is_async, "can't call async handler on sync receiver" msg_decoded: Message | None = None msgtype: type[Message] | None = None try: - msg_decoded = await self._decode_incoming_message_async( - bound_obj, msg - ) + msg_decoded = self._decode_incoming_message(bound_obj, msg) msgtype = type(msg_decoded) handler = self._handlers.get(msgtype) if handler is None: raise RuntimeError(f'Got unhandled message type: {msgtype}.') - response = await handler(bound_obj, msg_decoded) - assert isinstance(response, Response | None) - return self.encode_user_response(bound_obj, msg_decoded, response) + handler_awaitable = handler(bound_obj, msg_decoded) except Exception as exc: if raise_unregistered and isinstance( exc, UnregisteredMessageIDError ): raise - rstr, dolog = self.encode_error_response( - bound_obj, msg_decoded, exc + return self._handle_raw_message_async_error( + bound_obj, msg_decoded, msgtype, exc + ) + + # Return an awaitable to handle the rest asynchronously. + return self._handle_raw_message_async( + bound_obj, msg_decoded, msgtype, handler_awaitable + ) + + async def _handle_raw_message_async_error( + self, + bound_obj: Any, + msg_decoded: Message | None, + msgtype: type[Message] | None, + exc: Exception, + ) -> str: + rstr, dolog = self.encode_error_response(bound_obj, msg_decoded, exc) + if dolog: + if msgtype is not None: + logging.exception( + 'Error handling %s.%s message.', + msgtype.__module__, + msgtype.__qualname__, + ) + else: + logging.exception('Error in efro.message handling.') + return rstr + + async def _handle_raw_message_async( + self, + bound_obj: Any, + msg_decoded: Message, + msgtype: type[Message] | None, + handler_awaitable: Awaitable[Response | None], + ) -> str: + """Should be called when the receiver gets a message. + + The return value is the raw response to the message. + """ + try: + response = await handler_awaitable + assert isinstance(response, Response | None) + return self.encode_user_response(bound_obj, msg_decoded, response) + + except Exception as exc: + return await self._handle_raw_message_async_error( + bound_obj, msg_decoded, msgtype, exc ) - if dolog: - if msgtype is not None: - logging.exception( - 'Error handling %s.%s message.', - msgtype.__module__, - msgtype.__qualname__, - ) - else: - logging.exception('Error in efro.message handling.') - return rstr class BoundMessageReceiver: diff --git a/tools/efro/message/_sender.py b/tools/efro/message/_sender.py index 8d71d584..63effe76 100644 --- a/tools/efro/message/_sender.py +++ b/tools/efro/message/_sender.py @@ -78,6 +78,14 @@ class MessageSender: CommunicationErrors raised here will be returned to the sender as such; all other exceptions will result in a RuntimeError for the sender. + + IMPORTANT: Generally async send methods should not be implemented + as 'async' methods, but instead should be regular methods that + return awaitable objects. This way it can be guaranteed that + outgoing messages are synchronously enqueued in the correct + order, and then async calls can be returned which finish each + send. If the entire call is async, they may be enqueued out of + order in rare cases. """ assert self._send_async_raw_message_call is None self._send_async_raw_message_call = call @@ -88,8 +96,9 @@ class MessageSender: ) -> Callable[[Any, str, Message], Awaitable[str]]: """Function decorator for extended send-async method. - This version of the method also is passed the original unencoded - message. + Version of send_async_method which is also is passed the original + unencoded message; can be useful for cases where metadata is sent + along with messages referring to their payloads/etc. """ assert self._send_async_raw_message_ex_call is None self._send_async_raw_message_ex_call = call @@ -141,17 +150,34 @@ class MessageSender: ), ) - async def send_async( + def send_async( self, bound_obj: Any, message: Message - ) -> Response | None: + ) -> Awaitable[Response | None]: """Send a message asynchronously.""" + + # Note: This call is synchronous so that the first part of it can + # happen synchronously. If the whole call were async we wouldn't be + # able to guarantee that messages sent in order would actually go + # out in order. + raw_response_awaitable = self.fetch_raw_response_async( + bound_obj=bound_obj, + message=message, + ) + # Now return an awaitable that will finish the send. + return self._send_async_awaitable( + bound_obj, message, raw_response_awaitable + ) + + async def _send_async_awaitable( + self, + bound_obj: Any, + message: Message, + raw_response_awaitable: Awaitable[Response | SysResponse], + ) -> Response | None: return self.unpack_raw_response( bound_obj=bound_obj, message=message, - raw_response=await self.fetch_raw_response_async( - bound_obj=bound_obj, - message=message, - ), + raw_response=await raw_response_awaitable, ) def fetch_raw_response( @@ -186,19 +212,23 @@ class MessageSender: return response return self._decode_raw_response(bound_obj, message, response_encoded) - async def fetch_raw_response_async( + def fetch_raw_response_async( self, bound_obj: Any, message: Message - ) -> Response | SysResponse: - """Fetch a raw message response. + ) -> Awaitable[Response | SysResponse]: + """Fetch a raw message response awaitable. - The result of this should be passed to unpack_raw_response() to - produce the final message result. + The result of this should be awaited and then passed to + unpack_raw_response() to produce the final message result. Generally you can just call send(); calling fetch and unpack manually is for when message sending and response handling need to happen in different contexts/threads. """ + # Note: This call is synchronous so that the first part of it can + # happen synchronously. If the whole call were async we wouldn't be + # able to guarantee that messages sent in order would actually go + # out in order. if ( self._send_async_raw_message_call is None and self._send_async_raw_message_ex_call is None @@ -208,14 +238,42 @@ class MessageSender: msg_encoded = self._encode_message(bound_obj, message) try: if self._send_async_raw_message_ex_call is not None: - response_encoded = await self._send_async_raw_message_ex_call( + send_awaitable = self._send_async_raw_message_ex_call( bound_obj, msg_encoded, message ) else: assert self._send_async_raw_message_call is not None - response_encoded = await self._send_async_raw_message_call( + send_awaitable = self._send_async_raw_message_call( bound_obj, msg_encoded ) + except Exception as exc: + return self._error_awaitable(exc) + + # Now return an awaitable to finish the job. + return self._fetch_raw_response_awaitable( + bound_obj, message, send_awaitable + ) + + async def _error_awaitable(self, exc: Exception) -> SysResponse: + response = ErrorSysResponse( + error_message='Error in MessageSender @send_async_method.', + error_type=( + ErrorSysResponse.ErrorType.COMMUNICATION + if isinstance(exc, CommunicationError) + else ErrorSysResponse.ErrorType.LOCAL + ), + ) + # Can include the actual exception since we'll be looking at + # this locally; might be helpful. + response.set_local_exception(exc) + return response + + async def _fetch_raw_response_awaitable( + self, bound_obj: Any, message: Message, send_awaitable: Awaitable[str] + ) -> Response | SysResponse: + + try: + response_encoded = await send_awaitable except Exception as exc: response = ErrorSysResponse( error_message='Error in MessageSender @send_async_method.', @@ -378,23 +436,23 @@ class BoundMessageSender: assert self._obj is not None return self._sender.send(bound_obj=self._obj, message=message) - async def send_async_untyped(self, message: Message) -> Response | None: + def send_async_untyped( + self, message: Message + ) -> Awaitable[Response | None]: """Send a message asynchronously. Whenever possible, use the send_async() call provided by generated subclasses instead of this; it will provide better type safety. """ assert self._obj is not None - return await self._sender.send_async( - bound_obj=self._obj, message=message - ) + return self._sender.send_async(bound_obj=self._obj, message=message) - async def fetch_raw_response_async_untyped( + def fetch_raw_response_async_untyped( self, message: Message - ) -> Response | SysResponse: + ) -> Awaitable[Response | SysResponse]: """Split send (part 1 of 2).""" assert self._obj is not None - return await self._sender.fetch_raw_response_async( + return self._sender.fetch_raw_response_async( bound_obj=self._obj, message=message ) diff --git a/tools/efro/rpc.py b/tools/efro/rpc.py index 4fe7e639..fad19124 100644 --- a/tools/efro/rpc.py +++ b/tools/efro/rpc.py @@ -323,12 +323,12 @@ class RPCEndpoint: if self.debug_print: self.debug_print_call(f'{self._label}: finished.') - async def send_message( + def send_message( self, message: bytes, timeout: float | None = None, close_on_error: bool = True, - ) -> bytes: + ) -> Awaitable[bytes]: """Send a message to the peer and return a response. If timeout is not provided, the default will be used. @@ -340,7 +340,10 @@ class RPCEndpoint: respect to a given endpoint. Pass close_on_error=False to override this for a particular message. """ - # pylint: disable=too-many-branches + # Note: This call is synchronous so that the first part of it + # (enqueueing outgoing messages) happens synchronously. If it were + # a pure async call it could be possible for send order to vary + # based on how the async tasks get processed. if self.debug_print_io: self.debug_print_call( @@ -358,16 +361,6 @@ class RPCEndpoint: f'{self._label}: have peerinfo? {self._peer_info is not None}.' ) - # We need to know their protocol, so if we haven't gotten a handshake - # from them yet, just wait. - while self._peer_info is None: - await asyncio.sleep(0.01) - assert self._peer_info is not None - - if self._peer_info.protocol == 1: - if len(message) > 65535: - raise RuntimeError('Message cannot be larger than 65535 bytes') - # message_id is a 16 bit looping value. message_id = self._next_message_id self._next_message_id = (self._next_message_id + 1) % 65536 @@ -420,8 +413,35 @@ class RPCEndpoint: if timeout is None: timeout = self.DEFAULT_MESSAGE_TIMEOUT assert timeout is not None + + bytes_awaitable = msgobj.wait_task + + # Now complete the send asynchronously. + return self._send_message( + message, timeout, close_on_error, bytes_awaitable, message_id + ) + + async def _send_message( + self, + message: bytes, + timeout: float | None, + close_on_error: bool, + bytes_awaitable: asyncio.Task[bytes], + message_id: int, + ) -> bytes: + + # We need to know their protocol, so if we haven't gotten a handshake + # from them yet, just wait. + while self._peer_info is None: + await asyncio.sleep(0.01) + assert self._peer_info is not None + + if self._peer_info.protocol == 1: + if len(message) > 65535: + raise RuntimeError('Message cannot be larger than 65535 bytes') + try: - return await asyncio.wait_for(msgobj.wait_task, timeout=timeout) + return await asyncio.wait_for(bytes_awaitable, timeout=timeout) except asyncio.CancelledError as exc: # Question: we assume this means the above wait_for() was # cancelled; how do we distinguish between this and *us* being @@ -449,7 +469,7 @@ class RPCEndpoint: ) # Stop waiting on the response. - msgobj.wait_task.cancel() + bytes_awaitable.cancel() # Remove the record of this message. del self._in_flight_messages[message_id] From 6e799e76444cc4a00ec20bea84cbe50a1b2a1e92 Mon Sep 17 00:00:00 2001 From: Eric Date: Tue, 17 Jan 2023 13:45:09 -0800 Subject: [PATCH 26/26] version bump --- .efrocachemap | 40 +++++++++---------- .idea/dictionaries/ericf.xml | 2 + CHANGELOG.md | 4 +- assets/src/ba_data/python/ba/_bootstrap.py | 2 +- .../.idea/dictionaries/ericf.xml | 2 + src/ballistica/ballistica.cc | 4 +- 6 files changed, 30 insertions(+), 24 deletions(-) diff --git a/.efrocachemap b/.efrocachemap index 49d8de4a..b2a4ef26 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -4008,26 +4008,26 @@ "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/93/f0/feed13859ce5e9ea067b0e0529ff", - "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/0d/88/056f8877eb83cfa87fb581d09a52", - "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/f3/1f/14bf78a27530eec8d30e54392788", - "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/d5/f9/9acf2f6b0a04f122d937b671337b", - "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/21/b5/65486e588021c5a551a7faf60490", - "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/4f/3f/39a86bf3e6556628bac7e038eb51", - "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/6c/6f/7efeb16dffd3f1e205feb2ce99fa", - "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/21/e5/6e5bcfbf995ae8579638fc5d1488", - "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/a0/7c/7a09ecb3beedfa91cde84e964bb9", - "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/5a/fa/8491b8dac79d172c33747862e77f", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/4c/8f/90292472906d259c86c8a38bcbc7", - "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/18/c3/92d5a2465283e17bcf7af2bf26e8", - "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/f2/4a/222725049d0619e8c8d97e60d079", - "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/60/e4/d6798a2d698da031a1f97b2fd008", - "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/4e/96/d35f6076e1e01b7a959df4379b76", - "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/f9/56/d0f8e1eb5f17c33a99ee032a42ff", - "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/e6/fc/95cab0bca71d81826a30b7621852", - "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/99/93/23154000c5d940cd943deed2692f", - "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/ae/5b/3ccd55688d48429a7d2a4bd32919", - "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/ac/ef/5ed349d3c42d58a98a79c94404b0", + "build/prefab/full/linux_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/a2/53/595db696c112a17513214a62eee7", + "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/27/db/57461eaa99ad29c86aab36b26a82", + "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/63/39/ad16cba9e1efb90fb90ae4d564d2", + "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/53/1e/40e9ac482c8d04a56e340100fba6", + "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/52/6c/5cf1aa6b12d251faea83d2f63377", + "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/65/91/1e7e14afff621cb2070644f57bbc", + "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/0e/81/2cd5d6fbe320802b90d81768bd73", + "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/9a/02/d7393257500edfd7879baeea431d", + "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/96/a2/6d45db766e7299b743156cce615b", + "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/52/b8/99e7cb5fa71615795f272ed2c518", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/5b/c7/6d474e85577975383f1ae1fc7377", + "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/a1/df/9bd1a6b76c8bf77917753959195f", + "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/cb/da/9d073b52363b6bc0240fe5e79bf1", + "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/c9/23/7060ae125ba189320190b321d947", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/0f/43/49d1bee57cb412e0b7ba59dd9769", + "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/e0/38/826f664787217ca44d569a5723d7", + "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/36/57/0c4fc5b9294b04a312ccd8832254", + "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/98/90/f34fd62f7d512cffd3c9534da10b", + "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/cb/a5/5d01935a74a86efcf1885975cfbf", + "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/c7/78/a8765f7463f3651c71cd5ca71cb6", "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/cb/3b/83e6150eebf4fa7b5e8a7b863219", "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/44/70/2878a73f2d55849cd6a75e401575", "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/24/49/4baca475df5c7f87e6ed17d46696", diff --git a/.idea/dictionaries/ericf.xml b/.idea/dictionaries/ericf.xml index 4b9e6319..5f3cb01c 100644 --- a/.idea/dictionaries/ericf.xml +++ b/.idea/dictionaries/ericf.xml @@ -115,6 +115,7 @@ appmode appname appnameupper + appnow appspot appstate appstore @@ -731,6 +732,7 @@ eaddrnotavail easteregghunt echofile + echotime edcc editcontroller editgame diff --git a/CHANGELOG.md b/CHANGELOG.md index f86ca1d1..b84d61d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,6 @@ -### 1.7.18 (build 20991, api 7, 2023-01-17) +### 1.7.19 (build 20993, api 7, 2023-01-17) + +### 1.7.18 (build 20989, api 7, 2023-01-16) - Reworked some low level asynchronous messaging functionality in efro.message and efro.rpc. Previously these were a little *too* asynchronous which could lead to messages being received in a different order than they were sent, which is not desirable. - Added a way to suppress 'Your build is outdated' messages at launch (see `ba._hooks.show_client_too_old_error()`). diff --git a/assets/src/ba_data/python/ba/_bootstrap.py b/assets/src/ba_data/python/ba/_bootstrap.py index 4d616449..48f599b4 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 = 20991 + expected_build = 20993 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 2e0ef135..21191a9c 100644 --- a/ballisticacore-cmake/.idea/dictionaries/ericf.xml +++ b/ballisticacore-cmake/.idea/dictionaries/ericf.xml @@ -72,6 +72,7 @@ appconfig appname appnameupper + appnow appspot appstate apptime @@ -395,6 +396,7 @@ dynamicdata echidna echofile + echotime edef effmult efro diff --git a/src/ballistica/ballistica.cc b/src/ballistica/ballistica.cc index 757e253f..b4c024ee 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 = 20991; -const char* kAppVersion = "1.7.18"; +const int kAppBuildNumber = 20993; +const char* kAppVersion = "1.7.19"; // Our standalone globals. // These are separated out for easy access.