Work on android and detecting network problems

This commit is contained in:
Eric Froemling 2022-07-05 14:59:10 -07:00
parent d58ab12bc4
commit ea67658558
No known key found for this signature in database
GPG Key ID: 89C93F0F8D6D5A98
19 changed files with 247 additions and 119 deletions

View File

@ -420,18 +420,18 @@
"assets/build/ba_data/audio/zoeOw.ogg": "https://files.ballistica.net/cache/ba1/dc/d2/160fc27fcaff10793327ac2c70fd",
"assets/build/ba_data/audio/zoePickup01.ogg": "https://files.ballistica.net/cache/ba1/11/7a/87d6bca0acfb877fd4fd8fe3a598",
"assets/build/ba_data/audio/zoeScream01.ogg": "https://files.ballistica.net/cache/ba1/44/f5/c943c9075abb3e1835d2408a1ef8",
"assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/c4/e7/432f66c84194bd6d04ecc485e308",
"assets/build/ba_data/data/languages/arabic.json": "https://files.ballistica.net/cache/ba1/4c/fd/67a9dcdecb85dbaf549a8fbbdc78",
"assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/9d/0a/e98c8e794fe9cd741b5f8e5642c7",
"assets/build/ba_data/data/languages/arabic.json": "https://files.ballistica.net/cache/ba1/db/6a/02249b1d9bdc66f603a33e91d118",
"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/32/a7/b9208ab804dfe2d1c3960256e9f8",
"assets/build/ba_data/data/languages/chinese.json": "https://files.ballistica.net/cache/ba1/18/7f/03acf6a5fcc9d3958f9746eadaf4",
"assets/build/ba_data/data/languages/chinesetraditional.json": "https://files.ballistica.net/cache/ba1/61/e6/caf06ce99017fdf5d2da0c038445",
"assets/build/ba_data/data/languages/croatian.json": "https://files.ballistica.net/cache/ba1/f5/d4/683ef2d47b669e5f177bc1ae4ff0",
"assets/build/ba_data/data/languages/czech.json": "https://files.ballistica.net/cache/ba1/87/84/9f3d39610453b3bf350698a23316",
"assets/build/ba_data/data/languages/danish.json": "https://files.ballistica.net/cache/ba1/3f/46/e4da3c1d2b0ebf916df55c608b28",
"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/b9/72/96f5843dffe76fd16fa691845497",
"assets/build/ba_data/data/languages/english.json": "https://files.ballistica.net/cache/ba1/2c/41/2c43429b95bef4e88fc279071470",
"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/f8/ac/ade62ff2a8c13550f56c918d55fb",
"assets/build/ba_data/data/languages/filipino.json": "https://files.ballistica.net/cache/ba1/4b/d5/7c877f9550c0154c52f410b93315",
"assets/build/ba_data/data/languages/french.json": "https://files.ballistica.net/cache/ba1/b6/e0/37dd30b686f475733ccc4b3cab49",
"assets/build/ba_data/data/languages/german.json": "https://files.ballistica.net/cache/ba1/c0/26/04875251b9237f3133c84a910afd",
"assets/build/ba_data/data/languages/gibberish.json": "https://files.ballistica.net/cache/ba1/6b/f3/5ca25b080c7f04403ffd1c918787",
@ -439,22 +439,22 @@
"assets/build/ba_data/data/languages/hindi.json": "https://files.ballistica.net/cache/ba1/08/3b/68cea4d16f7020d932829af85323",
"assets/build/ba_data/data/languages/hungarian.json": "https://files.ballistica.net/cache/ba1/b0/48/e1ebe08bfdfc94fcb61a16b851e5",
"assets/build/ba_data/data/languages/indonesian.json": "https://files.ballistica.net/cache/ba1/75/70/e33e6ee95830052e8f36cd2135f7",
"assets/build/ba_data/data/languages/italian.json": "https://files.ballistica.net/cache/ba1/94/2d/4f17fc4b73260e99453ee3122c0c",
"assets/build/ba_data/data/languages/italian.json": "https://files.ballistica.net/cache/ba1/f3/11/d81cc9f0c76b81b0b8dcf64fe292",
"assets/build/ba_data/data/languages/korean.json": "https://files.ballistica.net/cache/ba1/07/37/ab65ccee3a555bd40e9661860c58",
"assets/build/ba_data/data/languages/persian.json": "https://files.ballistica.net/cache/ba1/02/ab/e310f81582b6dc2ae93348d45166",
"assets/build/ba_data/data/languages/polish.json": "https://files.ballistica.net/cache/ba1/76/be/84e567de0aabd9f9145b62179c2c",
"assets/build/ba_data/data/languages/portuguese.json": "https://files.ballistica.net/cache/ba1/e2/cd/8738b4ac572fc3f98714a4a4be67",
"assets/build/ba_data/data/languages/romanian.json": "https://files.ballistica.net/cache/ba1/c9/5c/ccbae41f2baa11599563b4aabe00",
"assets/build/ba_data/data/languages/russian.json": "https://files.ballistica.net/cache/ba1/8c/a7/1dea3643720ced9fa40a0b3d1add",
"assets/build/ba_data/data/languages/portuguese.json": "https://files.ballistica.net/cache/ba1/fa/21/62f7d0885c1ddf8cbdaf13a46685",
"assets/build/ba_data/data/languages/romanian.json": "https://files.ballistica.net/cache/ba1/20/35/19ab623ce299a61e325f2ac5354b",
"assets/build/ba_data/data/languages/russian.json": "https://files.ballistica.net/cache/ba1/92/a7/a6d22213dd30f5f57919d6cc2e94",
"assets/build/ba_data/data/languages/serbian.json": "https://files.ballistica.net/cache/ba1/13/19/828be486951be254445263f36c6e",
"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/b3/a3/3e1befdc621a503219fa78ba6d8b",
"assets/build/ba_data/data/languages/spanish.json": "https://files.ballistica.net/cache/ba1/a3/20/bf03c91445f7083378d55a476415",
"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/75/b3/c344f382251cb7e696bedb712421",
"assets/build/ba_data/data/languages/tamil.json": "https://files.ballistica.net/cache/ba1/9a/7f/39c9ac42c22776a65e59503b189e",
"assets/build/ba_data/data/languages/thai.json": "https://files.ballistica.net/cache/ba1/9d/51/f699dbd4beb88bc3cff699a287a7",
"assets/build/ba_data/data/languages/turkish.json": "https://files.ballistica.net/cache/ba1/6f/2e/20bed8fefb23ca42c18a7b6c75b2",
"assets/build/ba_data/data/languages/turkish.json": "https://files.ballistica.net/cache/ba1/d3/41/bef1112708d7ee012c7187967dcd",
"assets/build/ba_data/data/languages/ukrainian.json": "https://files.ballistica.net/cache/ba1/7f/bb/6239adeb551be5e09f3457d7b411",
"assets/build/ba_data/data/languages/venetian.json": "https://files.ballistica.net/cache/ba1/d9/97/e3ec72c08fcaeb2f69569c20f085",
"assets/build/ba_data/data/languages/venetian.json": "https://files.ballistica.net/cache/ba1/68/77/cc871b6ed611cb8d6f74cf1a9d00",
"assets/build/ba_data/data/languages/vietnamese.json": "https://files.ballistica.net/cache/ba1/f2/af/afd1503c7a10cacaa15bc02369b2",
"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",
@ -3992,50 +3992,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/b2/e5/0ee0561e16257a32830645239f34",
"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/14/32/34006cd68ca39d27add8c36839a9",
"build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/f9/27/943498c90fd48490581721549831",
"build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/99/ee/a7e516ce3d295c32a9fae1f61837",
"build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/33/1c/c84d7e2f9108787614e8fa47b178",
"build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/66/ca/89977fb3b87de266a9da81655879",
"build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/50/ed/fa670d5646074507df2bd11cc9f3",
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/5d/e1/7dde73d49d729d4ad722d7042821",
"build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/3a/57/a994445b5ba27e8b21df9218f05f",
"build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/3b/db/742462576b3e78cc42cbe8c15b4d",
"build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/98/52/3dd887570176346b2b0a9c40658e",
"build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/ad/26/9bc36871955e6bafc5a5c6f21e74",
"build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/5e/94/f021148e84ed3ba2997c51c701bf",
"build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/2b/11/63ecf6112d1a3ea71ee31c192d32",
"build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/ae/5a/bc6c4c10a64fb230edb1d16ec0e7",
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/76/ce/ba8b95c2ea1fbef5ee6fc22fc421",
"build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/bf/b3/6b576d8587719ec0f9dcdc851613",
"build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/a6/25/6c769b43530cc0f5870fde6b01f4",
"build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/4f/b2/915fa6ee32e67839fdab20b20e9f",
"build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/54/a0/02d658b28cee638eb2587e5800af",
"build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/e7/56/3aa98841dab173ddfe3e4c7dd19e",
"build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/3f/60/5fb1cb5bd1ee656517914df2eb26",
"build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/95/92/1bac3bcac3e1f71417b7ff053b52",
"build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/54/55/b16bb20de7c3ab30311e73707e17",
"build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/6d/79/9b588be3e8d74c8c8bd761899be5",
"build/prefab/lib/linux_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/e2/17/168f29b83ee04a412c0fa402258b",
"build/prefab/lib/linux_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a5/60/8d865d088dbc8d34d739b2c16fee",
"build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/38/4d/101a78df34eada8ffa73636cd178",
"build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/54/4b/4f8648af8ea56398da8b56babffa",
"build/prefab/lib/mac_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/3a/08/e5955806784ca0dbc2e9e679136a",
"build/prefab/lib/mac_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/e2/7c/6d600a764587eb8d74b9701fe73f",
"build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/96/4f/a761ffd6cbcc9d19015e8a2ebbd2",
"build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/4a/18/c94f7cf05127e82cd71f46dc7dd6",
"build/prefab/lib/mac_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/39/d1/0bd6a2cf0f447642d8e58b538243",
"build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/bc/c0/1230a5a3ff3786fc335b57800324",
"build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/b5/7f/0e2c1cf8683876727192587148ac",
"build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/fe/04/375a70cb1510e2ec904a8d413a84",
"build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/09/77/21bbba5f4a88b3534e133dc156d5",
"build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/72/95/fc9be2f3b29b4bcc19079269d4b3",
"build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/19/d8/d2728c0e48b220b7c20e2690ecae",
"build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/07/d6/d4305dab6a066c0a1459efcec85e",
"build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/75/26/dc45c1c15b7727a013fd98ce1796",
"build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/ee/39/9498eb5c1103b27df3454b52ba98",
"build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/61/b1/3ab8780ac812d4cdedf19f504aaa",
"build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/43/90/175c959c383fe983a614f92b6dec",
"build/prefab/full/linux_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/70/3b/0c7d541b3856884a747ff4606125",
"build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/af/8b/9191ae1c05ed11d77bf9099abdaf",
"build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/8f/88/e96a5cf5728280557a229c3cd196",
"build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/40/8c/e3932b01bfb03bf3d930fa6b0075",
"build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/4e/dd/cceaa79ecc33d116254129115ab6",
"build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/bc/d5/2992911e42d4019062a5ee7922be",
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/2d/75/b81d14e56fac5cb36204b99d438b",
"build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/bd/35/af73fd25f90b260a7e1f2b45604a",
"build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/a4/b9/2d9d7fdf7f8fc36a395396c17396",
"build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/ac/ec/cbd0cd6b30ffc5e9899df476ff75",
"build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/fb/db/28557fffa11dc30193dfdf2bc1cc",
"build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/cb/34/83e11c5a79dcb4a925b05a65741c",
"build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/d5/12/cd06cac7c7bb070397da839850df",
"build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/da/87/5df008ea5c203eb4a97bfa9648fe",
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/93/ca/2afe9fc10c37c16a91a556350be0",
"build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/19/cc/c1bb1e323387f590c3ad649cf2b1",
"build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/a0/31/1f941c66e9290a4ae69f5f4b0aa4",
"build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/74/15/89bb4aa1472f0848808b215fbab6",
"build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/25/a3/4c7334e53c11997b7cf292c96da8",
"build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/64/e0/f9f926a34c2e0243419b20a28138",
"build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/11/a6/7db8addcd876b1933e16f380696a",
"build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/c7/8a/3d8501efecca4f20b9702d24f9db",
"build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/74/fb/8ba0b3bddf4e0f1184a68e648959",
"build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/24/ab/393d381b77a85cdbba6c47d8a67a",
"build/prefab/lib/linux_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/da/23/026d70f770273a92def633d57935",
"build/prefab/lib/linux_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/35/e8/37eeb762bbae9daffae6d5d69b7e",
"build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/3a/6b/0e26e2ab6eab60258ddcab0601fd",
"build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/70/38/7ff58456d824e3461c6a1a3f3f5a",
"build/prefab/lib/mac_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/10/39/9501e3afd9a1a0af817989e18c7d",
"build/prefab/lib/mac_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/42/f6/e8943073f00d93b2e2cd1822916a",
"build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/67/82/220d9a12ed10c885aadc02b9919b",
"build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/3f/c5/dc64be0a0f9d09630074e630312b",
"build/prefab/lib/mac_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/f2/5f/e75027e1f6f31fae1f1d20a8b2ee",
"build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/1d/11/18a94007cbcaf2e10c46fc367f7a",
"build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/51/a8/414d1a0ad00982cd961f0a29a501",
"build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/4b/0c/26593bd6f6191a19531ce1dd492b",
"build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/62/9e/e8679467880812a2a31266704517",
"build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/56/f1/af68b9666c2ce5038b813719c458",
"build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/d2/a9/9087249ba5a8873f59503a7cb3e4",
"build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/fd/3f/57f64be3b335dbbe0f261edf0861",
"build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/8b/cf/cc26378a8800b0efd14455e7f6b5",
"build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/64/34/18f21d11fda7f1472e0212169904",
"build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/24/71/93680835ec6af90acf9d4e2fd63f",
"build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/af/ae/86b7f88249a684530c6d30831889",
"src/ballistica/generated/python_embedded/binding.inc": "https://files.ballistica.net/cache/ba1/6e/6f/004b696e9a13b083069374e4bb6a",
"src/ballistica/generated/python_embedded/bootstrap.inc": "https://files.ballistica.net/cache/ba1/d3/db/e73d4dcf1280d5f677c3cf8b47c3"
}

View File

@ -1,4 +1,4 @@
### 1.7.3 (20627, 2022-07-01)
### 1.7.3 (20629, 2022-07-05)
- Fixed an issue with King of the Hill flag regions not working when players entered them (Thanks itsre3!)
- Fixed an issue in Chosen One where the flag resetting on top of a player would not cause them to become the chosen one (Thanks Dliwk!)
- Fixed an issue where triple-bomb powerup would not flash before wearing off (Thanks Juleskie!).
@ -7,6 +7,14 @@
- The app now issues a gentle notice if plugins are removed instead of erroring and continuing to look for them on subsequent launches. This makes things much smoother when switching between workspaces or users.
- Added new translation entries for Workspace/Plugin stuff.
- tools/bacloud workspace get/put commands are now functional (wiki page with instructions coming soon).
- `_ba.android_get_external_storage_path` is now `_ba.android_get_external_files_dir` which maps to the actual call it makes under the hood these days.
- Android logging now breaks up long entries such as stack-traces into multiple log entries so they should not get truncated.
- The app now issues a warning if device time varies significantly from actual world time. This can lead to things like the app incorrectly treating SSL certificates as not yet valid and network functionality failing.
- The app now issues a warning if unable to establish secure connections to cloud servers (which can be due to aforementioned issue, but could also stem from other network problems).
- The Network Testing utility (Settings->Advanced->Network Testing) now tests for more potential issues including ones mentioned above.
- The Android version now stores files such as extracted assets and audio caches in the non-backed-up files dir (Android's Context.getNoBackupFilesDir()). These files can always be recreated by the app so they don't need backups, and this makes it more likely that Android will back up what's left in the regular files dir (the app config, etc).
### 1.7.2 (20620, 2022-06-25)
- Minor fixes in some minigames (Thanks Droopy!)

View File

@ -11,6 +11,8 @@ from __future__ import annotations
from typing import TYPE_CHECKING
import asyncio
import logging
import time
if TYPE_CHECKING:
import ba
@ -53,7 +55,17 @@ def setup_asyncio() -> asyncio.AbstractEventLoop:
def run_cycle() -> None:
assert _asyncio_event_loop is not None
_asyncio_event_loop.call_soon(_asyncio_event_loop.stop)
starttime = time.monotonic()
_asyncio_event_loop.run_forever()
endtime = time.monotonic()
# We'd like to keep the app running at a smooth 120hz, so
# complain if we're taking more than half that time per update.
warn_time = 1.0 / 240
duration = endtime - starttime
if duration > warn_time:
logging.warning('Asyncio loop step took %.4fs; ideal max is %.4f',
duration, warn_time)
global _asyncio_timer # pylint: disable=invalid-name
_asyncio_timer = _ba.Timer(1.0 / 30.0,

View File

@ -56,6 +56,14 @@ class CloudSubsystem:
) -> None:
...
@overload
def send_message_cb(
self,
msg: bacommon.cloud.PingMessage,
on_response: Callable[[bacommon.cloud.PingResponse | Exception], None],
) -> None:
...
def send_message_cb(
self,
msg: Message,

View File

@ -211,7 +211,7 @@ class MusicSubsystem:
return 'Mac' in uas
if entry_type in ('musicFile', 'musicFolder'):
return ('android' in uas
and _ba.android_get_external_storage_path() is not None)
and _ba.android_get_external_files_dir() is not None)
if entry_type == 'default':
return True
return False

View File

@ -29,7 +29,7 @@ class NetworkSubsystem:
# as it is updated by a background thread.
self.zone_pings_lock = threading.Lock()
# Region IDs mapped to average pings. This will remain empty
# Zone IDs mapped to average pings. This will remain empty
# until enough pings have been run to be reasonably certain
# that a nearby server has been pinged.
self.zone_pings: dict[str, float] = {}
@ -37,6 +37,7 @@ class NetworkSubsystem:
# For debugging.
self.v1_test_log: str = ''
self.v1_ctest_results: dict[int, str] = {}
self.server_time_offset_hours: float | None = None
def get_ip_address_type(addr: str) -> socket.AddressFamily:

View File

@ -112,10 +112,11 @@ class PluginSubsystem:
# or workspaces.
if disappeared_plugs:
_ba.playsound(_ba.getsound('shieldDown'))
_ba.screenmessage(Lstr(resource='pluginsRemovedText',
subs=[('${NUM}',
str(len(disappeared_plugs)))]),
color=(1, 1, 0))
_ba.screenmessage(
Lstr(resource='pluginsRemovedText',
subs=[('${NUM}', str(len(disappeared_plugs)))]),
color=(1, 1, 0),
)
_ba.log(
f'{len(disappeared_plugs)} plugin(s) no longer found:'
f' {disappeared_plugs}',

View File

@ -27,8 +27,7 @@ def get_human_readable_user_scripts_path() -> str:
# only visible to the user's processes and thus not really useful printed
# in its entirety; lets print it as <External Storage>/myfilepath.
if app.platform == 'android':
ext_storage_path: str | None = (
_ba.android_get_external_storage_path())
ext_storage_path: str | None = (_ba.android_get_external_files_dir())
if (ext_storage_path is not None
and app.python_directory_user.startswith(ext_storage_path)):
path = ('<' +

View File

@ -10,6 +10,7 @@ import weakref
from threading import Thread
from typing import TYPE_CHECKING
from efro.error import CleanError
import _ba
import ba
from bastd.ui.settings.testing import TestingWindow
@ -148,10 +149,12 @@ def _run_diagnostics(weakwin: weakref.ref[NetTestingWindow]) -> None:
call()
duration = time.monotonic() - starttime
_print(f'Succeeded in {duration:.2f}s.', color=(0, 1, 0))
except Exception:
except Exception as exc:
import traceback
duration = time.monotonic() - starttime
_print(traceback.format_exc(), color=(1.0, 1.0, 0.3))
msg = (str(exc)
if isinstance(exc, CleanError) else traceback.format_exc())
_print(msg, color=(1.0, 1.0, 0.3))
_print(f'Failed in {duration:.2f}s.', color=(1, 0, 0))
have_error[0] = True
@ -193,6 +196,9 @@ def _run_diagnostics(weakwin: weakref.ref[NetTestingWindow]) -> None:
_print(f'\nContacting V2 master-server ({baseaddr})...')
_print_test_results(lambda: _test_fetch(baseaddr))
_print('\nComparing local time to V2 server...')
_print_test_results(_test_v2_time)
# Get V2 nearby zone
with ba.app.net.zone_pings_lock:
zone_pings = copy.deepcopy(ba.app.net.zone_pings)
@ -206,6 +212,9 @@ def _run_diagnostics(weakwin: weakref.ref[NetTestingWindow]) -> None:
_print(f'\nChecking nearest V2 zone ping ({nearstr})...')
_print_test_results(lambda: _test_nearby_zone_ping(nearest_zone))
_print('\nSending V2 cloud message...')
_print_test_results(_test_v2_cloud_message)
if have_error[0]:
_print('\nDiagnostics complete. Some diagnostics failed.',
color=(10, 0, 0))
@ -271,6 +280,58 @@ def _test_v1_transaction() -> None:
raise RuntimeError(results[0])
def _test_v2_cloud_message() -> None:
from dataclasses import dataclass
import bacommon.cloud
@dataclass
class _Results:
errstr: str | None = None
send_time: float | None = None
response_time: float | None = None
results = _Results()
def _cb(response: bacommon.cloud.PingResponse | Exception) -> None:
# Note: this runs in another thread so need to avoid exceptions.
results.response_time = time.monotonic()
if isinstance(response, Exception):
results.errstr = str(response)
if not isinstance(response, bacommon.cloud.PingResponse):
results.errstr = f'invalid response type: {type(response)}.'
def _send() -> None:
# Note: this runs in another thread so need to avoid exceptions.
results.send_time = time.monotonic()
ba.app.cloud.send_message_cb(bacommon.cloud.PingMessage(), _cb)
# This stuff expects to be run from the logic thread.
ba.pushcall(_send, from_other_thread=True)
wait_start_time = time.monotonic()
while True:
if results.response_time is not None:
break
time.sleep(0.01)
if time.monotonic() - wait_start_time > 10.0:
raise RuntimeError('Timeout waiting for cloud message response')
if results.errstr is not None:
raise RuntimeError(results.errstr)
def _test_v2_time() -> None:
offset = ba.app.net.server_time_offset_hours
if offset is None:
raise RuntimeError('no time offset found;'
' perhaps unable to communicate with v2 server?')
if abs(offset) >= 2.0:
raise CleanError(
f'Your device time is off from world time by {offset:.1f} hours.\n'
'This may cause network operations to fail due to your device\n'
' incorrectly treating SSL certificates as not-yet-valid, etc.\n'
'Check your device time and time-zone settings to fix this.\n')
def _test_fetch(baseaddr: str) -> None:
# pylint: disable=consider-using-with
import urllib.request

View File

@ -160,7 +160,7 @@ class SoundtrackEntryTypeSelectWindow(ba.Window):
from ba.osmusic import OSMusicPlayer
from bastd.ui.fileselector import FileSelectorWindow
ba.containerwidget(edit=self._root_widget, transition='out_left')
base_path = _ba.android_get_external_storage_path()
base_path = _ba.android_get_external_files_dir()
ba.app.ui.set_main_menu_window(
FileSelectorWindow(
base_path,
@ -173,7 +173,7 @@ class SoundtrackEntryTypeSelectWindow(ba.Window):
def _on_music_folder_press(self) -> None:
from bastd.ui.fileselector import FileSelectorWindow
ba.containerwidget(edit=self._root_widget, transition='out_left')
base_path = _ba.android_get_external_storage_path()
base_path = _ba.android_get_external_files_dir()
ba.app.ui.set_main_menu_window(
FileSelectorWindow(base_path,
callback=self._music_folder_selector_cb,

View File

@ -21,7 +21,7 @@
namespace ballistica {
// These are set automatically via script; don't modify them here.
const int kAppBuildNumber = 20627;
const int kAppBuildNumber = 20629;
const char* kAppVersion = "1.7.3";
// Our standalone globals.

View File

@ -269,13 +269,18 @@ auto Platform::GetUserPythonDirectory() -> std::string {
auto Platform::GetVolatileDataDirectory() -> std::string {
if (!made_volatile_data_dir_) {
volatile_data_dir_ = GetConfigDirectory() + BA_DIRSLASH + "vdata";
volatile_data_dir_ = GetDefaultVolatileDataDirectory();
MakeDir(volatile_data_dir_);
made_volatile_data_dir_ = true;
}
return volatile_data_dir_;
}
auto Platform::GetDefaultVolatileDataDirectory() -> std::string {
// By default, stuff this in a subdir under our config dir.
return GetConfigDirectory() + BA_DIRSLASH + "vdata";
}
auto Platform::GetAppPythonDirectory() -> std::string {
static bool checked_dir = false;
if (!checked_dir) {
@ -437,8 +442,8 @@ void Platform::MakeDir(const std::string& dir, bool quiet) {
}
}
auto Platform::GetExternalStoragePath() -> std::string {
throw Exception("GetExternalStoragePath() unimplemented");
auto Platform::AndroidGetExternalFilesDir() -> std::string {
throw Exception("AndroidGetExternalFilesDir() unimplemented");
}
auto Platform::DoGetUserPythonDirectory() -> std::string {
@ -708,7 +713,7 @@ auto Platform::GetKeyName(int keycode) -> std::string {
void Platform::CreateAuxiliaryModules() {
#if !BA_HEADLESS_BUILD
auto bg_dynamics_thread = new Thread(ThreadIdentifier::kBGDynamics);
auto* bg_dynamics_thread = new Thread(ThreadIdentifier::kBGDynamics);
g_app_globals->pausable_threads.push_back(bg_dynamics_thread);
#endif
#if !BA_HEADLESS_BUILD
@ -719,7 +724,7 @@ void Platform::CreateAuxiliaryModules() {
// Start listening for stdin commands (on platforms where that makes sense).
// Note: this thread blocks indefinitely for input so we don't add it to the
// pausable list.
auto std_input_thread = new Thread(ThreadIdentifier::kStdin);
auto* std_input_thread = new Thread(ThreadIdentifier::kStdin);
std_input_thread->AddModule<StdInputModule>();
g_std_input_module->PushBeginReadCall();
}
@ -1209,7 +1214,7 @@ auto Platform::GetBroadcastAddrs() -> std::vector<uint32_t> {
throw Exception();
#else
std::vector<uint32_t> addrs;
struct ifaddrs* ifaddr;
struct ifaddrs* ifaddr{};
if (getifaddrs(&ifaddr) != -1) {
int i = 0;
for (ifaddrs* ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next) {
@ -1252,7 +1257,7 @@ auto Platform::SetSocketNonBlocking(int sd) -> bool {
#endif
}
auto Platform::GetTicks() -> millisecs_t {
auto Platform::GetTicks() const -> millisecs_t {
return GetCurrentMilliseconds() - starttime_;
}

View File

@ -239,9 +239,6 @@ class Platform {
/// Are we running on fireTV hardware?
virtual auto IsRunningOnFireTV() -> bool;
/// Return the external storage path (currently only relevant on Android).
virtual auto GetExternalStoragePath() -> std::string;
// For enabling some special hardware optimizations for nvidia.
auto is_tegra_k1() const -> bool { return is_tegra_k1_; }
auto set_is_tegra_k1(bool val) -> void { is_tegra_k1_ = val; }
@ -276,6 +273,7 @@ class Platform {
const std::string& code) -> void;
virtual auto AndroidRefreshFile(const std::string& file) -> void;
virtual auto AndroidShowWifiSettings() -> void;
virtual auto AndroidGetExternalFilesDir() -> std::string;
#pragma mark PERMISSIONS -------------------------------------------------------
@ -462,7 +460,7 @@ class Platform {
// Return a monotonic time measurement in milliseconds since launch.
// To get a time value that is guaranteed to not jump around or go backwards,
// use ballistica::GetRealTime() (which is an abstraction around this).
auto GetTicks() -> millisecs_t;
auto GetTicks() const -> millisecs_t;
// A raw milliseconds value (not relative to launch time).
static auto GetCurrentMilliseconds() -> millisecs_t;
@ -552,8 +550,15 @@ class Platform {
virtual auto DoGetUserPythonDirectory() -> std::string;
/// Return the default config directory for this platform.
/// This will be used as the config dir if not overridden via command
/// line options, etc.
virtual auto GetDefaultConfigDirectory() -> std::string;
/// Return the default Volatile data dir for this platform.
/// This will be used as the volatile-data-dir if not overridden via command
/// line options/etc.
virtual auto GetDefaultVolatileDataDirectory() -> std::string;
/// Generate a random UUID string.
virtual auto GenerateUUID() -> std::string;

View File

@ -729,17 +729,17 @@ auto PyAndroidMediaScanFile(PyObject* self, PyObject* args, PyObject* keywds)
#pragma clang diagnostic push
#pragma ide diagnostic ignored "ConstantFunctionResult"
auto PyAndroidGetExternalStoragePath(PyObject* self, PyObject* args,
PyObject* keywds) -> PyObject* {
auto PyAndroidGetExternalFilesDir(PyObject* self, PyObject* args,
PyObject* keywds) -> PyObject* {
BA_PYTHON_TRY;
Platform::SetLastPyCall("android_get_external_storage_path");
Platform::SetLastPyCall("android_get_external_files_dir");
static const char* kwlist[] = {nullptr};
if (!PyArg_ParseTupleAndKeywords(args, keywds, "",
const_cast<char**>(kwlist))) {
return nullptr;
}
#if BA_OSTYPE_ANDROID
std::string path = g_platform->GetExternalStoragePath();
std::string path = g_platform->AndroidGetExternalFilesDir();
if (path.empty()) {
Py_RETURN_NONE;
} else {
@ -883,10 +883,9 @@ auto PythonMethodsSystem::GetMethods() -> std::vector<PyMethodDef> {
"Refreshes Android MTP Index for a file; use this to get file\n"
"modifications to be reflected in Android File Transfer."},
{"android_get_external_storage_path",
(PyCFunction)PyAndroidGetExternalStoragePath,
METH_VARARGS | METH_KEYWORDS,
"android_get_external_storage_path() -> str\n"
{"android_get_external_files_dir",
(PyCFunction)PyAndroidGetExternalFilesDir, METH_VARARGS | METH_KEYWORDS,
"android_get_external_files_dir() -> str\n"
"\n"
"(internal)\n"
"\n"

View File

@ -423,8 +423,8 @@ TEST_PROTOCOL = MessageProtocol(
0: _TResp1,
1: _TResp2,
},
trusted_sender=True,
log_remote_exceptions=False,
receiver_returns_stack_traces=True,
receiver_logs_exceptions=False,
)
# Represents an 'evolved' TEST_PROTOCOL (one extra message type added).
@ -440,8 +440,8 @@ TEST_PROTOCOL_B = MessageProtocol(
0: _TResp1,
1: _TResp2,
},
trusted_sender=True,
log_remote_exceptions=False,
receiver_returns_stack_traces=True,
receiver_logs_exceptions=False,
)
TEST_PROTOCOL_SINGLE = MessageProtocol(
@ -451,8 +451,8 @@ TEST_PROTOCOL_SINGLE = MessageProtocol(
response_types={
0: _TResp1,
},
trusted_sender=True,
log_remote_exceptions=False,
receiver_returns_stack_traces=True,
receiver_logs_exceptions=False,
)

View File

@ -76,6 +76,22 @@ class LoginProxyCompleteMessage(Message):
proxyid: Annotated[str, IOAttrs('p')]
@ioprepped
@dataclass
class PingMessage(Message):
"""Standard ping."""
@classmethod
def get_response_types(cls) -> list[type[Response]]:
return [PingResponse]
@ioprepped
@dataclass
class PingResponse(Response):
"""pong."""
@ioprepped
@dataclass
class TestMessage(Message):

View File

@ -4,6 +4,7 @@
from __future__ import annotations
import datetime
from typing import TYPE_CHECKING, Any, Annotated
from dataclasses import dataclass, field
@ -27,6 +28,9 @@ class ServerNodeEntry:
class ServerNodeQueryResponse:
"""A response to a query about server-nodes."""
# The current utc time on the master server.
time: Annotated[datetime.datetime, IOAttrs('t')]
# If present, something went wrong, and this describes it.
error: Annotated[str | None, IOAttrs('e', store_default=False)] = None

View File

@ -25,28 +25,40 @@ class MessageProtocol:
"""Wrangles a set of message types, formats, and response types.
Both endpoints must be using a compatible Protocol for communication
to succeed. To maintain Protocol compatibility between revisions,
all message types must retain the same id, message attr storage names must
not change, newly added attrs must have default values, etc.
all message types must retain the same id, message attr storage
names must not change, newly added attrs must have default values,
etc.
"""
def __init__(self,
message_types: dict[int, type[Message]],
response_types: dict[int, type[Response]],
preserve_clean_errors: bool = True,
log_remote_exceptions: bool = True,
trusted_sender: bool = False) -> None:
receiver_logs_exceptions: bool = True,
receiver_returns_stack_traces: bool = False) -> None:
"""Create a protocol with a given configuration.
Note that common response types are automatically registered
with (unchanging negative ids) so they don't need to be passed
explicitly (but can be if a different id is desired).
If 'preserve_clean_errors' is True, efro.error.CleanError errors
on the remote end will result in the same error raised locally.
All other Exception types come across as efro.error.RemoteError.
If 'preserve_clean_errors' is True, efro.error.CleanError
exceptions raised on the receiver end will result in a matching
CleanError raised back on the sender. All other Exception types
come across as efro.error.RemoteError.
If 'trusted_sender' is True, stringified remote stack traces will
be included in the responses if errors occur.
When 'receiver_logs_exceptions' is True, any uncaught Exceptions
on the receiver end will be logged there via logging.exception()
(in addition to the usual behavior of returning an ErrorResponse
to the sender). This is good to leave enabled if your
intention is to never return ErrorResponses. Looser setups
making routine use of CleanErrors or whatnot may want to
disable this, however.
If 'receiver_returns_stack_traces' is True, stringified stack
traces will be returned to the sender for exceptions occurring
on the receiver end. This can make debugging easier but should
only be used when the client is trusted to see such info.
"""
self.message_types_by_id: dict[int, type[Message]] = {}
self.message_ids_by_type: dict[type[Message], int] = {}
@ -102,9 +114,9 @@ class MessageProtocol:
assert is_ioprepped_dataclass(cls)
assert issubclass(cls, Response)
if cls not in self.response_ids_by_type:
raise ValueError(f'Possible response type {cls}'
f' needs to be included in response_types'
f' for this protocol.')
raise ValueError(
f'Possible response type {cls} needs to be included'
f' in response_types for this protocol.')
# Make sure all registered types have unique base names.
# We can take advantage of this to generate cleaner looking
@ -116,8 +128,8 @@ class MessageProtocol:
' all types are required to have unique names.')
self.preserve_clean_errors = preserve_clean_errors
self.log_remote_exceptions = log_remote_exceptions
self.trusted_sender = trusted_sender
self.receiver_logs_exceptions = receiver_logs_exceptions
self.receiver_returns_stack_traces = receiver_returns_stack_traces
@staticmethod
def encode_dict(obj: dict) -> str:
@ -134,7 +146,9 @@ class MessageProtocol:
def error_to_response(self, exc: Exception) -> Response:
"""Translate an error to a response."""
if self.log_remote_exceptions:
# Log any errors we got during handling if so desired.
if self.receiver_logs_exceptions:
logging.exception('Error handling message.')
# If anything goes wrong, return a ErrorResponse instead.
@ -142,8 +156,9 @@ class MessageProtocol:
return ErrorResponse(error_message=str(exc),
error_type=ErrorResponse.ErrorType.CLEAN)
return ErrorResponse(
error_message=(traceback.format_exc() if self.trusted_sender else
'An unknown error has occurred.'),
error_message=(traceback.format_exc()
if self.receiver_returns_stack_traces else
'An internal error has occurred.'),
error_type=ErrorResponse.ErrorType.OTHER)
def _to_dict(self, message: Any, ids_by_type: dict[type, int],

View File

@ -71,12 +71,6 @@ def build_apple(arch: str, debug: bool = False) -> None:
txt = readfile('Makefile')
# Fix a bug where spaces in PATH cause errors (darn you vmware fusion!)
txt = replace_exact(
txt,
'\t\tPATH=$(PROJECT_DIR)/$(PYTHON_DIR-macOS)/_install/bin:$(PATH)',
'\t\tPATH="$(PROJECT_DIR)/$(PYTHON_DIR-macOS)/_install/bin:$(PATH)"')
# Turn doc strings on; looks like it only adds a few hundred k.
txt = replace_exact(txt,
'--without-doc-strings',