Merge branch 'master' into master

This commit is contained in:
Eric Froemling 2024-03-01 20:07:55 -08:00 committed by GitHub
commit 0e5db37db6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 278 additions and 194 deletions

84
.efrocachemap generated
View File

@ -421,39 +421,39 @@
"build/assets/ba_data/audio/zoeOw.ogg": "74befe45a8417e95b6a2233c51992a26", "build/assets/ba_data/audio/zoeOw.ogg": "74befe45a8417e95b6a2233c51992a26",
"build/assets/ba_data/audio/zoePickup01.ogg": "48ab8cddfcde36a750856f3f81dd20c8", "build/assets/ba_data/audio/zoePickup01.ogg": "48ab8cddfcde36a750856f3f81dd20c8",
"build/assets/ba_data/audio/zoeScream01.ogg": "2b468aedfa8741090247f04eb9e6df55", "build/assets/ba_data/audio/zoeScream01.ogg": "2b468aedfa8741090247f04eb9e6df55",
"build/assets/ba_data/data/langdata.json": "831b83240126d0a851104f4148712ed1", "build/assets/ba_data/data/langdata.json": "5273cf3bfe2d25d70395690bf3c21825",
"build/assets/ba_data/data/languages/arabic.json": "0db32e21b6d5337ccca478381744aa88", "build/assets/ba_data/data/languages/arabic.json": "0db32e21b6d5337ccca478381744aa88",
"build/assets/ba_data/data/languages/belarussian.json": "a112dfca3e188387516788bd8229c5b0", "build/assets/ba_data/data/languages/belarussian.json": "09954e550d13d3d9cb5a635a1d32a151",
"build/assets/ba_data/data/languages/chinese.json": "1360ffde06828b63ce4fe956c3c3cd1d", "build/assets/ba_data/data/languages/chinese.json": "1360ffde06828b63ce4fe956c3c3cd1d",
"build/assets/ba_data/data/languages/chinesetraditional.json": "319565f8a15667488f48dbce59278e39", "build/assets/ba_data/data/languages/chinesetraditional.json": "319565f8a15667488f48dbce59278e39",
"build/assets/ba_data/data/languages/croatian.json": "766532c67af5bd0144c2d63cab0516fa", "build/assets/ba_data/data/languages/croatian.json": "e671b9d0c012be1a30f9c15eb1b81860",
"build/assets/ba_data/data/languages/czech.json": "7171420af6d662e3a47b64576850a384", "build/assets/ba_data/data/languages/czech.json": "7171420af6d662e3a47b64576850a384",
"build/assets/ba_data/data/languages/danish.json": "3fd69080783d5c9dcc0af737f02b6f1e", "build/assets/ba_data/data/languages/danish.json": "8e57db30c5250df2abff14a822f83ea7",
"build/assets/ba_data/data/languages/dutch.json": "b0900d572c9141897d53d6574c471343", "build/assets/ba_data/data/languages/dutch.json": "b0900d572c9141897d53d6574c471343",
"build/assets/ba_data/data/languages/english.json": "1c4037fea1066d39d6eced419f314f35", "build/assets/ba_data/data/languages/english.json": "28a1c17925aba4f4f908732e5e5cb266",
"build/assets/ba_data/data/languages/esperanto.json": "0e397cfa5f3fb8cef5f4a64f21cda880", "build/assets/ba_data/data/languages/esperanto.json": "0e397cfa5f3fb8cef5f4a64f21cda880",
"build/assets/ba_data/data/languages/filipino.json": "43e838754fe013b8bac75f75aef78cb3", "build/assets/ba_data/data/languages/filipino.json": "fe3f1efcb47efaa23524300d21728933",
"build/assets/ba_data/data/languages/french.json": "cc8ac601f5443dd539893728db983f5c", "build/assets/ba_data/data/languages/french.json": "cc8ac601f5443dd539893728db983f5c",
"build/assets/ba_data/data/languages/german.json": "450fa41ae264f29a5d1af22143d0d0ad", "build/assets/ba_data/data/languages/german.json": "450fa41ae264f29a5d1af22143d0d0ad",
"build/assets/ba_data/data/languages/gibberish.json": "b461539243e8efe3137137b886256ba7", "build/assets/ba_data/data/languages/gibberish.json": "ab9571486f703b8d57eab61dbf1d54d8",
"build/assets/ba_data/data/languages/greek.json": "287c0ec437b38772284ef9d3e4fb2fc3", "build/assets/ba_data/data/languages/greek.json": "287c0ec437b38772284ef9d3e4fb2fc3",
"build/assets/ba_data/data/languages/hindi.json": "5b6c8e988ffa84a7e26d120b6cd8e1a4", "build/assets/ba_data/data/languages/hindi.json": "90f54663e15d85a163f1848a8e9d8d07",
"build/assets/ba_data/data/languages/hungarian.json": "796a290a8c44a1e7635208c2ff5fdc6e", "build/assets/ba_data/data/languages/hungarian.json": "796a290a8c44a1e7635208c2ff5fdc6e",
"build/assets/ba_data/data/languages/indonesian.json": "9103845242b572aa8ba48e24f81ddb68", "build/assets/ba_data/data/languages/indonesian.json": "9103845242b572aa8ba48e24f81ddb68",
"build/assets/ba_data/data/languages/italian.json": "f550810b6866ea9bcf1985b7228f8cff", "build/assets/ba_data/data/languages/italian.json": "f550810b6866ea9bcf1985b7228f8cff",
"build/assets/ba_data/data/languages/korean.json": "4e3524327a0174250aff5e1ef4c0c597", "build/assets/ba_data/data/languages/korean.json": "4e3524327a0174250aff5e1ef4c0c597",
"build/assets/ba_data/data/languages/malay.json": "832562ce997fc70704b9234c95fb2e38", "build/assets/ba_data/data/languages/malay.json": "832562ce997fc70704b9234c95fb2e38",
"build/assets/ba_data/data/languages/persian.json": "9728d631cf7d9ad3b209ae1244bb59c0", "build/assets/ba_data/data/languages/persian.json": "1a4c74ad9089cd746ad6fda4186c2220",
"build/assets/ba_data/data/languages/polish.json": "3a90b2d9e2c59305580c96f8098fc839", "build/assets/ba_data/data/languages/polish.json": "9d22c6643c097c4cb268d0d6b6319cd4",
"build/assets/ba_data/data/languages/portuguese.json": "b52164747c6308fc9d054eb6c0ff3c54", "build/assets/ba_data/data/languages/portuguese.json": "b52164747c6308fc9d054eb6c0ff3c54",
"build/assets/ba_data/data/languages/romanian.json": "aeebdd54f65939c2facc6ac50c117826", "build/assets/ba_data/data/languages/romanian.json": "b3e46efd6f869dbd78014570e037c290",
"build/assets/ba_data/data/languages/russian.json": "30d5f3d2415088e1fb6558fcd6ccfa98", "build/assets/ba_data/data/languages/russian.json": "30d5f3d2415088e1fb6558fcd6ccfa98",
"build/assets/ba_data/data/languages/serbian.json": "d7452dd72ac0e51680cb39b5ebaa1c69", "build/assets/ba_data/data/languages/serbian.json": "d7452dd72ac0e51680cb39b5ebaa1c69",
"build/assets/ba_data/data/languages/slovak.json": "27962d53dc3f7dd4e877cd40faafeeef", "build/assets/ba_data/data/languages/slovak.json": "c00fb27cf982ffad5a4370ad3b16bd21",
"build/assets/ba_data/data/languages/spanish.json": "e3e9ac8f96f52302a480c7e955aed71f", "build/assets/ba_data/data/languages/spanish.json": "e3e9ac8f96f52302a480c7e955aed71f",
"build/assets/ba_data/data/languages/swedish.json": "5142a96597d17d8344be96a603da64ac", "build/assets/ba_data/data/languages/swedish.json": "5142a96597d17d8344be96a603da64ac",
"build/assets/ba_data/data/languages/tamil.json": "b4de1a2851afe4869c82e9acd94cd89c", "build/assets/ba_data/data/languages/tamil.json": "b9fcc523639f55e05c7f4e7914f3321a",
"build/assets/ba_data/data/languages/thai.json": "9c425b420f0488a7f883da98947657ad", "build/assets/ba_data/data/languages/thai.json": "1d665629361f302693dead39de8fa945",
"build/assets/ba_data/data/languages/turkish.json": "2be25c89ca754341f27750e0d595f31e", "build/assets/ba_data/data/languages/turkish.json": "2be25c89ca754341f27750e0d595f31e",
"build/assets/ba_data/data/languages/ukrainian.json": "b54a38e93deebafa5706ba2d1f626892", "build/assets/ba_data/data/languages/ukrainian.json": "b54a38e93deebafa5706ba2d1f626892",
"build/assets/ba_data/data/languages/venetian.json": "f896fc3df13a42f1bef8813ca80b1a09", "build/assets/ba_data/data/languages/venetian.json": "f896fc3df13a42f1bef8813ca80b1a09",
@ -4060,26 +4060,26 @@
"build/assets/windows/Win32/ucrtbased.dll": "2def5335207d41b21b9823f6805997f1", "build/assets/windows/Win32/ucrtbased.dll": "2def5335207d41b21b9823f6805997f1",
"build/assets/windows/Win32/vc_redist.x86.exe": "b08a55e2e77623fe657bea24f223a3ae", "build/assets/windows/Win32/vc_redist.x86.exe": "b08a55e2e77623fe657bea24f223a3ae",
"build/assets/windows/Win32/vcruntime140d.dll": "865b2af4d1e26a1a8073c89acb06e599", "build/assets/windows/Win32/vcruntime140d.dll": "865b2af4d1e26a1a8073c89acb06e599",
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "d5a8312cd9cf65f32ca2a7c4a2063c03", "build/prefab/full/linux_arm64_gui/debug/ballisticakit": "a7161a4100172e2bb42b838a9851c353",
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "aecb00e9044fa677583e1036fa7875d8", "build/prefab/full/linux_arm64_gui/release/ballisticakit": "9a63e694db2ed7536374c58a45ce65d3",
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "eca7f9ab892edfa7423a9d4a6f89e571", "build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "9668ef38ddc59fadf323cf460c8b692c",
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "99647f48362f84112d23a9bc89eaa983", "build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "8f58837d238dba248ae2e23e20bc3f06",
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "31e21a64d77fc0834832b633a26d986b", "build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "f8a6e20f3fffd198494adfba4e884588",
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "7c12b4078c3af6e627a4051b1c1d8370", "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "255205c95d519a594041fc239e435883",
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "f7a66c48321efa4462e8eae6b72db2b2", "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "36facf256b69a8c0037370e23c82470d",
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "08cdbeb2ca4fa8c996f3369680c4e5cd", "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "d78aef348baf274f476ce9e344b80122",
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "f92679bab5a0d057427962869e19f057", "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "f1b9732cc7e7728dcedc39a55d9afea2",
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "d5bcd695f84dab1ab32655989d399c9e", "build/prefab/full/mac_arm64_gui/release/ballisticakit": "8cfc0e04c10a315cce91dae041dfc3ff",
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "c766f437ece15dae0ee971e4c2e10a2d", "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "a9fec1930c851f8ed743b08669df2d75",
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "cbecc4c11b9aa4621abfdc996fecfd74", "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "a6fcaa9d7eb10412787e4416f3536bb9",
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "7af782c9d9bcf1396a15dea6f2493d70", "build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "a39230df064404a3b1dd18a644f2f6d6",
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "2c04f3f68db3e73e4aad4c656d956c00", "build/prefab/full/mac_x86_64_gui/release/ballisticakit": "04e971f62a000383a13eb021e30afa7b",
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "132c83ee8811828739601ac3d0599fe9", "build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "a93fe4f0cfb3c2c9061df049068230ac",
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "8de942a2e1ff96c147a9500a56ca4f64", "build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "0f08a84bb09589991faaca9250171e3c",
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "6bf51ccbd01937bf1b28cfffe029d857", "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "12c079e62d0125b8a24b16e418405ba9",
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "c5f0d834a47852f1c240e17a6c933e0a", "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "eb0d76fd3be03082572b0d835df05252",
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "4f74b71dabd207bee732dc91c9a28dc4", "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "e4268ef0b50e94747081ee83666d80ab",
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "f48ab8e4c4d05f4b2231bebf33c965f1", "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "f4646fecfed11f5e2b2ee5c892b2940a",
"build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "ee36a39fd0f524989cb68930c89c8868", "build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "ee36a39fd0f524989cb68930c89c8868",
"build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "dbed9145e5db116d92aa47cb9e98da39", "build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "dbed9145e5db116d92aa47cb9e98da39",
"build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "ee36a39fd0f524989cb68930c89c8868", "build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "ee36a39fd0f524989cb68930c89c8868",
@ -4096,14 +4096,14 @@
"build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "0896e849885cef50bcf33ce863efa7d2", "build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "0896e849885cef50bcf33ce863efa7d2",
"build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "e53c808357cc0a2f0da7b870be147083", "build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "e53c808357cc0a2f0da7b870be147083",
"build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "0896e849885cef50bcf33ce863efa7d2", "build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "0896e849885cef50bcf33ce863efa7d2",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "e34cc55fd284e31d9ed1151c5a51bf34", "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "f53601899c23c90c2b7e65836c805d8e",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "36cb65be158a0103d81c82d8a51dc8b6", "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "f31b348a7612e5fa3a968f3cc81cefcd",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "21f8a61745c2fec88749299f5aeeeaf9", "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "b8339779a2571b169f9d63c11aa7dfa3",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "d61272f101f87b140b84895e482b07f4", "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "511bc23565e830778d5ff183a201579d",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "36c30bcd93d38569b9515ed17896d8de", "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "b02faf2aa2df1de233a0549295e6b0ed",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "841c7cd3cc96c91ecd11335a91c0c465", "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "2e07aaa6d445caf3b33d79dc40bd2475",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "305aab4423bf510f6bf95fe0c996128f", "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "00f50fb4a3a9bbecd1b1188b78abae4b",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "f1066b8591d7859df76c8e976ceee2d5", "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "88fb67cb3f3752f0b0db1d583f90490d",
"src/assets/ba_data/python/babase/_mgen/__init__.py": "f885fed7f2ed98ff2ba271f9dbe3391c", "src/assets/ba_data/python/babase/_mgen/__init__.py": "f885fed7f2ed98ff2ba271f9dbe3391c",
"src/assets/ba_data/python/babase/_mgen/enums.py": "b611c090513a21e2fe90e56582724e9d", "src/assets/ba_data/python/babase/_mgen/enums.py": "b611c090513a21e2fe90e56582724e9d",
"src/ballistica/base/mgen/pyembed/binding_base.inc": "72bfed2cce8ff19741989dec28302f3f", "src/ballistica/base/mgen/pyembed/binding_base.inc": "72bfed2cce8ff19741989dec28302f3f",

View File

@ -1,4 +1,4 @@
### 1.7.33 (build 21766, api 8, 2024-02-01) ### 1.7.33 (build 21770, api 8, 2024-03-01)
- Stress test input-devices are now a bit smarter; they won't press any buttons - Stress test input-devices are now a bit smarter; they won't press any buttons
while UIs are up (this could cause lots of chaos if it happened). while UIs are up (this could cause lots of chaos if it happened).
- Added a 'Show Demos When Idle' option in advanced settings. If enabled, the - Added a 'Show Demos When Idle' option in advanced settings. If enabled, the
@ -20,8 +20,17 @@
languages; I feel it helps keep logic more understandable and should help us languages; I feel it helps keep logic more understandable and should help us
catch problems where a base class changes or removes a method and child catch problems where a base class changes or removes a method and child
classes forget to adapt to the change. classes forget to adapt to the change.
- Custom spaz "curse_time" values now work properly. (Thanks Temp!)
- Implemented `efro.dataclassio.IOMultiType` which will make my life a lot - Implemented `efro.dataclassio.IOMultiType` which will make my life a lot
easier. easier.
- Punches no longer physically affect powerup boxes which should make it easier
to grab the powerup (Thanks VinniTR!).
- The 'Manual' party tab now supports entering IPv6 addresses (Thanks
brostos!).
- Fixes a bug where Meteor Shower could make the game-end bell sound twice
(Thanks 3alTemp!).
- Leaving the game or dying while touching your team's flag will no longer recover
& return it indefinitely in a teams game of Capture the Flag. (Thanks 3alTemp!)
### 1.7.32 (build 21741, api 8, 2023-12-20) ### 1.7.32 (build 21741, api 8, 2023-12-20)
- Fixed a screen message that no one will ever see (Thanks vishal332008?...) - Fixed a screen message that no one will ever see (Thanks vishal332008?...)

View File

@ -51,5 +51,9 @@
### Rikko ### Rikko
- Created the original "reject_recently_left_players" plugin - Created the original "reject_recently_left_players" plugin
### 3alTemp ### Temp (3alTemp)
- Original idea for customizable series length on GUI builds - Original idea for customizable series length on GUI builds
- Modder & Bug Fixer
### brostos
- Added support for joining using ipv6 address

View File

@ -136,7 +136,9 @@ def create_user_system_scripts() -> None:
path = f'{env.python_directory_user}/sys/{env.version}' path = f'{env.python_directory_user}/sys/{env.version}'
pathtmp = path + '_tmp' pathtmp = path + '_tmp'
if os.path.exists(path): if os.path.exists(path):
shutil.rmtree(path) print('Delete Existing User Scripts and try again.')
_babase.screenmessage('Delete Existing User Scripts and try again.')
return
if os.path.exists(pathtmp): if os.path.exists(pathtmp):
shutil.rmtree(pathtmp) shutil.rmtree(pathtmp)
@ -159,6 +161,7 @@ def create_user_system_scripts() -> None:
f"'\nRestart {_babase.appname()} to use them." f"'\nRestart {_babase.appname()} to use them."
f' (use babase.quit() to exit the game)' f' (use babase.quit() to exit the game)'
) )
_babase.screenmessage('Created User System Scripts')
if app.classic is not None and app.classic.platform == 'android': if app.classic is not None and app.classic.platform == 'android':
print( print(
'Note: the new files may not be visible via ' 'Note: the new files may not be visible via '
@ -183,6 +186,7 @@ def delete_user_system_scripts() -> None:
f'Restart {_babase.appname()} to use internal' f'Restart {_babase.appname()} to use internal'
f' scripts. (use babase.quit() to exit the game)' f' scripts. (use babase.quit() to exit the game)'
) )
_babase.screenmessage('Deleted User System Scripts')
else: else:
print(f"User system scripts not found at '{path}'.") print(f"User system scripts not found at '{path}'.")

View File

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

View File

@ -256,9 +256,7 @@ class Map(Actor):
return ( return (
None None
if val is None if val is None
else babase.vec3validate(val) else babase.vec3validate(val) if __debug__ else val
if __debug__
else val
) )
def get_def_points(self, name: str) -> list[Sequence[float]]: def get_def_points(self, name: str) -> list[Sequence[float]]:
@ -334,8 +332,7 @@ class Map(Actor):
closest_player_dist = 9999.0 closest_player_dist = 9999.0
for ppt in player_pts: for ppt in player_pts:
dist = (ppt - testpt).length() dist = (ppt - testpt).length()
if dist < closest_player_dist: closest_player_dist = min(dist, closest_player_dist)
closest_player_dist = dist
if closest_player_dist > farthestpt_dist: if closest_player_dist > farthestpt_dist:
farthestpt_dist = closest_player_dist farthestpt_dist = closest_player_dist
farthestpt = testpt farthestpt = testpt

View File

@ -13,7 +13,7 @@ from typing_extensions import override
import bascenev1 as bs import bascenev1 as bs
from bascenev1lib.actor.bomb import Bomb, Blast from bascenev1lib.actor.bomb import Bomb, Blast
from bascenev1lib.actor.powerupbox import PowerupBoxFactory from bascenev1lib.actor.powerupbox import PowerupBoxFactory, PowerupBox
from bascenev1lib.actor.spazfactory import SpazFactory from bascenev1lib.actor.spazfactory import SpazFactory
from bascenev1lib.gameutils import SharedObjects from bascenev1lib.gameutils import SharedObjects
@ -629,7 +629,8 @@ class Spaz(bs.Actor):
1000.0 * (tval + self.curse_time) 1000.0 * (tval + self.curse_time)
) )
self._curse_timer = bs.Timer( self._curse_timer = bs.Timer(
5.0, bs.WeakCall(self.handlemessage, CurseExplodeMessage()) self.curse_time,
bs.WeakCall(self.handlemessage, CurseExplodeMessage()),
) )
def equip_boxing_gloves(self) -> None: def equip_boxing_gloves(self) -> None:
@ -1227,6 +1228,10 @@ class Spaz(bs.Actor):
return None return None
node = bs.getcollision().opposingnode node = bs.getcollision().opposingnode
# Don't want to physically affect powerups.
if node.getdelegate(PowerupBox):
return None
# Only allow one hit per node per punch. # Only allow one hit per node per punch.
if node and (node not in self._punched_nodes): if node and (node not in self._punched_nodes):
punch_momentum_angular = ( punch_momentum_angular = (

View File

@ -529,6 +529,30 @@ class CaptureTheFlagGame(bs.TeamGameActivity[Player, Team]):
if team.flag_return_touches < 0: if team.flag_return_touches < 0:
logging.exception('CTF flag_return_touches < 0') logging.exception('CTF flag_return_touches < 0')
def _handle_death_flag_capture(self, player: Player) -> None:
"""Handles flag values when a player dies or leaves the game."""
# Don't do anything if the player hasn't touched the flag at all.
if not player.touching_own_flag:
return
team = player.team
# For each "point" our player has touched theflag (Could be multiple),
# deduct one from both our player and
# the flag's return touches variable.
for _ in range(player.touching_own_flag):
# Deduct
player.touching_own_flag -= 1
team.flag_return_touches -= 1
# Update our flag's timer accordingly
# (Prevents immediate resets in case
# there might be more people touching it).
if team.flag_return_touches == 0:
team.touch_return_timer = None
team.touch_return_timer_ticking = None
# Safety check, just to be sure!
if team.flag_return_touches < 0:
logging.exception('CTF flag_return_touches < 0')
def _flash_base(self, team: Team, length: float = 2.0) -> None: def _flash_base(self, team: Team, length: float = 2.0) -> None:
light = bs.newnode( light = bs.newnode(
'light', 'light',
@ -591,6 +615,7 @@ class CaptureTheFlagGame(bs.TeamGameActivity[Player, Team]):
def handlemessage(self, msg: Any) -> Any: def handlemessage(self, msg: Any) -> Any:
if isinstance(msg, bs.PlayerDiedMessage): if isinstance(msg, bs.PlayerDiedMessage):
super().handlemessage(msg) # Augment standard behavior. super().handlemessage(msg) # Augment standard behavior.
self._handle_death_flag_capture(msg.getplayer(Player))
self.respawn_player(msg.getplayer(Player)) self.respawn_player(msg.getplayer(Player))
elif isinstance(msg, FlagDiedMessage): elif isinstance(msg, FlagDiedMessage):
@ -617,3 +642,8 @@ class CaptureTheFlagGame(bs.TeamGameActivity[Player, Team]):
else: else:
super().handlemessage(msg) super().handlemessage(msg)
@override
def on_player_leave(self, player: Player) -> None:
"""Prevents leaving players from capturing their flag."""
self._handle_death_flag_capture(player)

View File

@ -73,6 +73,7 @@ class MeteorShowerGame(bs.TeamGameActivity[Player, Team]):
self._last_player_death_time: float | None = None self._last_player_death_time: float | None = None
self._meteor_time = 2.0 self._meteor_time = 2.0
self._timer: OnScreenTimer | None = None self._timer: OnScreenTimer | None = None
self._ended: bool = False
# Some base class overrides: # Some base class overrides:
self.default_music = ( self.default_music = (
@ -161,6 +162,10 @@ class MeteorShowerGame(bs.TeamGameActivity[Player, Team]):
return None return None
def _check_end_game(self) -> None: def _check_end_game(self) -> None:
# We don't want to end this activity more than once.
if self._ended:
return
living_team_count = 0 living_team_count = 0
for team in self.teams: for team in self.teams:
for player in team.players: for player in team.players:
@ -270,4 +275,5 @@ class MeteorShowerGame(bs.TeamGameActivity[Player, Team]):
# Submit the score value in milliseconds. # Submit the score value in milliseconds.
results.set_team_score(team, int(1000.0 * longest_life)) results.set_team_score(team, int(1000.0 * longest_life))
self._ended = True
self.end(results=results) self.end(results=results)

View File

@ -90,9 +90,7 @@ class CoopBrowserWindow(bui.Window):
self._height = ( self._height = (
657 657
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 730 else 730 if uiscale is bui.UIScale.MEDIUM else 800
if uiscale is bui.UIScale.MEDIUM
else 800
) )
app.ui_v1.set_main_menu_location('Coop Select') app.ui_v1.set_main_menu_location('Coop Select')
self._r = 'coopSelectWindow' self._r = 'coopSelectWindow'
@ -104,6 +102,19 @@ class CoopBrowserWindow(bui.Window):
'campaignDifficulty', 'easy' 'campaignDifficulty', 'easy'
) )
if (
self._campaign_difficulty == 'hard'
and not app.classic.accounts.have_pro_options()
):
plus.add_v1_account_transaction(
{
'type': 'SET_MISC_VAL',
'name': 'campaignDifficulty',
'value': 'easy',
}
)
self._campaign_difficulty = 'easy'
super().__init__( super().__init__(
root_widget=bui.containerwidget( root_widget=bui.containerwidget(
size=(self._width, self._height + top_extra), size=(self._width, self._height + top_extra),
@ -112,17 +123,13 @@ class CoopBrowserWindow(bui.Window):
stack_offset=( stack_offset=(
(0, -15) (0, -15)
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else (0, 0) else (0, 0) if uiscale is bui.UIScale.MEDIUM else (0, 0)
if uiscale is bui.UIScale.MEDIUM
else (0, 0)
), ),
transition=transition, transition=transition,
scale=( scale=(
1.2 1.2
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 0.8 else 0.8 if uiscale is bui.UIScale.MEDIUM else 0.75
if uiscale is bui.UIScale.MEDIUM
else 0.75
), ),
) )
) )
@ -271,9 +278,11 @@ class CoopBrowserWindow(bui.Window):
self._scrollwidget = bui.scrollwidget( self._scrollwidget = bui.scrollwidget(
parent=self._root_widget, parent=self._root_widget,
highlight=False, highlight=False,
position=(65 + x_inset, 120) position=(
if uiscale is bui.UIScale.SMALL and app.ui_v1.use_toolbars (65 + x_inset, 120)
else (65 + x_inset, 70), if uiscale is bui.UIScale.SMALL and app.ui_v1.use_toolbars
else (65 + x_inset, 70)
),
size=(self._scroll_width, self._scroll_height), size=(self._scroll_width, self._scroll_height),
simple_culling_v=10.0, simple_culling_v=10.0,
claims_left_right=True, claims_left_right=True,
@ -421,12 +430,14 @@ class CoopBrowserWindow(bui.Window):
if tbtn.time_remaining_value_text is not None: if tbtn.time_remaining_value_text is not None:
bui.textwidget( bui.textwidget(
edit=tbtn.time_remaining_value_text, edit=tbtn.time_remaining_value_text,
text=bui.timestring(tbtn.time_remaining, centi=False) text=(
if ( bui.timestring(tbtn.time_remaining, centi=False)
tbtn.has_time_remaining if (
and self._tourney_data_up_to_date tbtn.has_time_remaining
) and self._tourney_data_up_to_date
else '-', )
else '-'
),
) )
# Also adjust the ad icon visibility. # Also adjust the ad icon visibility.
@ -447,9 +458,9 @@ class CoopBrowserWindow(bui.Window):
try: try:
bui.imagewidget( bui.imagewidget(
edit=self._hard_button_lock_image, edit=self._hard_button_lock_image,
opacity=0.0 opacity=(
if bui.app.classic.accounts.have_pro_options() 0.0 if bui.app.classic.accounts.have_pro_options() else 1.0
else 1.0, ),
) )
except Exception: except Exception:
logging.exception('Error updating campaign lock.') logging.exception('Error updating campaign lock.')
@ -559,12 +570,16 @@ class CoopBrowserWindow(bui.Window):
enable_sound=False, enable_sound=False,
on_activate_call=bui.Call(self._set_campaign_difficulty, 'easy'), on_activate_call=bui.Call(self._set_campaign_difficulty, 'easy'),
on_select_call=bui.Call(self.sel_change, 'campaign', 'easyButton'), on_select_call=bui.Call(self.sel_change, 'campaign', 'easyButton'),
color=sel_color color=(
if self._campaign_difficulty == 'easy' sel_color
else un_sel_color, if self._campaign_difficulty == 'easy'
textcolor=sel_textcolor else un_sel_color
if self._campaign_difficulty == 'easy' ),
else un_sel_textcolor, textcolor=(
sel_textcolor
if self._campaign_difficulty == 'easy'
else un_sel_textcolor
),
) )
bui.widget(edit=self._easy_button, show_buffer_left=100) bui.widget(edit=self._easy_button, show_buffer_left=100)
if self._selected_campaign_level == 'easyButton': if self._selected_campaign_level == 'easyButton':
@ -585,12 +600,16 @@ class CoopBrowserWindow(bui.Window):
enable_sound=False, enable_sound=False,
on_activate_call=bui.Call(self._set_campaign_difficulty, 'hard'), on_activate_call=bui.Call(self._set_campaign_difficulty, 'hard'),
on_select_call=bui.Call(self.sel_change, 'campaign', 'hardButton'), on_select_call=bui.Call(self.sel_change, 'campaign', 'hardButton'),
color=sel_color_hard color=(
if self._campaign_difficulty == 'hard' sel_color_hard
else un_sel_color, if self._campaign_difficulty == 'hard'
textcolor=sel_textcolor else un_sel_color
if self._campaign_difficulty == 'hard' ),
else un_sel_textcolor, textcolor=(
sel_textcolor
if self._campaign_difficulty == 'hard'
else un_sel_textcolor
),
) )
self._hard_button_lock_image = bui.imagewidget( self._hard_button_lock_image = bui.imagewidget(
parent=parent_widget, parent=parent_widget,
@ -960,35 +979,43 @@ class CoopBrowserWindow(bui.Window):
for i, tbutton in enumerate(self._tournament_buttons): for i, tbutton in enumerate(self._tournament_buttons):
bui.widget( bui.widget(
edit=tbutton.button, edit=tbutton.button,
up_widget=self._tournament_info_button up_widget=(
if i == 0 self._tournament_info_button
else self._tournament_buttons[i - 1].button, if i == 0
down_widget=self._tournament_buttons[(i + 1)].button else self._tournament_buttons[i - 1].button
if i + 1 < len(self._tournament_buttons) ),
else custom_h_scroll, down_widget=(
self._tournament_buttons[(i + 1)].button
if i + 1 < len(self._tournament_buttons)
else custom_h_scroll
),
) )
bui.widget( bui.widget(
edit=tbutton.more_scores_button, edit=tbutton.more_scores_button,
down_widget=self._tournament_buttons[ down_widget=(
(i + 1) self._tournament_buttons[(i + 1)].current_leader_name_text
].current_leader_name_text if i + 1 < len(self._tournament_buttons)
if i + 1 < len(self._tournament_buttons) else custom_h_scroll
else custom_h_scroll, ),
) )
bui.widget( bui.widget(
edit=tbutton.current_leader_name_text, edit=tbutton.current_leader_name_text,
up_widget=self._tournament_info_button up_widget=(
if i == 0 self._tournament_info_button
else self._tournament_buttons[i - 1].more_scores_button, if i == 0
else self._tournament_buttons[i - 1].more_scores_button
),
) )
for btn in self._custom_buttons: for btn in self._custom_buttons:
try: try:
bui.widget( bui.widget(
edit=btn.get_button(), edit=btn.get_button(),
up_widget=tournament_h_scroll up_widget=(
if self._tournament_buttons tournament_h_scroll
else self._tournament_info_button, if self._tournament_buttons
else self._tournament_info_button
),
) )
except Exception: except Exception:
logging.exception('Error wiring up custom buttons.') logging.exception('Error wiring up custom buttons.')
@ -1042,8 +1069,9 @@ class CoopBrowserWindow(bui.Window):
def _switch_to_score( def _switch_to_score(
self, self,
show_tab: StoreBrowserWindow.TabID show_tab: (
| None = StoreBrowserWindow.TabID.EXTRAS, StoreBrowserWindow.TabID | None
) = StoreBrowserWindow.TabID.EXTRAS,
) -> None: ) -> None:
# pylint: disable=cyclic-import # pylint: disable=cyclic-import
from bauiv1lib.account import show_sign_in_prompt from bauiv1lib.account import show_sign_in_prompt

View File

@ -48,7 +48,10 @@ class _HostLookupThread(Thread):
try: try:
import socket import socket
result = socket.gethostbyname(self._name) result = [
item[-1][0]
for item in socket.getaddrinfo(self.name, self._port)
][0]
except Exception: except Exception:
result = None result = None
bui.pushcall( bui.pushcall(
@ -212,15 +215,19 @@ class ManualGatherTab(GatherTab):
inactive_color = (0.5, 0.4, 0.5) inactive_color = (0.5, 0.4, 0.5)
bui.textwidget( bui.textwidget(
edit=self._join_by_address_text, edit=self._join_by_address_text,
color=active_color color=(
if value is SubTabType.JOIN_BY_ADDRESS active_color
else inactive_color, if value is SubTabType.JOIN_BY_ADDRESS
else inactive_color
),
) )
bui.textwidget( bui.textwidget(
edit=self._favorites_text, edit=self._favorites_text,
color=active_color color=(
if value is SubTabType.FAVORITES active_color
else inactive_color, if value is SubTabType.FAVORITES
else inactive_color
),
) )
# Clear anything existing in the old sub-tab. # Clear anything existing in the old sub-tab.
@ -354,9 +361,7 @@ class ManualGatherTab(GatherTab):
self._height = ( self._height = (
578 578
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 670 else 670 if uiscale is bui.UIScale.MEDIUM else 800
if uiscale is bui.UIScale.MEDIUM
else 800
) )
self._scroll_width = self._width - 130 + 2 * x_inset self._scroll_width = self._width - 130 + 2 * x_inset
@ -375,16 +380,12 @@ class ManualGatherTab(GatherTab):
b_height = ( b_height = (
107 107
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 142 else 142 if uiscale is bui.UIScale.MEDIUM else 190
if uiscale is bui.UIScale.MEDIUM
else 190
) )
b_space_extra = ( b_space_extra = (
0 0
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else -2 else -2 if uiscale is bui.UIScale.MEDIUM else -5
if uiscale is bui.UIScale.MEDIUM
else -5
) )
btnv = ( btnv = (
@ -392,9 +393,7 @@ class ManualGatherTab(GatherTab):
- ( - (
48 48
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 45 else 45 if uiscale is bui.UIScale.MEDIUM else 40
if uiscale is bui.UIScale.MEDIUM
else 40
) )
- b_height - b_height
) )
@ -513,9 +512,7 @@ class ManualGatherTab(GatherTab):
scale=( scale=(
1.8 1.8
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 1.55 else 1.55 if uiscale is bui.UIScale.MEDIUM else 1.0
if uiscale is bui.UIScale.MEDIUM
else 1.0
), ),
size=(c_width, c_height), size=(c_width, c_height),
transition='in_scale', transition='in_scale',

View File

@ -52,9 +52,7 @@ class PlaylistCustomizeBrowserWindow(bui.Window):
self._height = ( self._height = (
380.0 380.0
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 420.0 else 420.0 if uiscale is bui.UIScale.MEDIUM else 500.0
if uiscale is bui.UIScale.MEDIUM
else 500.0
) )
top_extra = 20.0 if uiscale is bui.UIScale.SMALL else 0.0 top_extra = 20.0 if uiscale is bui.UIScale.SMALL else 0.0
@ -66,13 +64,11 @@ class PlaylistCustomizeBrowserWindow(bui.Window):
scale=( scale=(
2.05 2.05
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 1.5 else 1.5 if uiscale is bui.UIScale.MEDIUM else 1.0
if uiscale is bui.UIScale.MEDIUM ),
else 1.0 stack_offset=(
(0, -10) if uiscale is bui.UIScale.SMALL else (0, 0)
), ),
stack_offset=(0, -10)
if uiscale is bui.UIScale.SMALL
else (0, 0),
) )
) )
@ -118,9 +114,7 @@ class PlaylistCustomizeBrowserWindow(bui.Window):
scl = ( scl = (
1.1 1.1
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 1.27 else 1.27 if uiscale is bui.UIScale.MEDIUM else 1.57
if uiscale is bui.UIScale.MEDIUM
else 1.57
) )
scl *= 0.63 scl *= 0.63
v -= 65.0 * scl v -= 65.0 * scl
@ -285,9 +279,11 @@ class PlaylistCustomizeBrowserWindow(bui.Window):
bui.widget( bui.widget(
edit=scrollwidget, edit=scrollwidget,
left_widget=new_button, left_widget=new_button,
right_widget=bui.get_special_widget('party_button') right_widget=(
if bui.app.ui_v1.use_toolbars bui.get_special_widget('party_button')
else None, if bui.app.ui_v1.use_toolbars
else None
),
) )
# make sure config exists # make sure config exists
@ -329,9 +325,9 @@ class PlaylistCustomizeBrowserWindow(bui.Window):
if self._selected_playlist_name is not None: if self._selected_playlist_name is not None:
cfg = bui.app.config cfg = bui.app.config
cfg[ cfg[self._pvars.config_name + ' Playlist Selection'] = (
self._pvars.config_name + ' Playlist Selection' self._selected_playlist_name
] = self._selected_playlist_name )
cfg.commit() cfg.commit()
bui.containerwidget( bui.containerwidget(
@ -408,9 +404,11 @@ class PlaylistCustomizeBrowserWindow(bui.Window):
text=self._get_playlist_display_name(pname), text=self._get_playlist_display_name(pname),
h_align='left', h_align='left',
v_align='center', v_align='center',
color=(0.6, 0.6, 0.7, 1.0) color=(
if pname == '__default__' (0.6, 0.6, 0.7, 1.0)
else (0.85, 0.85, 0.85, 1), if pname == '__default__'
else (0.85, 0.85, 0.85, 1)
),
always_highlight=True, always_highlight=True,
on_select_call=bui.Call(self._select, pname, index), on_select_call=bui.Call(self._select, pname, index),
on_activate_call=bui.Call(self._edit_button.activate), on_activate_call=bui.Call(self._edit_button.activate),
@ -458,12 +456,12 @@ class PlaylistCustomizeBrowserWindow(bui.Window):
# if we want and also lets us pass it to the game (since we reset # if we want and also lets us pass it to the game (since we reset
# the whole python environment that's not actually easy). # the whole python environment that's not actually easy).
cfg = bui.app.config cfg = bui.app.config
cfg[ cfg[self._pvars.config_name + ' Playlist Selection'] = (
self._pvars.config_name + ' Playlist Selection' self._selected_playlist_name
] = self._selected_playlist_name )
cfg[ cfg[self._pvars.config_name + ' Playlist Randomize'] = (
self._pvars.config_name + ' Playlist Randomize' self._do_randomize_val
] = self._do_randomize_val )
cfg.commit() cfg.commit()
def _new_playlist(self) -> None: def _new_playlist(self) -> None:
@ -536,12 +534,10 @@ class PlaylistCustomizeBrowserWindow(bui.Window):
# (we don't use len()-1 here because the default list adds one) # (we don't use len()-1 here because the default list adds one)
assert self._selected_playlist_index is not None assert self._selected_playlist_index is not None
if self._selected_playlist_index > len( self._selected_playlist_index = min(
bui.app.config[self._pvars.config_name + ' Playlists'] self._selected_playlist_index,
): len(bui.app.config[self._pvars.config_name + ' Playlists']),
self._selected_playlist_index = len( )
bui.app.config[self._pvars.config_name + ' Playlists']
)
self._refresh() self._refresh()
def _import_playlist(self) -> None: def _import_playlist(self) -> None:

View File

@ -43,9 +43,7 @@ class SoundtrackBrowserWindow(bui.Window):
self._height = ( self._height = (
340 340
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 370 else 370 if uiscale is bui.UIScale.MEDIUM else 440
if uiscale is bui.UIScale.MEDIUM
else 440
) )
spacing = 40.0 spacing = 40.0
v = self._height - 40.0 v = self._height - 40.0
@ -60,13 +58,11 @@ class SoundtrackBrowserWindow(bui.Window):
scale=( scale=(
2.3 2.3
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 1.6 else 1.6 if uiscale is bui.UIScale.MEDIUM else 1.0
if uiscale is bui.UIScale.MEDIUM ),
else 1.0 stack_offset=(
(0, -18) if uiscale is bui.UIScale.SMALL else (0, 0)
), ),
stack_offset=(0, -18)
if uiscale is bui.UIScale.SMALL
else (0, 0),
) )
) )
@ -110,9 +106,7 @@ class SoundtrackBrowserWindow(bui.Window):
scl = ( scl = (
1.0 1.0
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 1.13 else 1.13 if uiscale is bui.UIScale.MEDIUM else 1.4
if uiscale is bui.UIScale.MEDIUM
else 1.4
) )
v -= 60.0 * scl v -= 60.0 * scl
self._new_button = btn = bui.buttonwidget( self._new_button = btn = bui.buttonwidget(
@ -245,9 +239,11 @@ class SoundtrackBrowserWindow(bui.Window):
bui.widget( bui.widget(
edit=self._scrollwidget, edit=self._scrollwidget,
left_widget=self._new_button, left_widget=self._new_button,
right_widget=bui.get_special_widget('party_button') right_widget=(
if bui.app.ui_v1.use_toolbars bui.get_special_widget('party_button')
else self._scrollwidget, if bui.app.ui_v1.use_toolbars
else self._scrollwidget
),
) )
self._col = bui.columnwidget(parent=scrollwidget, border=2, margin=0) self._col = bui.columnwidget(parent=scrollwidget, border=2, margin=0)
@ -286,8 +282,9 @@ class SoundtrackBrowserWindow(bui.Window):
bui.getsound('shieldDown').play() bui.getsound('shieldDown').play()
assert self._selected_soundtrack_index is not None assert self._selected_soundtrack_index is not None
assert self._soundtracks is not None assert self._soundtracks is not None
if self._selected_soundtrack_index >= len(self._soundtracks): self._selected_soundtrack_index = min(
self._selected_soundtrack_index = len(self._soundtracks) self._selected_soundtrack_index, len(self._soundtracks)
)
self._refresh() self._refresh()
def _delete_soundtrack(self) -> None: def _delete_soundtrack(self) -> None:

View File

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

View File

@ -32,6 +32,7 @@ class HostConfig:
user: str = 'ubuntu' user: str = 'ubuntu'
port: int = 22 port: int = 22
mosh_port: int | None = None mosh_port: int | None = None
mosh_port_2: int | None = None
mosh_server_path: str | None = None mosh_server_path: str | None = None
mosh_shell: str = 'sh' mosh_shell: str = 'sh'
workspaces_root: str = '/home/${USER}/cloudshell_workspaces' workspaces_root: str = '/home/${USER}/cloudshell_workspaces'

View File

@ -236,7 +236,7 @@ class DirtyBit:
auto_dirty_seconds: float | None = None, auto_dirty_seconds: float | None = None,
min_update_interval: float | None = None, min_update_interval: float | None = None,
): ):
curtime = time.time() curtime = time.monotonic()
self._retry_interval = retry_interval self._retry_interval = retry_interval
self._auto_dirty_seconds = auto_dirty_seconds self._auto_dirty_seconds = auto_dirty_seconds
self._min_update_interval = min_update_interval self._min_update_interval = min_update_interval
@ -268,11 +268,13 @@ class DirtyBit:
# If we're freshly clean, set our next auto-dirty time (if we have # If we're freshly clean, set our next auto-dirty time (if we have
# one). # one).
if self._dirty and not value and self._auto_dirty_seconds is not None: if self._dirty and not value and self._auto_dirty_seconds is not None:
self._next_auto_dirty_time = time.time() + self._auto_dirty_seconds self._next_auto_dirty_time = (
time.monotonic() + self._auto_dirty_seconds
)
# If we're freshly dirty, schedule an immediate update. # If we're freshly dirty, schedule an immediate update.
if not self._dirty and value: if not self._dirty and value:
self._next_update_time = time.time() self._next_update_time = time.monotonic()
# If they want to enforce a minimum update interval, # If they want to enforce a minimum update interval,
# push out the next update time if it hasn't been long enough. # push out the next update time if it hasn't been long enough.
@ -295,7 +297,7 @@ class DirtyBit:
Takes into account the amount of time passed since the target Takes into account the amount of time passed since the target
was marked dirty or since should_update last returned True. was marked dirty or since should_update last returned True.
""" """
curtime = time.time() curtime = time.monotonic()
# Auto-dirty ourself if we're into that. # Auto-dirty ourself if we're into that.
if ( if (
@ -871,3 +873,11 @@ def ago_str(
timedelta_str(now - timeval, maxparts=maxparts, decimals=decimals) timedelta_str(now - timeval, maxparts=maxparts, decimals=decimals)
+ ' ago' + ' ago'
) )
def split_list(input_list: list[T], max_length: int) -> list[list[T]]:
"""Split a single list into smaller lists."""
return [
input_list[i : i + max_length]
for i in range(0, len(input_list), max_length)
]

View File

@ -103,14 +103,14 @@ def format_project_cpp_files(projroot: Path, full: bool) -> None:
dirtyfiles = cache.get_dirty_files() dirtyfiles = cache.get_dirty_files()
def format_file(filename: str) -> dict[str, Any]: def format_file(filename: str) -> dict[str, Any]:
start_time = time.time() start_time = time.monotonic()
# Note: seems os.system does not unlock the gil; # Note: seems os.system does not unlock the gil;
# make sure to use subprocess. # make sure to use subprocess.
result = subprocess.call(['clang-format', '-i', filename]) result = subprocess.call(['clang-format', '-i', filename])
if result != 0: if result != 0:
raise RuntimeError(f'Formatting failed for {filename}') raise RuntimeError(f'Formatting failed for {filename}')
duration = time.time() - start_time duration = time.monotonic() - start_time
print(f'Formatted {filename} in {duration:.2f} seconds.') print(f'Formatted {filename} in {duration:.2f} seconds.')
sys.stdout.flush() sys.stdout.flush()
return {'f': filename, 't': duration} return {'f': filename, 't': duration}
@ -514,7 +514,7 @@ def _run_pylint(
from pylint import lint from pylint import lint
from efro.terminal import Clr from efro.terminal import Clr
start_time = time.time() start_time = time.monotonic()
args = ['--rcfile', str(pylintrc), '--output-format=colorized'] args = ['--rcfile', str(pylintrc), '--output-format=colorized']
args += dirtyfiles args += dirtyfiles
@ -540,7 +540,7 @@ def _run_pylint(
if run.linter.msg_status != 0: if run.linter.msg_status != 0:
raise CleanError('Pylint failed.') raise CleanError('Pylint failed.')
duration = time.time() - start_time duration = time.monotonic() - start_time
print( print(
f'{Clr.GRN}Pylint passed for {name}' f'{Clr.GRN}Pylint passed for {name}'
f' in {duration:.1f} seconds.{Clr.RST}' f' in {duration:.1f} seconds.{Clr.RST}'
@ -796,12 +796,12 @@ def mypy(projroot: Path, full: bool) -> None:
filenames = get_script_filenames(projroot) filenames = get_script_filenames(projroot)
desc = '(full)' if full else '(incremental)' desc = '(full)' if full else '(incremental)'
print(f'{Clr.BLU}Running Mypy {desc}...{Clr.RST}', flush=True) print(f'{Clr.BLU}Running Mypy {desc}...{Clr.RST}', flush=True)
starttime = time.time() starttime = time.monotonic()
try: try:
mypy_files(projroot, filenames, full) mypy_files(projroot, filenames, full)
except Exception as exc: except Exception as exc:
raise CleanError('Mypy failed.') from exc raise CleanError('Mypy failed.') from exc
duration = time.time() - starttime duration = time.monotonic() - starttime
print( print(
f'{Clr.GRN}Mypy passed in {duration:.1f} seconds.{Clr.RST}', flush=True f'{Clr.GRN}Mypy passed in {duration:.1f} seconds.{Clr.RST}', flush=True
) )
@ -819,7 +819,7 @@ def dmypy(projroot: Path) -> None:
return return
print('Running Mypy (daemon)...', flush=True) print('Running Mypy (daemon)...', flush=True)
starttime = time.time() starttime = time.monotonic()
try: try:
args = [ args = [
'dmypy', 'dmypy',
@ -834,7 +834,7 @@ def dmypy(projroot: Path) -> None:
subprocess.run(args, check=True) subprocess.run(args, check=True)
except Exception as exc: except Exception as exc:
raise CleanError('Mypy daemon: fail.') from exc raise CleanError('Mypy daemon: fail.') from exc
duration = time.time() - starttime duration = time.monotonic() - starttime
print( print(
f'{Clr.GRN}Mypy daemon passed in {duration:.1f} seconds.{Clr.RST}', f'{Clr.GRN}Mypy daemon passed in {duration:.1f} seconds.{Clr.RST}',
flush=True, flush=True,
@ -893,7 +893,7 @@ def _run_idea_inspections(
from efro.terminal import Clr from efro.terminal import Clr
start_time = time.time() start_time = time.monotonic()
print( print(
f'{Clr.BLU}{displayname} checking' f'{Clr.BLU}{displayname} checking'
f' {len(scripts)} file(s)...{Clr.RST}', f' {len(scripts)} file(s)...{Clr.RST}',
@ -944,7 +944,7 @@ def _run_idea_inspections(
f'{Clr.SRED}{displayname} inspection' f'{Clr.SRED}{displayname} inspection'
f' found {total_errors} error(s).{Clr.RST}' f' found {total_errors} error(s).{Clr.RST}'
) )
duration = time.time() - start_time duration = time.monotonic() - start_time
print( print(
f'{Clr.GRN}{displayname} passed for {len(scripts)} files' f'{Clr.GRN}{displayname} passed for {len(scripts)} files'
f' in {duration:.1f} seconds.{Clr.RST}', f' in {duration:.1f} seconds.{Clr.RST}',

View File

@ -37,8 +37,8 @@ VERSION_MIN_TVOS = '9.0'
# why-is-lldb-generating-exc-bad-instruction-with-user-compiled-library-on-macos # why-is-lldb-generating-exc-bad-instruction-with-user-compiled-library-on-macos
# #
# For now will try to ride out this 3.0 LTS version as long as possible. # For now will try to ride out this 3.0 LTS version as long as possible.
OPENSSL_VER_APPLE = '3.0.12' OPENSSL_VER_APPLE = '3.0.13'
OPENSSL_VER_ANDROID = '3.0.12' OPENSSL_VER_ANDROID = '3.0.13'
LIBFFI_VER_APPLE = '3.4.4' LIBFFI_VER_APPLE = '3.4.4'
BZIP2_VER_APPLE = '1.0.8' BZIP2_VER_APPLE = '1.0.8'