mirror of
https://github.com/RYDE-WORK/ballistica.git
synced 2026-02-07 16:13:23 +08:00
lang updates and cache functionality for LogHandler
This commit is contained in:
parent
3816f1dcb9
commit
d3f3679473
@ -420,8 +420,8 @@
|
|||||||
"assets/build/ba_data/audio/zoeOw.ogg": "https://files.ballistica.net/cache/ba1/60/ad/38269b7f1c7dc20cb9a506cd0681",
|
"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/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/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/e8/42/a43c158be7fa45f2c0c3d4b84a1f",
|
"assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/d4/64/6fff42a428e5c775795c081474e6",
|
||||||
"assets/build/ba_data/data/languages/arabic.json": "https://files.ballistica.net/cache/ba1/5b/cf/4501b151257c3d8d6ee8d0497d14",
|
"assets/build/ba_data/data/languages/arabic.json": "https://files.ballistica.net/cache/ba1/e2/24/5e7ea9ca5c9de4d3b7a28e53564d",
|
||||||
"assets/build/ba_data/data/languages/belarussian.json": "https://files.ballistica.net/cache/ba1/61/03/89070ca765e06da3a419a579f503",
|
"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/f8/15/e1a2fa38697417bcf2cf19cd34ef",
|
"assets/build/ba_data/data/languages/chinese.json": "https://files.ballistica.net/cache/ba1/f8/15/e1a2fa38697417bcf2cf19cd34ef",
|
||||||
"assets/build/ba_data/data/languages/chinesetraditional.json": "https://files.ballistica.net/cache/ba1/44/aa/c12568afb4558dc7f9f2fa155467",
|
"assets/build/ba_data/data/languages/chinesetraditional.json": "https://files.ballistica.net/cache/ba1/44/aa/c12568afb4558dc7f9f2fa155467",
|
||||||
@ -431,17 +431,17 @@
|
|||||||
"assets/build/ba_data/data/languages/dutch.json": "https://files.ballistica.net/cache/ba1/68/93/da8e9874f41a786edf52ba4ccaad",
|
"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/72/80/d6395c8a168558750c0d79ce769b",
|
"assets/build/ba_data/data/languages/english.json": "https://files.ballistica.net/cache/ba1/72/80/d6395c8a168558750c0d79ce769b",
|
||||||
"assets/build/ba_data/data/languages/esperanto.json": "https://files.ballistica.net/cache/ba1/4c/c7/0184b8178869d1a3827a1bfcd5bb",
|
"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/8f/73/093120ae2241d8f4b899ccda2d75",
|
"assets/build/ba_data/data/languages/filipino.json": "https://files.ballistica.net/cache/ba1/e9/07/b2dc862601bcd70701b083d43279",
|
||||||
"assets/build/ba_data/data/languages/french.json": "https://files.ballistica.net/cache/ba1/25/65/1cb03566e73811fc6e1b841d9072",
|
"assets/build/ba_data/data/languages/french.json": "https://files.ballistica.net/cache/ba1/2e/48/b0a8fafc5e5436e99d9a3d697d23",
|
||||||
"assets/build/ba_data/data/languages/german.json": "https://files.ballistica.net/cache/ba1/ef/e6/d4909f571d7473fd04055728490e",
|
"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/8a/2a/b2bc00eed0608b2199b2bc379b2e",
|
"assets/build/ba_data/data/languages/gibberish.json": "https://files.ballistica.net/cache/ba1/8a/2a/b2bc00eed0608b2199b2bc379b2e",
|
||||||
"assets/build/ba_data/data/languages/greek.json": "https://files.ballistica.net/cache/ba1/82/eb/37ff44af76812097f9c98f05c730",
|
"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/50/e8/837be1324c8128507b3df89b689f",
|
"assets/build/ba_data/data/languages/hindi.json": "https://files.ballistica.net/cache/ba1/91/98/42701cd595c2f70b7484614a8f49",
|
||||||
"assets/build/ba_data/data/languages/hungarian.json": "https://files.ballistica.net/cache/ba1/d8/f2/aa16bc336bd7660cc86c3264bfc4",
|
"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/e3/85/14e57e3f49505e5a190daf7fe276",
|
"assets/build/ba_data/data/languages/indonesian.json": "https://files.ballistica.net/cache/ba1/23/3b/26e9be528460af952a11e98c3b68",
|
||||||
"assets/build/ba_data/data/languages/italian.json": "https://files.ballistica.net/cache/ba1/1a/10/9563348e729d1e5c8ae8c9cbc1f2",
|
"assets/build/ba_data/data/languages/italian.json": "https://files.ballistica.net/cache/ba1/1a/10/9563348e729d1e5c8ae8c9cbc1f2",
|
||||||
"assets/build/ba_data/data/languages/korean.json": "https://files.ballistica.net/cache/ba1/a8/e9/171a904f1331fdb7b1918a0f2598",
|
"assets/build/ba_data/data/languages/korean.json": "https://files.ballistica.net/cache/ba1/a8/e9/171a904f1331fdb7b1918a0f2598",
|
||||||
"assets/build/ba_data/data/languages/persian.json": "https://files.ballistica.net/cache/ba1/83/4a/ec10142ac479bf8d80455b47a62b",
|
"assets/build/ba_data/data/languages/persian.json": "https://files.ballistica.net/cache/ba1/df/b1/b2c9ebaad5e873ebedd365726d3d",
|
||||||
"assets/build/ba_data/data/languages/polish.json": "https://files.ballistica.net/cache/ba1/19/e9/59c891b1fb85f3ba9f19283c233d",
|
"assets/build/ba_data/data/languages/polish.json": "https://files.ballistica.net/cache/ba1/19/e9/59c891b1fb85f3ba9f19283c233d",
|
||||||
"assets/build/ba_data/data/languages/portuguese.json": "https://files.ballistica.net/cache/ba1/da/95/36797ec53a697a04e55b225a701d",
|
"assets/build/ba_data/data/languages/portuguese.json": "https://files.ballistica.net/cache/ba1/da/95/36797ec53a697a04e55b225a701d",
|
||||||
"assets/build/ba_data/data/languages/romanian.json": "https://files.ballistica.net/cache/ba1/d7/06/9d70642d0a4d1e3b1c2149d7a17c",
|
"assets/build/ba_data/data/languages/romanian.json": "https://files.ballistica.net/cache/ba1/d7/06/9d70642d0a4d1e3b1c2149d7a17c",
|
||||||
@ -452,7 +452,7 @@
|
|||||||
"assets/build/ba_data/data/languages/swedish.json": "https://files.ballistica.net/cache/ba1/91/0a/35c4baf539d5951fc03a794c0e0b",
|
"assets/build/ba_data/data/languages/swedish.json": "https://files.ballistica.net/cache/ba1/91/0a/35c4baf539d5951fc03a794c0e0b",
|
||||||
"assets/build/ba_data/data/languages/tamil.json": "https://files.ballistica.net/cache/ba1/94/1a/533bc718e676191bafc25e2dc98f",
|
"assets/build/ba_data/data/languages/tamil.json": "https://files.ballistica.net/cache/ba1/94/1a/533bc718e676191bafc25e2dc98f",
|
||||||
"assets/build/ba_data/data/languages/thai.json": "https://files.ballistica.net/cache/ba1/f7/df/7ba5f99c5c2c4c86fc0503fcf0b7",
|
"assets/build/ba_data/data/languages/thai.json": "https://files.ballistica.net/cache/ba1/f7/df/7ba5f99c5c2c4c86fc0503fcf0b7",
|
||||||
"assets/build/ba_data/data/languages/turkish.json": "https://files.ballistica.net/cache/ba1/14/a0/783cc6da2d122e9a7482c6a5ef8c",
|
"assets/build/ba_data/data/languages/turkish.json": "https://files.ballistica.net/cache/ba1/9a/90/8e2ed626def09f88c3b9ab5215a3",
|
||||||
"assets/build/ba_data/data/languages/ukrainian.json": "https://files.ballistica.net/cache/ba1/ab/35/644e4239cfa62a597a905412b90c",
|
"assets/build/ba_data/data/languages/ukrainian.json": "https://files.ballistica.net/cache/ba1/ab/35/644e4239cfa62a597a905412b90c",
|
||||||
"assets/build/ba_data/data/languages/venetian.json": "https://files.ballistica.net/cache/ba1/53/9e/068074156b38bab7f732977a4031",
|
"assets/build/ba_data/data/languages/venetian.json": "https://files.ballistica.net/cache/ba1/53/9e/068074156b38bab7f732977a4031",
|
||||||
"assets/build/ba_data/data/languages/vietnamese.json": "https://files.ballistica.net/cache/ba1/25/13/b64b849fc9fedcc18d81f6e08c4d",
|
"assets/build/ba_data/data/languages/vietnamese.json": "https://files.ballistica.net/cache/ba1/25/13/b64b849fc9fedcc18d81f6e08c4d",
|
||||||
@ -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/__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",
|
"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",
|
"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/15/b2/0744afc264f1e55a5944bf8ae964",
|
"build/prefab/full/linux_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/f3/e1/0ee9ade5e9943dc4749aa4cc2182",
|
||||||
"build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/8e/98/ea10bd892f89c7ba5aec76721667",
|
"build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/32/4e/a7c1b096c62864641a59e65e7778",
|
||||||
"build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/aa/e4/7c73515c9044e051a5d07cb1e964",
|
"build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/6a/f4/8b86611cbaa7237c8a52e8fe6428",
|
||||||
"build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/ba/37/245e7c3dc79588d73a57f9f08b55",
|
"build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/13/f5/fa3c97269613316994f0c2134860",
|
||||||
"build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/ad/28/034d014eea6aeba4b67d51cfc262",
|
"build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/f8/7a/87877003ee3a13ff7cbbf1ec76a2",
|
||||||
"build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/77/df/c85dfe5cb062b6925da7df8e740c",
|
"build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/81/0c/708a16fff55ee37338b2d87f7620",
|
||||||
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/58/6b/058b05227950f5d83f23b01617d1",
|
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/4a/91/89523b8f155261e0045a6bb6e277",
|
||||||
"build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/bd/31/02ecb4d8c3bea8eb68d92befdd9d",
|
"build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/a9/04/da76c8e848852fef1e58577f59e3",
|
||||||
"build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/aa/9d/96555101ebf8b14223b7639cea5b",
|
"build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/dd/ac/33aed9cc1396ccba2111dfed02f6",
|
||||||
"build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/1d/9a/16feda78b815cbed47b89983c48e",
|
"build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/1a/5a/0f1e671137a2ec60c2df8e95e078",
|
||||||
"build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/b0/31/f60dc64681a35406595ed4836f0a",
|
"build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/92/50/ec5fbb3f8b9f4a60934f2dacf180",
|
||||||
"build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/b5/44/eb4645945794253446c55dc682bc",
|
"build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/7c/77/a430bf182d5210792716b6dbd8ee",
|
||||||
"build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/43/56/592cd419bfad9cbbb6e3f57c1007",
|
"build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/ef/6b/de6c811fa70bf4d5d1cdfe49eaae",
|
||||||
"build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/c6/55/0dfcc3d90a9cee9212e2e10a91b1",
|
"build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/92/e0/b9b1053231d7323d185298f8caaa",
|
||||||
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/19/c6/994729e095b54e6963ac2d4bbd10",
|
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/08/ef/c70efcd89a666758437f0736d956",
|
||||||
"build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/ce/21/77cd76cd1b0307ae8cc7038152e7",
|
"build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/9d/94/1f0d32c943b64ff558f28ad89653",
|
||||||
"build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/a9/e6/23835561d55b6c1d1862217fc115",
|
"build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/a6/fb/a6e6a78d7b04d547c9c716ff0a8e",
|
||||||
"build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/21/3d/e0a1e20ae12dd7b5ba1d61aed074",
|
"build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/5a/b0/d0e087fcdf1756a0b9b5bf805f10",
|
||||||
"build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/be/b5/fc827900f411576b992fc15a25fc",
|
"build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/34/fb/e6c9fb0e20af0ba3376ca2abba29",
|
||||||
"build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/6f/51/d6a0951b6ab9122dd99ef33d4427",
|
"build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/b1/8b/5ba626c39ef586f3ba4bfd508181",
|
||||||
"build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/d5/f6/d62e6e6d5e7fe1945f08ccbb9a8f",
|
"build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/d5/f6/d62e6e6d5e7fe1945f08ccbb9a8f",
|
||||||
"build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/02/c5/44d0082442b06153a7d7dce4c8ce",
|
"build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/02/c5/44d0082442b06153a7d7dce4c8ce",
|
||||||
"build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/d0/00/61378fb26ddcbf023fd3c40e4ffb",
|
"build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/d0/00/61378fb26ddcbf023fd3c40e4ffb",
|
||||||
@ -4031,14 +4031,14 @@
|
|||||||
"build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ff/26/da4a58abecf5d9275477eaec0c17",
|
"build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ff/26/da4a58abecf5d9275477eaec0c17",
|
||||||
"build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/62/5d/8658a206b8c9b741be2422162784",
|
"build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/62/5d/8658a206b8c9b741be2422162784",
|
||||||
"build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/fc/57/d59920e098d23a2d150c899cde29",
|
"build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/fc/57/d59920e098d23a2d150c899cde29",
|
||||||
"build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/fb/8e/3bb1c858451a447f1a102d77c281",
|
"build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/39/a1/bce547622da143fcf9ea970cd3ab",
|
||||||
"build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/ae/ad/13ae735e45d31d2944c89e8bdcec",
|
"build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/d6/f3/8ca052a667342e316fa09655bc51",
|
||||||
"build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/e8/3e/6c2546278ad0428965a05c9bd536",
|
"build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/e0/b4/99c403ccbfd0c4b9b071e656d480",
|
||||||
"build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/d4/e5/0fe217cac5837cf663c7c7f1aa92",
|
"build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/11/a0/e06103dae63a4648850bd089aacb",
|
||||||
"build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/ea/38/a5082d73202113900166a1ebd15f",
|
"build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/77/17/99eba0c7d42a9452306f7927ae4e",
|
||||||
"build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/ba/1c/16df69d156e23ab29e2c84465bd7",
|
"build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/92/da/2faf9031e7c5ba5a99dd9e0c609d",
|
||||||
"build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/9e/b0/91b2e0b1dbd4541543f3f147bc06",
|
"build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/64/2a/1b30ee7b4e8238ec2ea16bcacdeb",
|
||||||
"build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/c1/04/ad892d77317be76bc8fa035f9e86",
|
"build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/41/92/35b689da32ee45a4e7483feae8f8",
|
||||||
"src/ballistica/generated/python_embedded/binding.inc": "https://files.ballistica.net/cache/ba1/c0/32/b7907e3859a5c5013a3d97b6b523",
|
"src/ballistica/generated/python_embedded/binding.inc": "https://files.ballistica.net/cache/ba1/c0/32/b7907e3859a5c5013a3d97b6b523",
|
||||||
"src/ballistica/generated/python_embedded/bootstrap.inc": "https://files.ballistica.net/cache/ba1/2d/4f/f4fe67827f36cd59cd5193333a02",
|
"src/ballistica/generated/python_embedded/bootstrap.inc": "https://files.ballistica.net/cache/ba1/2d/4f/f4fe67827f36cd59cd5193333a02",
|
||||||
"src/ballistica/generated/python_embedded/bootstrap_monolithic.inc": "https://files.ballistica.net/cache/ba1/ef/c1/aa5f1aa10af89f5c0b1e616355fd"
|
"src/ballistica/generated/python_embedded/bootstrap_monolithic.inc": "https://files.ballistica.net/cache/ba1/ef/c1/aa5f1aa10af89f5c0b1e616355fd"
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
### 1.7.7 (build 20856, api 7, 2022-09-15)
|
### 1.7.7 (build 20857, api 7, 2022-09-15)
|
||||||
- Added `ba.app.meta.load_exported_classes()` for loading classes discovered by the meta subsystem cleanly in a background thread.
|
- 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.
|
- Improved logging of missing playlist game types.
|
||||||
- Some ba.Lstr functionality can now be used in background threads.
|
- Some ba.Lstr functionality can now be used in background threads.
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
76251027805752156826413428926087661089
|
41453813326605937968225345803585801012
|
||||||
@ -2518,11 +2518,12 @@ def screenmessage(message: str | ba.Lstr,
|
|||||||
Category: **General Utility Functions**
|
Category: **General Utility Functions**
|
||||||
|
|
||||||
If 'top' is True, the message will go to the top message area.
|
If 'top' is True, the message will go to the top message area.
|
||||||
For 'top' messages, 'image' can be a texture to display alongside the
|
For 'top' messages, 'image' must be a dict containing 'texture'
|
||||||
message.
|
and 'tint_texture' textures and 'tint_color' and 'tint2_color'
|
||||||
If 'log' is True, the message will also be printed to the output log
|
colors. This defines an icon to display alongside the message.
|
||||||
'clients' can be a list of client-ids the message should be sent to,
|
If 'log' is True, the message will also be submitted to the log.
|
||||||
or None to specify that everyone should receive it.
|
'clients' can be a list of client-ids the message should be sent
|
||||||
|
to, or None to specify that everyone should receive it.
|
||||||
If 'transient' is True, the message will not be included in the
|
If 'transient' is True, the message will not be included in the
|
||||||
game-stream and thus will not show up when viewing replays.
|
game-stream and thus will not show up when viewing replays.
|
||||||
Currently the 'clients' option only works for transient messages.
|
Currently the 'clients' option only works for transient messages.
|
||||||
|
|||||||
@ -35,7 +35,8 @@ def bootstrap() -> None:
|
|||||||
log_handler = setup_logging(log_path=None,
|
log_handler = setup_logging(log_path=None,
|
||||||
level=LogLevel.DEBUG,
|
level=LogLevel.DEBUG,
|
||||||
suppress_non_root_debug=True,
|
suppress_non_root_debug=True,
|
||||||
log_stdout_stderr=True)
|
log_stdout_stderr=True,
|
||||||
|
cache_size_limit=1024 * 1024)
|
||||||
|
|
||||||
log_handler.add_callback(_on_log)
|
log_handler.add_callback(_on_log)
|
||||||
|
|
||||||
@ -43,7 +44,7 @@ def bootstrap() -> None:
|
|||||||
|
|
||||||
# Give a soft warning if we're being used with a different binary
|
# Give a soft warning if we're being used with a different binary
|
||||||
# version than we expect.
|
# version than we expect.
|
||||||
expected_build = 20856
|
expected_build = 20857
|
||||||
running_build: int = env['build_number']
|
running_build: int = env['build_number']
|
||||||
if running_build != expected_build:
|
if running_build != expected_build:
|
||||||
print(
|
print(
|
||||||
|
|||||||
@ -32,7 +32,7 @@
|
|||||||
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 kAppBuildNumber = 20856;
|
const int kAppBuildNumber = 20857;
|
||||||
const char* kAppVersion = "1.7.7";
|
const char* kAppVersion = "1.7.7";
|
||||||
|
|
||||||
// Our standalone globals.
|
// Our standalone globals.
|
||||||
|
|||||||
@ -19,9 +19,9 @@ namespace ballistica {
|
|||||||
|
|
||||||
const int kMaxPartyNameCombinedSize = 25;
|
const int kMaxPartyNameCombinedSize = 25;
|
||||||
|
|
||||||
/// The Game Module generally runs on a dedicated thread; it manages
|
/// The logic subsystem of the app. This runs on a dedicated thread
|
||||||
/// all game logic, builds frame_defs to send to the graphics-server for
|
/// and is where high level app logic happens. Much app functionality
|
||||||
/// rendering, etc.
|
/// including UI calls must be run on the logic thread.
|
||||||
class Logic {
|
class Logic {
|
||||||
public:
|
public:
|
||||||
Logic();
|
Logic();
|
||||||
|
|||||||
@ -988,14 +988,12 @@ auto PythonMethodsApp::GetMethods() -> std::vector<PyMethodDef> {
|
|||||||
"Category: **General Utility Functions**\n"
|
"Category: **General Utility Functions**\n"
|
||||||
"\n"
|
"\n"
|
||||||
"If 'top' is True, the message will go to the top message area.\n"
|
"If 'top' is True, the message will go to the top message area.\n"
|
||||||
"For 'top' messages, 'image' can be a texture to display alongside "
|
"For 'top' messages, 'image' must be a dict containing 'texture'\n"
|
||||||
"the\n"
|
"and 'tint_texture' textures and 'tint_color' and 'tint2_color'\n"
|
||||||
"message.\n"
|
"colors. This defines an icon to display alongside the message.\n"
|
||||||
"If 'log' is True, the message will also be printed to the output "
|
"If 'log' is True, the message will also be submitted to the log.\n"
|
||||||
"log\n"
|
"'clients' can be a list of client-ids the message should be sent\n"
|
||||||
"'clients' can be a list of client-ids the message should be sent "
|
"to, or None to specify that everyone should receive it.\n"
|
||||||
"to,\n"
|
|
||||||
"or None to specify that everyone should receive it.\n"
|
|
||||||
"If 'transient' is True, the message will not be included in the\n"
|
"If 'transient' is True, the message will not be included in the\n"
|
||||||
"game-stream and thus will not show up when viewing replays.\n"
|
"game-stream and thus will not show up when viewing replays.\n"
|
||||||
"Currently the 'clients' option only works for transient messages."},
|
"Currently the 'clients' option only works for transient messages."},
|
||||||
|
|||||||
@ -70,7 +70,7 @@ namespace ballistica {
|
|||||||
|
|
||||||
auto Python::LoggingCall(LogLevel loglevel, const std::string& msg) -> void {
|
auto Python::LoggingCall(LogLevel loglevel, const std::string& msg) -> void {
|
||||||
// If we've not yet captured our Python logging calls, stash this call away.
|
// If we've not yet captured our Python logging calls, stash this call away.
|
||||||
// We'll submit all accumulated entries after we bootstrap python.
|
// We'll submit all accumulated entries after we bootstrap Python.
|
||||||
if (!objexists(ObjID::kLoggingCriticalCall)) {
|
if (!objexists(ObjID::kLoggingCriticalCall)) {
|
||||||
std::scoped_lock lock(early_log_lock_);
|
std::scoped_lock lock(early_log_lock_);
|
||||||
early_logs_.emplace_back(std::make_pair(loglevel, msg));
|
early_logs_.emplace_back(std::make_pair(loglevel, msg));
|
||||||
|
|||||||
@ -67,6 +67,21 @@ class LogEntry:
|
|||||||
time: Annotated[datetime.datetime, IOAttrs('t')]
|
time: Annotated[datetime.datetime, IOAttrs('t')]
|
||||||
|
|
||||||
|
|
||||||
|
@ioprepped
|
||||||
|
@dataclass
|
||||||
|
class LogArchive:
|
||||||
|
"""Info and data for a log."""
|
||||||
|
|
||||||
|
# Total number of entries submitted to the log.
|
||||||
|
log_size: Annotated[int, IOAttrs('t')]
|
||||||
|
|
||||||
|
# Offset for the entries contained here.
|
||||||
|
# (10 means our first entry is the 10th in the log, etc.)
|
||||||
|
start_index: Annotated[int, IOAttrs('c')]
|
||||||
|
|
||||||
|
entries: Annotated[list[LogEntry], IOAttrs('e')]
|
||||||
|
|
||||||
|
|
||||||
class LogHandler(logging.Handler):
|
class LogHandler(logging.Handler):
|
||||||
"""Fancy-pants handler for logging output.
|
"""Fancy-pants handler for logging output.
|
||||||
|
|
||||||
@ -83,7 +98,8 @@ class LogHandler(logging.Handler):
|
|||||||
def __init__(self,
|
def __init__(self,
|
||||||
path: str | Path | None,
|
path: str | Path | None,
|
||||||
echofile: TextIO | None,
|
echofile: TextIO | None,
|
||||||
suppress_non_root_debug: bool = False):
|
suppress_non_root_debug: bool = False,
|
||||||
|
cache_size_limit: int = 0):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
# pylint: disable=consider-using-with
|
# pylint: disable=consider-using-with
|
||||||
self._file = (None
|
self._file = (None
|
||||||
@ -97,14 +113,20 @@ class LogHandler(logging.Handler):
|
|||||||
'stdout': None,
|
'stdout': None,
|
||||||
'stderr': None
|
'stderr': None
|
||||||
}
|
}
|
||||||
|
self._cache_size = 0
|
||||||
|
assert cache_size_limit >= 0
|
||||||
|
self._cache_size_limit = cache_size_limit
|
||||||
|
self._cache: list[tuple[int, LogEntry]] = []
|
||||||
|
self._cache_index_offset = 0
|
||||||
|
self._cache_lock = Lock()
|
||||||
self._printed_callback_error = False
|
self._printed_callback_error = False
|
||||||
self._thread_bootstrapped = False
|
self._thread_bootstrapped = False
|
||||||
self._thread = Thread(target=self._thread_main, daemon=True)
|
self._thread = Thread(target=self._thread_main, daemon=True)
|
||||||
self._thread.start()
|
self._thread.start()
|
||||||
|
|
||||||
# Spin until our thread has set up its basic stuff;
|
# Spin until our thread is up and running; otherwise we could
|
||||||
# otherwise we could wind up trying to push stuff to our
|
# wind up trying to push stuff to our event loop before the
|
||||||
# event loop before the loop exists.
|
# loop exists.
|
||||||
while not self._thread_bootstrapped:
|
while not self._thread_bootstrapped:
|
||||||
time.sleep(0.001)
|
time.sleep(0.001)
|
||||||
|
|
||||||
@ -124,6 +146,37 @@ class LogHandler(logging.Handler):
|
|||||||
self._thread_bootstrapped = True
|
self._thread_bootstrapped = True
|
||||||
self._event_loop.run_forever()
|
self._event_loop.run_forever()
|
||||||
|
|
||||||
|
def get_archive(self,
|
||||||
|
start_index: int = 0,
|
||||||
|
max_entries: int | None = None) -> LogArchive:
|
||||||
|
"""Build and return an archive of log entries.
|
||||||
|
|
||||||
|
This will only return entries that have been processed by the
|
||||||
|
background thread so may not include just-submitted logs.
|
||||||
|
Entries in the range [start_index:start_index+max_entries] that
|
||||||
|
are still in the cache will be returned. Be aware that this may
|
||||||
|
not be the full requested range.
|
||||||
|
"""
|
||||||
|
|
||||||
|
assert start_index >= 0
|
||||||
|
if max_entries is not None:
|
||||||
|
assert max_entries >= 0
|
||||||
|
with self._cache_lock:
|
||||||
|
# Transform start_index to our present cache space.
|
||||||
|
start_index -= self._cache_index_offset
|
||||||
|
# Calc end-index in our present cache space.
|
||||||
|
end_index = (len(self._cache)
|
||||||
|
if max_entries is None else start_index + max_entries)
|
||||||
|
|
||||||
|
# Clamp both indexes to both ends of our present space.
|
||||||
|
start_index = max(0, min(start_index, len(self._cache)))
|
||||||
|
end_index = max(0, min(end_index, len(self._cache)))
|
||||||
|
|
||||||
|
return LogArchive(
|
||||||
|
log_size=self._cache_index_offset + len(self._cache),
|
||||||
|
start_index=start_index + self._cache_index_offset,
|
||||||
|
entries=[e[1] for e in self._cache[start_index:end_index]])
|
||||||
|
|
||||||
def emit(self, record: logging.LogRecord) -> None:
|
def emit(self, record: logging.LogRecord) -> None:
|
||||||
# Called by logging to send us records.
|
# Called by logging to send us records.
|
||||||
# We simply package them up and ship them to our thread.
|
# We simply package them up and ship them to our thread.
|
||||||
@ -143,22 +196,23 @@ class LogHandler(logging.Handler):
|
|||||||
# didn't expect to be stringified.
|
# didn't expect to be stringified.
|
||||||
msg = self.format(record)
|
msg = self.format(record)
|
||||||
|
|
||||||
# Also print pretty colored output to our echo file (generally
|
# Also immediately print pretty colored output to our echo file
|
||||||
# stderr). We do this part here instead of in our bg thread
|
# (generally stderr). We do this part here instead of in our bg
|
||||||
# because the delay can throw off command line prompts or make
|
# thread because the delay can throw off command line prompts or
|
||||||
# tight debugging harder.
|
# make tight debugging harder.
|
||||||
if self._echofile is not None:
|
if self._echofile is not None:
|
||||||
cbegin: str
|
ends = LEVELNO_COLOR_CODES.get(record.levelno)
|
||||||
cend: str
|
if ends is not None:
|
||||||
cbegin, cend = LEVELNO_COLOR_CODES.get(record.levelno, ('', ''))
|
self._echofile.write(f'{ends[0]}{msg}{ends[1]}\n')
|
||||||
self._echofile.write(f'{cbegin}{msg}{cend}\n')
|
else:
|
||||||
|
self._echofile.write(f'{msg}\n')
|
||||||
|
|
||||||
self._event_loop.call_soon_threadsafe(
|
self._event_loop.call_soon_threadsafe(
|
||||||
tpartial(self._emit_in_loop, record.name, record.levelno,
|
tpartial(self._emit_in_thread, record.name, record.levelno,
|
||||||
record.created, msg))
|
record.created, msg))
|
||||||
|
|
||||||
def _emit_in_loop(self, name: str, levelno: int, created: float,
|
def _emit_in_thread(self, name: str, levelno: int, created: float,
|
||||||
message: str) -> None:
|
message: str) -> None:
|
||||||
try:
|
try:
|
||||||
self._emit_entry(
|
self._emit_entry(
|
||||||
LogEntry(name=name,
|
LogEntry(name=name,
|
||||||
@ -174,9 +228,9 @@ class LogHandler(logging.Handler):
|
|||||||
"""Send raw stdout/stderr output to the logger to be collated."""
|
"""Send raw stdout/stderr output to the logger to be collated."""
|
||||||
|
|
||||||
self._event_loop.call_soon_threadsafe(
|
self._event_loop.call_soon_threadsafe(
|
||||||
tpartial(self._file_write_in_loop, name, output))
|
tpartial(self._file_write_in_thread, name, output))
|
||||||
|
|
||||||
def _file_write_in_loop(self, name: str, output: str) -> None:
|
def _file_write_in_thread(self, name: str, output: str) -> None:
|
||||||
try:
|
try:
|
||||||
assert name in ('stdout', 'stderr')
|
assert name in ('stdout', 'stderr')
|
||||||
|
|
||||||
@ -222,9 +276,26 @@ class LogHandler(logging.Handler):
|
|||||||
self._file_chunk_ship_task[name] = None
|
self._file_chunk_ship_task[name] = None
|
||||||
|
|
||||||
def _emit_entry(self, entry: LogEntry) -> None:
|
def _emit_entry(self, entry: LogEntry) -> None:
|
||||||
# This runs in our bg event loop thread and does most of the work.
|
|
||||||
assert current_thread() is self._thread
|
assert current_thread() is self._thread
|
||||||
|
|
||||||
|
# Store to our cache.
|
||||||
|
if self._cache_size_limit > 0:
|
||||||
|
with self._cache_lock:
|
||||||
|
# Do a rough calc of how many bytes this entry consumes.
|
||||||
|
entry_size = sum(
|
||||||
|
sys.getsizeof(x)
|
||||||
|
for x in (entry, entry.name, entry.message, entry.level,
|
||||||
|
entry.time))
|
||||||
|
self._cache.append((entry_size, entry))
|
||||||
|
self._cache_size += entry_size
|
||||||
|
|
||||||
|
# Prune old until we are back at or under our limit.
|
||||||
|
while self._cache_size > self._cache_size_limit:
|
||||||
|
popped = self._cache.pop(0)
|
||||||
|
self._cache_size -= popped[0]
|
||||||
|
self._cache_index_offset += 1
|
||||||
|
|
||||||
|
# Pass to callbacks.
|
||||||
with self._callbacks_lock:
|
with self._callbacks_lock:
|
||||||
for call in self._callbacks:
|
for call in self._callbacks:
|
||||||
try:
|
try:
|
||||||
@ -271,11 +342,12 @@ class FileLogEcho:
|
|||||||
def setup_logging(log_path: str | Path | None,
|
def setup_logging(log_path: str | Path | None,
|
||||||
level: LogLevel,
|
level: LogLevel,
|
||||||
suppress_non_root_debug: bool = False,
|
suppress_non_root_debug: bool = False,
|
||||||
log_stdout_stderr: bool = False) -> LogHandler:
|
log_stdout_stderr: bool = False,
|
||||||
|
cache_size_limit: int = 0) -> LogHandler:
|
||||||
"""Set up our logging environment.
|
"""Set up our logging environment.
|
||||||
|
|
||||||
Returns the custom handler which can be used to fetch information
|
Returns the custom handler which can be used to fetch information
|
||||||
about logs that have passed through it. (worst log-levels, etc.).
|
about logs that have passed through it. (worst log-levels, caches, etc.).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
lmap = {
|
lmap = {
|
||||||
@ -295,7 +367,8 @@ def setup_logging(log_path: str | Path | None,
|
|||||||
loghandler = LogHandler(
|
loghandler = LogHandler(
|
||||||
log_path,
|
log_path,
|
||||||
echofile=sys.stderr if sys.stderr.isatty() else None,
|
echofile=sys.stderr if sys.stderr.isatty() else None,
|
||||||
suppress_non_root_debug=suppress_non_root_debug)
|
suppress_non_root_debug=suppress_non_root_debug,
|
||||||
|
cache_size_limit=cache_size_limit)
|
||||||
|
|
||||||
# Note: going ahead with force=True here so that we replace any
|
# Note: going ahead with force=True here so that we replace any
|
||||||
# existing logger. Though we warn if it looks like we are doing
|
# existing logger. Though we warn if it looks like we are doing
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user