This commit is contained in:
Eric Froemling 2020-06-23 02:10:34 -07:00
parent 1bbe987f15
commit 4655cc7391
8 changed files with 101 additions and 63 deletions

View File

@ -4135,16 +4135,16 @@
"assets/build/windows/x64/vc_redist.x64.exe": "https://files.ballistica.net/cache/ba1/ea/19/8b8787d81abcdce158ba608cd24f", "assets/build/windows/x64/vc_redist.x64.exe": "https://files.ballistica.net/cache/ba1/ea/19/8b8787d81abcdce158ba608cd24f",
"assets/build/windows/x64/vcruntime140_1d.dll": "https://files.ballistica.net/cache/ba1/11/d8/ff6344b429b00c24d9a1930d4338", "assets/build/windows/x64/vcruntime140_1d.dll": "https://files.ballistica.net/cache/ba1/11/d8/ff6344b429b00c24d9a1930d4338",
"assets/build/windows/x64/vcruntime140d.dll": "https://files.ballistica.net/cache/ba1/20/33/0825e11e6518f87ece3009309933", "assets/build/windows/x64/vcruntime140d.dll": "https://files.ballistica.net/cache/ba1/20/33/0825e11e6518f87ece3009309933",
"build/prefab/linux-server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/ef/00/26669a4c745046379f89f9dd14da", "build/prefab/linux-server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/3f/a1/dbaa655aeffc956c419ecbb3a0f1",
"build/prefab/linux-server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/5b/2c/bd7e5d1aa459ae3c0b21e4d057fa", "build/prefab/linux-server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/a5/10/3d7cb0d4b13a27574735e2b1aa63",
"build/prefab/linux/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/da/39/d33b31a44837a70473c2dc4bcd33", "build/prefab/linux/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/00/67/1089a04debbb8b0523c7311780d2",
"build/prefab/linux/release/ballisticacore": "https://files.ballistica.net/cache/ba1/ca/96/3cc53735853bd6e8d60b433f95a0", "build/prefab/linux/release/ballisticacore": "https://files.ballistica.net/cache/ba1/4c/57/d17251f72bb763fbdb7741d0da9d",
"build/prefab/mac-server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/e1/c5/658f143679fd8f56150357e090af", "build/prefab/mac-server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/7b/e9/44c85334c39d41b2f9ea592de605",
"build/prefab/mac-server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/38/9b/b62d121f0c6fb665a26c7832a015", "build/prefab/mac-server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/d4/1f/034553946265bacfc722b86d57f8",
"build/prefab/mac/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/86/8f/59e767e409088cedb70b7ebad514", "build/prefab/mac/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/83/2f/350d0e3ffbe1e4a3eca662fc2e1a",
"build/prefab/mac/release/ballisticacore": "https://files.ballistica.net/cache/ba1/5c/10/3356ad1eefadf9902dac526d70f8", "build/prefab/mac/release/ballisticacore": "https://files.ballistica.net/cache/ba1/62/38/6615fedcf4c970ea3dc66147de18",
"build/prefab/windows-server/debug/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/8d/dc/80d1aca955cff4ce0d6e27b67fbd", "build/prefab/windows-server/debug/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/13/47/d84222f416e0da118cda7e8862ae",
"build/prefab/windows-server/release/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/0d/76/aa2714c41e4c996c0f47f3e82699", "build/prefab/windows-server/release/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/7f/3e/0cb90e11e701f560fa037604e919",
"build/prefab/windows/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/5d/bc/eed0ece2e4a641f74ec3f2d1bee1", "build/prefab/windows/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/34/df/1f16b4633ec30aa50a64016d87b1",
"build/prefab/windows/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/75/1e/0bcec9cbe6fcc933249cbfcccb9f" "build/prefab/windows/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/94/f7/ce16094966391c21be78f541bc2c"
} }

View File

@ -1385,6 +1385,7 @@
<w>pathlib</w> <w>pathlib</w>
<w>pathnames</w> <w>pathnames</w>
<w>pathstonames</w> <w>pathstonames</w>
<w>pathtmp</w>
<w>patsubst</w> <w>patsubst</w>
<w>pausable</w> <w>pausable</w>
<w>pbrowser</w> <w>pbrowser</w>

View File

@ -1,5 +1,8 @@
### 1.5.10 (20083) ### 1.5.10 (20083)
- Streamlined C++ layer bootstrapping process a bit. - Streamlined C++ layer bootstrapping process a bit.
- Creating sys scripts via ba.modutils now works properly.
- Custom soundtracks should now work again under Android 10.
- Misc other bug fixes.
### 1.5.9 (20082) ### 1.5.9 (20082)
- Reduced some hitches when clicking on certain buttons in the UI - Reduced some hitches when clicking on certain buttons in the UI

View File

@ -105,9 +105,11 @@ class ServerCallThread(threading.Thread):
self._callback(arg) self._callback(arg)
def run(self) -> None: def run(self) -> None:
# pylint: disable=too-many-branches
import urllib.request import urllib.request
import urllib.error import urllib.error
import json import json
import http.client
from ba import _general from ba import _general
try: try:
self._data = _general.utf8_all(self._data) self._data = _general.utf8_all(self._data)
@ -145,16 +147,35 @@ class ServerCallThread(threading.Thread):
response_data = json.loads(raw_data_s) response_data = json.loads(raw_data_s)
else: else:
raise TypeError(f'invalid responsetype: {self._response_type}') raise TypeError(f'invalid responsetype: {self._response_type}')
except (urllib.error.URLError, ConnectionError):
# Server rejected us, broken pipe, etc. It happens. Ignoring.
response_data = None
except Exception as exc: except Exception as exc:
# Any other error here is unexpected, so let's make a note of it. import errno
print('Exc in ServerCallThread:', exc) do_print = False
import traceback
traceback.print_exc()
response_data = None response_data = None
# Ignore common network errors; note unexpected ones.
if isinstance(exc, (urllib.error.URLError, ConnectionError,
http.client.IncompleteRead)):
pass
elif isinstance(exc, OSError):
if exc.errno == 10051: # Windows unreachable network error.
pass
elif exc.errno in [errno.ETIMEDOUT]:
pass
else:
do_print = True
else:
do_print = True
if do_print:
# Any other error here is unexpected,
# so let's make a note of it,
print(f'Error in ServerCallThread'
f' (response-type={self._response_type},'
f' response-data={response_data}):')
import traceback
traceback.print_exc()
if self._callback is not None: if self._callback is not None:
_ba.pushcall(_general.Call(self._run_callback, response_data), _ba.pushcall(_general.Call(self._run_callback, response_data),
from_other_thread=True) from_other_thread=True)

View File

@ -27,7 +27,7 @@ import os
import _ba import _ba
if TYPE_CHECKING: if TYPE_CHECKING:
from typing import Optional from typing import Optional, List, Sequence
def get_human_readable_user_scripts_path() -> str: def get_human_readable_user_scripts_path() -> str:
@ -55,18 +55,25 @@ def get_human_readable_user_scripts_path() -> str:
return path return path
def _request_storage_permission() -> bool:
"""If needed, requests storage permission from the user (& return true)."""
from ba._lang import Lstr
from ba._enums import Permission
if not _ba.have_permission(Permission.STORAGE):
_ba.playsound(_ba.getsound('error'))
_ba.screenmessage(Lstr(resource='storagePermissionAccessText'),
color=(1, 0, 0))
_ba.timer(1.0, lambda: _ba.request_permission(Permission.STORAGE))
return True
return False
def show_user_scripts() -> None: def show_user_scripts() -> None:
"""Open or nicely print the location of the user-scripts directory.""" """Open or nicely print the location of the user-scripts directory."""
from ba import _lang
from ba._enums import Permission
app = _ba.app app = _ba.app
# First off, if we need permission for this, ask for it. # First off, if we need permission for this, ask for it.
if not _ba.have_permission(Permission.STORAGE): if _request_storage_permission():
_ba.playsound(_ba.getsound('error'))
_ba.screenmessage(_lang.Lstr(resource='storagePermissionAccessText'),
color=(1, 0, 0))
_ba.request_permission(Permission.STORAGE)
return return
# Secondly, if the dir doesn't exist, attempt to make it. # Secondly, if the dir doesn't exist, attempt to make it.
@ -107,31 +114,37 @@ def create_user_system_scripts() -> None:
(for editing and experiment with) (for editing and experiment with)
""" """
app = _ba.app
import shutil import shutil
app = _ba.app
# First off, if we need permission for this, ask for it.
if _request_storage_permission():
return
path = (app.python_directory_user + '/sys/' + app.version) path = (app.python_directory_user + '/sys/' + app.version)
pathtmp = path + '_tmp'
if os.path.exists(path): if os.path.exists(path):
shutil.rmtree(path) shutil.rmtree(path)
if os.path.exists(path + '_tmp'): if os.path.exists(pathtmp):
shutil.rmtree(path + '_tmp') shutil.rmtree(pathtmp)
os.makedirs(path + '_tmp', exist_ok=True)
# Hmm; shutil.copytree doesn't seem to work nicely on android, def _ignore_filter(src: str, names: Sequence[str]) -> Sequence[str]:
# so lets do it manually. del src, names # Unused
# NOTE: Should retry this now that we have 3.7 (this note was for 2.7)
src_dir = app.python_directory_app
dst_dir = path + '_tmp'
filenames = os.listdir(app.python_directory_app)
for fname in filenames:
print('COPYING', src_dir + '/' + fname, '->', dst_dir)
shutil.copyfile(src_dir + '/' + fname, dst_dir + '/' + fname)
print('MOVING', path + '_tmp', path) # We simply skip all __pycache__ directories. (the user would have
shutil.move(path + '_tmp', path) # to blow them away anyway to make changes;
print( # See https://github.com/efroemling/ballistica/wiki
('Created system scripts at :\'' + path + # /Knowledge-Nuggets#python-cache-files-gotcha
'\'\nRestart Ballistica to use them. (use ba.quit() to exit the game)' return ('__pycache__', )
))
print(f'COPYING "{app.python_directory_app}" -> "{pathtmp}".')
shutil.copytree(app.python_directory_app, pathtmp, ignore=_ignore_filter)
print(f'MOVING "{pathtmp}" -> "{path}".')
shutil.move(pathtmp, path)
print(f"Created system scripts at :'{path}"
f"'\nRestart {_ba.appname()} to use them."
f' (use ba.quit() to exit the game)')
if app.platform == 'android': if app.platform == 'android':
print('Note: the new files may not be visible via ' print('Note: the new files may not be visible via '
'android-file-transfer until you restart your device.') 'android-file-transfer until you restart your device.')
@ -144,9 +157,9 @@ def delete_user_system_scripts() -> None:
path = (app.python_directory_user + '/sys/' + app.version) path = (app.python_directory_user + '/sys/' + app.version)
if os.path.exists(path): if os.path.exists(path):
shutil.rmtree(path) shutil.rmtree(path)
print( print(f'User system scripts deleted.\n'
'User system scripts deleted.\nRestart Ballistica to use internal' f'Restart {_ba.appname()} to use internal'
' scripts. (use ba.quit() to exit the game)') f' scripts. (use ba.quit() to exit the game)')
else: else:
print('User system scripts not found.') print('User system scripts not found.')

View File

@ -123,6 +123,7 @@ class _PickFolderSongThread(threading.Thread):
def run(self) -> None: def run(self) -> None:
from ba import _lang from ba import _lang
from ba._general import Call from ba._general import Call
do_print_error = True
try: try:
_ba.set_thread_name('BA_PickFolderSongThread') _ba.set_thread_name('BA_PickFolderSongThread')
all_files: List[str] = [] all_files: List[str] = []
@ -134,14 +135,16 @@ class _PickFolderSongThread(threading.Thread):
all_files.insert(random.randrange(len(all_files) + 1), all_files.insert(random.randrange(len(all_files) + 1),
root + '/' + fname) root + '/' + fname)
if not all_files: if not all_files:
raise Exception( do_print_error = False
raise RuntimeError(
_lang.Lstr(resource='internal.noMusicFilesInFolderText'). _lang.Lstr(resource='internal.noMusicFilesInFolderText').
evaluate()) evaluate())
_ba.pushcall(Call(self._callback, all_files, None), _ba.pushcall(Call(self._callback, all_files, None),
from_other_thread=True) from_other_thread=True)
except Exception as exc: except Exception as exc:
from ba import _error from ba import _error
_error.print_exception() if do_print_error:
_error.print_exception()
try: try:
err_str = str(exc) err_str = str(exc)
except Exception: except Exception:

View File

@ -435,19 +435,16 @@ class GatherWindow(ba.Window):
sock.connect(('8.8.8.8', 80)) sock.connect(('8.8.8.8', 80))
val = sock.getsockname()[0] val = sock.getsockname()[0]
sock.close() sock.close()
# val = ([
# (s.connect(('8.8.8.8', 80)),
# s.getsockname()[0],
# s.close()) for s in
# [socket.socket(socket.AF_INET,
# socket.SOCK_DGRAM)]
# ][0][1])
ba.pushcall(ba.Call(self._call, val), ba.pushcall(ba.Call(self._call, val),
from_other_thread=True) from_other_thread=True)
except Exception: except Exception as exc:
# FIXME: Should filter out expected errors and # Ignore expected network errors; log others.
# report others here. import errno
ba.print_exception() if (isinstance(exc, OSError)
and exc.errno == errno.ENETUNREACH):
pass
else:
ba.print_exception()
AddrFetchThread(ba.WeakCall( AddrFetchThread(ba.WeakCall(
self._internet_fetch_local_addr_cb)).start() self._internet_fetch_local_addr_cb)).start()

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-22 for Ballistica version 1.5.9 build 20081</em></h4> <h4><em>last updated on 2020-06-23 for Ballistica version 1.5.10 build 20084</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>