lang updates, mac/apple work, polishing

This commit is contained in:
Eric 2023-11-07 08:31:30 -08:00
parent 544e26f129
commit 0d2a9c19b5
No known key found for this signature in database
GPG Key ID: 89C93F0F8D6D5A98
37 changed files with 404 additions and 127 deletions

118
.efrocachemap generated
View File

@ -421,40 +421,40 @@
"build/assets/ba_data/audio/zoeOw.ogg": "74befe45a8417e95b6a2233c51992a26", "build/assets/ba_data/audio/zoeOw.ogg": "74befe45a8417e95b6a2233c51992a26",
"build/assets/ba_data/audio/zoePickup01.ogg": "48ab8cddfcde36a750856f3f81dd20c8", "build/assets/ba_data/audio/zoePickup01.ogg": "48ab8cddfcde36a750856f3f81dd20c8",
"build/assets/ba_data/audio/zoeScream01.ogg": "2b468aedfa8741090247f04eb9e6df55", "build/assets/ba_data/audio/zoeScream01.ogg": "2b468aedfa8741090247f04eb9e6df55",
"build/assets/ba_data/data/langdata.json": "0b15d171ebcc56d324875b48436b58c2", "build/assets/ba_data/data/langdata.json": "d3d2ff5c566f5ebbfd4c2cb838bddec8",
"build/assets/ba_data/data/languages/arabic.json": "c21378ee214a9dd0cb2971cd46b74374", "build/assets/ba_data/data/languages/arabic.json": "cb5ad1bc4ce57a43902ef2f8770d3721",
"build/assets/ba_data/data/languages/belarussian.json": "4d89ed5f9c615771d4fa2bb1834942d3", "build/assets/ba_data/data/languages/belarussian.json": "4d89ed5f9c615771d4fa2bb1834942d3",
"build/assets/ba_data/data/languages/chinese.json": "1ff4350df6d81c3b1b765fddace6b4c8", "build/assets/ba_data/data/languages/chinese.json": "a87b1ebef100d9cdce0d29123735e90c",
"build/assets/ba_data/data/languages/chinesetraditional.json": "f858da49be0a5374157c627857751078", "build/assets/ba_data/data/languages/chinesetraditional.json": "f858da49be0a5374157c627857751078",
"build/assets/ba_data/data/languages/croatian.json": "766532c67af5bd0144c2d63cab0516fa", "build/assets/ba_data/data/languages/croatian.json": "766532c67af5bd0144c2d63cab0516fa",
"build/assets/ba_data/data/languages/czech.json": "93c5fe0d884d95435da6c675f64e30e0", "build/assets/ba_data/data/languages/czech.json": "93c5fe0d884d95435da6c675f64e30e0",
"build/assets/ba_data/data/languages/danish.json": "3fd69080783d5c9dcc0af737f02b6f1e", "build/assets/ba_data/data/languages/danish.json": "3fd69080783d5c9dcc0af737f02b6f1e",
"build/assets/ba_data/data/languages/dutch.json": "22b44a33bf81142ba2befad14eb5746e", "build/assets/ba_data/data/languages/dutch.json": "22b44a33bf81142ba2befad14eb5746e",
"build/assets/ba_data/data/languages/english.json": "b0c8dc8bd35a5606e5d3318d7cb52cba", "build/assets/ba_data/data/languages/english.json": "0e84003f1d3ebf3d48e00ec962c96de4",
"build/assets/ba_data/data/languages/esperanto.json": "0e397cfa5f3fb8cef5f4a64f21cda880", "build/assets/ba_data/data/languages/esperanto.json": "0e397cfa5f3fb8cef5f4a64f21cda880",
"build/assets/ba_data/data/languages/filipino.json": "afbda3adf14555e1567ee63c32e340e7", "build/assets/ba_data/data/languages/filipino.json": "afbda3adf14555e1567ee63c32e340e7",
"build/assets/ba_data/data/languages/french.json": "4e218dcd488fa63e7db5b4da2261b9e1", "build/assets/ba_data/data/languages/french.json": "49ff6d211537b8003b8241438dca661d",
"build/assets/ba_data/data/languages/german.json": "450fa41ae264f29a5d1af22143d0d0ad", "build/assets/ba_data/data/languages/german.json": "450fa41ae264f29a5d1af22143d0d0ad",
"build/assets/ba_data/data/languages/gibberish.json": "d9022a7e655da5ac41b9cef7f3b114a6", "build/assets/ba_data/data/languages/gibberish.json": "efcc8b133365c9080f99decb75acde02",
"build/assets/ba_data/data/languages/greek.json": "287c0ec437b38772284ef9d3e4fb2fc3", "build/assets/ba_data/data/languages/greek.json": "287c0ec437b38772284ef9d3e4fb2fc3",
"build/assets/ba_data/data/languages/hindi.json": "8ea0c58a44a24edb131d0e53b074d1f6", "build/assets/ba_data/data/languages/hindi.json": "8ea0c58a44a24edb131d0e53b074d1f6",
"build/assets/ba_data/data/languages/hungarian.json": "796a290a8c44a1e7635208c2ff5fdc6e", "build/assets/ba_data/data/languages/hungarian.json": "796a290a8c44a1e7635208c2ff5fdc6e",
"build/assets/ba_data/data/languages/indonesian.json": "15a50690e5588d4acd3e07dfdaf755b0", "build/assets/ba_data/data/languages/indonesian.json": "d7e06971ae1df89ac070593d6ca5cd10",
"build/assets/ba_data/data/languages/italian.json": "e4acd4e58ef8db78f3369bf881f84c55", "build/assets/ba_data/data/languages/italian.json": "840a44facc3f203be505e97ce517e008",
"build/assets/ba_data/data/languages/korean.json": "ca1122a9ee551da3f75ae632012bd0e2", "build/assets/ba_data/data/languages/korean.json": "ca1122a9ee551da3f75ae632012bd0e2",
"build/assets/ba_data/data/languages/malay.json": "832562ce997fc70704b9234c95fb2e38", "build/assets/ba_data/data/languages/malay.json": "832562ce997fc70704b9234c95fb2e38",
"build/assets/ba_data/data/languages/persian.json": "4585070bd509600019ec8dc3bb47bfb8", "build/assets/ba_data/data/languages/persian.json": "07162e160abd7452d1b25d069425653b",
"build/assets/ba_data/data/languages/polish.json": "5e25428554893155a5f81f3eeb418bae", "build/assets/ba_data/data/languages/polish.json": "5e25428554893155a5f81f3eeb418bae",
"build/assets/ba_data/data/languages/portuguese.json": "51e362956f89da3eec980f587c092253", "build/assets/ba_data/data/languages/portuguese.json": "a1af6ebf382969cbe16083fbfdb445da",
"build/assets/ba_data/data/languages/romanian.json": "aeebdd54f65939c2facc6ac50c117826", "build/assets/ba_data/data/languages/romanian.json": "aeebdd54f65939c2facc6ac50c117826",
"build/assets/ba_data/data/languages/russian.json": "6e524210149d95479d6cbfd3506c630b", "build/assets/ba_data/data/languages/russian.json": "a88a107d9643084ecec41649c1d6300e",
"build/assets/ba_data/data/languages/serbian.json": "d7452dd72ac0e51680cb39b5ebaa1c69", "build/assets/ba_data/data/languages/serbian.json": "d7452dd72ac0e51680cb39b5ebaa1c69",
"build/assets/ba_data/data/languages/slovak.json": "27962d53dc3f7dd4e877cd40faafeeef", "build/assets/ba_data/data/languages/slovak.json": "27962d53dc3f7dd4e877cd40faafeeef",
"build/assets/ba_data/data/languages/spanish.json": "b179da96097e2b4df9f0397da672be69", "build/assets/ba_data/data/languages/spanish.json": "af2d0fd078144dc649da0bb10bb1f5cd",
"build/assets/ba_data/data/languages/swedish.json": "77d671f10613291ebf9c71da66f18a18", "build/assets/ba_data/data/languages/swedish.json": "77d671f10613291ebf9c71da66f18a18",
"build/assets/ba_data/data/languages/tamil.json": "65ab7798d637fa62a703750179eeb723", "build/assets/ba_data/data/languages/tamil.json": "b4de1a2851afe4869c82e9acd94cd89c",
"build/assets/ba_data/data/languages/thai.json": "33f63753c9af9a5b238d229a0bf23fbc", "build/assets/ba_data/data/languages/thai.json": "33f63753c9af9a5b238d229a0bf23fbc",
"build/assets/ba_data/data/languages/turkish.json": "71fd6c59650c03164a94d884bc7e5263", "build/assets/ba_data/data/languages/turkish.json": "c3674336e746bf7b23617a6ff296c69a",
"build/assets/ba_data/data/languages/ukrainian.json": "f72eb51abfbbb56e27866895d7e947d2", "build/assets/ba_data/data/languages/ukrainian.json": "f72eb51abfbbb56e27866895d7e947d2",
"build/assets/ba_data/data/languages/venetian.json": "9fe1a58d9e5dfb00f31ce3b2eb9993f4", "build/assets/ba_data/data/languages/venetian.json": "9fe1a58d9e5dfb00f31ce3b2eb9993f4",
"build/assets/ba_data/data/languages/vietnamese.json": "921cd1e50f60fe3e101f246e172750ba", "build/assets/ba_data/data/languages/vietnamese.json": "921cd1e50f60fe3e101f246e172750ba",
@ -4056,53 +4056,53 @@
"build/assets/windows/Win32/ucrtbased.dll": "2def5335207d41b21b9823f6805997f1", "build/assets/windows/Win32/ucrtbased.dll": "2def5335207d41b21b9823f6805997f1",
"build/assets/windows/Win32/vc_redist.x86.exe": "b08a55e2e77623fe657bea24f223a3ae", "build/assets/windows/Win32/vc_redist.x86.exe": "b08a55e2e77623fe657bea24f223a3ae",
"build/assets/windows/Win32/vcruntime140d.dll": "865b2af4d1e26a1a8073c89acb06e599", "build/assets/windows/Win32/vcruntime140d.dll": "865b2af4d1e26a1a8073c89acb06e599",
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "1204dd2c8c75de926c75e4502f57078c", "build/prefab/full/linux_arm64_gui/debug/ballisticakit": "19845a4215bc313b1a4dd9d69942265a",
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "264ac33e0b3a273ffd7ef9769dde5cf6", "build/prefab/full/linux_arm64_gui/release/ballisticakit": "40617b9787763afac039ad0d4fc6eadd",
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "2fa0bf5f0a41977b5ec6b00ed4f17e2a", "build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "f824e95be076fe725529fade8e67c7bf",
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "ef726bab56ae11cf3ef215e01e21c9ad", "build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "b9fc05ff4ea772b67d13e4fa502d7e96",
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "f5d464b59bf9cdb8c1196c7884e2f173", "build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "94ab7152a2e807a0a5a86f15fa994ef1",
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "56c886224798634fcea2ddfb5591ce45", "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "2b8826ec31f972d3695f3cc764c2d948",
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "8fb46e16a41be252433e01b1fe8e5beb", "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "e4c860d74e777557c7450ad2768397a3",
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "19fb1ea3b52056948eb8cb09527ebe8f", "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "95aadd6ff910cc97d713d89e7b4b7204",
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "4abe83d555baef553005792bb2afba97", "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "f9716cc12cd895de300a0e2f4081d26c",
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "0166ad734496b21d70e4d830cbb1ec19", "build/prefab/full/mac_arm64_gui/release/ballisticakit": "27b743836b3026b1188fbc61e88ac63f",
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "bfd52a1ce35dfbabc57e6de74e2a61d0", "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "33fded513bdfc0a71e58c29f5f491b2e",
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "f5a7ecb24c30c46f3ea7d340f3373fdb", "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "71c7005881cff6ff7746d5727c2707a5",
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "3a9e88a6e7242f7488a59c9d8c42e8ee", "build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "ee418012d124c7f3268e9f533a865d74",
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "fba815a45d4eec03f9d03d3adcb65261", "build/prefab/full/mac_x86_64_gui/release/ballisticakit": "8653169242b6f5b1fdb3649585da37ed",
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "f4ee5cbc285b34d905dbc28dbcd25762", "build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "d02f8dd537b65dcd1580f97dc215a2f4",
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "3fd648584a9a1168b2c7e5cb4e6e18b9", "build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "7da065b3e1a360df7bc0f0b047e26a8d",
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "47e28b96a08f68902cbe206e6ba652d1", "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "8845c707fa5c004f33b84e6515d7de27",
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "fd7b02a98cc446f848f5c19182737b62", "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "91cfbdc3c4ed14bb7febd1ebee73a652",
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "5218e7604faabfb6b5574d756753edc8", "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "34fb266dcb2900931232fc4807d646ad",
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "cc3a4942b16dbd28698cfa677e1bd4ac", "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "7820f6e29bf5f06ca395ca0e939bb24c",
"build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "d9f919fe87d497529cd8aed24a961ea3", "build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "542350a6380ee39396048bf7e311492e",
"build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "56972014971024060e6014c2027debd2", "build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "55e5254a8d2b7a57a70daf0e49c9f3de",
"build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "d9f919fe87d497529cd8aed24a961ea3", "build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "542350a6380ee39396048bf7e311492e",
"build/prefab/lib/linux_arm64_server/release/libballisticaplus.a": "56972014971024060e6014c2027debd2", "build/prefab/lib/linux_arm64_server/release/libballisticaplus.a": "55e5254a8d2b7a57a70daf0e49c9f3de",
"build/prefab/lib/linux_x86_64_gui/debug/libballisticaplus.a": "3b0da9dfd7b2efe967aaafd3e68d4a86", "build/prefab/lib/linux_x86_64_gui/debug/libballisticaplus.a": "e5f96639a0806a7c6a7e76c3c602d71e",
"build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "d4889e0f44a762e4bf067af33e8885e1", "build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "aa334ef3a0b9883c64a979abfac03614",
"build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "3b0da9dfd7b2efe967aaafd3e68d4a86", "build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "e5f96639a0806a7c6a7e76c3c602d71e",
"build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "d4889e0f44a762e4bf067af33e8885e1", "build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "aa334ef3a0b9883c64a979abfac03614",
"build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "5d6b77d2280ad8366f1386f7af0d8e6b", "build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "d8e77274adbd49f54cb0ae10932a1cd4",
"build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "0c8ab52403a77eb7a11137afb6946f8b", "build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "00d78e3bd28bb2d151f6b2dabb28bf6b",
"build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "5d6b77d2280ad8366f1386f7af0d8e6b", "build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "d8e77274adbd49f54cb0ae10932a1cd4",
"build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "0c8ab52403a77eb7a11137afb6946f8b", "build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "00d78e3bd28bb2d151f6b2dabb28bf6b",
"build/prefab/lib/mac_x86_64_gui/debug/libballisticaplus.a": "85ab9b2e82eb2ddca6e915b4a3c3589e", "build/prefab/lib/mac_x86_64_gui/debug/libballisticaplus.a": "7062c43dfcb22a4dab751d4d63a77bcc",
"build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "39a0f3efabd9d2f62202ef9790e5cecd", "build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "d5d54553e6069cb258bc2aee960de714",
"build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "2609429078b69b48c3cda49abac7065c", "build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "aad9457aaa3f0d12be511fcec6168090",
"build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "39a0f3efabd9d2f62202ef9790e5cecd", "build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "d5d54553e6069cb258bc2aee960de714",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "61c6cc3186a52a11fb139d223b09cb52", "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "ab4eae4c6dff6e748e67017d21f1e8c8",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "783012d8d15a7345b4b73d1b9e0b3981", "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "f5eac099166269081a9ba49b354979d5",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "2320d558ecad7debab45d723d4324eae", "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "52ae423620dede6bfd35face89277298",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "be03efae4c21cd3645754f9dd64e00ad", "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "0fa3164cb9bedac84418c5223b1c8b05",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "51d50c4a0dae45415ab465f13fdc7a92", "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "b4051c8e3eca5a9d2b1d1fd613c0e563",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "10a651d1815134112b9dc3e151c6adfa", "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "0a3fed54d59a681df074d56c3dc76268",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "4f7c320636d09bc598c38fc1a2db6d7d", "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "42f69e30b6cf087bbc01fa5e508f1e6c",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "9e9244b097860ad6a76478b0a1fa137f", "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "08d7f5d30a2c84e2f325d51f08e0611a",
"src/assets/ba_data/python/babase/_mgen/__init__.py": "f885fed7f2ed98ff2ba271f9dbe3391c", "src/assets/ba_data/python/babase/_mgen/__init__.py": "f885fed7f2ed98ff2ba271f9dbe3391c",
"src/assets/ba_data/python/babase/_mgen/enums.py": "28323912b56ec07701eda3d41a6a4101", "src/assets/ba_data/python/babase/_mgen/enums.py": "28323912b56ec07701eda3d41a6a4101",
"src/ballistica/base/mgen/pyembed/binding_base.inc": "6df0f34207346d89a72924249ddd4706", "src/ballistica/base/mgen/pyembed/binding_base.inc": "72bfed2cce8ff19741989dec28302f3f",
"src/ballistica/base/mgen/pyembed/binding_base_app.inc": "00f81f9bd92386ec12a6e60170678a98", "src/ballistica/base/mgen/pyembed/binding_base_app.inc": "00f81f9bd92386ec12a6e60170678a98",
"src/ballistica/classic/mgen/pyembed/binding_classic.inc": "3ceb412513963f0818ab39c58bf292e3", "src/ballistica/classic/mgen/pyembed/binding_classic.inc": "3ceb412513963f0818ab39c58bf292e3",
"src/ballistica/core/mgen/pyembed/binding_core.inc": "9d0a3c9636138e35284923e0c8311c69", "src/ballistica/core/mgen/pyembed/binding_core.inc": "9d0a3c9636138e35284923e0c8311c69",

View File

@ -1,4 +1,4 @@
### 1.7.28 (build 21556, api 8, 2023-11-01) ### 1.7.28 (build 21570, api 8, 2023-11-07)
- Massively cleaned up code related to rendering and window systems (OpenGL, - Massively cleaned up code related to rendering and window systems (OpenGL,
SDL, etc). This code had been growing into a nasty tangle for 15 years SDL, etc). This code had been growing into a nasty tangle for 15 years
@ -202,6 +202,9 @@
several hundred FPS, milliseconds per frame would drop to 0 which caused some several hundred FPS, milliseconds per frame would drop to 0 which caused some
problems. Note that scenev1 will be remaining on milliseconds internally for problems. Note that scenev1 will be remaining on milliseconds internally for
compatibility reasons. Scenev2 should move to microseconds though. compatibility reasons. Scenev2 should move to microseconds though.
- The V2 account id for the signed in account is now available at
`ba*.app.plus.accounts.primary.accountid` (alongside some other existing
account info).
### 1.7.27 (build 21282, api 8, 2023-08-30) ### 1.7.27 (build 21282, api 8, 2023-08-30)

View File

@ -31,6 +31,8 @@ class AccountV2Subsystem:
""" """
def __init__(self) -> None: def __init__(self) -> None:
from babase._login import LoginAdapterGPGS
# Whether or not everything related to an initial login # Whether or not everything related to an initial login
# (or lack thereof) has completed. This includes things like # (or lack thereof) has completed. This includes things like
# workspace syncing. Completion of this is what flips the app # workspace syncing. Completion of this is what flips the app
@ -45,15 +47,7 @@ class AccountV2Subsystem:
self._implicit_state_changed = False self._implicit_state_changed = False
self._can_do_auto_sign_in = True self._can_do_auto_sign_in = True
if _babase.app.classic is None: if _babase.using_google_play_game_services():
raise RuntimeError('Needs updating for no-classic case.')
if (
_babase.app.classic.platform == 'android'
and _babase.app.classic.subplatform == 'google'
):
from babase._login import LoginAdapterGPGS
self.login_adapters[LoginType.GPGS] = LoginAdapterGPGS() self.login_adapters[LoginType.GPGS] = LoginAdapterGPGS()
def on_app_loading(self) -> None: def on_app_loading(self) -> None:
@ -62,10 +56,6 @@ class AccountV2Subsystem:
for adapter in self.login_adapters.values(): for adapter in self.login_adapters.values():
adapter.on_app_loading() adapter.on_app_loading()
def set_primary_credentials(self, credentials: str | None) -> None:
"""Set credentials for the primary app account."""
raise NotImplementedError('This should be overridden.')
def have_primary_credentials(self) -> bool: def have_primary_credentials(self) -> bool:
"""Are credentials currently set for the primary app account? """Are credentials currently set for the primary app account?
@ -80,10 +70,6 @@ class AccountV2Subsystem:
"""The primary account for the app, or None if not logged in.""" """The primary account for the app, or None if not logged in."""
return self.do_get_primary() return self.do_get_primary()
def do_get_primary(self) -> AccountV2Handle | None:
"""Internal - should be overridden by subclass."""
return None
def on_primary_account_changed( def on_primary_account_changed(
self, account: AccountV2Handle | None self, account: AccountV2Handle | None
) -> None: ) -> None:
@ -259,6 +245,14 @@ class AccountV2Subsystem:
# We may want to auto-sign-in based on this new state. # We may want to auto-sign-in based on this new state.
self._update_auto_sign_in() self._update_auto_sign_in()
def do_get_primary(self) -> AccountV2Handle | None:
"""Internal - should be overridden by subclass."""
raise NotImplementedError('This should be overridden.')
def set_primary_credentials(self, credentials: str | None) -> None:
"""Set credentials for the primary app account."""
raise NotImplementedError('This should be overridden.')
def _update_auto_sign_in(self) -> None: def _update_auto_sign_in(self) -> None:
plus = _babase.app.plus plus = _babase.app.plus
assert plus is not None assert plus is not None
@ -419,14 +413,21 @@ class AccountV2Handle:
used with some operations such as cloud messaging. used with some operations such as cloud messaging.
""" """
def __init__(self) -> None: accountid: str
self.tag = '?' tag: str
workspacename: str | None
workspaceid: str | None
logins: dict[LoginType, str]
self.workspacename: str | None = None # def __init__(self) -> None:
self.workspaceid: str | None = None
# Login types and their display-names associated with this account. # self.workspacename: str | None = None
self.logins: dict[LoginType, str] = {} # self.workspaceid: str | None = None
# # Login types and their display-names associated with this account.
# self.logins: dict[LoginType, str] = {}
# self.accountid: str =
def __enter__(self) -> None: def __enter__(self) -> None:
"""Support for "with" statement. """Support for "with" statement.

View File

@ -33,6 +33,23 @@ def reset_to_main_menu() -> None:
logging.warning('reset_to_main_menu: no-op due to classic not present.') logging.warning('reset_to_main_menu: no-op due to classic not present.')
def get_v2_account_id() -> str | None:
"""Return the current V2 account id if signed in, or None if not."""
try:
plus = _babase.app.plus
if plus is not None:
account = plus.accounts.primary
if account is not None:
accountid = account.accountid
# (Avoids mypy complaints when plus is not present)
assert isinstance(accountid, (str, type(None)))
return accountid
return None
except Exception:
logging.exception('Error fetching v2 account id.')
return None
def store_config_fullscreen_on() -> None: def store_config_fullscreen_on() -> None:
"""The OS has changed our fullscreen state and we should take note.""" """The OS has changed our fullscreen state and we should take note."""
_babase.app.config['Fullscreen'] = True _babase.app.config['Fullscreen'] = True
@ -123,6 +140,14 @@ def error_message() -> None:
_babase.screenmessage(Lstr(resource='errorText'), color=(1, 0, 0)) _babase.screenmessage(Lstr(resource='errorText'), color=(1, 0, 0))
def success_message() -> None:
from babase._language import Lstr
if _babase.app.env.gui:
_babase.getsimplesound('dingSmall').play()
_babase.screenmessage(Lstr(resource='successText'), color=(0, 1, 0))
def purchase_not_valid_error() -> None: def purchase_not_valid_error() -> None:
from babase._language import Lstr from babase._language import Lstr

View File

@ -340,8 +340,8 @@ class LoginAdapter:
class LoginAdapterNative(LoginAdapter): class LoginAdapterNative(LoginAdapter):
"""A login adapter that does its work in the native layer.""" """A login adapter that does its work in the native layer."""
def __init__(self) -> None: def __init__(self, login_type: LoginType) -> None:
super().__init__(LoginType.GPGS) super().__init__(login_type)
# Store int ids for in-flight attempts since they may go through # Store int ids for in-flight attempts since they may go through
# various platform layers and back. # various platform layers and back.
@ -375,3 +375,6 @@ class LoginAdapterNative(LoginAdapter):
class LoginAdapterGPGS(LoginAdapterNative): class LoginAdapterGPGS(LoginAdapterNative):
"""Google Play Game Services adapter.""" """Google Play Game Services adapter."""
def __init__(self) -> None:
super().__init__(LoginType.GPGS)

View File

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

View File

@ -1,6 +1,6 @@
# Released under the MIT License. See LICENSE for details. # Released under the MIT License. See LICENSE for details.
# #
"""Provides classic app subsystem.""" """Provides plus app subsystem."""
from __future__ import annotations from __future__ import annotations
from typing import TYPE_CHECKING from typing import TYPE_CHECKING

View File

@ -352,7 +352,7 @@ class StoreBrowserWindow(bui.Window):
plus = bui.app.plus plus = bui.app.plus
assert plus is not None assert plus is not None
if plus.get_v1_account_state() != 'signed_in': if plus.accounts.primary is None:
account.show_sign_in_prompt() account.show_sign_in_prompt()
else: else:
plus.restore_purchases() plus.restore_purchases()

View File

@ -51,6 +51,13 @@ void AppAdapterApple::DoPushMainThreadRunnable(Runnable* runnable) {
BallisticaKit::FromCpp::PushRawRunnableToMain(runnable); BallisticaKit::FromCpp::PushRawRunnableToMain(runnable);
} }
void AppAdapterApple::OnMainThreadStartApp() {
AppAdapter::OnMainThreadStartApp();
#if BA_USE_STORE_KIT
BallisticaKit::StoreKitContext::onAppStart();
#endif
}
void AppAdapterApple::DoApplyAppConfig() { assert(g_base->InLogicThread()); } void AppAdapterApple::DoApplyAppConfig() { assert(g_base->InLogicThread()); }
void AppAdapterApple::ApplyGraphicsSettings(const GraphicsSettings* settings) { void AppAdapterApple::ApplyGraphicsSettings(const GraphicsSettings* settings) {

View File

@ -26,6 +26,8 @@ class AppAdapterApple : public AppAdapter {
return val; return val;
} }
void OnMainThreadStartApp() override;
auto ManagesMainThreadEventLoop() const -> bool override; auto ManagesMainThreadEventLoop() const -> bool override;
void DoApplyAppConfig() override; void DoApplyAppConfig() override;

View File

@ -151,6 +151,43 @@ auto BaseFeatureSet::IsBaseCompletelyImported() -> bool {
return base_import_completed_ && base_native_import_completed_; return base_import_completed_ && base_native_import_completed_;
} }
void BaseFeatureSet::SuccessScreenMessage() {
if (auto* event_loop = logic->event_loop()) {
event_loop->PushCall([this] {
python->objs().Get(BasePython::ObjID::kSuccessMessageCall).Call();
});
} else {
Log(LogLevel::kError,
"SuccessScreenMessage called without logic event_loop in place.");
}
}
void BaseFeatureSet::ErrorScreenMessage() {
if (auto* event_loop = logic->event_loop()) {
event_loop->PushCall([this] {
python->objs().Get(BasePython::ObjID::kErrorMessageCall).Call();
});
} else {
Log(LogLevel::kError,
"ErrorScreenMessage called without logic event_loop in place.");
}
}
auto BaseFeatureSet::GetV2AccountID() -> std::optional<std::string> {
auto gil = Python::ScopedInterpreterLock();
auto result =
python->objs().Get(BasePython::ObjID::kGetV2AccountIdCall).Call();
if (result.Exists()) {
if (result.ValueIsNone()) {
return {};
}
return result.ValueAsString();
} else {
Log(LogLevel::kError, "GetV2AccountID() py call errored.");
return {};
}
}
void BaseFeatureSet::OnAssetsAvailable() { void BaseFeatureSet::OnAssetsAvailable() {
assert(InLogicThread()); assert(InLogicThread());

View File

@ -632,6 +632,13 @@ class BaseFeatureSet : public FeatureSetNativeComponent,
return *context_ref; return *context_ref;
} }
/// Utility call to print 'Success!' with a happy sound.
/// Safe to call from any thread.
void SuccessScreenMessage();
/// Utility call to print 'Error.' with a beep sound.
/// Safe to call from any thread.
void ErrorScreenMessage();
void SetCurrentContext(const ContextRef& context); void SetCurrentContext(const ContextRef& context);
/// Try to load the plus feature-set and return whether it is available. /// Try to load the plus feature-set and return whether it is available.
@ -725,6 +732,10 @@ class BaseFeatureSet : public FeatureSetNativeComponent,
void PushMainThreadRunnable(Runnable* runnable) override; void PushMainThreadRunnable(Runnable* runnable) override;
/// Return the currently signed in V2 account id as
/// reported by the Python layer.
auto GetV2AccountID() -> std::optional<std::string>;
// Const subsystems. // Const subsystems.
AppAdapter* const app_adapter; AppAdapter* const app_adapter;
AppConfig* const app_config; AppConfig* const app_config;

View File

@ -25,7 +25,8 @@ BasePlatformApple::BasePlatformApple() {
void BasePlatformApple::DoPurchase(const std::string& item) { void BasePlatformApple::DoPurchase(const std::string& item) {
#if BA_USE_STORE_KIT #if BA_USE_STORE_KIT
AppleUtils::DoStoreKitPurchase(item); BallisticaKit::StoreKitContext::purchase(item);
// AppleUtils::DoStoreKitPurchase(item);
#else #else
BasePlatform::DoPurchase(item); BasePlatform::DoPurchase(item);
#endif #endif
@ -33,7 +34,8 @@ void BasePlatformApple::DoPurchase(const std::string& item) {
void BasePlatformApple::RestorePurchases() { void BasePlatformApple::RestorePurchases() {
#if BA_USE_STORE_KIT #if BA_USE_STORE_KIT
AppleUtils::DoStoreKitPurchaseRestore(); BallisticaKit::StoreKitContext::restorePurchases();
// AppleUtils::DoStoreKitPurchaseRestore();
#else #else
BasePlatform::RestorePurchases(); BasePlatform::RestorePurchases();
#endif #endif
@ -41,8 +43,9 @@ void BasePlatformApple::RestorePurchases() {
void BasePlatformApple::PurchaseAck(const std::string& purchase, void BasePlatformApple::PurchaseAck(const std::string& purchase,
const std::string& order_id) { const std::string& order_id) {
#if BA_XCODE_BUILD && BA_USE_STORE_KIT #if BA_USE_STORE_KIT
AppleUtils::PurchaseAck(purchase, order_id); BallisticaKit::StoreKitContext::purchaseAck(purchase, order_id);
// AppleUtils::PurchaseAck(purchase, order_id);
#else #else
BasePlatform::PurchaseAck(purchase, order_id); BasePlatform::PurchaseAck(purchase, order_id);
#endif #endif

View File

@ -48,6 +48,7 @@ class BasePython {
kTemporarilyUnavailableMessageCall, kTemporarilyUnavailableMessageCall,
kInProgressMessageCall, kInProgressMessageCall,
kErrorMessageCall, kErrorMessageCall,
kSuccessMessageCall,
kPurchaseNotValidErrorCall, kPurchaseNotValidErrorCall,
kPurchaseAlreadyInProgressErrorCall, kPurchaseAlreadyInProgressErrorCall,
kVROrientationResetCBMessageCall, kVROrientationResetCBMessageCall,
@ -111,6 +112,7 @@ class BasePython {
kGetDevConsoleTabNamesCall, kGetDevConsoleTabNamesCall,
kAppDevConsoleDoRefreshTabCall, kAppDevConsoleDoRefreshTabCall,
kUnsupportedControllerMessageCall, kUnsupportedControllerMessageCall,
kGetV2AccountIdCall,
kLast // Sentinel; must be at end. kLast // Sentinel; must be at end.
}; };

View File

@ -1682,6 +1682,27 @@ static PyMethodDef PyAssetLoadsAllowedDef = {
"(internal)", "(internal)",
}; };
// -------------------- using_google_play_game_services ------------------------
static auto PyUsingGooglePlayGameServices(PyObject* self) -> PyObject* {
BA_PYTHON_TRY;
if (g_buildconfig.use_google_play_game_services()) {
Py_RETURN_TRUE;
}
Py_RETURN_FALSE;
BA_PYTHON_CATCH;
}
static PyMethodDef PyUsingGooglePlayGameServicesDef = {
"using_google_play_game_services", // name
(PyCFunction)PyUsingGooglePlayGameServices, // method
METH_NOARGS, // flags
"using_google_play_game_services() -> bool\n"
"\n"
"(internal)",
};
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
auto PythonMethodsMisc::GetMethods() -> std::vector<PyMethodDef> { auto PythonMethodsMisc::GetMethods() -> std::vector<PyMethodDef> {
@ -1745,6 +1766,7 @@ auto PythonMethodsMisc::GetMethods() -> std::vector<PyMethodDef> {
PyDevConsoleBaseScaleDef, PyDevConsoleBaseScaleDef,
PyDevConsoleRequestRefreshDef, PyDevConsoleRequestRefreshDef,
PyAssetLoadsAllowedDef, PyAssetLoadsAllowedDef,
PyUsingGooglePlayGameServicesDef,
}; };
} }

View File

@ -33,6 +33,7 @@ class PlusSoftInterface {
virtual auto PutLog(bool fatal) -> bool = 0; virtual auto PutLog(bool fatal) -> bool = 0;
virtual void AAT() = 0; virtual void AAT() = 0;
virtual void AATE() = 0; virtual void AATE() = 0;
virtual auto GAHU() -> std::optional<std::string> = 0;
virtual void V1LoginDidChange() = 0; virtual void V1LoginDidChange() = 0;
virtual void SetAdCompletionCall(PyObject* obj, virtual void SetAdCompletionCall(PyObject* obj,
bool pass_actually_showed) = 0; bool pass_actually_showed) = 0;

View File

@ -935,7 +935,8 @@ auto DevConsole::HandleKeyPress(const SDL_Keysym* keysym) -> bool {
g_base->app_adapter->GetKeyRepeatDelay(), g_base->app_adapter->GetKeyRepeatDelay(),
g_base->app_adapter->GetKeyRepeatInterval(), [this] { g_base->app_adapter->GetKeyRepeatInterval(), [this] {
auto unichars = Utils::UnicodeFromUTF8(input_string_, "fjco33"); auto unichars = Utils::UnicodeFromUTF8(input_string_, "fjco33");
if (!unichars.empty() && carat_char_ < unichars.size()) { if (!unichars.empty()
&& carat_char_ < static_cast<int>(unichars.size())) {
assert(CaratCharValid_()); assert(CaratCharValid_());
unichars.erase(unichars.begin() + carat_char_); unichars.erase(unichars.begin() + carat_char_);
input_string_ = Utils::UTF8FromUnicode(unichars); input_string_ = Utils::UTF8FromUnicode(unichars);

View File

@ -157,9 +157,6 @@ static auto PySetStressTesting(PyObject* self, PyObject* args) -> PyObject* {
if (!PyArg_ParseTuple(args, "pi", &enable, &player_count)) { if (!PyArg_ParseTuple(args, "pi", &enable, &player_count)) {
return nullptr; return nullptr;
} }
// g_base->app_adapter->PushMainThreadCall([enable, player_count] {
// g_base->stress_test()->Set(enable, player_count);
// });
g_base->logic->event_loop()->PushCall([enable, player_count] { g_base->logic->event_loop()->PushCall([enable, player_count] {
g_classic->stress_test()->Set(enable, player_count); g_classic->stress_test()->Set(enable, player_count);
}); });

View File

@ -34,6 +34,33 @@ auto CorePlatformApple::GetDeviceV1AccountUUIDPrefix() -> std::string {
#endif #endif
} }
auto CorePlatformApple::DoGetDeviceName() -> std::string {
#if BA_OSTYPE_MACOS && BA_XCODE_BUILD
// Ask swift for a pretty name if possible.
auto val = BallisticaKit::CocoaFromCpp::GetDeviceName();
if (val) {
return val.get();
}
#elif BA_OSTYPE_IOS_TVOS && BA_XCODE_BUILD
return BallisticaKit::UIKitFromCpp::GetDeviceName();
#endif
return CorePlatform::DoGetDeviceName();
}
auto CorePlatformApple::DoGetDeviceDescription() -> std::string {
#if BA_OSTYPE_MACOS && BA_XCODE_BUILD
return BallisticaKit::CocoaFromCpp::GetDeviceModelName();
#endif
return CorePlatform::DoGetDeviceDescription();
}
auto CorePlatformApple::GetOSVersionString() -> std::string {
#if BA_XCODE_BUILD
return BallisticaKit::FromCpp::GetOSVersion();
#endif
return CorePlatform::GetOSVersionString();
}
// Legacy for device-accounts; don't modify this code. // Legacy for device-accounts; don't modify this code.
auto CorePlatformApple::GetRealLegacyDeviceUUID(std::string* uuid) -> bool { auto CorePlatformApple::GetRealLegacyDeviceUUID(std::string* uuid) -> bool {
#if BA_OSTYPE_MACOS && BA_XCODE_BUILD #if BA_OSTYPE_MACOS && BA_XCODE_BUILD

View File

@ -59,6 +59,9 @@ class CorePlatformApple : public CorePlatform {
auto GetDeviceUUIDInputs() -> std::list<std::string> override; auto GetDeviceUUIDInputs() -> std::list<std::string> override;
auto GetLocale() -> std::string override; auto GetLocale() -> std::string override;
auto DoGetDeviceName() -> std::string override;
auto DoGetDeviceDescription() -> std::string override;
auto GetOSVersionString() -> std::string override;
protected: protected:
auto DoGetDataDirectoryMonolithicDefault() -> std::string override; auto DoGetDataDirectoryMonolithicDefault() -> std::string override;

View File

@ -112,6 +112,8 @@ void CorePlatform::PostInit() {
// this sometimes (mainly on windows). Should look into that // this sometimes (mainly on windows). Should look into that
// more closely or at least log it somewhere. // more closely or at least log it somewhere.
device_name_ = Utils::GetValidUTF8(DoGetDeviceName().c_str(), "dn"); device_name_ = Utils::GetValidUTF8(DoGetDeviceName().c_str(), "dn");
device_description_ =
Utils::GetValidUTF8(DoGetDeviceDescription().c_str(), "fc");
ran_base_post_init_ = true; ran_base_post_init_ = true;
// Are we running in a terminal? // Are we running in a terminal?
@ -424,6 +426,11 @@ auto CorePlatform::GetDeviceName() -> std::string {
return device_name_; return device_name_;
} }
auto CorePlatform::GetDeviceDescription() -> std::string {
assert(ran_base_post_init_);
return device_description_;
}
auto CorePlatform::DoGetDeviceName() -> std::string { auto CorePlatform::DoGetDeviceName() -> std::string {
// Check devicename in env_var // Check devicename in env_var
char* devicename; char* devicename;
@ -439,7 +446,11 @@ auto CorePlatform::DoGetDeviceName() -> std::string {
nbuffer[sizeof(nbuffer) - 1] = 0; // Make sure its terminated. nbuffer[sizeof(nbuffer) - 1] = 0; // Make sure its terminated.
return nbuffer; return nbuffer;
} }
return "Untitled Device"; return "Unnamed Device";
}
auto CorePlatform::DoGetDeviceDescription() -> std::string {
return "Unknown Device Type";
} }
auto CorePlatform::IsRunningOnTV() -> bool { return false; } auto CorePlatform::IsRunningOnTV() -> bool { return false; }
@ -567,7 +578,7 @@ auto CorePlatform::GetIsStdinATerminal() -> bool {
auto CorePlatform::GetOSVersionString() -> std::string { return ""; } auto CorePlatform::GetOSVersionString() -> std::string { return ""; }
auto CorePlatform::GetLegacyUserAgentString() -> std::string { auto CorePlatform::GetLegacyUserAgentString() -> std::string {
std::string device = GetDeviceName(); std::string device = GetDeviceDescription();
std::string version = GetOSVersionString(); std::string version = GetOSVersionString();
if (!version.empty()) { if (!version.empty()) {
version = " " + version; version = " " + version;
@ -597,7 +608,7 @@ auto CorePlatform::GetLegacyUserAgentString() -> std::string {
subplatform = "DeMo"; subplatform = "DeMo";
} else if (g_buildconfig.arcade_build()) { } else if (g_buildconfig.arcade_build()) {
subplatform = "ArCd"; subplatform = "ArCd";
} else { } else if (g_buildconfig.test_build()) {
subplatform = "TstB"; subplatform = "TstB";
} }
@ -608,10 +619,10 @@ auto CorePlatform::GetLegacyUserAgentString() -> std::string {
subplatform += " OnTV"; subplatform += " OnTV";
} }
std::string out{std::string("BallisticaKit ") + kEngineVersion + subplatform std::string out{std::string("BallisticaKit ") + kEngineVersion + " ("
+ " (" + std::to_string(kEngineBuildNumber) + ") (" + std::to_string(kEngineBuildNumber) + ")" + subplatform
+ g_buildconfig.platform_string() + version + "; " + device + " (" + g_buildconfig.platform_string() + version + "; "
+ "; " + GetLocale() + ")"}; + device + "; " + GetLocale() + ")"};
// This gets shipped to various places which might choke on fancy unicode // This gets shipped to various places which might choke on fancy unicode
// characters, so let's limit to simple ascii. // characters, so let's limit to simple ascii.

View File

@ -116,13 +116,15 @@ class CorePlatform {
/// Return the directory where game replay files live. /// Return the directory where game replay files live.
auto GetReplaysDir() -> std::string; auto GetReplaysDir() -> std::string;
/// Return en_US or whatnot. /// Return something like `en_US` or whatnot.
virtual auto GetLocale() -> std::string; virtual auto GetLocale() -> std::string;
/// Get the older more complex user-agent-string, used for communication /// Get the older more complex user-agent-string, used for communication
/// with v1 servers/etc. This can go away eventually. /// with v1 servers/etc. This should go away eventually.
auto GetLegacyUserAgentString() -> std::string; virtual auto GetLegacyUserAgentString() -> std::string;
/// Return a human readable os version such as "10.4.2".
/// Can return a blank string when not known/relevant.
virtual auto GetOSVersionString() -> std::string; virtual auto GetOSVersionString() -> std::string;
/// Set an environment variable as utf8, overwriting if it already exists. /// Set an environment variable as utf8, overwriting if it already exists.
@ -135,6 +137,9 @@ class CorePlatform {
/// results, etc. /// results, etc.
auto GetDeviceName() -> std::string; auto GetDeviceName() -> std::string;
/// Return a general identifier for the hardware device.
auto GetDeviceDescription() -> std::string;
/// Get a UUID for use with things like device-accounts. This function /// Get a UUID for use with things like device-accounts. This function
/// should not be used for other purposes, should not be modified, and /// should not be used for other purposes, should not be modified, and
/// eventually should go away after device accounts are phased out. Also, /// eventually should go away after device accounts are phased out. Also,
@ -407,9 +412,15 @@ class CorePlatform {
/// Called once per platform to determine touchscreen presence. /// Called once per platform to determine touchscreen presence.
virtual auto DoHasTouchScreen() -> bool; virtual auto DoHasTouchScreen() -> bool;
/// Platforms should override this to provide device name. /// Platforms should override this to provide a device name suitable for
/// displaying in network join lists/etc. Technically this is more like
/// hostname.
virtual auto DoGetDeviceName() -> std::string; virtual auto DoGetDeviceName() -> std::string;
/// Platforms should override this to provide a generic description of the
/// device; something like "iPhone 12 Pro".
virtual auto DoGetDeviceDescription() -> std::string;
/// Attempt to actually create a directory. /// Attempt to actually create a directory.
/// Should *not* raise Exceptions if it already exists or if quiet is true. /// Should *not* raise Exceptions if it already exists or if quiet is true.
virtual void DoMakeDir(const std::string& dir, bool quiet); virtual void DoMakeDir(const std::string& dir, bool quiet);
@ -462,6 +473,7 @@ class CorePlatform {
bool ran_base_post_init_ : 1 {}; bool ran_base_post_init_ : 1 {};
millisecs_t start_time_millisecs_{}; millisecs_t start_time_millisecs_{};
std::string device_name_; std::string device_name_;
std::string device_description_;
std::string legacy_device_uuid_; std::string legacy_device_uuid_;
std::string volatile_data_dir_; std::string volatile_data_dir_;
std::string replays_dir_; std::string replays_dir_;

View File

@ -3,8 +3,10 @@
#if BA_OSTYPE_LINUX #if BA_OSTYPE_LINUX
#include "ballistica/core/platform/linux/core_platform_linux.h" #include "ballistica/core/platform/linux/core_platform_linux.h"
#include <stdlib.h> #include <sys/utsname.h>
#include <cstdlib>
#include <cstring>
#include <string> #include <string>
namespace ballistica::core { namespace ballistica::core {
@ -29,6 +31,53 @@ std::string CorePlatformLinux::GenerateUUID() {
return val; return val;
} }
auto CorePlatformLinux::DoGetDeviceDescription() -> std::string {
// Let's look for something pretty like "Ubuntu 20.04", etc.
FILE* file = fopen("/etc/os-release", "r");
std::optional<std::string> out;
if (file != NULL) {
char line[256]; // Adjust the buffer size as needed
while (fgets(line, sizeof(line), file)) {
if (strstr(line, "PRETTY_NAME=") != nullptr) {
// Extract the distribution name and version
char* start = strchr(line, '"');
char* end = strrchr(line, '"');
if (start != nullptr && end != nullptr) {
*end = '\0'; // Remove the trailing quote
out = start + 1;
}
break;
}
}
fclose(file);
}
if (out.has_value()) {
return *out;
}
return CorePlatform::GetDeviceDescription();
}
auto CorePlatformLinux::GetOSVersionString() -> std::string {
std::optional<std::string> out;
struct utsname uts;
if (uname(&uts) == 0) {
out = uts.release;
// Try to parse 3 version numbers.
unsigned int major, minor, bugfix;
if (sscanf(uts.release, "%u.%u.%u", &major, &minor, &bugfix) == 3) {
char buf[128];
snprintf(buf, sizeof(buf), "%.u.%u.%u", major, minor, bugfix);
out = buf;
}
}
if (out.has_value()) {
return *out;
}
return CorePlatform::GetOSVersionString();
}
auto CorePlatformLinux::GetDeviceUUIDInputs() -> std::list<std::string> { auto CorePlatformLinux::GetDeviceUUIDInputs() -> std::list<std::string> {
std::list<std::string> out; std::list<std::string> out;

View File

@ -21,6 +21,8 @@ class CorePlatformLinux : public CorePlatform {
auto GetPlatformName() -> std::string override; auto GetPlatformName() -> std::string override;
auto GetSubplatformName() -> std::string override; auto GetSubplatformName() -> std::string override;
auto GetDeviceUUIDInputs() -> std::list<std::string> override; auto GetDeviceUUIDInputs() -> std::list<std::string> override;
auto DoGetDeviceDescription() -> std::string override;
auto GetOSVersionString() -> std::string override;
}; };
} // namespace ballistica::core } // namespace ballistica::core

View File

@ -814,15 +814,33 @@ std::string CorePlatformWindows::DoGetDeviceName() {
wchar_t computer_name[256]; wchar_t computer_name[256];
DWORD computer_name_size = 256; DWORD computer_name_size = 256;
int result = GetComputerName(computer_name, &computer_name_size); int result = GetComputerName(computer_name, &computer_name_size);
if (result == 0) { if (result != 0) {
device_name = "BallisticaKit Game";
} else {
device_name = UTF8Encode(computer_name); device_name = UTF8Encode(computer_name);
if (device_name.size() == 0) { if (device_name.size() != 0) {
device_name = "BallisticaKit Game"; return device_name;
} }
} }
return device_name; // Fall back on default.
return CorePlatform::DoGetDeviceName();
}
std::string CorePlatformWindows::DoGetDeviceDescription() {
std::string device_name;
wchar_t computer_name[256];
DWORD computer_name_size = 256;
// We currently return computer name for both the device name
// and description. Is there a way to get a more hardware-y name
// (like manufacturer make/model?)
int result = GetComputerName(computer_name, &computer_name_size);
if (result != 0) {
device_name = UTF8Encode(computer_name);
if (device_name.size() != 0) {
return device_name;
}
}
// Fall back on default.
return CorePlatform::DoGetDeviceDescription();
} }
bool CorePlatformWindows::DoHasTouchScreen() { return false; } bool CorePlatformWindows::DoHasTouchScreen() { return false; }

View File

@ -40,6 +40,7 @@ class CorePlatformWindows : public CorePlatform {
void DoMakeDir(const std::string& dir, bool quiet) override; void DoMakeDir(const std::string& dir, bool quiet) override;
auto GetLocale() -> std::string override; auto GetLocale() -> std::string override;
auto DoGetDeviceName() -> std::string override; auto DoGetDeviceName() -> std::string override;
auto DoGetDeviceDescription() -> std::string override;
auto DoHasTouchScreen() -> bool override; auto DoHasTouchScreen() -> bool override;
void EmitPlatformLog(const std::string& name, LogLevel level, void EmitPlatformLog(const std::string& name, LogLevel level,
const std::string& msg) override; const std::string& msg) override;

View File

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

View File

@ -13,9 +13,9 @@
// We currently support regular and client builds on 64 bit mac posix // We currently support regular and client builds on 64 bit mac posix
#if __amd64__ #if __amd64__
#define BA_PLATFORM_STRING "x86_64_macos" #define BA_PLATFORM_STRING "macos x86_64"
#elif __aarch64__ #elif __aarch64__
#define BA_PLATFORM_STRING "arm64_macos" #define BA_PLATFORM_STRING "macos arm64"
#else #else
#error Unknown processor architecture. #error Unknown processor architecture.
#endif #endif
@ -26,16 +26,16 @@
#elif __linux__ #elif __linux__
#if __amd64__ #if __amd64__
#define BA_PLATFORM_STRING "x86_64_linux" #define BA_PLATFORM_STRING "linux x86_64"
#define BA_OSTYPE_LINUX 1 #define BA_OSTYPE_LINUX 1
#elif __i386__ #elif __i386__
#define BA_PLATFORM_STRING "x86_32_linux" #define BA_PLATFORM_STRING "linux x86"
#define BA_OSTYPE_LINUX 1 #define BA_OSTYPE_LINUX 1
#elif __arm__ #elif __arm__
#define BA_PLATFORM_STRING "arm_linux" #define BA_PLATFORM_STRING "linux arm"
#define BA_OSTYPE_LINUX 1 #define BA_OSTYPE_LINUX 1
#elif __aarch64__ #elif __aarch64__
#define BA_PLATFORM_STRING "arm64_linux" #define BA_PLATFORM_STRING "linux arm64"
#define BA_OSTYPE_LINUX 1 #define BA_OSTYPE_LINUX 1
#else #else

View File

@ -166,6 +166,10 @@ namespace ballistica {
#define BA_AMAZON_BUILD 0 #define BA_AMAZON_BUILD 0
#endif #endif
#ifndef BA_STEAM_BUILD
#define BA_STEAM_BUILD 0
#endif
#ifndef BA_GOOGLE_BUILD #ifndef BA_GOOGLE_BUILD
#define BA_GOOGLE_BUILD 0 #define BA_GOOGLE_BUILD 0
#endif #endif
@ -259,6 +263,7 @@ class BuildConfig {
bool google_build() const { return EXPBOOL_(BA_GOOGLE_BUILD); } bool google_build() const { return EXPBOOL_(BA_GOOGLE_BUILD); }
bool demo_build() const { return EXPBOOL_(BA_DEMO_BUILD); } bool demo_build() const { return EXPBOOL_(BA_DEMO_BUILD); }
bool arcade_build() const { return EXPBOOL_(BA_ARCADE_BUILD); } bool arcade_build() const { return EXPBOOL_(BA_ARCADE_BUILD); }
bool steam_build() const { return EXPBOOL_(BA_STEAM_BUILD); }
bool contains_python_dist() const { bool contains_python_dist() const {
return EXPBOOL_(BA_CONTAINS_PYTHON_DIST); return EXPBOOL_(BA_CONTAINS_PYTHON_DIST);
} }

View File

@ -32,7 +32,16 @@
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#define BA_PLATFORM_STRING "x86_windows" #if defined(_M_ARM64)
#define BA_PLATFORM_STRING "windows arm64"
#elif defined(_M_IX86)
#define BA_PLATFORM_STRING "windows x86"
#elif defined(_M_X64)
#define BA_PLATFORM_STRING "windows x86_64"
#else
#error unknown cpu architecture
#endif
#define BA_OSTYPE_WINDOWS 1 #define BA_OSTYPE_WINDOWS 1
#define BA_SOCKET_SEND_DATA_TYPE char #define BA_SOCKET_SEND_DATA_TYPE char

View File

@ -151,6 +151,12 @@ auto PythonRef::Type() const -> PythonRef {
return {PyObject_Type(obj_), PythonRef::kSteal}; return {PyObject_Type(obj_), PythonRef::kSteal};
} }
auto PythonRef::ValueIsNone() const -> bool {
assert(Python::HaveGIL());
ThrowIfUnset();
return obj_ == Py_None;
}
auto PythonRef::ValueAsLString() const -> std::string { auto PythonRef::ValueAsLString() const -> std::string {
assert(Python::HaveGIL()); assert(Python::HaveGIL());
ThrowIfUnset(); ThrowIfUnset();

View File

@ -162,6 +162,8 @@ class PythonRef {
/// Return the object's Python type object. /// Return the object's Python type object.
auto Type() const -> PythonRef; auto Type() const -> PythonRef;
auto ValueIsNone() const -> bool;
/// For string and babase.Lstr types, returns a utf8 string. /// For string and babase.Lstr types, returns a utf8 string.
/// Throws an exception for other types. /// Throws an exception for other types.
auto ValueAsLString() const -> std::string; auto ValueAsLString() const -> std::string;

View File

@ -2717,14 +2717,14 @@ static auto PyOpenURL(PyObject* self, PyObject* args, PyObject* keywds)
return nullptr; return nullptr;
} }
// Need to pass a self-contained string to a lambda; not a char*. // Need to pass a self-contained string to a lambda; not a char*.
std::string address2{address}; std::string address_s{address};
assert(g_base->app_adapter); assert(g_base->app_adapter);
if (force_internal) { if (force_internal) {
g_base->ui->ShowURL(address); g_base->ui->ShowURL(address);
} else { } else {
g_base->app_adapter->PushMainThreadCall( g_base->app_adapter->PushMainThreadCall(
[address2] { g_base->platform->OpenURL(address2); }); [address_s] { g_base->platform->OpenURL(address_s); });
} }
Py_RETURN_NONE; Py_RETURN_NONE;
BA_PYTHON_CATCH; BA_PYTHON_CATCH;

View File

@ -31,6 +31,7 @@ values = [
_hooks.temporarily_unavailable_message, # kTemporarilyUnavailableMessageCall _hooks.temporarily_unavailable_message, # kTemporarilyUnavailableMessageCall
_hooks.in_progress_message, # kInProgressMessageCall _hooks.in_progress_message, # kInProgressMessageCall
_hooks.error_message, # kErrorMessageCall _hooks.error_message, # kErrorMessageCall
_hooks.success_message, # kSuccessMessageCall
_hooks.purchase_not_valid_error, # kPurchaseNotValidErrorCall _hooks.purchase_not_valid_error, # kPurchaseNotValidErrorCall
_hooks.purchase_already_in_progress_error, # kPurchaseAlreadyInProgressErrorCall _hooks.purchase_already_in_progress_error, # kPurchaseAlreadyInProgressErrorCall
_hooks.orientation_reset_cb_message, # kVROrientationResetCBMessageCall _hooks.orientation_reset_cb_message, # kVROrientationResetCBMessageCall
@ -57,6 +58,7 @@ values = [
_hooks.string_edit_adapter_can_be_replaced, # kStringEditAdapterCanBeReplacedCall _hooks.string_edit_adapter_can_be_replaced, # kStringEditAdapterCanBeReplacedCall
_hooks.get_dev_console_tab_names, # kGetDevConsoleTabNamesCall _hooks.get_dev_console_tab_names, # kGetDevConsoleTabNamesCall
_hooks.unsupported_controller_message, # kUnsupportedControllerMessageCall _hooks.unsupported_controller_message, # kUnsupportedControllerMessageCall
_hooks.get_v2_account_id, # kGetV2AccountIdCall
_language.Lstr, # kLStrClass _language.Lstr, # kLStrClass
_general.Call, # kCallClass _general.Call, # kCallClass
_apputils.garbage_collect_session_end, # kGarbageCollectSessionEndCall _apputils.garbage_collect_session_end, # kGarbageCollectSessionEndCall

View File

@ -20,6 +20,9 @@ class LoginType(Enum):
# Google Play Game Services # Google Play Game Services
GPGS = 'gpgs' GPGS = 'gpgs'
# Apple's Game Center
GAME_CENTER = 'game_center'
@property @property
def displayname(self) -> str: def displayname(self) -> str:
"""Human readable name for this value.""" """Human readable name for this value."""
@ -29,3 +32,5 @@ class LoginType(Enum):
return 'Email/Password' return 'Email/Password'
case cls.GPGS: case cls.GPGS:
return 'Google Play Games' return 'Google Play Games'
case cls.GAME_CENTER:
return 'Game Center'

View File

@ -43,8 +43,8 @@ class PyRequirement:
# remove our custom module based stuff soon if nobody complains, which # remove our custom module based stuff soon if nobody complains, which
# would free us to theoretically move to a requirements.txt based setup. # would free us to theoretically move to a requirements.txt based setup.
PY_REQUIREMENTS = [ PY_REQUIREMENTS = [
PyRequirement(pipname='pylint', minversion=[3, 0, 1]), PyRequirement(pipname='pylint', minversion=[3, 0, 2]),
PyRequirement(pipname='mypy', minversion=[1, 6, 0]), PyRequirement(pipname='mypy', minversion=[1, 6, 1]),
PyRequirement(pipname='cpplint', minversion=[1, 6, 1]), PyRequirement(pipname='cpplint', minversion=[1, 6, 1]),
PyRequirement(pipname='pytest', minversion=[7, 4, 2]), PyRequirement(pipname='pytest', minversion=[7, 4, 2]),
PyRequirement(pipname='pytz', minversion=[2023, 3]), PyRequirement(pipname='pytz', minversion=[2023, 3]),

View File

@ -423,10 +423,20 @@ class Updater:
f'{self.pnameu} macOS AppStore', f'{self.pnameu} macOS AppStore',
f'{self.pnameu} macOS Steam', f'{self.pnameu} macOS Steam',
] ]
# A few things only for AppStore bound builds.
if filename == 'StoreKitContext.swift':
return [
f'{self.pnameu} iOS',
f'{self.pnameu} tvOS',
f'{self.pnameu} macOS AppStore',
]
# UIKit stuff applies to our iOS/tvOS targets. # UIKit stuff applies to our iOS/tvOS targets.
if filename.startswith('UIKit') and filename.endswith('.swift'): if filename.startswith('UIKit') and filename.endswith('.swift'):
return [f'{self.pnameu} iOS', f'{self.pnameu} tvOS'] return [
f'{self.pnameu} iOS',
f'{self.pnameu} tvOS',
]
# Everything else applies to everything. # Everything else applies to everything.
return None return None