From 501f544ff8339b107896988292dc0d1ed0730479 Mon Sep 17 00:00:00 2001 From: FAL-Guys <85888040+FAL-Guys@users.noreply.github.com> Date: Fri, 19 Aug 2022 21:40:08 +0430 Subject: [PATCH 01/10] Epic mode in keepaway.py Added Epic mode support. --- assets/src/ba_data/python/bastd/game/keepaway.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/assets/src/ba_data/python/bastd/game/keepaway.py b/assets/src/ba_data/python/bastd/game/keepaway.py index 0dd355ee..e3b4eca7 100644 --- a/assets/src/ba_data/python/bastd/game/keepaway.py +++ b/assets/src/ba_data/python/bastd/game/keepaway.py @@ -76,6 +76,7 @@ class KeepAwayGame(ba.TeamGameActivity[Player, Team]): ], default=1.0, ), + ba.BoolSetting('Epic Mode', default=False), ] scoreconfig = ba.ScoreConfig(label='Time Held') default_music = ba.MusicType.KEEP_AWAY @@ -115,6 +116,8 @@ class KeepAwayGame(ba.TeamGameActivity[Player, Team]): self._flag: Flag | None = None self._hold_time = int(settings['Hold Time']) self._time_limit = float(settings['Time Limit']) + self._epic_mode = bool(settings['Epic Mode']) + self.slow_motion = self._epic_mode def get_instance_description(self) -> str | Sequence: return 'Carry the flag for ${ARG1} seconds.', self._hold_time From 23d2f9ec539335c2f927cec13fafecffc3a1f58c Mon Sep 17 00:00:00 2001 From: FAL-Guys <85888040+FAL-Guys@users.noreply.github.com> Date: Fri, 19 Aug 2022 21:53:30 +0430 Subject: [PATCH 02/10] Update kingofthehill.py --- assets/src/ba_data/python/bastd/game/kingofthehill.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/assets/src/ba_data/python/bastd/game/kingofthehill.py b/assets/src/ba_data/python/bastd/game/kingofthehill.py index becdc8b7..c573141b 100644 --- a/assets/src/ba_data/python/bastd/game/kingofthehill.py +++ b/assets/src/ba_data/python/bastd/game/kingofthehill.py @@ -79,6 +79,7 @@ class KingOfTheHillGame(ba.TeamGameActivity[Player, Team]): ], default=1.0, ), + ba.BoolSetting('Epic Mode', default=False), ] scoreconfig = ba.ScoreConfig(label='Time Held') @@ -115,6 +116,7 @@ class KingOfTheHillGame(ba.TeamGameActivity[Player, Team]): self._scoring_team: weakref.ref[Team] | None = None self._hold_time = int(settings['Hold Time']) self._time_limit = float(settings['Time Limit']) + self._epic_mode = bool(settings['Epic Mode']) self._flag_region_material = ba.Material() self._flag_region_material.add_actions( conditions=('they_have_material', shared.player_material), @@ -128,6 +130,7 @@ class KingOfTheHillGame(ba.TeamGameActivity[Player, Team]): )) # Base class overrides. + self.slow_motion = self._epic_mode self.default_music = ba.MusicType.SCARY def get_instance_description(self) -> str | Sequence: From 6fbbe5ca52f545d0043e6c2cc03c57a167bfd4fc Mon Sep 17 00:00:00 2001 From: FAL-Guys <85888040+FAL-Guys@users.noreply.github.com> Date: Thu, 1 Sep 2022 19:48:02 +0430 Subject: [PATCH 03/10] Update keepaway.py --- assets/src/ba_data/python/bastd/game/keepaway.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assets/src/ba_data/python/bastd/game/keepaway.py b/assets/src/ba_data/python/bastd/game/keepaway.py index e3b4eca7..2e179534 100644 --- a/assets/src/ba_data/python/bastd/game/keepaway.py +++ b/assets/src/ba_data/python/bastd/game/keepaway.py @@ -79,7 +79,6 @@ class KeepAwayGame(ba.TeamGameActivity[Player, Team]): ba.BoolSetting('Epic Mode', default=False), ] scoreconfig = ba.ScoreConfig(label='Time Held') - default_music = ba.MusicType.KEEP_AWAY @classmethod def supports_session_type(cls, sessiontype: type[ba.Session]) -> bool: @@ -118,6 +117,8 @@ class KeepAwayGame(ba.TeamGameActivity[Player, Team]): self._time_limit = float(settings['Time Limit']) self._epic_mode = bool(settings['Epic Mode']) self.slow_motion = self._epic_mode + self.default_music = (ba.MusicType.EPIC if self._epic_mode else + ba.MusicType.KEEP_AWAY) def get_instance_description(self) -> str | Sequence: return 'Carry the flag for ${ARG1} seconds.', self._hold_time From d6f7971af7e26c4dc5f0d5646e1a6dc182e57a99 Mon Sep 17 00:00:00 2001 From: FAL-Guys <85888040+FAL-Guys@users.noreply.github.com> Date: Thu, 1 Sep 2022 19:49:02 +0430 Subject: [PATCH 04/10] Update kingofthehill.py --- assets/src/ba_data/python/bastd/game/kingofthehill.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assets/src/ba_data/python/bastd/game/kingofthehill.py b/assets/src/ba_data/python/bastd/game/kingofthehill.py index c573141b..87b8080e 100644 --- a/assets/src/ba_data/python/bastd/game/kingofthehill.py +++ b/assets/src/ba_data/python/bastd/game/kingofthehill.py @@ -131,7 +131,8 @@ class KingOfTheHillGame(ba.TeamGameActivity[Player, Team]): # Base class overrides. self.slow_motion = self._epic_mode - self.default_music = ba.MusicType.SCARY + self.default_music = (ba.MusicType.EPIC if self._epic_mode else + ba.MusicType.SCARY) def get_instance_description(self) -> str | Sequence: return 'Secure the flag for ${ARG1} seconds.', self._hold_time From de44f8b459f9cbb707cf5ac5d8d992bdc84eae87 Mon Sep 17 00:00:00 2001 From: FAL-Guys <85888040+FAL-Guys@users.noreply.github.com> Date: Thu, 1 Sep 2022 20:02:11 +0430 Subject: [PATCH 05/10] Update hockey.py --- assets/src/ba_data/python/bastd/game/hockey.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/assets/src/ba_data/python/bastd/game/hockey.py b/assets/src/ba_data/python/bastd/game/hockey.py index 97213a60..77a95ce0 100644 --- a/assets/src/ba_data/python/bastd/game/hockey.py +++ b/assets/src/ba_data/python/bastd/game/hockey.py @@ -137,8 +137,8 @@ class HockeyGame(ba.TeamGameActivity[Player, Team]): ], default=1.0, ), + ba.BoolSetting('Epic Mode', default=False), ] - default_music = ba.MusicType.HOCKEY @classmethod def supports_session_type(cls, sessiontype: type[ba.Session]) -> bool: @@ -203,6 +203,10 @@ class HockeyGame(ba.TeamGameActivity[Player, Team]): self._puck: Puck | None = None self._score_to_win = int(settings['Score to Win']) self._time_limit = float(settings['Time Limit']) + self._epic_mode = bool(settings['Epic Mode']) + self.slow_motion = self._epic_mode + self.default_music = (ba.MusicType.EPIC if self._epic_mode else + ba.MusicType.HOCKEY) def get_instance_description(self) -> str | Sequence: if self._score_to_win == 1: From 8793937c16bcf22cdc911caccf470042175a8da2 Mon Sep 17 00:00:00 2001 From: FAL-Guys <85888040+FAL-Guys@users.noreply.github.com> Date: Thu, 1 Sep 2022 20:06:44 +0430 Subject: [PATCH 06/10] Update football.py --- assets/src/ba_data/python/bastd/game/football.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/assets/src/ba_data/python/bastd/game/football.py b/assets/src/ba_data/python/bastd/game/football.py index c499435f..63236c19 100644 --- a/assets/src/ba_data/python/bastd/game/football.py +++ b/assets/src/ba_data/python/bastd/game/football.py @@ -106,8 +106,8 @@ class FootballTeamGame(ba.TeamGameActivity[Player, Team]): ], default=1.0, ), + ba.BoolSetting('Epic Mode', default=False), ] - default_music = ba.MusicType.FOOTBALL @classmethod def supports_session_type(cls, sessiontype: type[ba.Session]) -> bool: @@ -143,6 +143,10 @@ class FootballTeamGame(ba.TeamGameActivity[Player, Team]): self._flag_respawn_light: ba.NodeActor | None = None self._score_to_win = int(settings['Score to Win']) self._time_limit = float(settings['Time Limit']) + self._epic_mode = bool(settings['Epic Mode']) + self.slow_motion = self._epic_mode + self.default_music = (ba.MusicType.EPIC if self._epic_mode else + ba.MusicType.FOOTBALL) def get_instance_description(self) -> str | Sequence: touchdowns = self._score_to_win / 7 @@ -330,7 +334,6 @@ class FootballCoopGame(ba.CoopGameActivity[Player, Team]): tips = ['Use the pick-up button to grab the flag < ${PICKUP} >'] scoreconfig = ba.ScoreConfig(scoretype=ba.ScoreType.MILLISECONDS, version='B') - default_music = ba.MusicType.FOOTBALL # FIXME: Need to update co-op games to use getscoreconfig. def get_score_type(self) -> str: From 3ef33a8467fb5a221a9be949b4ef587e2a0e9772 Mon Sep 17 00:00:00 2001 From: Eric Date: Thu, 1 Sep 2022 10:47:59 -0700 Subject: [PATCH 07/10] logging revamp groundwork --- .efrocachemap | 56 ++-- .idea/dictionaries/ericf.xml | 4 + CHANGELOG.md | 2 +- assets/.asset_manifest_public.json | 2 + assets/Makefile | 2 + .../.idea/dictionaries/ericf.xml | 4 + src/ballistica/ballistica.cc | 2 +- tools/efro/log.py | 241 ++++++++++++++++++ 8 files changed, 283 insertions(+), 30 deletions(-) create mode 100644 tools/efro/log.py diff --git a/.efrocachemap b/.efrocachemap index 808538f8..19ae2423 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -3995,26 +3995,26 @@ "assets/src/ba_data/python/ba/_generated/__init__.py": "https://files.ballistica.net/cache/ba1/ee/e8/cad05aa531c7faf7ff7b96db7f6e", "assets/src/ba_data/python/ba/_generated/enums.py": "https://files.ballistica.net/cache/ba1/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/0a/56/252de9190ee6367ccbf37174783d", - "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/f5/30/29f5a9d9cc5c6f5c76e3058d3621", - "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/3e/e5/037d736cacd93a4b005cc93e72ad", - "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/22/04/430aa3457c427f0814058c2b4483", - "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/93/68/307719e44199480a5ee051d993f5", - "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/9f/50/6f8a60e5375bf651bdebda617249", - "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/cf/03/a5a5748fda33c876fbf3e8261b02", - "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/82/3e/5725b87a8cc1e90f69bec58c65d5", - "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/64/16/1589abfd35715bd2aa2915766148", - "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/a8/36/584d685f3bea03753acf7344dfce", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/3d/09/cbb451c2e8f856de61c0eafc5fdc", - "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/b3/c9/9b3e221426dae6a047a893a4eb39", - "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/61/2e/af3b07614ea2fb60f70b3d3b442a", - "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/6e/fb/4b6e3e14ae9e329ae2a5c2eaab24", - "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/86/3b/f8fc04eefa313d673ee98d20e360", - "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/d1/83/544e088664612666bbaa6c1ff422", - "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/79/13/29d322c6e8f7717ec87d5027bb20", - "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/94/01/19f43fe2ee530d48f31665d22ff0", - "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/17/e9/d6369d897f3595fbe03202887447", - "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/07/ff/cd46cba42a67cf31d6454b9eba7d", + "build/prefab/full/linux_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/8f/35/1a6fbc2bd9d367b5b5d8350199da", + "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/e8/df/e7aae0645d3813227e32628a0ff3", + "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/ce/43/1d18f5d73d3fe5d7f1ed4fdc472c", + "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/cb/04/5dc6236fd0ebeafbd013299a4766", + "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/e1/3a/bbe527aae553058d38a89a85e6b5", + "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/60/1c/2e11dded6067b1cb27e6f6d48a0a", + "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/59/fd/0f61ebccbcfb85d01693c431f5a6", + "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/9b/94/8a16341d49d6de25102c07c70675", + "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/ac/1d/d48d569a072d45d96ea86760b9f0", + "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/d7/31/f3a671560f4efb8708430f0ce985", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/6e/76/fa07d7183f1bd0d438657339d33a", + "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/b0/8b/60a531e23f24bba638e3fc615ed3", + "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/9c/1b/519b7ba8f1718787d8ab62f61222", + "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/4b/a0/138ece248132798d69cc81bce581", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/a1/58/18ba7845fb9524a5cfef4d14bf7f", + "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/12/93/7e04d239fd333188b1412272c873", + "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/44/cb/2144fb8e2fc054d605e8e3baea77", + "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/89/90/a98081fbe24f8d062443ce84f3cc", + "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/c9/80/1de60807e22d9a46c6902badbe7f", + "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/d7/f1/e2d6d8fdedd4ec4f3a6c0cc6bc14", "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/3b/0c/2f4061ab877d415a1c30e0e736db", "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/3c/5a/2b0714af254c64954ccfe51c70b3", "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/1f/ae/c8a885b1a1868b6846b606cdb456", @@ -4031,14 +4031,14 @@ "build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/44/df/efb51d1c226eac613d48e2cbf0b8", "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/1c/f6/357fe951c86c9fc5b1b737cd91ae", "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/04/17/e2de0ab5df6b938d828e8662ce6d", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/69/dc/6fc1614b2548c6ac76c9e891c2e2", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/c2/1b/263c5e001c6891d774d941f0bdfd", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/7b/3a/f77ffca8d7c45b859d1e48c1b468", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/88/15/1aa07f986d0bf7dac9a1f39635f2", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/4b/e1/646d3095ab442e0b18d4c0de9689", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/0f/fe/034c116781ddfe6cc89ada030056", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/91/64/10fcd883cf0d15895d72a638e2ad", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/1e/69/bf40bc8defe923cfa6d48cb5dd04", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/97/5d/5255b7a90235bc570e71bfaf9f60", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/07/0b/c65c6f6b009633a7cf66ea1c9e08", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/81/09/10f7873ec315479806a9daa6e100", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/0f/09/ab4219ed9d6b6b63439a33f38aac", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/fd/ae/d0a4fb20969028322bab2ae2365d", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/0b/cf/4b7529302b842bc75695f93c4172", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/ad/b0/7d2ca14baad3fdb2aac296352570", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/68/f8/156cbf9f5cf0fcbae9f12e8b18e8", "src/ballistica/generated/python_embedded/binding.inc": "https://files.ballistica.net/cache/ba1/7d/3e/229a581cb2454ed856f1d8b564a7", "src/ballistica/generated/python_embedded/bootstrap.inc": "https://files.ballistica.net/cache/ba1/aa/a5/3ddc86d1789b2bf1d376b7671a3d" } \ No newline at end of file diff --git a/.idea/dictionaries/ericf.xml b/.idea/dictionaries/ericf.xml index a679acc7..ab5c5eba 100644 --- a/.idea/dictionaries/ericf.xml +++ b/.idea/dictionaries/ericf.xml @@ -337,6 +337,7 @@ capturetheflag carentity cashregistersound + cbegin cbgn cbits cbot @@ -699,6 +700,7 @@ eachother eaddrnotavail easteregghunt + echofile edcc editcontroller editgame @@ -891,6 +893,7 @@ floofcls floooff floop + flushhhhh flycheck fmod fname @@ -1391,6 +1394,7 @@ listvalidconfigs lival llzma + lmap lmerged lmod lmodfile diff --git a/CHANGELOG.md b/CHANGELOG.md index b0e80f79..ca34f7b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -### 1.7.7 (build 20723, api 7, 2022-08-26) +### 1.7.7 (build 20725, api 7, 2022-09-01) - Added `ba.app.meta.load_exported_classes()` for loading classes discovered by the meta subsystem cleanly in a background thread. - Improved logging of missing playlist game types. - Some ba.Lstr functionality can now be used in background threads. diff --git a/assets/.asset_manifest_public.json b/assets/.asset_manifest_public.json index 306022cc..b447e3ff 100644 --- a/assets/.asset_manifest_public.json +++ b/assets/.asset_manifest_public.json @@ -511,6 +511,7 @@ "ba_data/python/efro/__pycache__/__init__.cpython-310.opt-1.pyc", "ba_data/python/efro/__pycache__/call.cpython-310.opt-1.pyc", "ba_data/python/efro/__pycache__/error.cpython-310.opt-1.pyc", + "ba_data/python/efro/__pycache__/log.cpython-310.opt-1.pyc", "ba_data/python/efro/__pycache__/rpc.cpython-310.opt-1.pyc", "ba_data/python/efro/__pycache__/terminal.cpython-310.opt-1.pyc", "ba_data/python/efro/__pycache__/util.cpython-310.opt-1.pyc", @@ -532,6 +533,7 @@ "ba_data/python/efro/dataclassio/_prep.py", "ba_data/python/efro/dataclassio/extras.py", "ba_data/python/efro/error.py", + "ba_data/python/efro/log.py", "ba_data/python/efro/message/__init__.py", "ba_data/python/efro/message/__pycache__/__init__.cpython-310.opt-1.pyc", "ba_data/python/efro/message/__pycache__/_message.cpython-310.opt-1.pyc", diff --git a/assets/Makefile b/assets/Makefile index bda34d3f..a8898ae9 100644 --- a/assets/Makefile +++ b/assets/Makefile @@ -664,6 +664,7 @@ SCRIPT_TARGETS_PY_PUBLIC_TOOLS = \ build/ba_data/python/efro/dataclassio/_prep.py \ build/ba_data/python/efro/dataclassio/extras.py \ build/ba_data/python/efro/error.py \ + build/ba_data/python/efro/log.py \ build/ba_data/python/efro/message/__init__.py \ build/ba_data/python/efro/message/_message.py \ build/ba_data/python/efro/message/_module.py \ @@ -694,6 +695,7 @@ SCRIPT_TARGETS_PYC_PUBLIC_TOOLS = \ build/ba_data/python/efro/dataclassio/__pycache__/_prep.cpython-310.opt-1.pyc \ build/ba_data/python/efro/dataclassio/__pycache__/extras.cpython-310.opt-1.pyc \ build/ba_data/python/efro/__pycache__/error.cpython-310.opt-1.pyc \ + build/ba_data/python/efro/__pycache__/log.cpython-310.opt-1.pyc \ build/ba_data/python/efro/message/__pycache__/__init__.cpython-310.opt-1.pyc \ build/ba_data/python/efro/message/__pycache__/_message.cpython-310.opt-1.pyc \ build/ba_data/python/efro/message/__pycache__/_module.cpython-310.opt-1.pyc \ diff --git a/ballisticacore-cmake/.idea/dictionaries/ericf.xml b/ballisticacore-cmake/.idea/dictionaries/ericf.xml index b9d0ddbe..b10c4aa3 100644 --- a/ballisticacore-cmake/.idea/dictionaries/ericf.xml +++ b/ballisticacore-cmake/.idea/dictionaries/ericf.xml @@ -188,6 +188,7 @@ cancelbtn capitan cargs + cbegin cbgn cbresults cbtnoffs @@ -362,6 +363,7 @@ dxgi dynamicdata echidna + echofile edef effmult efro @@ -460,6 +462,7 @@ floooff floop flopsy + flushhhhh fname fnode fnumc @@ -703,6 +706,7 @@ linkstoryboards listobj llock + lmap localmodlibs localns lockpath diff --git a/src/ballistica/ballistica.cc b/src/ballistica/ballistica.cc index e781430d..1c7d2d9f 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 = 20723; +const int kAppBuildNumber = 20725; const char* kAppVersion = "1.7.7"; // Our standalone globals. diff --git a/tools/efro/log.py b/tools/efro/log.py new file mode 100644 index 00000000..a2e78637 --- /dev/null +++ b/tools/efro/log.py @@ -0,0 +1,241 @@ +# Released under the MIT License. See LICENSE for details. +# +"""Logging functionality.""" +from __future__ import annotations + +import sys +import time +import logging +import datetime +import threading +from enum import Enum +from typing import TYPE_CHECKING, Annotated +from dataclasses import dataclass + +from efro.util import utc_now +from efro.dataclassio import ioprepped, IOAttrs, dataclass_to_json +from efro.terminal import TerminalColor + +if TYPE_CHECKING: + from typing import Any, Callable + from pathlib import Path + + +class LogLevel(Enum): + """Severity level for a log entry. + + Note: these are numeric values so they can be compared in severity. + """ + DEBUG = 0 + INFO = 1 + WARNING = 2 + ERROR = 3 + CRITICAL = 4 + + +@ioprepped +@dataclass +class LogEntry: + """Structured log entry.""" + name: Annotated[str, + IOAttrs('n', soft_default='root', store_default=False)] + message: Annotated[str, IOAttrs('m')] + level: Annotated[LogLevel, IOAttrs('l')] + time: Annotated[datetime.datetime, IOAttrs('t')] + + +class StructuredLogHandler(logging.StreamHandler): + """Fancy-pants handler for logging output. + + Writes logs to disk in structured json format and echoes them + to stdout/stderr with pretty colors. + """ + + def __init__(self, + path: str | Path | None, + echofile: Any, + suppress_non_root_debug: bool = False): + super().__init__() + # pylint: disable=consider-using-with + self._file = (None + if path is None else open(path, 'w', encoding='utf-8')) + self._echofile = echofile + self._callbacks: list[Callable[[LogEntry], None]] = [] + self._suppress_non_root_debug = suppress_non_root_debug + + def emit(self, record: logging.LogRecord) -> None: + if (self._suppress_non_root_debug and record.name != 'root' + and record.levelname == 'DEBUG'): + return + msg = self.format(record) + + # Translate Python log levels to our own. + level = { + 'DEBUG': LogLevel.DEBUG, + 'INFO': LogLevel.INFO, + 'WARNING': LogLevel.WARNING, + 'ERROR': LogLevel.ERROR, + 'CRITICAL': LogLevel.CRITICAL + }[record.levelname] + + entry = LogEntry(message=msg, + name=record.name, + level=level, + time=datetime.datetime.fromtimestamp( + record.created, datetime.timezone.utc)) + + for call in self._callbacks: + call(entry) + + # Also route log entries to the echo file (generally stdout) + if self._echofile is not None: + cbegin: str + cend: str + cbegin, cend = { + LogLevel.DEBUG: + (TerminalColor.CYAN.value, TerminalColor.RESET.value), + LogLevel.INFO: ('', ''), + LogLevel.WARNING: + (TerminalColor.YELLOW.value, TerminalColor.RESET.value), + LogLevel.ERROR: + (TerminalColor.RED.value, TerminalColor.RESET.value), + LogLevel.CRITICAL: + (TerminalColor.STRONG_MAGENTA.value + + TerminalColor.BOLD.value + TerminalColor.BG_BLACK.value, + TerminalColor.RESET.value), + }[level] + + self._echofile.write(f'{cbegin}{msg}{cend}\n') + + # Note to self: it sounds like logging wraps calls to us + # in a lock so we shouldn't have to worry about garbled + # json output due to multiple threads writing at once, + # but may be good to find out for sure? + if self._file is not None: + entry_s = dataclass_to_json(entry) + assert '\n' not in entry_s # make sure its a single line + print(entry_s, file=self._file, flush=True) + + def emit_custom(self, name: str, message: str, level: LogLevel) -> None: + """Custom emit call for our stdout/stderr redirection.""" + entry = LogEntry(name=name, + message=message, + level=level, + time=utc_now()) + + # Inform anyone who wants to know about this log's level. + for call in self._callbacks: + call(entry) + + if self._file is not None: + entry_s = dataclass_to_json(entry) + assert '\n' not in entry_s # Make sure its a single line. + print(entry_s, file=self._file, flush=True) + + def add_callback(self, call: Callable[[LogEntry], None]) -> None: + """Add a callback to be run for each added entry.""" + self._callbacks.append(call) + + +class LogRedirect: + """A file-like object for redirecting stdout/stderr to our log.""" + + def __init__(self, name: str, orig_out: Any, + log_handler: StructuredLogHandler, log_level: LogLevel): + self._name = name + self._orig_out = orig_out + self._log_handler = log_handler + self._log_level = log_level + self._chunk = '' + self._chunk_start_time = 0.0 + self._lock = threading.Lock() + + def write(self, s: str) -> None: + """Write something to output.""" + + assert isinstance(s, str) + + # First, ship it off to the original destination. + self._orig_out.write(s) + + # Now add this to our chunk and ship completed chunks + # off to the logger. + # Let's consider a chunk completed when we're passed + # a single '\n' by itself. (print() statement will do + # this at the end by default). + # We may get some false positives/negatives this way + # but it should result in *most* big multi-line print + # statements being wrapped into a single log entry. + # Also, flush with only_old=True can be called periodically + # to dump any pending chunks that don't happen to fit + # this pattern. + with self._lock: + if s == '\n': + self._log_handler.emit_custom(name=self._name, + message=self._chunk, + level=self._log_level) + self._chunk = '' + else: + if self._chunk == '': + self._chunk_start_time = time.time() + self._chunk += s + + def flush(self, only_old: bool = False) -> None: + """Flushhhhh!""" + self._orig_out.flush() + if only_old and time.time() - self._chunk_start_time < 0.5: + return + with self._lock: + if self._chunk != '': + chunk = self._chunk + if chunk.endswith('\n'): + chunk = chunk[:-1] + self._log_handler.emit_custom(name=self._name, + message=chunk, + level=self._log_level) + self._chunk = '' + + +def setup_logging( + log_path: str | Path | None, + level: LogLevel, + suppress_non_root_debug: bool = False) -> StructuredLogHandler: + """Set up our logging environment. + + Returns the custom handler which can be used to fetch information + about logs that have passed through it. (worst log-levels, etc.). + """ + + lmap = { + LogLevel.DEBUG: logging.DEBUG, + LogLevel.INFO: logging.INFO, + LogLevel.WARNING: logging.WARNING, + LogLevel.ERROR: logging.ERROR, + LogLevel.CRITICAL: logging.CRITICAL, + } + + # Wire logger output to go to a structured log file. + # Also echo it to stderr IF we're running in a terminal. + loghandler = StructuredLogHandler( + log_path, + echofile=sys.stderr if sys.stderr.isatty() else None, + suppress_non_root_debug=suppress_non_root_debug) + + logging.basicConfig(level=lmap[level], + format='%(message)s', + handlers=[loghandler]) + + # DISABLING THIS BIT FOR NOW - want to keep things as pure as possible. + if bool(False): + # Now wire Python stdout/stderr output to generate log entries + # in addition to its regular routing. Make sure to do this *after* we + # tell the log-handler to write to stderr, otherwise we get an infinite + # loop. + # NOTE: remember that this won't capture subcommands or other + # non-python stdout/stderr output. + sys.stdout = LogRedirect( # type: ignore + 'stdout', sys.stdout, loghandler, LogLevel.INFO) + sys.stderr = LogRedirect( # type: ignore + 'stderr', sys.stderr, loghandler, LogLevel.INFO) + + return loghandler From 94cd7070e8ba2f45032f3af732f1c56351a3b26c Mon Sep 17 00:00:00 2001 From: Eric Date: Fri, 2 Sep 2022 08:33:50 -0700 Subject: [PATCH 08/10] moving some bootstrapping to python layer --- .efrocachemap | 58 +++--- CHANGELOG.md | 3 +- assets/.asset_manifest_public.json | 2 + assets/Makefile | 2 + assets/src/ba_data/python/ba/_bootstrap.py | 182 +++++++++++++++++++ src/ballistica/ballistica.cc | 2 +- src/meta/bameta/python_embedded/bootstrap.py | 158 +--------------- tools/efro/log.py | 36 ++-- 8 files changed, 247 insertions(+), 196 deletions(-) create mode 100644 assets/src/ba_data/python/ba/_bootstrap.py diff --git a/.efrocachemap b/.efrocachemap index 19ae2423..dd6f427f 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -3995,26 +3995,26 @@ "assets/src/ba_data/python/ba/_generated/__init__.py": "https://files.ballistica.net/cache/ba1/ee/e8/cad05aa531c7faf7ff7b96db7f6e", "assets/src/ba_data/python/ba/_generated/enums.py": "https://files.ballistica.net/cache/ba1/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/8f/35/1a6fbc2bd9d367b5b5d8350199da", - "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/e8/df/e7aae0645d3813227e32628a0ff3", - "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/ce/43/1d18f5d73d3fe5d7f1ed4fdc472c", - "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/cb/04/5dc6236fd0ebeafbd013299a4766", - "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/e1/3a/bbe527aae553058d38a89a85e6b5", - "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/60/1c/2e11dded6067b1cb27e6f6d48a0a", - "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/59/fd/0f61ebccbcfb85d01693c431f5a6", - "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/9b/94/8a16341d49d6de25102c07c70675", - "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/ac/1d/d48d569a072d45d96ea86760b9f0", - "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/d7/31/f3a671560f4efb8708430f0ce985", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/6e/76/fa07d7183f1bd0d438657339d33a", - "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/b0/8b/60a531e23f24bba638e3fc615ed3", - "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/9c/1b/519b7ba8f1718787d8ab62f61222", - "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/4b/a0/138ece248132798d69cc81bce581", - "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/a1/58/18ba7845fb9524a5cfef4d14bf7f", - "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/12/93/7e04d239fd333188b1412272c873", - "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/44/cb/2144fb8e2fc054d605e8e3baea77", - "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/89/90/a98081fbe24f8d062443ce84f3cc", - "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/c9/80/1de60807e22d9a46c6902badbe7f", - "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/d7/f1/e2d6d8fdedd4ec4f3a6c0cc6bc14", + "build/prefab/full/linux_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/16/68/50bab5698a6f581fb56ba314d953", + "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/88/e0/d5043781c54e6eceb273b6df0d38", + "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/da/dd/d847840917c2b44c3faa7f360133", + "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/73/06/99a81805a891faed7f126e795dda", + "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/e3/45/1cba0d26da1b275b36e6dd5e2487", + "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/28/8b/40a34cf4436f6644b4c60dd75ea5", + "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/d0/51/3a2ca66c96aca2f9649de78fa076", + "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/c3/b3/4900e33f2a75408842f568a53f6b", + "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/32/26/b90ad9ea1ed8c6fc32684b52f741", + "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/8c/3c/77eaf5714f5fb4c793b8e5d2b7cf", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/ff/9b/d13d185b8091790b28804d918d07", + "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/c1/39/b3aeb79b72a36df1069c495ec8fd", + "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/b9/8f/5e01bcc248400251f6a1ac45ca96", + "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/14/73/29cc3cba5c54c6f29700e9392f30", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/e4/60/b20fbb2f034ba8f0d250f287bad5", + "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/89/14/5529452723c8477b8882b1aecd81", + "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/07/08/5abca1559160b52c5cb51366b9e5", + "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/25/03/978fc62e0298b7d8322ade9fca18", + "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/bd/31/d8242ecff0934e358fb8fcb2675a", + "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/7c/7d/6c02413bb4bd8ed58a067c78884f", "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/3b/0c/2f4061ab877d415a1c30e0e736db", "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/3c/5a/2b0714af254c64954ccfe51c70b3", "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/1f/ae/c8a885b1a1868b6846b606cdb456", @@ -4031,14 +4031,14 @@ "build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/44/df/efb51d1c226eac613d48e2cbf0b8", "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/1c/f6/357fe951c86c9fc5b1b737cd91ae", "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/04/17/e2de0ab5df6b938d828e8662ce6d", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/97/5d/5255b7a90235bc570e71bfaf9f60", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/07/0b/c65c6f6b009633a7cf66ea1c9e08", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/81/09/10f7873ec315479806a9daa6e100", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/0f/09/ab4219ed9d6b6b63439a33f38aac", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/fd/ae/d0a4fb20969028322bab2ae2365d", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/0b/cf/4b7529302b842bc75695f93c4172", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/ad/b0/7d2ca14baad3fdb2aac296352570", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/68/f8/156cbf9f5cf0fcbae9f12e8b18e8", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/34/77/1986ffe869aca7b8aee6b24ea64b", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/0f/af/5430940c906f3d0c6e0983b9a2b9", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/22/84/02b9109e1449f2acca49f4f9b934", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/2b/22/b32d8e18c6a258929f091a14419d", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/a2/08/ecf905f1c6ede831e66e8d84c6f6", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/83/d7/01a034b1d9e2f028cb5f964396d3", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/81/a5/e780126b52d530cce18a64ae65e4", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/d8/39/51a851a77b6ce36073e9d190b9bf", "src/ballistica/generated/python_embedded/binding.inc": "https://files.ballistica.net/cache/ba1/7d/3e/229a581cb2454ed856f1d8b564a7", - "src/ballistica/generated/python_embedded/bootstrap.inc": "https://files.ballistica.net/cache/ba1/aa/a5/3ddc86d1789b2bf1d376b7671a3d" + "src/ballistica/generated/python_embedded/bootstrap.inc": "https://files.ballistica.net/cache/ba1/98/12/571b2160d69d42580e8f31fa6a8d" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index ca34f7b6..c17744a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -### 1.7.7 (build 20725, api 7, 2022-09-01) +### 1.7.7 (build 20728, api 7, 2022-09-02) - Added `ba.app.meta.load_exported_classes()` for loading classes discovered by the meta subsystem cleanly in a background thread. - Improved logging of missing playlist game types. - Some ba.Lstr functionality can now be used in background threads. @@ -8,6 +8,7 @@ - Added support for the console tool in the new devices section on ballistica.net. - Increased timeouts in net-testing gui and a few other places to be able to better diagnose/handle places with very poor connectivity. - Removed `Platform::SetLastPyCall()` which was just for debugging and which has not been useful in a while. +- Moved some app bootstrapping from the C++ layer to the ba._bootstrap module. ### 1.7.6 (build 20687, api 7, 2022-08-11) - Cleaned up da MetaSubsystem code. diff --git a/assets/.asset_manifest_public.json b/assets/.asset_manifest_public.json index b447e3ff..075dc768 100644 --- a/assets/.asset_manifest_public.json +++ b/assets/.asset_manifest_public.json @@ -17,6 +17,7 @@ "ba_data/python/ba/__pycache__/_assetmanager.cpython-310.opt-1.pyc", "ba_data/python/ba/__pycache__/_asyncio.cpython-310.opt-1.pyc", "ba_data/python/ba/__pycache__/_benchmark.cpython-310.opt-1.pyc", + "ba_data/python/ba/__pycache__/_bootstrap.cpython-310.opt-1.pyc", "ba_data/python/ba/__pycache__/_campaign.cpython-310.opt-1.pyc", "ba_data/python/ba/__pycache__/_cloud.cpython-310.opt-1.pyc", "ba_data/python/ba/__pycache__/_collision.cpython-310.opt-1.pyc", @@ -82,6 +83,7 @@ "ba_data/python/ba/_assetmanager.py", "ba_data/python/ba/_asyncio.py", "ba_data/python/ba/_benchmark.py", + "ba_data/python/ba/_bootstrap.py", "ba_data/python/ba/_campaign.py", "ba_data/python/ba/_cloud.py", "ba_data/python/ba/_collision.py", diff --git a/assets/Makefile b/assets/Makefile index a8898ae9..88f68306 100644 --- a/assets/Makefile +++ b/assets/Makefile @@ -150,6 +150,7 @@ SCRIPT_TARGETS_PY_PUBLIC = \ build/ba_data/python/ba/_assetmanager.py \ build/ba_data/python/ba/_asyncio.py \ build/ba_data/python/ba/_benchmark.py \ + build/ba_data/python/ba/_bootstrap.py \ build/ba_data/python/ba/_campaign.py \ build/ba_data/python/ba/_cloud.py \ build/ba_data/python/ba/_collision.py \ @@ -399,6 +400,7 @@ SCRIPT_TARGETS_PYC_PUBLIC = \ build/ba_data/python/ba/__pycache__/_assetmanager.cpython-310.opt-1.pyc \ build/ba_data/python/ba/__pycache__/_asyncio.cpython-310.opt-1.pyc \ build/ba_data/python/ba/__pycache__/_benchmark.cpython-310.opt-1.pyc \ + build/ba_data/python/ba/__pycache__/_bootstrap.cpython-310.opt-1.pyc \ build/ba_data/python/ba/__pycache__/_campaign.cpython-310.opt-1.pyc \ build/ba_data/python/ba/__pycache__/_cloud.cpython-310.opt-1.pyc \ build/ba_data/python/ba/__pycache__/_collision.cpython-310.opt-1.pyc \ diff --git a/assets/src/ba_data/python/ba/_bootstrap.py b/assets/src/ba_data/python/ba/_bootstrap.py new file mode 100644 index 00000000..b1e2c765 --- /dev/null +++ b/assets/src/ba_data/python/ba/_bootstrap.py @@ -0,0 +1,182 @@ +# Released under the MIT License. See LICENSE for details. +# +"""Bootstrapping.""" +from __future__ import annotations + +import threading +from typing import TYPE_CHECKING + +import _ba + +if TYPE_CHECKING: + from typing import Any, TextIO, Callable + + +def bootstrap() -> None: + """Run bootstrapping logic. + + This is the very first userland code that runs. + It sets up low level environment bits and creates the app instance. + """ + import os + import sys + import signal + + # The first thing we set up is capturing/redirecting Python + # stdout/stderr so we can at least debug problems on systems where + # native stdout/stderr is not easily accessible (looking at you, Android). + sys.stdout = _Redirect(sys.stdout, _ba.print_stdout) # type: ignore + sys.stderr = _Redirect(sys.stderr, _ba.print_stderr) # type: ignore + + # Give a soft warning if we're being used with a different binary + # version than we expect. + expected_build = 20728 + running_build = _ba.env().get('build_number') + if running_build != expected_build: + print( + f'WARNING: These script files are meant to be used with' + f' Ballistica build {expected_build}.\n' + f' You are running build {running_build}.' + f' This might cause the app to error or misbehave.', + file=sys.stderr) + + # Tell Python to not handle SIGINT itself (it normally generates + # KeyboardInterrupts which make a mess; we want to intercept them + # for simple clean exit). We capture interrupts per-platform in + # the C++ layer. + # Note: I tried creating a handler in Python but it seemed to often have + # a delay of up to a second before getting called. (not a huge deal + # but I'm picky). + signal.signal(signal.SIGINT, signal.SIG_DFL) # Do default handling. + + # ..though it turns out we need to set up our C signal handling AFTER + # we've told Python to disable its own; otherwise (on Mac at least) it + # wipes out our existing C handler. + _ba.setup_sigint() + + # Sanity check: we should always be run in UTF-8 mode. + if sys.flags.utf8_mode != 1: + print('ERROR: Python\'s UTF-8 mode is not set.' + ' This will likely result in errors.') + + debug_build = _ba.env()['debug_build'] + + # We expect dev_mode on in debug builds and off otherwise. + if debug_build != sys.flags.dev_mode: + print(f'WARNING: Mismatch in debug_build {debug_build}' + f' and sys.flags.dev_mode {sys.flags.dev_mode}') + + # In embedded situations (when we're providing our own Python) let's + # also provide our own root certs so ssl works. We can consider overriding + # this in particular embedded cases if we can verify that system certs + # are working. + # (We also allow forcing this via an env var if the user desires) + if (_ba.contains_python_dist() + or os.environ.get('BA_USE_BUNDLED_ROOT_CERTS') == '1'): + import certifi + + # Let both OpenSSL and requests (if present) know to use this. + os.environ['SSL_CERT_FILE'] = os.environ['REQUESTS_CA_BUNDLE'] = ( + certifi.where()) + + # FIXME: I think we should init Python in the main thread, which should + # also avoid these issues. (and also might help us play better with + # Python debuggers?) + + # Gloriously hacky workaround here: + # Our 'main' Python thread is the game thread (not the app's main + # thread) which means it has a small stack compared to the main + # thread (at least on apple). Sadly it turns out this causes the + # debug build of Python to blow its stack immediately when doing + # some big imports. + # Normally we'd just give the game thread the same stack size as + # the main thread and that'd be the end of it. However + # we're using std::threads which it turns out have no way to set + # the stack size (as of fall '19). Grumble. + # + # However python threads *can* take custom stack sizes. + # (and it appears they might use the main thread's by default?..) + # ...so as a workaround in the debug version, we can run problematic + # heavy imports here in another thread and all is well. + # If we ever see stack overflows in our release build we'll have + # to take more drastic measures like switching from std::threads + # to pthreads. + + if debug_build: + + # noinspection PyUnresolvedReferences + def _thread_func() -> None: + # pylint: disable=unused-import + import json + import urllib.request + + testthread = threading.Thread(target=_thread_func) + testthread.start() + testthread.join() + del testthread + + # Clear out the standard quit/exit messages since they don't work for us. + # pylint: disable=c-extension-no-member + if not TYPE_CHECKING: + import __main__ + del __main__.__builtins__.quit + del __main__.__builtins__.exit + + # Now spin up our App instance, store it on both _ba and ba, + # and return it to the C++ layer. + # noinspection PyProtectedMember + from ba._app import App + import ba + + _ba.app = ba.app = App() + + +class _Redirect: + + def __init__(self, original: TextIO, call: Callable[[str], None]) -> None: + self._lock = threading.Lock() + self._linebits: list[str] = [] + self._original = original + self._call = call + self._pending_ship = False + + def write(self, sval: Any) -> None: + """Override standard write call.""" + + self._call(sval) + + # Now do logging: + # Add it to our accumulated line. + # If the message ends in a newline, we can ship it + # immediately as a log entry. Otherwise, schedule a ship + # next cycle (if it hasn't yet at that point) so that we + # can accumulate subsequent prints. + # (so stuff like print('foo', 123, 'bar') will ship as one entry) + with self._lock: + self._linebits.append(sval) + if sval.endswith('\n'): + self._shiplog() + else: + _ba.pushcall(self._shiplog, + from_other_thread=True, + suppress_other_thread_warning=True) + + def _shiplog(self) -> None: + with self._lock: + line = ''.join(self._linebits) + if not line: + return + self._linebits = [] + + # Log messages aren't expected to have trailing newlines. + if line.endswith('\n'): + line = line[:-1] + _ba.log(line, to_stdout=False) + + def flush(self) -> None: + """Flush the file.""" + self._original.flush() + + def isatty(self) -> bool: + """Are we a terminal?""" + return self._original.isatty() diff --git a/src/ballistica/ballistica.cc b/src/ballistica/ballistica.cc index 1c7d2d9f..98908462 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 = 20725; +const int kAppBuildNumber = 20728; const char* kAppVersion = "1.7.7"; // Our standalone globals. diff --git a/src/meta/bameta/python_embedded/bootstrap.py b/src/meta/bameta/python_embedded/bootstrap.py index 26e409ca..d84cd45d 100644 --- a/src/meta/bameta/python_embedded/bootstrap.py +++ b/src/meta/bameta/python_embedded/bootstrap.py @@ -1,78 +1,20 @@ # Released under the MIT License. See LICENSE for details. +# """Initial ballistica bootstrapping.""" from __future__ import annotations -import os import sys -import signal -import threading from typing import TYPE_CHECKING import _ba if TYPE_CHECKING: - from typing import Any, TextIO, Callable + pass +# All we do here is make our script files accessible and then hand it off +# to them. -class _BAConsoleRedirect: - - def __init__(self, original: TextIO, call: Callable[[str], None]) -> None: - self._lock = threading.Lock() - self._linebits: list[str] = [] - self._original = original - self._call = call - self._pending_ship = False - - def write(self, sval: Any) -> None: - """Override standard write call.""" - - self._call(sval) - - # Now do logging: - # Add it to our accumulated line. - # If the message ends in a newline, we can ship it - # immediately as a log entry. Otherwise, schedule a ship - # next cycle (if it hasn't yet at that point) so that we - # can accumulate subsequent prints. - # (so stuff like print('foo', 123, 'bar') will ship as one entry) - with self._lock: - self._linebits.append(sval) - if sval.endswith('\n'): - self._shiplog() - else: - _ba.pushcall(self._shiplog, - from_other_thread=True, - suppress_other_thread_warning=True) - - def _shiplog(self) -> None: - with self._lock: - line = ''.join(self._linebits) - if not line: - return - self._linebits = [] - - # Log messages aren't expected to have trailing newlines. - if line.endswith('\n'): - line = line[:-1] - _ba.log(line, to_stdout=False) - - def flush(self) -> None: - """Flush the file.""" - self._original.flush() - - def isatty(self) -> bool: - """Are we a terminal?""" - return self._original.isatty() - - -# The very first thing we set up is redirecting Python stdout/stderr so -# we can at least debug problems on systems where native stdout/stderr -# is not easily accessible (looking at you, Android). -sys.stdout = _BAConsoleRedirect(sys.stdout, _ba.print_stdout) # type: ignore -sys.stderr = _BAConsoleRedirect(sys.stderr, _ba.print_stderr) # type: ignore - -# Now get access to our various script files. # Let's lookup mods first (so users can do whatever they want). # and then our bundled scripts last (don't want bundled site-package # stuff overwriting system versions) @@ -80,93 +22,9 @@ sys.path.insert(0, _ba.env()['python_directory_user']) sys.path.append(_ba.env()['python_directory_app']) sys.path.append(_ba.env()['python_directory_app_site']) -# Tell Python to not handle SIGINT itself (it normally generates -# KeyboardInterrupts which make a mess; we want to intercept them -# for simple clean exit). We capture interrupts per-platform in -# the C++ layer. -# Note: I tried creating a handler in Python but it seemed to often have -# a delay of up to a second before getting called. (not a huge deal -# but I'm picky). -signal.signal(signal.SIGINT, signal.SIG_DFL) # Do default handling. - -# ..though it turns out we need to set up our C signal handling AFTER -# we've told Python to disable its own; otherwise (on Mac at least) it -# wipes out our existing C handler. -_ba.setup_sigint() - -# Sanity check: we should always be run in UTF-8 mode. -if sys.flags.utf8_mode != 1: - print('ERROR: Python\'s UTF-8 mode is not set.' - ' This will likely result in errors.') - -debug_build = _ba.env()['debug_build'] - -# We expect dev_mode on in debug builds and off otherwise. -if debug_build != sys.flags.dev_mode: - print(f'WARNING: Mismatch in debug_build {debug_build}' - f' and sys.flags.dev_mode {sys.flags.dev_mode}') - -# In embedded situations (when we're providing our own Python) let's -# also provide our own root certs so ssl works. We can consider overriding -# this in particular embedded cases if we can verify that system certs -# are working. -# (We also allow forcing this via an env var if the user desires) -# pylint: disable=wrong-import-position -if (_ba.contains_python_dist() - or os.environ.get('BA_USE_BUNDLED_ROOT_CERTS') == '1'): - import certifi - - # Let both OpenSSL and requests (if present) know to use this. - os.environ['SSL_CERT_FILE'] = os.environ['REQUESTS_CA_BUNDLE'] = ( - certifi.where()) - -# FIXME: I think we should init Python in the main thread, which should -# also avoid these issues. (and also might help us play better with -# Python debuggers?) - -# Gloriously hacky workaround here: -# Our 'main' Python thread is the game thread (not the app's main -# thread) which means it has a small stack compared to the main -# thread (at least on apple). Sadly it turns out this causes the -# debug build of Python to blow its stack immediately when doing -# some big imports. -# Normally we'd just give the game thread the same stack size as -# the main thread and that'd be the end of it. However -# we're using std::threads which it turns out have no way to set -# the stack size (as of fall '19). Grumble. -# -# However python threads *can* take custom stack sizes. -# (and it appears they might use the main thread's by default?..) -# ...so as a workaround in the debug version, we can run problematic -# heavy imports here in another thread and all is well. -# If we ever see stack overflows in our release build we'll have -# to take more drastic measures like switching from std::threads -# to pthreads. - -if debug_build: - - # noinspection PyUnresolvedReferences - def _thread_func() -> None: - # pylint: disable=unused-import - import json - import urllib.request - - testthread = threading.Thread(target=_thread_func) - testthread.start() - testthread.join() - del testthread - -# Clear out the standard quit/exit messages since they don't work for us. -# pylint: disable=c-extension-no-member -if not TYPE_CHECKING: - import __main__ - del __main__.__builtins__.quit - del __main__.__builtins__.exit - -# Now spin up our App instance, store it on both _ba and ba, -# and return it to the C++ layer. +# The import is down here since it won't work until we muck with paths. # noinspection PyProtectedMember -from ba._app import App -import ba +# pylint: disable=wrong-import-position +from ba._bootstrap import bootstrap -_ba.app = ba.app = App() +bootstrap() diff --git a/tools/efro/log.py b/tools/efro/log.py index a2e78637..af647f56 100644 --- a/tools/efro/log.py +++ b/tools/efro/log.py @@ -9,22 +9,24 @@ import logging import datetime import threading from enum import Enum -from typing import TYPE_CHECKING, Annotated from dataclasses import dataclass +from typing import TYPE_CHECKING, Annotated from efro.util import utc_now -from efro.dataclassio import ioprepped, IOAttrs, dataclass_to_json from efro.terminal import TerminalColor +from efro.dataclassio import ioprepped, IOAttrs, dataclass_to_json if TYPE_CHECKING: - from typing import Any, Callable from pathlib import Path + from typing import Any, Callable class LogLevel(Enum): """Severity level for a log entry. - Note: these are numeric values so they can be compared in severity. + These enums have numeric values so they can be compared in severity. + Note that these values are not currently interchangeable with the + logging.ERROR, logging.DEBUG, etc. values. """ DEBUG = 0 INFO = 1 @@ -36,7 +38,7 @@ class LogLevel(Enum): @ioprepped @dataclass class LogEntry: - """Structured log entry.""" + """Single logged message.""" name: Annotated[str, IOAttrs('n', soft_default='root', store_default=False)] message: Annotated[str, IOAttrs('m')] @@ -44,7 +46,7 @@ class LogEntry: time: Annotated[datetime.datetime, IOAttrs('t')] -class StructuredLogHandler(logging.StreamHandler): +class LogHandler(logging.Handler): """Fancy-pants handler for logging output. Writes logs to disk in structured json format and echoes them @@ -64,9 +66,14 @@ class StructuredLogHandler(logging.StreamHandler): self._suppress_non_root_debug = suppress_non_root_debug def emit(self, record: logging.LogRecord) -> None: + + # Special case - filter out this common extra-chatty category. + # TODO - should use a standard logging.Filter for this. if (self._suppress_non_root_debug and record.name != 'root' and record.levelname == 'DEBUG'): return + + # Bake down all log formatting into a simple string. msg = self.format(record) # Translate Python log levels to our own. @@ -87,7 +94,8 @@ class StructuredLogHandler(logging.StreamHandler): for call in self._callbacks: call(entry) - # Also route log entries to the echo file (generally stdout) + # Also route log entries to the echo file (generally stdout/stderr) + # with pretty colors. if self._echofile is not None: cbegin: str cend: str @@ -123,7 +131,6 @@ class StructuredLogHandler(logging.StreamHandler): level=level, time=utc_now()) - # Inform anyone who wants to know about this log's level. for call in self._callbacks: call(entry) @@ -140,8 +147,8 @@ class StructuredLogHandler(logging.StreamHandler): class LogRedirect: """A file-like object for redirecting stdout/stderr to our log.""" - def __init__(self, name: str, orig_out: Any, - log_handler: StructuredLogHandler, log_level: LogLevel): + def __init__(self, name: str, orig_out: Any, log_handler: LogHandler, + log_level: LogLevel): self._name = name self._orig_out = orig_out self._log_handler = log_handler @@ -196,10 +203,9 @@ class LogRedirect: self._chunk = '' -def setup_logging( - log_path: str | Path | None, - level: LogLevel, - suppress_non_root_debug: bool = False) -> StructuredLogHandler: +def setup_logging(log_path: str | Path | None, + level: LogLevel, + suppress_non_root_debug: bool = False) -> LogHandler: """Set up our logging environment. Returns the custom handler which can be used to fetch information @@ -216,7 +222,7 @@ def setup_logging( # Wire logger output to go to a structured log file. # Also echo it to stderr IF we're running in a terminal. - loghandler = StructuredLogHandler( + loghandler = LogHandler( log_path, echofile=sys.stderr if sys.stderr.isatty() else None, suppress_non_root_debug=suppress_non_root_debug) From d9a49c88422a0747ac6f145322eb51d52b264b50 Mon Sep 17 00:00:00 2001 From: Eric Date: Fri, 2 Sep 2022 08:52:59 -0700 Subject: [PATCH 09/10] langs and tidying --- .efrocachemap | 46 +++++++++++----------- CHANGELOG.md | 2 +- assets/src/ba_data/python/ba/_bootstrap.py | 25 ++++++------ src/ballistica/ballistica.cc | 2 +- 4 files changed, 39 insertions(+), 36 deletions(-) diff --git a/.efrocachemap b/.efrocachemap index dd6f427f..bc3ad06f 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -420,7 +420,7 @@ "assets/build/ba_data/audio/zoeOw.ogg": "https://files.ballistica.net/cache/ba1/60/ad/38269b7f1c7dc20cb9a506cd0681", "assets/build/ba_data/audio/zoePickup01.ogg": "https://files.ballistica.net/cache/ba1/72/85/d6fc4d16b7081d91fba2850b5b10", "assets/build/ba_data/audio/zoeScream01.ogg": "https://files.ballistica.net/cache/ba1/e9/ae/1d674d0c086eaa0bd1c3b1db0505", - "assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/a3/38/05424b4cfb6e23e902b6dc20b209", + "assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/68/22/ee4cff9f9fa011db6a2ed7092d1f", "assets/build/ba_data/data/languages/arabic.json": "https://files.ballistica.net/cache/ba1/5b/cf/4501b151257c3d8d6ee8d0497d14", "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/17/21/7b6371bde52392eb4a38e7c6d55a", @@ -431,12 +431,12 @@ "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/70/7d/6cbdaf130eaa5c58cffb1f321e3d", "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/c1/3c/2d45627563fbfbbbda2b7e6799e1", + "assets/build/ba_data/data/languages/filipino.json": "https://files.ballistica.net/cache/ba1/8f/73/093120ae2241d8f4b899ccda2d75", "assets/build/ba_data/data/languages/french.json": "https://files.ballistica.net/cache/ba1/25/65/1cb03566e73811fc6e1b841d9072", "assets/build/ba_data/data/languages/german.json": "https://files.ballistica.net/cache/ba1/ef/e6/d4909f571d7473fd04055728490e", "assets/build/ba_data/data/languages/gibberish.json": "https://files.ballistica.net/cache/ba1/a5/28/6bf6b15f8359a145cd2e599849f1", "assets/build/ba_data/data/languages/greek.json": "https://files.ballistica.net/cache/ba1/82/eb/37ff44af76812097f9c98f05c730", - "assets/build/ba_data/data/languages/hindi.json": "https://files.ballistica.net/cache/ba1/08/3b/68cea4d16f7020d932829af85323", + "assets/build/ba_data/data/languages/hindi.json": "https://files.ballistica.net/cache/ba1/50/e8/837be1324c8128507b3df89b689f", "assets/build/ba_data/data/languages/hungarian.json": "https://files.ballistica.net/cache/ba1/d8/f2/aa16bc336bd7660cc86c3264bfc4", "assets/build/ba_data/data/languages/indonesian.json": "https://files.ballistica.net/cache/ba1/09/6c/942dd354447772a69ea5cae1d486", "assets/build/ba_data/data/languages/italian.json": "https://files.ballistica.net/cache/ba1/91/70/05ad4a6fdbdaa0f471225f7ad317", @@ -3995,26 +3995,26 @@ "assets/src/ba_data/python/ba/_generated/__init__.py": "https://files.ballistica.net/cache/ba1/ee/e8/cad05aa531c7faf7ff7b96db7f6e", "assets/src/ba_data/python/ba/_generated/enums.py": "https://files.ballistica.net/cache/ba1/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/16/68/50bab5698a6f581fb56ba314d953", - "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/88/e0/d5043781c54e6eceb273b6df0d38", - "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/da/dd/d847840917c2b44c3faa7f360133", - "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/73/06/99a81805a891faed7f126e795dda", - "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/e3/45/1cba0d26da1b275b36e6dd5e2487", - "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/28/8b/40a34cf4436f6644b4c60dd75ea5", - "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/d0/51/3a2ca66c96aca2f9649de78fa076", - "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/c3/b3/4900e33f2a75408842f568a53f6b", - "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/32/26/b90ad9ea1ed8c6fc32684b52f741", - "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/8c/3c/77eaf5714f5fb4c793b8e5d2b7cf", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/ff/9b/d13d185b8091790b28804d918d07", - "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/c1/39/b3aeb79b72a36df1069c495ec8fd", - "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/b9/8f/5e01bcc248400251f6a1ac45ca96", - "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/14/73/29cc3cba5c54c6f29700e9392f30", - "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/e4/60/b20fbb2f034ba8f0d250f287bad5", - "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/89/14/5529452723c8477b8882b1aecd81", - "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/07/08/5abca1559160b52c5cb51366b9e5", - "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/25/03/978fc62e0298b7d8322ade9fca18", - "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/bd/31/d8242ecff0934e358fb8fcb2675a", - "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/7c/7d/6c02413bb4bd8ed58a067c78884f", + "build/prefab/full/linux_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/eb/f6/0fa02f0dd61fe86f030e235cb65d", + "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/e8/5a/c49738579f58cff159f78330685e", + "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/77/79/d970690e3fa5d24e0cdfb5aff646", + "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/83/56/8203d51e88d563f373bd73304219", + "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/2b/7a/3eb09023c93e907472043fbccfff", + "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/d0/4f/d139bb2f0a1e4e400dade616f5d3", + "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/5d/5d/20bd4d3a607a8b3a5d9d9d925146", + "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/a0/f2/0646e8a3ed1c1ae091bee9628b8e", + "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/08/e8/064033db53071b97422d21386e8f", + "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/e7/e6/3cc5634143190749753a806a4792", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/d1/94/513926fe5432ba722b0e4f119f0c", + "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/ff/7e/884381d6bc009c804496a512beaf", + "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/be/06/c6f50e95926031616daf349acc64", + "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/16/95/4a354d9d8faa18f26be3a7c57f63", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/f1/39/6da99f25127e5ec62b5586e30378", + "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/d6/17/65c7d490b78d8ae0120e1d254b83", + "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/de/28/bea57ab25706df395792f06fd08b", + "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/4c/29/17e37dd645bb9d5fb6f85db2b1bd", + "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/26/22/bbd9535c97eedfc2c18c45e65f9b", + "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/a6/40/e9517fe39850dca141f0cc086503", "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/3b/0c/2f4061ab877d415a1c30e0e736db", "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/3c/5a/2b0714af254c64954ccfe51c70b3", "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/1f/ae/c8a885b1a1868b6846b606cdb456", diff --git a/CHANGELOG.md b/CHANGELOG.md index c17744a1..ee10f39a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -### 1.7.7 (build 20728, api 7, 2022-09-02) +### 1.7.7 (build 20730, api 7, 2022-09-02) - Added `ba.app.meta.load_exported_classes()` for loading classes discovered by the meta subsystem cleanly in a background thread. - Improved logging of missing playlist game types. - Some ba.Lstr functionality can now be used in background threads. diff --git a/assets/src/ba_data/python/ba/_bootstrap.py b/assets/src/ba_data/python/ba/_bootstrap.py index b1e2c765..cb12e496 100644 --- a/assets/src/ba_data/python/ba/_bootstrap.py +++ b/assets/src/ba_data/python/ba/_bootstrap.py @@ -28,10 +28,12 @@ def bootstrap() -> None: sys.stdout = _Redirect(sys.stdout, _ba.print_stdout) # type: ignore sys.stderr = _Redirect(sys.stderr, _ba.print_stderr) # type: ignore + env = _ba.env() + # Give a soft warning if we're being used with a different binary # version than we expect. - expected_build = 20728 - running_build = _ba.env().get('build_number') + expected_build = 20730 + running_build: int = env['build_number'] if running_build != expected_build: print( f'WARNING: These script files are meant to be used with' @@ -56,15 +58,19 @@ def bootstrap() -> None: # Sanity check: we should always be run in UTF-8 mode. if sys.flags.utf8_mode != 1: - print('ERROR: Python\'s UTF-8 mode is not set.' - ' This will likely result in errors.') + print( + 'ERROR: Python\'s UTF-8 mode is not set.' + ' This will likely result in errors.', + file=sys.stderr) - debug_build = _ba.env()['debug_build'] + debug_build = env['debug_build'] # We expect dev_mode on in debug builds and off otherwise. if debug_build != sys.flags.dev_mode: - print(f'WARNING: Mismatch in debug_build {debug_build}' - f' and sys.flags.dev_mode {sys.flags.dev_mode}') + print( + f'WARNING: Mismatch in debug_build {debug_build}' + f' and sys.flags.dev_mode {sys.flags.dev_mode}', + file=sys.stderr) # In embedded situations (when we're providing our own Python) let's # also provide our own root certs so ssl works. We can consider overriding @@ -122,12 +128,9 @@ def bootstrap() -> None: del __main__.__builtins__.quit del __main__.__builtins__.exit - # Now spin up our App instance, store it on both _ba and ba, - # and return it to the C++ layer. - # noinspection PyProtectedMember + # Now spin up our App instance and store it on both _ba and ba. from ba._app import App import ba - _ba.app = ba.app = App() diff --git a/src/ballistica/ballistica.cc b/src/ballistica/ballistica.cc index 98908462..7ece08e1 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 = 20728; +const int kAppBuildNumber = 20730; const char* kAppVersion = "1.7.7"; // Our standalone globals. From 54eb290b64f7dd65e97c4712f19ce8781086971c Mon Sep 17 00:00:00 2001 From: Eric Date: Fri, 2 Sep 2022 09:05:35 -0700 Subject: [PATCH 10/10] Latest changes from private. --- assets/src/ba_data/python/bastd/game/football.py | 4 ++-- assets/src/ba_data/python/bastd/game/hockey.py | 4 ++-- assets/src/ba_data/python/bastd/game/keepaway.py | 4 ++-- assets/src/ba_data/python/bastd/game/kingofthehill.py | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/assets/src/ba_data/python/bastd/game/football.py b/assets/src/ba_data/python/bastd/game/football.py index 63236c19..263f8e3e 100644 --- a/assets/src/ba_data/python/bastd/game/football.py +++ b/assets/src/ba_data/python/bastd/game/football.py @@ -145,8 +145,8 @@ class FootballTeamGame(ba.TeamGameActivity[Player, Team]): self._time_limit = float(settings['Time Limit']) self._epic_mode = bool(settings['Epic Mode']) self.slow_motion = self._epic_mode - self.default_music = (ba.MusicType.EPIC if self._epic_mode else - ba.MusicType.FOOTBALL) + self.default_music = (ba.MusicType.EPIC + if self._epic_mode else ba.MusicType.FOOTBALL) def get_instance_description(self) -> str | Sequence: touchdowns = self._score_to_win / 7 diff --git a/assets/src/ba_data/python/bastd/game/hockey.py b/assets/src/ba_data/python/bastd/game/hockey.py index 77a95ce0..11110e78 100644 --- a/assets/src/ba_data/python/bastd/game/hockey.py +++ b/assets/src/ba_data/python/bastd/game/hockey.py @@ -205,8 +205,8 @@ class HockeyGame(ba.TeamGameActivity[Player, Team]): self._time_limit = float(settings['Time Limit']) self._epic_mode = bool(settings['Epic Mode']) self.slow_motion = self._epic_mode - self.default_music = (ba.MusicType.EPIC if self._epic_mode else - ba.MusicType.HOCKEY) + self.default_music = (ba.MusicType.EPIC + if self._epic_mode else ba.MusicType.HOCKEY) def get_instance_description(self) -> str | Sequence: if self._score_to_win == 1: diff --git a/assets/src/ba_data/python/bastd/game/keepaway.py b/assets/src/ba_data/python/bastd/game/keepaway.py index 2e179534..3d3477e3 100644 --- a/assets/src/ba_data/python/bastd/game/keepaway.py +++ b/assets/src/ba_data/python/bastd/game/keepaway.py @@ -117,8 +117,8 @@ class KeepAwayGame(ba.TeamGameActivity[Player, Team]): self._time_limit = float(settings['Time Limit']) self._epic_mode = bool(settings['Epic Mode']) self.slow_motion = self._epic_mode - self.default_music = (ba.MusicType.EPIC if self._epic_mode else - ba.MusicType.KEEP_AWAY) + self.default_music = (ba.MusicType.EPIC + if self._epic_mode else ba.MusicType.KEEP_AWAY) def get_instance_description(self) -> str | Sequence: return 'Carry the flag for ${ARG1} seconds.', self._hold_time diff --git a/assets/src/ba_data/python/bastd/game/kingofthehill.py b/assets/src/ba_data/python/bastd/game/kingofthehill.py index 87b8080e..677c9fdf 100644 --- a/assets/src/ba_data/python/bastd/game/kingofthehill.py +++ b/assets/src/ba_data/python/bastd/game/kingofthehill.py @@ -131,8 +131,8 @@ class KingOfTheHillGame(ba.TeamGameActivity[Player, Team]): # Base class overrides. self.slow_motion = self._epic_mode - self.default_music = (ba.MusicType.EPIC if self._epic_mode else - ba.MusicType.SCARY) + self.default_music = (ba.MusicType.EPIC + if self._epic_mode else ba.MusicType.SCARY) def get_instance_description(self) -> str | Sequence: return 'Secure the flag for ${ARG1} seconds.', self._hold_time