Internal work related to tourney security

This commit is contained in:
Eric Froemling 2020-06-07 23:17:48 -07:00
parent 431e6e80bf
commit 5565b4bfa5
33 changed files with 2671 additions and 2596 deletions

View File

@ -420,34 +420,34 @@
"assets/build/ba_data/audio/zoeOw.ogg": "https://files.ballistica.net/cache/ba1/75/1d/868bb04cf691736035c917d02762", "assets/build/ba_data/audio/zoeOw.ogg": "https://files.ballistica.net/cache/ba1/75/1d/868bb04cf691736035c917d02762",
"assets/build/ba_data/audio/zoePickup01.ogg": "https://files.ballistica.net/cache/ba1/44/2a/8535b446284235cb503947ece074", "assets/build/ba_data/audio/zoePickup01.ogg": "https://files.ballistica.net/cache/ba1/44/2a/8535b446284235cb503947ece074",
"assets/build/ba_data/audio/zoeScream01.ogg": "https://files.ballistica.net/cache/ba1/f5/d3/8e941851c4310465646c4167afc1", "assets/build/ba_data/audio/zoeScream01.ogg": "https://files.ballistica.net/cache/ba1/f5/d3/8e941851c4310465646c4167afc1",
"assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/98/6d/e6de20b119fd6a5914982cd468b6", "assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/d4/df/3ab21c23dedf45ab454b0c4286b1",
"assets/build/ba_data/data/languages/arabic.json": "https://files.ballistica.net/cache/ba1/b8/ed/e18bec56ff1d094aae86517a7854", "assets/build/ba_data/data/languages/arabic.json": "https://files.ballistica.net/cache/ba1/b8/ed/e18bec56ff1d094aae86517a7854",
"assets/build/ba_data/data/languages/belarussian.json": "https://files.ballistica.net/cache/ba1/49/5f/b29bb65369040892fe6601801637", "assets/build/ba_data/data/languages/belarussian.json": "https://files.ballistica.net/cache/ba1/49/5f/b29bb65369040892fe6601801637",
"assets/build/ba_data/data/languages/chinese.json": "https://files.ballistica.net/cache/ba1/80/b2/b24a9a8395580ef2dea714abf478", "assets/build/ba_data/data/languages/chinese.json": "https://files.ballistica.net/cache/ba1/bc/59/21bb0b4ef33c733022340c60aebf",
"assets/build/ba_data/data/languages/chinesetraditional.json": "https://files.ballistica.net/cache/ba1/aa/91/2411c0728bae33619c21237a2689", "assets/build/ba_data/data/languages/chinesetraditional.json": "https://files.ballistica.net/cache/ba1/aa/91/2411c0728bae33619c21237a2689",
"assets/build/ba_data/data/languages/croatian.json": "https://files.ballistica.net/cache/ba1/bb/9c/360fc084e6254a087096993af219", "assets/build/ba_data/data/languages/croatian.json": "https://files.ballistica.net/cache/ba1/bb/9c/360fc084e6254a087096993af219",
"assets/build/ba_data/data/languages/czech.json": "https://files.ballistica.net/cache/ba1/f2/90/62968ad28a2499a8d182a5740a85", "assets/build/ba_data/data/languages/czech.json": "https://files.ballistica.net/cache/ba1/f2/90/62968ad28a2499a8d182a5740a85",
"assets/build/ba_data/data/languages/danish.json": "https://files.ballistica.net/cache/ba1/3f/46/e4da3c1d2b0ebf916df55c608b28", "assets/build/ba_data/data/languages/danish.json": "https://files.ballistica.net/cache/ba1/3f/46/e4da3c1d2b0ebf916df55c608b28",
"assets/build/ba_data/data/languages/dutch.json": "https://files.ballistica.net/cache/ba1/5b/a3/a46a77f0cc498e1f1e369d772414", "assets/build/ba_data/data/languages/dutch.json": "https://files.ballistica.net/cache/ba1/5b/a3/a46a77f0cc498e1f1e369d772414",
"assets/build/ba_data/data/languages/english.json": "https://files.ballistica.net/cache/ba1/b4/fe/f33399347c16a13f17e920c7e33c", "assets/build/ba_data/data/languages/english.json": "https://files.ballistica.net/cache/ba1/30/f3/4ef3bbaf1e5b7abe114c119ec106",
"assets/build/ba_data/data/languages/esperanto.json": "https://files.ballistica.net/cache/ba1/6e/fd/685a4e1da031474d47a1d9eb2731", "assets/build/ba_data/data/languages/esperanto.json": "https://files.ballistica.net/cache/ba1/6e/fd/685a4e1da031474d47a1d9eb2731",
"assets/build/ba_data/data/languages/french.json": "https://files.ballistica.net/cache/ba1/95/9b/66e9080c82ef76387832dedee9b4", "assets/build/ba_data/data/languages/french.json": "https://files.ballistica.net/cache/ba1/95/9b/66e9080c82ef76387832dedee9b4",
"assets/build/ba_data/data/languages/german.json": "https://files.ballistica.net/cache/ba1/9d/00/a8c4ef9f0a25e789c046bd741203", "assets/build/ba_data/data/languages/german.json": "https://files.ballistica.net/cache/ba1/9d/00/a8c4ef9f0a25e789c046bd741203",
"assets/build/ba_data/data/languages/gibberish.json": "https://files.ballistica.net/cache/ba1/e7/ff/638467708af1e2eea569e9225906", "assets/build/ba_data/data/languages/gibberish.json": "https://files.ballistica.net/cache/ba1/8e/24/f070599beb7b09e1268569fa55b1",
"assets/build/ba_data/data/languages/greek.json": "https://files.ballistica.net/cache/ba1/17/78/3fd0dca40e632ce53d03a944e7fa", "assets/build/ba_data/data/languages/greek.json": "https://files.ballistica.net/cache/ba1/17/78/3fd0dca40e632ce53d03a944e7fa",
"assets/build/ba_data/data/languages/hindi.json": "https://files.ballistica.net/cache/ba1/7a/64/04464dc6ee8a45632857fa436bff", "assets/build/ba_data/data/languages/hindi.json": "https://files.ballistica.net/cache/ba1/7a/64/04464dc6ee8a45632857fa436bff",
"assets/build/ba_data/data/languages/hungarian.json": "https://files.ballistica.net/cache/ba1/4d/4b/0790110201c9adb1b521e9a55e63", "assets/build/ba_data/data/languages/hungarian.json": "https://files.ballistica.net/cache/ba1/4d/4b/0790110201c9adb1b521e9a55e63",
"assets/build/ba_data/data/languages/indonesian.json": "https://files.ballistica.net/cache/ba1/8e/e7/38e093014a917418e6cf7aa9315d", "assets/build/ba_data/data/languages/indonesian.json": "https://files.ballistica.net/cache/ba1/8e/e7/38e093014a917418e6cf7aa9315d",
"assets/build/ba_data/data/languages/italian.json": "https://files.ballistica.net/cache/ba1/a5/05/fbdf4d90b85609e4fa258e1ce814", "assets/build/ba_data/data/languages/italian.json": "https://files.ballistica.net/cache/ba1/a5/ef/b1935b3767692070f070847f40df",
"assets/build/ba_data/data/languages/korean.json": "https://files.ballistica.net/cache/ba1/0a/84/bbb6ed2abf66509406f534cbbb52", "assets/build/ba_data/data/languages/korean.json": "https://files.ballistica.net/cache/ba1/0a/84/bbb6ed2abf66509406f534cbbb52",
"assets/build/ba_data/data/languages/persian.json": "https://files.ballistica.net/cache/ba1/c2/fc/dd1c15cf9ecb411d9defbd000c06", "assets/build/ba_data/data/languages/persian.json": "https://files.ballistica.net/cache/ba1/c2/fc/dd1c15cf9ecb411d9defbd000c06",
"assets/build/ba_data/data/languages/polish.json": "https://files.ballistica.net/cache/ba1/db/eb/324f86a4b714240ae50ffeeed2f8", "assets/build/ba_data/data/languages/polish.json": "https://files.ballistica.net/cache/ba1/db/eb/324f86a4b714240ae50ffeeed2f8",
"assets/build/ba_data/data/languages/portuguese.json": "https://files.ballistica.net/cache/ba1/a9/bc/ea61ebd23066c685fb779e23d10f", "assets/build/ba_data/data/languages/portuguese.json": "https://files.ballistica.net/cache/ba1/66/0b/df2cd57be4eb505876d209a673d9",
"assets/build/ba_data/data/languages/romanian.json": "https://files.ballistica.net/cache/ba1/f6/d0/335b952306d211d56172b5c72d8c", "assets/build/ba_data/data/languages/romanian.json": "https://files.ballistica.net/cache/ba1/f6/d0/335b952306d211d56172b5c72d8c",
"assets/build/ba_data/data/languages/russian.json": "https://files.ballistica.net/cache/ba1/56/f4/b76f1e862b29db5f642a67da67f3", "assets/build/ba_data/data/languages/russian.json": "https://files.ballistica.net/cache/ba1/33/82/be19758f3563ba6617db4736de74",
"assets/build/ba_data/data/languages/serbian.json": "https://files.ballistica.net/cache/ba1/e7/d8/ace32888249fc8b8cca0e2edb48b", "assets/build/ba_data/data/languages/serbian.json": "https://files.ballistica.net/cache/ba1/e7/d8/ace32888249fc8b8cca0e2edb48b",
"assets/build/ba_data/data/languages/slovak.json": "https://files.ballistica.net/cache/ba1/b7/0a/fab820b96e7aa587ee56427ecdc2", "assets/build/ba_data/data/languages/slovak.json": "https://files.ballistica.net/cache/ba1/b7/0a/fab820b96e7aa587ee56427ecdc2",
"assets/build/ba_data/data/languages/spanish.json": "https://files.ballistica.net/cache/ba1/90/d9/0f8f5b03bbe2dfebfb544cee6bd6", "assets/build/ba_data/data/languages/spanish.json": "https://files.ballistica.net/cache/ba1/a9/77/722faae6a695f19501bac76098db",
"assets/build/ba_data/data/languages/swedish.json": "https://files.ballistica.net/cache/ba1/50/9f/be006ba19be6a69a57837eb6dca0", "assets/build/ba_data/data/languages/swedish.json": "https://files.ballistica.net/cache/ba1/50/9f/be006ba19be6a69a57837eb6dca0",
"assets/build/ba_data/data/languages/turkish.json": "https://files.ballistica.net/cache/ba1/30/70/ba6f57b2d865d0027a50c6e1dba5", "assets/build/ba_data/data/languages/turkish.json": "https://files.ballistica.net/cache/ba1/30/70/ba6f57b2d865d0027a50c6e1dba5",
"assets/build/ba_data/data/languages/ukrainian.json": "https://files.ballistica.net/cache/ba1/e0/f7/f6daa488dc29e303dea69aae864b", "assets/build/ba_data/data/languages/ukrainian.json": "https://files.ballistica.net/cache/ba1/e0/f7/f6daa488dc29e303dea69aae864b",
@ -4132,16 +4132,16 @@
"assets/build/windows/x64/python.exe": "https://files.ballistica.net/cache/ba1/25/a7/dc87c1be41605eb6fefd0145144c", "assets/build/windows/x64/python.exe": "https://files.ballistica.net/cache/ba1/25/a7/dc87c1be41605eb6fefd0145144c",
"assets/build/windows/x64/python37.dll": "https://files.ballistica.net/cache/ba1/b9/e4/d912f56e42e9991bcbb4c804cfcb", "assets/build/windows/x64/python37.dll": "https://files.ballistica.net/cache/ba1/b9/e4/d912f56e42e9991bcbb4c804cfcb",
"assets/build/windows/x64/pythonw.exe": "https://files.ballistica.net/cache/ba1/6c/bb/b6f52c306aa4e88061510e96cefe", "assets/build/windows/x64/pythonw.exe": "https://files.ballistica.net/cache/ba1/6c/bb/b6f52c306aa4e88061510e96cefe",
"build/prefab/linux-server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/92/ca/9fa8a48f38554ef676a900136ce9", "build/prefab/linux-server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/1e/2c/09ca7e7ab982a04608a9cee6230b",
"build/prefab/linux-server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/e3/2c/f3e52a261f8dabced7a41d925053", "build/prefab/linux-server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/7b/d6/25671c9f875c9eb1f25f09d1000f",
"build/prefab/linux/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/df/82/1c63fa091da3fb52bcecf87f8ea6", "build/prefab/linux/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/f8/ee/6989965b6929d55044156e41017b",
"build/prefab/linux/release/ballisticacore": "https://files.ballistica.net/cache/ba1/83/18/a60e9e2f6e37e2f36ca8c8f4f42c", "build/prefab/linux/release/ballisticacore": "https://files.ballistica.net/cache/ba1/ca/e9/c7b41ca260cb04e539cc81fd79c4",
"build/prefab/mac-server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/96/6a/cc35319fd83bca6ff578e4c8dad6", "build/prefab/mac-server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/5b/ef/9d427caa8a691f225cbf3e0c649e",
"build/prefab/mac-server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/5a/a2/b04d489862ae208c6b2b31697519", "build/prefab/mac-server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/88/61/63b817195328d360c02c8705405a",
"build/prefab/mac/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/a8/ca/89e007ea20b4f2a3dee09e1361c3", "build/prefab/mac/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/3b/51/bf8fdbea96a0e76f9203bcd1c427",
"build/prefab/mac/release/ballisticacore": "https://files.ballistica.net/cache/ba1/6e/cd/f8ad50715cb46d5cae7bd87bb498", "build/prefab/mac/release/ballisticacore": "https://files.ballistica.net/cache/ba1/c1/34/ad36c057f3d2c890617a25311cd8",
"build/prefab/windows-server/debug/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/36/d1/67a51def178a07f99acc3cc2b11c", "build/prefab/windows-server/debug/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/e3/00/d0cfc8d72ef8dd1567ca7e48a58e",
"build/prefab/windows-server/release/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/52/4a/a7a5b56eda157fde6e58a90ab98a", "build/prefab/windows-server/release/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/cd/c0/56c8c49c60298727d7593f91928a",
"build/prefab/windows/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/cc/ec/d82c9ba9d587598f8183bc360326", "build/prefab/windows/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/24/d1/d73ae026e9797924e5257d87fe98",
"build/prefab/windows/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/8e/2a/f24b48e15ef4fd5794c5e426081b" "build/prefab/windows/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/8b/4f/112f32d713898abca7fa465779c1"
} }

View File

@ -79,6 +79,8 @@
<w>appkit</w> <w>appkit</w>
<w>applescript</w> <w>applescript</w>
<w>appletv</w> <w>appletv</w>
<w>appname</w>
<w>appnameupper</w>
<w>appstate</w> <w>appstate</w>
<w>appstore</w> <w>appstore</w>
<w>apputils</w> <w>apputils</w>
@ -155,6 +157,7 @@
<w>basespaz</w> <w>basespaz</w>
<w>basetime</w> <w>basetime</w>
<w>baseurl</w> <w>baseurl</w>
<w>baseval</w>
<w>basew</w> <w>basew</w>
<w>bastd</w> <w>bastd</w>
<w>batools</w> <w>batools</w>
@ -184,6 +187,7 @@
<w>blas</w> <w>blas</w>
<w>blastos</w> <w>blastos</w>
<w>bldtp</w> <w>bldtp</w>
<w>blesspath</w>
<w>blocksize</w> <w>blocksize</w>
<w>bluetooth</w> <w>bluetooth</w>
<w>bmag</w> <w>bmag</w>
@ -222,8 +226,11 @@
<w>btnh</w> <w>btnh</w>
<w>btnv</w> <w>btnv</w>
<w>btnx</w> <w>btnx</w>
<w>buildblessing</w>
<w>buildblessingcheck</w>
<w>builddir</w> <w>builddir</w>
<w>buildfile</w> <w>buildfile</w>
<w>buildnum</w>
<w>buildtype</w> <w>buildtype</w>
<w>bullseye</w> <w>bullseye</w>
<w>bumpmap</w> <w>bumpmap</w>
@ -780,6 +787,7 @@
<w>getlevel</w> <w>getlevel</w>
<w>getlevelname</w> <w>getlevelname</w>
<w>getlevels</w> <w>getlevels</w>
<w>getlocalconfig</w>
<w>getlog</w> <w>getlog</w>
<w>getmaps</w> <w>getmaps</w>
<w>getmodel</w> <w>getmodel</w>
@ -850,6 +858,7 @@
<w>hasstarted</w> <w>hasstarted</w>
<w>hatmotion</w> <w>hatmotion</w>
<w>hattach</w> <w>hattach</w>
<w>hcalc</w>
<w>hdpi</w> <w>hdpi</w>
<w>headercheckline</w> <w>headercheckline</w>
<w>headerregistry</w> <w>headerregistry</w>
@ -1051,6 +1060,7 @@
<w>lineno</w> <w>lineno</w>
<w>linenum</w> <w>linenum</w>
<w>linenumber</w> <w>linenumber</w>
<w>linenums</w>
<w>linetype</w> <w>linetype</w>
<w>linetypes</w> <w>linetypes</w>
<w>linflav</w> <w>linflav</w>
@ -1127,6 +1137,7 @@
<w>markupbase</w> <w>markupbase</w>
<w>masktex</w> <w>masktex</w>
<w>masktexstorename</w> <w>masktexstorename</w>
<w>masterhash</w>
<w>mathmodule</w> <w>mathmodule</w>
<w>mathnode</w> <w>mathnode</w>
<w>mathutils</w> <w>mathutils</w>
@ -1148,6 +1159,8 @@
<w>meteorshower</w> <w>meteorshower</w>
<w>mfpath</w> <w>mfpath</w>
<w>mhash</w> <w>mhash</w>
<w>mhbegin</w>
<w>mhend</w>
<w>mhsh</w> <w>mhsh</w>
<w>microprotocols</w> <w>microprotocols</w>
<w>mikirog</w> <w>mikirog</w>
@ -1326,6 +1339,7 @@
<w>osval</w> <w>osval</w>
<w>otherplayer</w> <w>otherplayer</w>
<w>otherspawn</w> <w>otherspawn</w>
<w>ourhash</w>
<w>ourself</w> <w>ourself</w>
<w>outdata</w> <w>outdata</w>
<w>outdelay</w> <w>outdelay</w>
@ -1548,7 +1562,9 @@
<w>pysources</w> <w>pysources</w>
<w>pytest</w> <w>pytest</w>
<w>pythondontwritebytecode</w> <w>pythondontwritebytecode</w>
<w>pythonhashseed</w>
<w>pythonpath</w> <w>pythonpath</w>
<w>pythonpaths</w>
<w>pythonw</w> <w>pythonw</w>
<w>pytree</w> <w>pytree</w>
<w>pytz</w> <w>pytz</w>

File diff suppressed because it is too large Load Diff

View File

@ -34,7 +34,7 @@ NOTE: This file was autogenerated by gendummymodule; do not edit by hand.
""" """
# (hash we can use to see if this file is out of date) # (hash we can use to see if this file is out of date)
# SOURCES_HASH=102801821147286215106809880997032542189 # SOURCES_HASH=197797300249336200681012613336602141418
# I'm sorry Pylint. I know this file saddens you. Be strong. # I'm sorry Pylint. I know this file saddens you. Be strong.
# pylint: disable=useless-suppression # pylint: disable=useless-suppression
@ -1334,6 +1334,22 @@ def apply_config() -> None:
return None return None
def appname() -> str:
"""appname() -> str
(internal)
"""
return str()
def appnameupper() -> str:
"""appnameupper() -> str
(internal)
"""
return str()
def back_press() -> None: def back_press() -> None:
"""back_press() -> None """back_press() -> None
@ -2708,6 +2724,14 @@ def invite_players() -> None:
return None return None
def is_blessed() -> bool:
"""is_blessed() -> bool
(internal)
"""
return bool()
def is_in_replay() -> bool: def is_in_replay() -> bool:
"""is_in_replay() -> bool """is_in_replay() -> bool

View File

@ -163,7 +163,7 @@ def have_pro() -> bool:
return bool( return bool(
_ba.get_purchased('upgrades.pro') or _ba.get_purchased('static.pro') _ba.get_purchased('upgrades.pro') or _ba.get_purchased('static.pro')
or _ba.get_purchased('static.pro_sale') or _ba.get_purchased('static.pro_sale')
or 'ballistica' + 'core' == 'ballisticacore') or 'ballistica' + 'core' == _ba.appname())
def have_pro_options() -> bool: def have_pro_options() -> bool:

View File

@ -185,14 +185,14 @@ class App:
return self._python_directory_user return self._python_directory_user
@property @property
def python_directory_ba(self) -> str: def python_directory_app(self) -> str:
"""Path where the app looks for its bundled scripts.""" """Path where the app looks for its bundled scripts."""
return self._python_directory_ba return self._python_directory_app
@property @property
def python_directory_site(self) -> str: def python_directory_app_site(self) -> str:
"""Path containing pip packages bundled with the app.""" """Path containing pip packages bundled with the app."""
return self._python_directory_site return self._python_directory_app_site
@property @property
def config(self) -> ba.AppConfig: def config(self) -> ba.AppConfig:
@ -297,10 +297,10 @@ class App:
assert isinstance(self._test_build, bool) assert isinstance(self._test_build, bool)
self._python_directory_user: str = env['python_directory_user'] self._python_directory_user: str = env['python_directory_user']
assert isinstance(self._python_directory_user, str) assert isinstance(self._python_directory_user, str)
self._python_directory_ba: str = env['python_directory_ba'] self._python_directory_app: str = env['python_directory_app']
assert isinstance(self._python_directory_ba, str) assert isinstance(self._python_directory_app, str)
self._python_directory_site: str = env['python_directory_site'] self._python_directory_app_site: str = env['python_directory_app_site']
assert isinstance(self._python_directory_site, str) assert isinstance(self._python_directory_app_site, str)
self._platform: str = env['platform'] self._platform: str = env['platform']
assert isinstance(self._platform, str) assert isinstance(self._platform, str)
self._subplatform: str = env['subplatform'] self._subplatform: str = env['subplatform']
@ -325,7 +325,6 @@ class App:
self.metascan: Optional[_meta.ScanResults] = None self.metascan: Optional[_meta.ScanResults] = None
self.tips: List[str] = [] self.tips: List[str] = []
self.stress_test_reset_timer: Optional[ba.Timer] = None self.stress_test_reset_timer: Optional[ba.Timer] = None
self.suppress_debug_reports = False
self.last_ad_completion_time: Optional[float] = None self.last_ad_completion_time: Optional[float] = None
self.last_ad_was_short = False self.last_ad_was_short = False
self.did_weak_call_warning = False self.did_weak_call_warning = False
@ -477,8 +476,11 @@ class App:
]: ]:
_map.register_map(maptype) _map.register_map(maptype)
if self.debug_build: # Non-test, non-debug builds should generally be blessed; warn if not.
_apputils.suppress_debug_reports() # (so I don't accidentally release a build that can't play tourneys)
if (not self.debug_build and not self.test_build
and not _ba.is_blessed()):
_ba.screenmessage('WARNING: NON-BLESSED BUILD', color=(1, 0, 0))
# IMPORTANT - if tweaking UI stuff, you need to make sure it behaves # IMPORTANT - if tweaking UI stuff, you need to make sure it behaves
# for small, medium, and large UI modes. (doesn't run off screen, etc). # for small, medium, and large UI modes. (doesn't run off screen, etc).
@ -526,7 +528,7 @@ class App:
# Notify the user if we're using custom system scripts. # Notify the user if we're using custom system scripts.
# FIXME: This no longer works since sys-scripts is an absolute path; # FIXME: This no longer works since sys-scripts is an absolute path;
# need to just add a proper call to query this. # need to just add a proper call to query this.
# if env['python_directory_ba'] != 'data/scripts': # if env['python_directory_app'] != 'data/scripts':
# ba.screenmessage("Using custom system scripts...", # ba.screenmessage("Using custom system scripts...",
# color=(0, 1, 0)) # color=(0, 1, 0))
@ -795,8 +797,9 @@ class App:
"""Handle a deep link URL.""" """Handle a deep link URL."""
from ba._lang import Lstr from ba._lang import Lstr
from ba._enums import TimeType from ba._enums import TimeType
if url.startswith('ballisticacore://code/'): appname = _ba.appname()
code = url.replace('ballisticacore://code/', '') if url.startswith(f'{appname}://code/'):
code = url.replace(f'{appname}://code/', '')
# If we're not signed in, queue up the code to run the next time we # If we're not signed in, queue up the code to run the next time we
# are and issue a warning if we haven't signed in within the next # are and issue a warning if we haven't signed in within the next

View File

@ -67,15 +67,6 @@ def should_submit_debug_info() -> bool:
return _ba.app.config.get('Submit Debug Info', True) return _ba.app.config.get('Submit Debug Info', True)
def suppress_debug_reports() -> None:
"""Turn debug-reporting to the master server off.
This should be called in devel/debug situations to avoid spamming
the master server with spurious logs.
"""
_ba.app.suppress_debug_reports = True
def handle_log() -> None: def handle_log() -> None:
"""Called on debug log prints. """Called on debug log prints.
@ -89,37 +80,38 @@ def handle_log() -> None:
if not app.log_upload_timer_started: if not app.log_upload_timer_started:
def _put_log() -> None: def _put_log() -> None:
if not app.suppress_debug_reports: try:
try: sessionname = str(_ba.get_foreground_host_session())
sessionname = str(_ba.get_foreground_host_session()) except Exception:
except Exception: sessionname = 'unavailable'
sessionname = 'unavailable' try:
try: activityname = str(_ba.get_foreground_host_activity())
activityname = str(_ba.get_foreground_host_activity()) except Exception:
except Exception: activityname = 'unavailable'
activityname = 'unavailable'
info = {
'log': _ba.getlog(),
'version': app.version,
'build': app.build_number,
'userAgentString': app.user_agent_string,
'session': sessionname,
'activity': activityname,
'fatal': 0,
'userRanCommands': _ba.has_user_run_commands(),
'time': _ba.time(TimeType.REAL),
'userModded': _ba.has_user_mods()
}
def response(data: Any) -> None: info = {
# A non-None response means success; lets 'log': _ba.getlog(),
# take note that we don't need to report further 'version': app.version,
# log info this run 'build': app.build_number,
if data is not None: 'userAgentString': app.user_agent_string,
app.log_have_new = False 'session': sessionname,
_ba.mark_log_sent() 'activity': activityname,
'fatal': 0,
'userRanCommands': _ba.has_user_run_commands(),
'time': _ba.time(TimeType.REAL),
'userModded': _ba.has_user_mods(),
'newsShow': _ba.get_news_show(),
}
serverput('bsLog', info, response) def response(data: Any) -> None:
# A non-None response means success; lets
# take note that we don't need to report further
# log info this run
if data is not None:
app.log_have_new = False
_ba.mark_log_sent()
serverput('bsLog', info, response)
app.log_upload_timer_started = True app.log_upload_timer_started = True

View File

@ -122,6 +122,9 @@ def init_campaigns() -> None:
from bastd.game.easteregghunt import EasterEggHuntGame from bastd.game.easteregghunt import EasterEggHuntGame
from bastd.game.ninjafight import NinjaFightGame from bastd.game.ninjafight import NinjaFightGame
# TODO: Campaigns should be load-on-demand; not all imported at launch
# like this.
# FIXME: Once translations catch up, we can convert these to use the # FIXME: Once translations catch up, we can convert these to use the
# generic display-name '${GAME} Training' type stuff. # generic display-name '${GAME} Training' type stuff.
campaign = Campaign('Easy') campaign = Campaign('Easy')

View File

@ -264,10 +264,7 @@ class CoopSession(Session):
if isinstance(results, GameResults): if isinstance(results, GameResults):
outcome = 'defeat' # This can't be 'beaten'. outcome = 'defeat' # This can't be 'beaten'.
else: else:
try: outcome = '' if results is None else results.get('outcome', '')
outcome = results['outcome']
except Exception:
outcome = ''
# If at any point we have no in-game players, quit out of the session # If at any point we have no in-game players, quit out of the session
# (this can happen if someone leaves in the tutorial for instance). # (this can happen if someone leaves in the tutorial for instance).
@ -315,7 +312,7 @@ class CoopSession(Session):
self.stats.register_sessionplayer(player) self.stats.register_sessionplayer(player)
self.stats.setactivity(next_game) self.stats.setactivity(next_game)
# Now flip the current activity. # Now flip the current activity..
self.setactivity(next_game) self.setactivity(next_game)
if not app.kiosk_mode: if not app.kiosk_mode:

View File

@ -26,6 +26,8 @@ import weakref
from dataclasses import dataclass from dataclasses import dataclass
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from ba._team import Team, SessionTeam
if TYPE_CHECKING: if TYPE_CHECKING:
from weakref import ReferenceType from weakref import ReferenceType
from typing import Sequence, Tuple, Any, Optional, Dict, List, Union from typing import Sequence, Tuple, Any, Optional, Dict, List, Union
@ -66,7 +68,9 @@ class GameResults:
if self._game_set: if self._game_set:
raise RuntimeError('Game set twice for GameResults.') raise RuntimeError('Game set twice for GameResults.')
self._game_set = True self._game_set = True
self._sessionteams = [weakref.ref(team) for team in game.teams] self._sessionteams = [
weakref.ref(team.sessionteam) for team in game.teams
]
scoreconfig = game.getscoreconfig() scoreconfig = game.getscoreconfig()
self._playerinfos = copy.deepcopy(game.initialplayerinfos) self._playerinfos = copy.deepcopy(game.initialplayerinfos)
self._lower_is_better = scoreconfig.lower_is_better self._lower_is_better = scoreconfig.lower_is_better
@ -80,12 +84,14 @@ class GameResults:
This can be a number or None. This can be a number or None.
(see the none_is_winner arg in the constructor) (see the none_is_winner arg in the constructor)
""" """
assert isinstance(team, Team)
sessionteam = team.sessionteam sessionteam = team.sessionteam
self._scores[sessionteam.id] = (weakref.ref(sessionteam), score) self._scores[sessionteam.id] = (weakref.ref(sessionteam), score)
def get_sessionteam_score(self, def get_sessionteam_score(self,
sessionteam: ba.SessionTeam) -> Optional[int]: sessionteam: ba.SessionTeam) -> Optional[int]:
"""Return the score for a given ba.SessionTeam.""" """Return the score for a given ba.SessionTeam."""
assert isinstance(sessionteam, SessionTeam)
for score in list(self._scores.values()): for score in list(self._scores.values()):
if score[0]() is sessionteam: if score[0]() is sessionteam:
return score[1] return score[1]

View File

@ -89,7 +89,7 @@ def getclass(name: str, subclassof: Type[T]) -> Type[T]:
cls: Type = getattr(module, classname) cls: Type = getattr(module, classname)
if not issubclass(cls, subclassof): if not issubclass(cls, subclassof):
raise TypeError(name + ' is not a subclass of ' + str(subclassof)) raise TypeError(f'{name} is not a subclass of {subclassof}.')
return cls return cls

View File

@ -56,7 +56,7 @@ def start_scan() -> None:
app = _ba.app app = _ba.app
if app.metascan is not None: if app.metascan is not None:
print('WARNING: meta scan run more than once.') print('WARNING: meta scan run more than once.')
scriptdirs = [app.python_directory_ba, app.python_directory_user] scriptdirs = [app.python_directory_app, app.python_directory_user]
thread = ScanThread(scriptdirs) thread = ScanThread(scriptdirs)
thread.start() thread.start()

View File

@ -119,9 +119,9 @@ def create_user_system_scripts() -> None:
# Hmm; shutil.copytree doesn't seem to work nicely on android, # Hmm; shutil.copytree doesn't seem to work nicely on android,
# so lets do it manually. # so lets do it manually.
# NOTE: Should retry this now that we have 3.7 (this note was for 2.7) # NOTE: Should retry this now that we have 3.7 (this note was for 2.7)
src_dir = app.python_directory_ba src_dir = app.python_directory_app
dst_dir = path + '_tmp' dst_dir = path + '_tmp'
filenames = os.listdir(app.python_directory_ba) filenames = os.listdir(app.python_directory_app)
for fname in filenames: for fname in filenames:
print('COPYING', src_dir + '/' + fname, '->', dst_dir) print('COPYING', src_dir + '/' + fname, '->', dst_dir)
shutil.copyfile(src_dir + '/' + fname, dst_dir + '/' + fname) shutil.copyfile(src_dir + '/' + fname, dst_dir + '/' + fname)

View File

@ -321,7 +321,7 @@ class ServerController:
if self._first_run: if self._first_run:
curtimestr = time.strftime('%c') curtimestr = time.strftime('%c')
print(f'{Clr.BLD}{Clr.BLU}BallisticaCore {app.version}' print(f'{Clr.BLD}{Clr.BLU}{_ba.appnameupper()} {app.version}'
f' ({app.build_number})' f' ({app.build_number})'
f' entering server-mode {curtimestr}{Clr.RST}') f' entering server-mode {curtimestr}{Clr.RST}')

View File

@ -71,7 +71,7 @@ class OSMusicPlayer(MusicPlayer):
elif entry_type == 'musicFolder': elif entry_type == 'musicFolder':
# Launch a thread to scan this folder and give us a random # Launch a thread to scan this folder and give us a random
# valid file within. # valid file within it.
self._want_to_play = True self._want_to_play = True
self._actually_playing = False self._actually_playing = False
_PickFolderSongThread(name, self.get_valid_music_file_extensions(), _PickFolderSongThread(name, self.get_valid_music_file_extensions(),

View File

@ -18,6 +18,6 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE. # SOFTWARE.
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
"""BallisticaCore standard library: games, UI, etc.""" """Ballistica standard library: games, UI, etc."""
# ba_meta require api 6 # ba_meta require api 6

View File

@ -239,7 +239,6 @@ class TutorialActivity(ba.Activity[Player, Team]):
self.bomb_image_color = (1.0, 1.0, 1.0) self.bomb_image_color = (1.0, 1.0, 1.0)
self.pickup_image_color = (1.0, 1.0, 1.0) self.pickup_image_color = (1.0, 1.0, 1.0)
self.control_ui_nodes: List[ba.Node] = [] self.control_ui_nodes: List[ba.Node] = []
self._test_file = ''
self.spazzes: Dict[int, basespaz.Spaz] = {} self.spazzes: Dict[int, basespaz.Spaz] = {}
self.jump_image_color = (1.0, 1.0, 1.0) self.jump_image_color = (1.0, 1.0, 1.0)
self._entries: List[Any] = [] self._entries: List[Any] = []
@ -400,9 +399,6 @@ class TutorialActivity(ba.Activity[Player, Team]):
] ]
for n in self.control_ui_nodes: for n in self.control_ui_nodes:
n.opacity = 0.0 n.opacity = 0.0
self._test_file = ('/Users/ericf/Library/Containers/'
'net.froemling.ballisticacore/Data/'
'Library/Application Support/Ballisticacore/foo.py')
self._read_entries() self._read_entries()
def set_stick_image_position(self, x: float, y: float) -> None: def set_stick_image_position(self, x: float, y: float) -> None:
@ -844,7 +840,7 @@ class TutorialActivity(ba.Activity[Player, Team]):
ba.Lstr(resource=self._r + '.phrase02Text', ba.Lstr(resource=self._r + '.phrase02Text',
subs=[ subs=[
('${APP_NAME}', ba.Lstr(resource='titleText')) ('${APP_NAME}', ba.Lstr(resource='titleText'))
])), # welcome to ballisticacore ])), # welcome to <appname>
DelayOld(80), DelayOld(80),
Run(release=False), Run(release=False),
Jump(release=False), Jump(release=False),

View File

@ -47,7 +47,7 @@ class ConfigErrorWindow(ba.Window):
h_align='center', h_align='center',
v_align='top', v_align='top',
scale=0.73, scale=0.73,
text=('Error reading BallisticaCore config file' text=(f'Error reading {_ba.appnameupper()} config file'
':\n\n\nCheck the console' ':\n\n\nCheck the console'
' (press ~ twice) for details.\n\nWould you like to quit and' ' (press ~ twice) for details.\n\nWould you like to quit and'
' try to fix it by hand\nor overwrite it with defaults?\n\n' ' try to fix it by hand\nor overwrite it with defaults?\n\n'

View File

@ -61,6 +61,16 @@ class CoopBrowserWindow(ba.Window):
app = ba.app app = ba.app
cfg = app.config cfg = app.config
# Quick note to players that tourneys won't work if we're a non-blessed
# or a debug build...
if not _ba.is_blessed() or ba.app.debug_build:
ba.timer(1.0,
lambda: ba.screenmessage(
ba.Lstr(resource='noTournamentsInTestBuildText'),
color=(1, 1, 0),
),
timetype=ba.TimeType.REAL)
# If they provided an origin-widget, scale up from that. # If they provided an origin-widget, scale up from that.
scale_origin: Optional[Tuple[float, float]] scale_origin: Optional[Tuple[float, float]]
if origin_widget is not None: if origin_widget is not None:
@ -99,10 +109,8 @@ class CoopBrowserWindow(ba.Window):
size=(self._width, self._height + top_extra), size=(self._width, self._height + top_extra),
toolbar_visibility='menu_full', toolbar_visibility='menu_full',
scale_origin_stack_offset=scale_origin, scale_origin_stack_offset=scale_origin,
stack_offset=(0, stack_offset=((0, -15) if app.small_ui else (
-15) if app.small_ui else (0, 0, 0) if app.med_ui else (0, 0)),
0) if app.med_ui else (0,
0),
transition=transition, transition=transition,
scale=1.2 if app.small_ui else 0.8 if app.med_ui else 0.75)) scale=1.2 if app.small_ui else 0.8 if app.med_ui else 0.75))

View File

@ -66,11 +66,13 @@ def ask_for_rating() -> Optional[ba.Widget]:
v_align='center') v_align='center')
def do_rating() -> None: def do_rating() -> None:
import _ba
if platform == 'android': if platform == 'android':
appname = _ba.appname()
if subplatform == 'google': if subplatform == 'google':
url = 'market://details?id=net.froemling.ballisticacore' url = f'market://details?id=net.froemling.{appname}'
else: else:
url = 'market://details?id=net.froemling.ballisticacorecb' url = 'market://details?id=net.froemling.{appname}cb'
else: else:
url = 'macappstore://itunes.apple.com/app/id416482767?ls=1&mt=12' url = 'macappstore://itunes.apple.com/app/id416482767?ls=1&mt=12'

View File

@ -61,8 +61,8 @@ class PlaylistTypeVars:
self.sessiontype = ba.FreeForAllSession self.sessiontype = ba.FreeForAllSession
else: else:
raise TypeError('playlist type vars undefined for session type: ' + raise RuntimeError(
str(sessiontype)) f'Playlist type vars undefined for sessiontype: {sessiontype}')
self.default_list_name = ba.Lstr(resource='defaultGameListNameText', self.default_list_name = ba.Lstr(resource='defaultGameListNameText',
subs=[('${PLAYMODE}', play_mode_name) subs=[('${PLAYMODE}', play_mode_name)
]) ])

View File

@ -87,7 +87,7 @@ class ReportPlayerWindow(ba.Window):
}) })
body = ba.Lstr(resource='reportPlayerExplanationText').evaluate() body = ba.Lstr(resource='reportPlayerExplanationText').evaluate()
ba.open_url('mailto:support@froemling.net' ba.open_url('mailto:support@froemling.net'
'?subject=BallisticaCore Player Report: ' + f'?subject={_ba.appnameupper()} Player Report: ' +
self._account_id + '&body=' + parse.quote(body)) self._account_id + '&body=' + parse.quote(body))
self.close() self.close()
@ -100,7 +100,7 @@ class ReportPlayerWindow(ba.Window):
}) })
body = ba.Lstr(resource='reportPlayerExplanationText').evaluate() body = ba.Lstr(resource='reportPlayerExplanationText').evaluate()
ba.open_url('mailto:support@froemling.net' ba.open_url('mailto:support@froemling.net'
'?subject=BallisticaCore Player Report: ' + f'?subject={_ba.appnameupper()} Player Report: ' +
self._account_id + '&body=' + parse.quote(body)) self._account_id + '&body=' + parse.quote(body))
self.close() self.close()

View File

@ -1,5 +1,5 @@
<!-- THIS FILE IS AUTO GENERATED; DO NOT EDIT BY HAND --> <!-- THIS FILE IS AUTO GENERATED; DO NOT EDIT BY HAND -->
<h4><em>last updated on 2020-06-04 for Ballistica version 1.5.0 build 20045</em></h4> <h4><em>last updated on 2020-06-07 for Ballistica version 1.5.0 build 20059</em></h4>
<p>This page documents the Python classes and functions in the 'ba' module, <p>This page documents the Python classes and functions in the 'ba' module,
which are the ones most relevant to modding in Ballistica. If you come across something you feel should be included here or could be better explained, please <a href="mailto:support@froemling.net">let me know</a>. Happy modding!</p> which are the ones most relevant to modding in Ballistica. If you come across something you feel should be included here or could be better explained, please <a href="mailto:support@froemling.net">let me know</a>. Happy modding!</p>
<hr> <hr>
@ -805,7 +805,7 @@ likely result in errors.</p>
</p> </p>
<h3>Attributes:</h3> <h3>Attributes:</h3>
<h5><a href="#attr_ba_App__api_version">api_version</a>, <a href="#attr_ba_App__build_number">build_number</a>, <a href="#attr_ba_App__config">config</a>, <a href="#attr_ba_App__config_file_path">config_file_path</a>, <a href="#attr_ba_App__debug_build">debug_build</a>, <a href="#attr_ba_App__interface_type">interface_type</a>, <a href="#attr_ba_App__language">language</a>, <a href="#attr_ba_App__locale">locale</a>, <a href="#attr_ba_App__on_tv">on_tv</a>, <a href="#attr_ba_App__platform">platform</a>, <a href="#attr_ba_App__python_directory_ba">python_directory_ba</a>, <a href="#attr_ba_App__python_directory_site">python_directory_site</a>, <a href="#attr_ba_App__python_directory_user">python_directory_user</a>, <a href="#attr_ba_App__subplatform">subplatform</a>, <a href="#attr_ba_App__test_build">test_build</a>, <a href="#attr_ba_App__ui_bounds">ui_bounds</a>, <a href="#attr_ba_App__user_agent_string">user_agent_string</a>, <a href="#attr_ba_App__version">version</a>, <a href="#attr_ba_App__vr_mode">vr_mode</a></h5> <h5><a href="#attr_ba_App__api_version">api_version</a>, <a href="#attr_ba_App__build_number">build_number</a>, <a href="#attr_ba_App__config">config</a>, <a href="#attr_ba_App__config_file_path">config_file_path</a>, <a href="#attr_ba_App__debug_build">debug_build</a>, <a href="#attr_ba_App__interface_type">interface_type</a>, <a href="#attr_ba_App__language">language</a>, <a href="#attr_ba_App__locale">locale</a>, <a href="#attr_ba_App__on_tv">on_tv</a>, <a href="#attr_ba_App__platform">platform</a>, <a href="#attr_ba_App__python_directory_app">python_directory_app</a>, <a href="#attr_ba_App__python_directory_app_site">python_directory_app_site</a>, <a href="#attr_ba_App__python_directory_user">python_directory_user</a>, <a href="#attr_ba_App__subplatform">subplatform</a>, <a href="#attr_ba_App__test_build">test_build</a>, <a href="#attr_ba_App__ui_bounds">ui_bounds</a>, <a href="#attr_ba_App__user_agent_string">user_agent_string</a>, <a href="#attr_ba_App__version">version</a>, <a href="#attr_ba_App__vr_mode">vr_mode</a></h5>
<dl> <dl>
<dt><h4><a name="attr_ba_App__api_version">api_version</a></h4></dt><dd> <dt><h4><a name="attr_ba_App__api_version">api_version</a></h4></dt><dd>
<p><span>int</span></p> <p><span>int</span></p>
@ -886,12 +886,12 @@ likely result in errors.</p>
<p> Examples are: 'mac', 'windows', android'.</p> <p> Examples are: 'mac', 'windows', android'.</p>
</dd> </dd>
<dt><h4><a name="attr_ba_App__python_directory_ba">python_directory_ba</a></h4></dt><dd> <dt><h4><a name="attr_ba_App__python_directory_app">python_directory_app</a></h4></dt><dd>
<p><span>str</span></p> <p><span>str</span></p>
<p>Path where the app looks for its bundled scripts.</p> <p>Path where the app looks for its bundled scripts.</p>
</dd> </dd>
<dt><h4><a name="attr_ba_App__python_directory_site">python_directory_site</a></h4></dt><dd> <dt><h4><a name="attr_ba_App__python_directory_app_site">python_directory_app_site</a></h4></dt><dd>
<p><span>str</span></p> <p><span>str</span></p>
<p>Path containing pip packages bundled with the app.</p> <p>Path containing pip packages bundled with the app.</p>

View File

@ -31,7 +31,7 @@ if TYPE_CHECKING:
@dataclass @dataclass
class ServerConfig: class ServerConfig:
"""Configuration for the server manager app (ballisticacore_server).""" """Configuration for the server manager app (<appname>_server)."""
# Name of our server in the public parties list. # Name of our server in the public parties list.
party_name: str = 'FFA' party_name: str = 'FFA'
@ -87,7 +87,7 @@ class ServerConfig:
# Whether to enable telnet access. # Whether to enable telnet access.
# IMPORTANT: This option is no longer available, as it was being used # IMPORTANT: This option is no longer available, as it was being used
# for exploits. Live access to the running server is still possible through # for exploits. Live access to the running server is still possible through
# the mgr.cmd() function in ballisticacore_server. Run your server through # the mgr.cmd() function in the server script. Run your server through
# tools such as 'screen' or 'tmux' and you can reconnect to it remotely # tools such as 'screen' or 'tmux' and you can reconnect to it remotely
# over a secure ssh connection. # over a secure ssh connection.
enable_telnet: bool = False enable_telnet: bool = False

View File

@ -158,7 +158,7 @@ def _lazybuild_check_paths(inpaths: List[str], category: SourceCategory,
if _testpath(fpath): if _testpath(fpath):
return True return True
unchanged_count += 1 unchanged_count += 1
print(f'{Clr.SBLU}Lazybuild: skipping "{tnamepretty}"' print(f'{Clr.BLU}Lazybuild: skipping "{tnamepretty}"'
f' ({unchanged_count} inputs unchanged).{Clr.RST}') f' ({unchanged_count} inputs unchanged).{Clr.RST}')
return False return False

View File

@ -70,7 +70,7 @@ def explicit_bool(value: bool) -> bool:
return value return value
def get_localconfig(projroot: Path) -> Dict[str, Any]: def getlocalconfig(projroot: Path) -> Dict[str, Any]:
"""Return a project's localconfig contents (or default if missing).""" """Return a project's localconfig contents (or default if missing)."""
localconfig: Dict[str, Any] localconfig: Dict[str, Any]
try: try:
@ -81,7 +81,7 @@ def get_localconfig(projroot: Path) -> Dict[str, Any]:
return localconfig return localconfig
def get_config(projroot: Path) -> Dict[str, Any]: def getconfig(projroot: Path) -> Dict[str, Any]:
"""Return a project's config contents (or default if missing).""" """Return a project's config contents (or default if missing)."""
config: Dict[str, Any] config: Dict[str, Any]
try: try:

View File

@ -86,7 +86,7 @@ def cpplint(projroot: Path, full: bool) -> None:
import tempfile import tempfile
from concurrent.futures import ThreadPoolExecutor from concurrent.futures import ThreadPoolExecutor
from multiprocessing import cpu_count from multiprocessing import cpu_count
from efrotools import get_config from efrotools import getconfig
from efro.terminal import Clr from efro.terminal import Clr
from efro.error import CleanError from efro.error import CleanError
@ -97,7 +97,7 @@ def cpplint(projroot: Path, full: bool) -> None:
raise Exception(f'Found space in path {fpath}; unexpected.') raise Exception(f'Found space in path {fpath}; unexpected.')
# Check the config for a list of ones to ignore. # Check the config for a list of ones to ignore.
code_blacklist: List[str] = get_config(projroot).get( code_blacklist: List[str] = getconfig(projroot).get(
'cpplint_blacklist', []) 'cpplint_blacklist', [])
# Just pretend blacklisted ones don't exist. # Just pretend blacklisted ones don't exist.
@ -170,9 +170,9 @@ def cpplint(projroot: Path, full: bool) -> None:
def get_code_filenames(projroot: Path) -> List[str]: def get_code_filenames(projroot: Path) -> List[str]:
"""Return the list of files to lint-check or auto-formatting.""" """Return the list of files to lint-check or auto-formatting."""
from efrotools import get_config from efrotools import getconfig
exts = ('.h', '.c', '.cc', '.cpp', '.cxx', '.m', '.mm') exts = ('.h', '.c', '.cc', '.cpp', '.cxx', '.m', '.mm')
places = get_config(projroot).get('code_source_dirs', None) places = getconfig(projroot).get('code_source_dirs', None)
if places is None: if places is None:
raise RuntimeError('code_source_dirs not declared in config') raise RuntimeError('code_source_dirs not declared in config')
codefilenames = [] codefilenames = []
@ -249,9 +249,9 @@ def _should_include_script(fnamefull: str) -> bool:
def get_script_filenames(projroot: Path) -> List[str]: def get_script_filenames(projroot: Path) -> List[str]:
"""Return the Python filenames to lint-check or auto-format.""" """Return the Python filenames to lint-check or auto-format."""
from efrotools import get_config from efrotools import getconfig
filenames = set() filenames = set()
places = get_config(projroot).get('python_source_dirs', None) places = getconfig(projroot).get('python_source_dirs', None)
if places is None: if places is None:
raise RuntimeError('python_source_dirs not declared in config') raise RuntimeError('python_source_dirs not declared in config')
for place in places: for place in places:
@ -436,7 +436,7 @@ def _apply_pylint_run_to_cache(projroot: Path, run: Any, dirtyfiles: List[str],
# pylint: disable=too-many-branches # pylint: disable=too-many-branches
# pylint: disable=too-many-statements # pylint: disable=too-many-statements
from astroid import modutils from astroid import modutils
from efrotools import get_config from efrotools import getconfig
from efro.error import CleanError from efro.error import CleanError
# First off, build a map of dirtyfiles to module names # First off, build a map of dirtyfiles to module names
@ -484,7 +484,7 @@ def _apply_pylint_run_to_cache(projroot: Path, run: Any, dirtyfiles: List[str],
else: else:
untracked_deps.add(mname) untracked_deps.add(mname)
ignored_untracked_deps: List[str] = get_config(projroot).get( ignored_untracked_deps: List[str] = getconfig(projroot).get(
'pylint_ignored_untracked_deps', []) 'pylint_ignored_untracked_deps', [])
# Add a few that this package itself triggers. # Add a few that this package itself triggers.

View File

@ -27,7 +27,7 @@ import subprocess
import sys import sys
from dataclasses import dataclass from dataclasses import dataclass
from efrotools import get_localconfig, get_config from efrotools import getlocalconfig, getconfig
MODES = { MODES = {
'debug': { 'debug': {
@ -78,8 +78,8 @@ def push_ipa(root: pathlib.Path, modename: str) -> None:
""" """
# Load both the local and project config data. # Load both the local and project config data.
cfg = Config(**get_config(root)['push_ipa_config']) cfg = Config(**getconfig(root)['push_ipa_config'])
lcfg = LocalConfig(**get_localconfig(root)['push_ipa_local_config']) lcfg = LocalConfig(**getlocalconfig(root)['push_ipa_local_config'])
if modename not in MODES: if modename not in MODES:
raise Exception('invalid mode: "' + str(modename) + '"') raise Exception('invalid mode: "' + str(modename) + '"')

View File

@ -353,7 +353,7 @@ def tool_config_install() -> None:
def _filter_tool_config(cfg: str) -> str: def _filter_tool_config(cfg: str) -> str:
import textwrap import textwrap
from efrotools import get_config from efrotools import getconfig
# Stick project-root wherever they want. # Stick project-root wherever they want.
cfg = cfg.replace('__EFRO_PROJECT_ROOT__', str(PROJROOT)) cfg = cfg.replace('__EFRO_PROJECT_ROOT__', str(PROJROOT))
@ -391,7 +391,7 @@ def _filter_tool_config(cfg: str) -> str:
# Gen a pylint init to set up our python paths: # Gen a pylint init to set up our python paths:
pylint_init_tag = '__EFRO_PYLINT_INIT__' pylint_init_tag = '__EFRO_PYLINT_INIT__'
if pylint_init_tag in cfg: if pylint_init_tag in cfg:
pypaths = get_config(PROJROOT).get('python_paths') pypaths = getconfig(PROJROOT).get('python_paths')
if pypaths is None: if pypaths is None:
raise RuntimeError('python_paths not set in project config') raise RuntimeError('python_paths not set in project config')
cstr = "init-hook='import sys;" cstr = "init-hook='import sys;"
@ -460,13 +460,13 @@ def sync_all() -> None:
def sync() -> None: def sync() -> None:
"""Runs standard syncs between this project and others.""" """Runs standard syncs between this project and others."""
from efrotools import get_config from efrotools import getconfig
from efrotools.sync import Mode, SyncItem, run_standard_syncs from efrotools.sync import Mode, SyncItem, run_standard_syncs
mode = Mode(sys.argv[2]) if len(sys.argv) > 2 else Mode.PULL mode = Mode(sys.argv[2]) if len(sys.argv) > 2 else Mode.PULL
# Load sync-items from project config and run them # Load sync-items from project config and run them
sync_items = [ sync_items = [
SyncItem(**i) for i in get_config(PROJROOT).get('sync_items', []) SyncItem(**i) for i in getconfig(PROJROOT).get('sync_items', [])
] ]
run_standard_syncs(PROJROOT, mode, sync_items) run_standard_syncs(PROJROOT, mode, sync_items)
@ -498,11 +498,11 @@ def pytest() -> None:
import os import os
import platform import platform
import subprocess import subprocess
from efrotools import get_config, PYTHON_BIN from efrotools import getconfig, PYTHON_BIN
from efro.error import CleanError from efro.error import CleanError
# Grab our python paths for the project and stuff them in PYTHONPATH. # Grab our python paths for the project and stuff them in PYTHONPATH.
pypaths = get_config(PROJROOT).get('python_paths') pypaths = getconfig(PROJROOT).get('python_paths')
if pypaths is None: if pypaths is None:
raise CleanError('python_paths not found in project config.') raise CleanError('python_paths not found in project config.')

View File

@ -76,8 +76,8 @@ def run_standard_syncs(projectroot: Path, mode: Mode,
Syncitems should be a list of tuples consisting of a src project name, Syncitems should be a list of tuples consisting of a src project name,
a src subpath, and optionally a dst subpath (src will be used by default). a src subpath, and optionally a dst subpath (src will be used by default).
""" """
from efrotools import get_localconfig from efrotools import getlocalconfig
localconfig = get_localconfig(projectroot) localconfig = getlocalconfig(projectroot)
for syncitem in syncitems: for syncitem in syncitems:
assert isinstance(syncitem, SyncItem) assert isinstance(syncitem, SyncItem)
src_project = syncitem.src_project_id src_project = syncitem.src_project_id

View File

@ -41,14 +41,36 @@ from efrotools.snippets import (
PROJROOT, snippets_main, formatcode, formatscripts, formatmakefile, PROJROOT, snippets_main, formatcode, formatscripts, formatmakefile,
cpplint, pylint, runpylint, mypy, runmypy, dmypy, tool_config_install, cpplint, pylint, runpylint, mypy, runmypy, dmypy, tool_config_install,
sync, sync_all, scriptfiles, pycharm, clioncode, androidstudiocode, sync, sync_all, scriptfiles, pycharm, clioncode, androidstudiocode,
makefile_target_list, spelling, spelling_all, compile_python_files, pytest, makefile_target_list, spelling, spelling_all, pytest, echo)
echo) from efrotools.snippets import compile_python_files as _orig_compile_py_files
# pylint: enable=unused-import # pylint: enable=unused-import
if TYPE_CHECKING: if TYPE_CHECKING:
from typing import Optional from typing import Optional
def compile_python_files() -> None:
"""Override for compiling python files."""
from pathlib import Path
import subprocess
import os
from efrotools import getlocalconfig
# Run the standard command
_orig_compile_py_files()
# Optionally also blow away blessing status to keep it clear that
# things need to be re-blessed.
blesspath = Path(PROJROOT, 'tools/bless')
if os.path.exists(blesspath) and getlocalconfig(PROJROOT).get(
'auto_clear_blessing', False):
subprocess.run([blesspath, 'clear'], check=True, cwd=PROJROOT)
# Copy the original func's doc-string
compile_python_files.__doc__ = _orig_compile_py_files.__doc__
def archive_old_builds() -> None: def archive_old_builds() -> None:
"""Stuff our old public builds into the 'old' dir. """Stuff our old public builds into the 'old' dir.
@ -156,7 +178,7 @@ def get_master_asset_src_dir() -> None:
if ('origin/master' in output.splitlines()[0] if ('origin/master' in output.splitlines()[0]
and 'ballistica' + 'core' == 'ballisticacore'): and 'ballistica' + 'core' == 'ballisticacore'):
# We seem to be in master in core repo.. lets do it. # We seem to be in master in core repo; lets do it.
print('/Users/ericf/Dropbox/ballisticacore_master_assets') print('/Users/ericf/Dropbox/ballisticacore_master_assets')
else: else:
# Still need to supply dummy path for makefile if not.. # Still need to supply dummy path for makefile if not..
@ -399,8 +421,8 @@ def warm_start_asset_build() -> None:
import os import os
import subprocess import subprocess
from pathlib import Path from pathlib import Path
from efrotools import get_config from efrotools import getconfig
public: bool = get_config(PROJROOT)['public'] public: bool = getconfig(PROJROOT)['public']
if public: if public:
from efrotools.efrocache import warm_start_cache from efrotools.efrocache import warm_start_cache

View File

@ -180,9 +180,15 @@ def _get_py_targets_subset(all_targets: Set[str], subset: str,
' instead, but perhaps listing these explicitly isn\'t so bad.\n') ' instead, but perhaps listing these explicitly isn\'t so bad.\n')
for i, target in enumerate(pyc_targets): for i, target in enumerate(pyc_targets):
# Note: there's currently a bug which can cause python bytecode
# generation to be non-deterministic. This can break our blessing
# process since we bless in core but then regenerate bytecode in
# spinoffs. See https://bugs.python.org/issue34722
# For now setting PYTHONHASHSEED=1 is a workaround.
out += ('\n' + target + ': \\\n ' + py_targets[i] + out += ('\n' + target + ': \\\n ' + py_targets[i] +
'\n\t@echo Compiling script: $^\n' '\n\t@echo Compiling script: $^\n'
'\t@rm -rf $@ && $(TOOLS_DIR)/snippets compile_python_files $^' '\t@rm -rf $@ && PYTHONHASHSEED=1 $(TOOLS_DIR)/snippets'
' compile_python_files $^'
' && chmod 444 $@\n') ' && chmod 444 $@\n')
return out return out
@ -248,7 +254,7 @@ def _get_extras_targets_win(all_targets: Set[str], platform: str) -> str:
def main() -> None: def main() -> None:
"""Main script entry point.""" """Main script entry point."""
# pylint: disable=too-many-locals # pylint: disable=too-many-locals
from efrotools import get_config from efrotools import getconfig
from pathlib import Path from pathlib import Path
# In 'check' mode we simply error on differences. # In 'check' mode we simply error on differences.
@ -257,7 +263,7 @@ def main() -> None:
# Always operate out of dist root dir. # Always operate out of dist root dir.
os.chdir(os.path.join(os.path.dirname(sys.argv[0]), '..')) os.chdir(os.path.join(os.path.dirname(sys.argv[0]), '..'))
public = get_config(Path('.'))['public'] public = getconfig(Path('.'))['public']
assert isinstance(public, bool) assert isinstance(public, bool)
fname = 'assets/Makefile' fname = 'assets/Makefile'

View File

@ -67,14 +67,14 @@ class App:
"""Context for an app run.""" """Context for an app run."""
def __init__(self) -> None: def __init__(self) -> None:
from efrotools import get_config, get_localconfig from efrotools import getconfig, getlocalconfig
from pathlib import Path from pathlib import Path
self._check = ('--check' in sys.argv) self._check = ('--check' in sys.argv)
self._fix = ('--fix' in sys.argv) self._fix = ('--fix' in sys.argv)
self._checkarg = ' --check' if self._check else '' self._checkarg = ' --check' if self._check else ''
# We behave differently in the public repo # We behave differently in the public repo
self._public = get_config(Path('.'))['public'] self._public = getconfig(Path('.'))['public']
assert isinstance(self._public, bool) assert isinstance(self._public, bool)
self._source_files: List[str] = [] self._source_files: List[str] = []
@ -84,7 +84,7 @@ class App:
self._file_changes: Dict[str, str] = {} self._file_changes: Dict[str, str] = {}
self._copyright_checks = bool( self._copyright_checks = bool(
get_localconfig(Path('.')).get('copyright_checks', True)) getlocalconfig(Path('.')).get('copyright_checks', True))
def run(self) -> None: def run(self) -> None:
"""Do the thing.""" """Do the thing."""