diff --git a/.efrocachemap b/.efrocachemap index c5f35717..9a964e39 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -420,16 +420,16 @@ "assets/build/ba_data/audio/zoeOw.ogg": "https://files.ballistica.net/cache/ba1/51/eb/0a567253cc08c94c5d315a64d9af", "assets/build/ba_data/audio/zoePickup01.ogg": "https://files.ballistica.net/cache/ba1/bc/8f/a9c51a09c418136e386b7fdf21c7", "assets/build/ba_data/audio/zoeScream01.ogg": "https://files.ballistica.net/cache/ba1/02/e5/84916e123f47ccf11ddda380d699", - "assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/aa/52/0eb8b7da64db10e02b695a1806f6", + "assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/d9/3d/da829892fc4c495a6cdd51bbc4d0", "assets/build/ba_data/data/languages/arabic.json": "https://files.ballistica.net/cache/ba1/0f/e1/94378b32c786d5365a7810a15d73", "assets/build/ba_data/data/languages/belarussian.json": "https://files.ballistica.net/cache/ba1/55/8c/8d0a0585e434b94865ae4befc090", "assets/build/ba_data/data/languages/chinese.json": "https://files.ballistica.net/cache/ba1/db/e1/03b6c717e7e0eacb7bc29d3d4ae3", - "assets/build/ba_data/data/languages/chinesetraditional.json": "https://files.ballistica.net/cache/ba1/ff/7c/3bcab4ae1f39977434acb0d6f795", + "assets/build/ba_data/data/languages/chinesetraditional.json": "https://files.ballistica.net/cache/ba1/ef/c2/a607f318b815f025a20ab92f0a7b", "assets/build/ba_data/data/languages/croatian.json": "https://files.ballistica.net/cache/ba1/66/bf/6e98398016da261296b8c306560e", "assets/build/ba_data/data/languages/czech.json": "https://files.ballistica.net/cache/ba1/82/61/8319e81bc3fed77e8319a2fd6988", "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/97/90/39ba65c2ad714429aec82ea1ae3e", - "assets/build/ba_data/data/languages/english.json": "https://files.ballistica.net/cache/ba1/5a/63/382c2cd707cd34d232f28f45f5d3", + "assets/build/ba_data/data/languages/english.json": "https://files.ballistica.net/cache/ba1/99/2a/bdcfa0932cf73e5cf63fd8113b1b", "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/52/09/449a5ff97460b32cf13edfd1fdbc", "assets/build/ba_data/data/languages/french.json": "https://files.ballistica.net/cache/ba1/b6/e0/37dd30b686f475733ccc4b3cab49", @@ -439,9 +439,9 @@ "assets/build/ba_data/data/languages/hindi.json": "https://files.ballistica.net/cache/ba1/c2/f5/e7549f5179c22c6da97fafffc058", "assets/build/ba_data/data/languages/hungarian.json": "https://files.ballistica.net/cache/ba1/2d/e5/3737c6c3979cf381321c5472bea5", "assets/build/ba_data/data/languages/indonesian.json": "https://files.ballistica.net/cache/ba1/b1/81/d99fb5b8c368430944b357aa15fe", - "assets/build/ba_data/data/languages/italian.json": "https://files.ballistica.net/cache/ba1/d7/f0/436072225f713259eaa5fa39ba5d", + "assets/build/ba_data/data/languages/italian.json": "https://files.ballistica.net/cache/ba1/c7/16/e31ce16d1b4150c271401669f24f", "assets/build/ba_data/data/languages/korean.json": "https://files.ballistica.net/cache/ba1/d7/8b/acdfb39196be7856f8bad77eb6a0", - "assets/build/ba_data/data/languages/persian.json": "https://files.ballistica.net/cache/ba1/5b/77/f09dfde1b14ff978737c8935474a", + "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/04/fa/b24dd48bfbf3c2d67ee5ad1269c3", "assets/build/ba_data/data/languages/portuguese.json": "https://files.ballistica.net/cache/ba1/26/41/f1246ab56c6b7853f605c3a95889", "assets/build/ba_data/data/languages/romanian.json": "https://files.ballistica.net/cache/ba1/82/12/57bf144e12be229a9b70da9c45cb", @@ -3971,50 +3971,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/22/91/9788a455078b2c6ae6b0530b376f", + "build/prefab/full/linux_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/1a/f8/ad0c078b60b48e42c6338adf6593", "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/74/1d/fc9e33e565475daaac80da5252f0", - "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/c1/4b/87fc75b8f04952794a897fb19fc7", - "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/e3/66/afbe79ac0d6fbd593ec1e549d5c0", - "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/e4/73/d07113aab410b1c51090952bfafe", + "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/4f/56/2f420e3ff1dfbcbc27e9b6f8cab1", + "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/75/08/a3aa8a9b72b395427d80a799ce8a", + "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/c1/fd/cf7c98243cf9c09a60e53dcf5fea", "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/9c/7b/ac1a200be0f37078af0991faca3b", - "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/c2/7c/0c439110ac2fdbeb5548ad35632b", - "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/c1/41/fe950818630506df8fdfd04d674d", - "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/e4/a9/59db1426754a1c7716850c17be91", - "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/7e/c9/90e3afef7cc1aea9e11a252e3379", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/6d/f6/41fcb16519bb5257c337749a78ea", - "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/e3/f4/27e8aa597a15296c07cb77263451", - "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/35/0c/be285aa08f62ac2420126455357c", - "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/36/69/075a41d69723e230e9ae9ca0f6c7", - "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/09/f3/e81bb333811f848a056f2a2d4c92", - "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/8d/7b/e5d18bf5d8f78a9c2ac050f17979", - "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/5b/6d/1fcbd8637eb1c2d09a0ec042d2f9", - "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/04/85/c400c05b6b6ea1d41cff444f2608", - "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/07/1c/7c4e59c63f8a359c179a2a74a802", - "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/fe/37/e82e03fdf5b5396f975ab15cbc71", - "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/f9/29/302b9242929cb49edf898ed1ba7a", - "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ed/9d/dd639f3199ec5bc1caf901987ff4", - "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/d2/f5/848874824f57b67c5b6b3c6a2baa", - "build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/d8/c0/a522335c7ba3150af576bb7136a3", - "build/prefab/lib/linux_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/21/3d/75e919b2acd230c2f107f0a4776a", - "build/prefab/lib/linux_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ad/88/01e67d29156c38f2774cea30c188", - "build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/e0/a3/924f6b88737442fc0190ee6bfed7", - "build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/7e/96/52a2c78644879deb38677259fdaa", - "build/prefab/lib/mac_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/6a/45/47fa87fc676af9b738afd5a89fc7", - "build/prefab/lib/mac_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/47/17/eaffbc7ed2863ab398a23d5d247c", - "build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/8b/42/b133f6e102f69ae685ad5b3f87eb", - "build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/06/08/60a2858cb8760b8e5d5b24d525ad", - "build/prefab/lib/mac_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/43/76/21a77c1d04568338ee36e476dfb4", - "build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/9f/01/cfdeb633d83f043df25405c24e7b", - "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/27/09/8433d1e7e83d80223a47bb6e9e57", - "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/79/12/b247bac22dc3af4ade11f805901a", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/da/a3/75db770dd02eb2049fa84de64a3b", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/b4/e7/0e6c1bdc7b66093c5613dfbb5c5d", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/04/2d/0c5eb518b40c9c31cafad1bab5d5", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/42/f3/ac8ddc452b6380f902f3de61f180", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/58/c8/ab5043d41c6bd0d556e037cfca97", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/c6/16/a8a82b70227523b5ee154763468d", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/36/76/be5b138bcdefd00a033c657b004c", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/53/91/c294c4bd174ce28f2546dd9a57b4", + "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/f6/4b/555e3b9a9e2d86daed786e962cdc", + "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/ab/b9/5251e7cf19ce49426ed06abab235", + "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/c4/62/a30289b64948799104f09f5b523a", + "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/35/34/91df78166ea43e9d293bc9272575", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/6d/1d/7c362a4bc1e9e59636a5327a611f", + "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/5c/75/cde9c1909117d7442cb2302c274f", + "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/54/df/d28fbd98a92ce45cdb8141563205", + "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/42/bb/e022386630ffcb17f567c8bb65b1", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/c9/c2/1e8ad4f633f662a0d142883cd7a0", + "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/8a/a4/479729125294f2aed832491ed2ca", + "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/7d/9c/009ee3c03e90ffdca73aaed30ffa", + "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/9d/62/1bbbf5499f99f2749b54ac7f85ca", + "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/92/5c/315e8b6475c502a96d7cc393712d", + "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/d3/45/d6f13256b2238c1bda90faf3e02d", + "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/c0/e6/606201d69229c046ed9fb5c3338b", + "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/63/a9/9da6ca254d462675cdce8abdbf0b", + "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/61/45/eee74c4c33a9a76376b452a75689", + "build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/7a/74/60613067338c57246225eb95828d", + "build/prefab/lib/linux_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/f9/75/28d109017fc6233bf6c5e18c3ad3", + "build/prefab/lib/linux_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/bc/38/15e5bde3bd60cd8d760cacb7c825", + "build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ff/4d/95cf853485249ae7110b10093e65", + "build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/43/6a/85802eec068c4aad35253ade806c", + "build/prefab/lib/mac_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/b1/07/3409386feb1e5cd448a4e89007db", + "build/prefab/lib/mac_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/87/6c/560bd65f3fbdb007e562593079df", + "build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/3e/03/8d57f7814793dab7907834cf29ff", + "build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/d9/c8/6e1236bd6f7e6067fd43a2a3b28d", + "build/prefab/lib/mac_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/c5/d7/7b3d6226d950c09d90ca8dbf3732", + "build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/78/3a/d36f49ada60ed6d8cb4fabceca2d", + "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/d0/49/5818e127d362afa6ab928323ff43", + "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/6c/d9/dce5d751277c55ad994446dcf4e2", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/ca/74/2be44182ddaf1ff46c02ce461bb8", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/89/40/d140336bb8aba43c63a192ed5626", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/f1/db/6de5b4ba914384b8e77a3c207be2", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/c6/96/e6d4806efe59a47cd6a0e7119dfe", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/18/77/57cae7a43acfce18ad25d311ae30", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/6d/a8/3d30810f5efbea3e501216269e7a", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/3d/a4/3a98bbe8716ed349005076422ca9", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/ad/b2/335bf62301d7b6bc7b9444192693", "src/ballistica/generated/python_embedded/binding.inc": "https://files.ballistica.net/cache/ba1/c5/18/29d9fe8e483ce222d3263336f7e6", "src/ballistica/generated/python_embedded/bootstrap.inc": "https://files.ballistica.net/cache/ba1/9d/7e/0a5125aa421e722c59d22b8beb19" } \ No newline at end of file diff --git a/.idea/dictionaries/ericf.xml b/.idea/dictionaries/ericf.xml index f90bcf08..28760bb1 100644 --- a/.idea/dictionaries/ericf.xml +++ b/.idea/dictionaries/ericf.xml @@ -167,6 +167,7 @@ bacfg backgrounded backgrounding + backwin bacloud bacloudcmd bacommon @@ -183,6 +184,7 @@ bametainternal barcolor barebones + baseaddr baseh basemult basepos @@ -317,6 +319,7 @@ cbgn cbits cbot + cbresults cbtn cbtnoffs ccfgs @@ -1523,6 +1526,7 @@ ndbm ndkpath nearbytab + nearstr neededsettings ness netcode @@ -2456,6 +2460,7 @@ tval tvalue tvos + twidth twrths txtactor txtl @@ -2591,6 +2596,7 @@ weakref weakrefs weakrefset + weakwin webbrowser webpage webpages diff --git a/CHANGELOG.md b/CHANGELOG.md index 773b65db..250182b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ -### 1.6.9 (20461, 2022-02-17) +### 1.6.9 (20466, 2022-02-18) - Upgraded Android Python to 3.9.10 - Fixed an issue with SSL in Android builds that was preventing communication with the master-server in 1.6.8 +- Added a new network-diagnostics tool at 'Settings->Advanced->Network Testing'. Can be used to diagnose issues talking to master-servers/etc. (especially useful now that SSL can factor in) ### 1.6.8 (20458, 2022-02-16) - Added Filipino language (Thanks David!) diff --git a/README.md b/README.md index e84378f9..65c96357 100644 --- a/README.md +++ b/README.md @@ -6,13 +6,13 @@ ![](https://github.com/efroemling/ballistica/workflows/CI/badge.svg) -The Ballistica project is the foundation for the next generation of [BombSquad](http://bombsquadgame.com). It will be debuting with the upcoming 1.5 release of the game and lays the foundation for some of the big changes coming in 2.0. +The Ballistica project is the foundation for the next generation of [BombSquad](http://bombsquadgame.com). It debuted with version 1.5 of the game and lays the foundation for some of the big changes coming in 2.0. [Head to the project wiki to get started](https://github.com/efroemling/ballistica/wiki), or learn more about the project below. ### Project Goals * Cleanup - * BombSquad's codebase, and especially its scripting layer, have grown a lot over its lifetime, but not always in a 'designed' way. It was overdue for a major refactoring, which should keep it more maintainable for years to come. Examples of this include breaking up the monstrous twenty-six-thousand-line bsUI.py file into a much cleaner individual subpackages, updating all code from Python 2.7 to 3.7, and adding type annotations to the entire codebase. + * BombSquad's codebase, and especially its scripting layer, have grown a lot over its lifetime, but not always in a 'designed' way. It was overdue for a major refactoring, which should keep it more maintainable for years to come. Examples of this include breaking up the monstrous twenty-six-thousand-line bsUI.py file into a much cleaner individual subpackages, updating all code from Python 2.7 to the latest 3.X versions, and adding type annotations to the entire codebase. * Provide modders and tinkerers with the best possible development environment * I've spent a lot of time incorporating auto-formatters, type-checkers, linters, and smart IDEs into my development workflow and have found them to be an enormous help. By sharing my setup here I hope to make them easily accessible to everyone. * Improve transparency diff --git a/assets/src/ba_data/python/bastd/ui/settings/nettesting.py b/assets/src/ba_data/python/bastd/ui/settings/nettesting.py index e8b645c5..9fe1910e 100644 --- a/assets/src/ba_data/python/bastd/ui/settings/nettesting.py +++ b/assets/src/ba_data/python/bastd/ui/settings/nettesting.py @@ -4,11 +4,290 @@ from __future__ import annotations +import time +import copy +import weakref +from threading import Thread +from typing import TYPE_CHECKING + +import _ba import ba -from bastd.ui.settings import testing +from bastd.ui.settings.testing import TestingWindow + +if TYPE_CHECKING: + from typing import Callable, Any, Optional -class NetTestingWindow(testing.TestingWindow): +class NetTestingWindow(ba.Window): + """Window that runs a networking test suite to help diagnose issues.""" + + def __init__(self, transition: str = 'in_right'): + self._width = 820 + self._height = 500 + self._printed_lines: list[str] = [] + uiscale = ba.app.ui.uiscale + super().__init__(root_widget=ba.containerwidget( + size=(self._width, self._height), + scale=(1.56 if uiscale is ba.UIScale.SMALL else + 1.2 if uiscale is ba.UIScale.MEDIUM else 0.8), + stack_offset=(0.0, -7 if uiscale is ba.UIScale.SMALL else 0.0), + transition=transition)) + self._done_button = ba.buttonwidget(parent=self._root_widget, + position=(40, self._height - 77), + size=(120, 60), + scale=0.8, + autoselect=True, + label=ba.Lstr(resource='doneText'), + on_activate_call=self._done) + + self._copy_button = ba.buttonwidget(parent=self._root_widget, + position=(self._width - 200, + self._height - 77), + size=(100, 60), + scale=0.8, + autoselect=True, + label=ba.Lstr(resource='copyText'), + on_activate_call=self._copy) + + self._settings_button = ba.buttonwidget( + parent=self._root_widget, + position=(self._width - 100, self._height - 77), + size=(60, 60), + scale=0.8, + autoselect=True, + label=ba.Lstr(value='...'), + on_activate_call=self._show_val_testing) + + twidth = self._width - 450 + ba.textwidget( + parent=self._root_widget, + position=(self._width * 0.5, self._height - 55), + size=(0, 0), + text=ba.Lstr(resource='settingsWindowAdvanced.netTestingText'), + color=(0.8, 0.8, 0.8, 1.0), + h_align='center', + v_align='center', + maxwidth=twidth) + + self._scroll = ba.scrollwidget(parent=self._root_widget, + position=(50, 50), + size=(self._width - 100, + self._height - 140), + capture_arrows=True, + autoselect=True) + self._rows = ba.columnwidget(parent=self._scroll) + + ba.containerwidget(edit=self._root_widget, + cancel_button=self._done_button) + + # Now kick off the tests. + # Pass a weak-ref to this window so we don't keep it alive + # if we back out before it completes. Also set is as daemon + # so it doesn't keep the app running if the user is trying to quit. + Thread( + daemon=True, + target=ba.Call(_run_diagnostics, weakref.ref(self)), + ).start() + + def print(self, text: str, color: tuple[float, float, float]) -> None: + """Print text to our console thingie.""" + for line in text.splitlines(): + txt = ba.textwidget(parent=self._rows, + color=color, + text=line, + scale=0.75, + flatness=1.0, + shadow=0.0, + size=(0, 20)) + ba.containerwidget(edit=self._rows, visible_child=txt) + self._printed_lines.append(line) + + def _copy(self) -> None: + if not ba.clipboard_is_supported(): + ba.screenmessage('Clipboard not supported on this platform.', + color=(1, 0, 0)) + return + ba.clipboard_set_text('\n'.join(self._printed_lines)) + ba.screenmessage(f'{len(self._printed_lines)} lines copied.') + + def _show_val_testing(self) -> None: + ba.app.ui.set_main_menu_window(NetValTestingWindow().get_root_widget()) + ba.containerwidget(edit=self._root_widget, transition='out_left') + + def _done(self) -> None: + # pylint: disable=cyclic-import + from bastd.ui.settings.advanced import AdvancedSettingsWindow + ba.app.ui.set_main_menu_window( + AdvancedSettingsWindow(transition='in_left').get_root_widget()) + ba.containerwidget(edit=self._root_widget, transition='out_right') + + +def _run_diagnostics(weakwin: weakref.ref[NetTestingWindow]) -> None: + + from efro.util import utc_now + + have_error = [False] + + # We're running in a background thread but UI stuff needs to run + # in the logic thread; give ourself a way to pass stuff to it. + def _print(text: str, color: tuple[float, float, float] = None) -> None: + + def _print_in_logic_thread() -> None: + win = weakwin() + if win is not None: + win.print(text, (1.0, 1.0, 1.0) if color is None else color) + + ba.pushcall(_print_in_logic_thread, from_other_thread=True) + + def _print_test_results(call: Callable[[], Any]) -> None: + """Run the provided call; return success/fail text & color.""" + starttime = time.monotonic() + try: + call() + duration = time.monotonic() - starttime + _print(f'Succeeded in {duration:.2f}s.', color=(0, 1, 0)) + except Exception as exc: + duration = time.monotonic() - starttime + _print(f'Failed in {duration:.2f}s. Error={exc!r}', + color=(1, 0, 0)) + have_error[0] = True + + try: + _print(f'Running network diagnostics...\n' + f'ua: {_ba.app.user_agent_string}\n' + f'time: {utc_now()}.') + + if bool(False): + _print('\nRunning dummy success test...') + _print_test_results(_dummy_success) + + _print('\nRunning dummy fail test...') + _print_test_results(_dummy_fail) + + # V1 ping + baseaddr = _ba.get_master_server_address(internal=True, + source=0, + version=1) + _print(f'\nContacting V1 master-server ({baseaddr})...') + _print_test_results(lambda: _test_fetch(baseaddr)) + + # V1 alternate ping + baseaddr = _ba.get_master_server_address(internal=True, + source=1, + version=1) + _print(f'\nContacting V1 alt master-server ({baseaddr})...') + _print_test_results(lambda: _test_fetch(baseaddr)) + + _print('\nRunning V1 transaction...') + _print_test_results(_test_v1_transaction) + + # V2 ping + baseaddr = _ba.get_master_server_address(internal=True, version=2) + _print(f'\nContacting V2 master-server ({baseaddr})...') + _print_test_results(lambda: _test_fetch(baseaddr)) + + # Get V2 nearby region + with ba.app.net.region_pings_lock: + region_pings = copy.deepcopy(ba.app.net.region_pings) + nearest_region = (None if not region_pings else sorted( + region_pings.items(), key=lambda i: i[1])[0]) + + if nearest_region is not None: + nearstr = f'{nearest_region[0]}: {nearest_region[1]:.0f}ms' + else: + nearstr = '-' + _print(f'\nChecking nearest V2 region ping ({nearstr})...') + _print_test_results(lambda: _test_nearby_region_ping(nearest_region)) + + if have_error[0]: + _print('\nDiagnostics complete. Some diagnostics failed.', + color=(10, 0, 0)) + else: + _print('\nDiagnostics complete. Everything looks good!', + color=(0, 1, 0)) + except Exception: + import traceback + _print( + f'An unexpected error occurred during testing;' + f' please report this.\n' + f'{traceback.format_exc()}', + color=(1, 0, 0)) + + +def _dummy_success() -> None: + """Dummy success test.""" + time.sleep(1.2) + + +def _dummy_fail() -> None: + """Dummy fail test case.""" + raise RuntimeError('fail-test') + + +def _test_v1_transaction() -> None: + """Dummy fail test case.""" + if _ba.get_account_state() != 'signed_in': + raise RuntimeError('Not signed in.') + + starttime = time.monotonic() + + # Gets set to True on success or string on error. + results: list[Any] = [False] + + def _cb(cbresults: Any) -> None: + # Simply set results here; our other thread acts on them. + if not isinstance(cbresults, dict) or 'party_code' not in cbresults: + results[0] = 'Unexpected transaction response' + return + results[0] = True # Success! + + def _do_it() -> None: + # Fire off a transaction with a callback. + _ba.add_transaction( + { + 'type': 'PRIVATE_PARTY_QUERY', + 'expire_time': time.time() + 20, + }, + callback=_cb, + ) + _ba.run_transactions() + + ba.pushcall(_do_it, from_other_thread=True) + + while results[0] is False: + time.sleep(0.01) + if time.monotonic() - starttime > 10.0: + raise RuntimeError('timed out') + + # If we got left a string, its an error. + if isinstance(results[0], str): + raise RuntimeError(results[0]) + + +def _test_fetch(baseaddr: str) -> None: + # pylint: disable=consider-using-with + import urllib.request + response = urllib.request.urlopen(urllib.request.Request( + f'{baseaddr}/ping', None, {'User-Agent': _ba.app.user_agent_string}), + timeout=10.0) + if response.getcode() != 200: + raise RuntimeError( + f'Got unexpected response code {response.getcode()}.') + data = response.read() + if data != b'pong': + raise RuntimeError('Got unexpected response data.') + + +def _test_nearby_region_ping( + nearest_region: Optional[tuple[str, float]]) -> None: + """Try to ping nearest v2 region.""" + if nearest_region is None: + raise RuntimeError('No nearest region.') + if nearest_region[1] > 500: + raise RuntimeError('Ping too high.') + + +class NetValTestingWindow(TestingWindow): """Window to test network related settings.""" def __init__(self, transition: str = 'in_right'): @@ -35,6 +314,8 @@ class NetTestingWindow(testing.TestingWindow): 'increment': 1 }, ] - testing.TestingWindow.__init__( - self, ba.Lstr(resource='settingsWindowAdvanced.netTestingText'), - entries, transition) + super().__init__( + title=ba.Lstr(resource='settingsWindowAdvanced.netTestingText'), + entries=entries, + transition=transition, + back_call=lambda: NetTestingWindow(transition='in_left')) diff --git a/assets/src/ba_data/python/bastd/ui/settings/testing.py b/assets/src/ba_data/python/bastd/ui/settings/testing.py index 51f237e8..54e8349e 100644 --- a/assets/src/ba_data/python/bastd/ui/settings/testing.py +++ b/assets/src/ba_data/python/bastd/ui/settings/testing.py @@ -11,7 +11,7 @@ import _ba import ba if TYPE_CHECKING: - from typing import Any + from typing import Any, Callable, Optional class TestingWindow(ba.Window): @@ -20,11 +20,13 @@ class TestingWindow(ba.Window): def __init__(self, title: ba.Lstr, entries: list[dict[str, Any]], - transition: str = 'in_right'): + transition: str = 'in_right', + back_call: Optional[Callable[[], ba.Window]] = None): uiscale = ba.app.ui.uiscale self._width = 600 self._height = 324 if uiscale is ba.UIScale.SMALL else 400 self._entries = copy.deepcopy(entries) + self._back_call = back_call super().__init__(root_widget=ba.containerwidget( size=(self._width, self._height), transition=transition, @@ -176,8 +178,8 @@ class TestingWindow(ba.Window): def _do_back(self) -> None: # pylint: disable=cyclic-import - import bastd.ui.settings.advanced + from bastd.ui.settings.advanced import AdvancedSettingsWindow ba.containerwidget(edit=self._root_widget, transition='out_right') - ba.app.ui.set_main_menu_window( - bastd.ui.settings.advanced.AdvancedSettingsWindow( - transition='in_left').get_root_widget()) + backwin = (self._back_call() if self._back_call is not None else + AdvancedSettingsWindow(transition='in_left')) + ba.app.ui.set_main_menu_window(backwin.get_root_widget()) diff --git a/assets/src/ba_data/python/bastd/ui/settings/vrtesting.py b/assets/src/ba_data/python/bastd/ui/settings/vrtesting.py index a899caac..a6723f78 100644 --- a/assets/src/ba_data/python/bastd/ui/settings/vrtesting.py +++ b/assets/src/ba_data/python/bastd/ui/settings/vrtesting.py @@ -7,13 +7,13 @@ from __future__ import annotations from typing import TYPE_CHECKING import ba -from bastd.ui.settings import testing +from bastd.ui.settings.testing import TestingWindow if TYPE_CHECKING: from typing import Any -class VRTestingWindow(testing.TestingWindow): +class VRTestingWindow(TestingWindow): """Window for testing vr settings.""" def __init__(self, transition: str = 'in_right'): diff --git a/ballisticacore-cmake/.idea/dictionaries/ericf.xml b/ballisticacore-cmake/.idea/dictionaries/ericf.xml index 1ffa37a4..4e9a01f4 100644 --- a/ballisticacore-cmake/.idea/dictionaries/ericf.xml +++ b/ballisticacore-cmake/.idea/dictionaries/ericf.xml @@ -77,6 +77,7 @@ backgrounded backgrounding backtraces + backwin ballistica ballisticacore bamasteraddr @@ -84,6 +85,7 @@ bameta bametainternal barebones + baseaddr basetype basicsize basn @@ -167,6 +169,7 @@ capitan cargs cbgn + cbresults cbtnoffs ccdd ccind @@ -720,6 +723,7 @@ nameval ndebug nearbytab + nearstr nearval needwindow negativex @@ -1169,6 +1173,7 @@ tval tvos tweakage + twidth twotimer twst typeobj @@ -1241,6 +1246,7 @@ wdeprecated weakref weakthis + weakwin weeeird welp whaaaaaaa diff --git a/src/ballistica/ballistica.cc b/src/ballistica/ballistica.cc index 96a921db..7d5fbdd9 100644 --- a/src/ballistica/ballistica.cc +++ b/src/ballistica/ballistica.cc @@ -21,7 +21,7 @@ namespace ballistica { // These are set automatically via script; don't modify them here. -const int kAppBuildNumber = 20461; +const int kAppBuildNumber = 20466; const char* kAppVersion = "1.6.9"; // Our standalone globals. diff --git a/src/ballistica/core/fatal_error.cc b/src/ballistica/core/fatal_error.cc index 1e231b59..80736b28 100644 --- a/src/ballistica/core/fatal_error.cc +++ b/src/ballistica/core/fatal_error.cc @@ -42,15 +42,12 @@ auto FatalError::ReportFatalError(const std::string& message, if (!dialog_msg.empty()) { dialog_msg += "\n"; } - // (No longer adding this note; individual errors to which the log is - // relevant can do to themselves). - // dialog_msg += "See BallisticaCore log for details."; auto starttime = time(nullptr); // Launch a thread and give it a chance to directly send our logs to the // master-server. The standard mechanism probably won't get the job done - // since it relies on the game thread loop and we're likely blocking that. + // since it relies on the logic thread loop and we're likely blocking that. // But generally we want to stay in this function and call abort() or whatnot // from here so that our stack trace makes it into platform logs. int result{};