diff --git a/.efrocachemap b/.efrocachemap index 6aa18ef9..ae2de923 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -3932,40 +3932,40 @@ "assets/build/windows/Win32/ucrtbased.dll": "https://files.ballistica.net/cache/ba1/b5/85/f8b6d0558ddb87267f34254b1450", "assets/build/windows/Win32/vc_redist.x86.exe": "https://files.ballistica.net/cache/ba1/1c/e1/4a1a2eddda2f4aebd5f8b64ab08e", "assets/build/windows/Win32/vcruntime140d.dll": "https://files.ballistica.net/cache/ba1/50/8d/bc2600ac9491f1b14d659709451f", - "build/prefab/full/linux_arm64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/4d/69/2e4c0ba6b6a7f27c9754e6fa2028", - "build/prefab/full/linux_arm64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/54/e1/f8d826dfbe0ff9f192edc232857c", - "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/b1/fd/2258453c18672fd79398b0c2030c", - "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/3e/74/9417d078cb0a0eaecdf30e531c4e", - "build/prefab/full/linux_x86_64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/b0/e8/495cc0e784c6b98d33ee8e83f922", - "build/prefab/full/linux_x86_64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/7b/73/c72308a21aeb876e4192719f4445", - "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/11/d4/474b2f2cf46689f7cb7733b66a10", - "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/0e/d3/e1d791f6a6411c7acfdd72d2c75e", - "build/prefab/full/mac_arm64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/89/f9/7b3ec953d17beaa42560aa09bbdb", - "build/prefab/full/mac_arm64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/57/81/c00fc47949becf3fa7b8fda7737e", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/63/87/4f12518d69e5974124744a99b9cc", - "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/34/16/d383c070bc3ee1692f729d817ba5", - "build/prefab/full/mac_x86_64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/0c/68/d5c5a2e2511e597ab13f0e23f62b", - "build/prefab/full/mac_x86_64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/10/3a/e8cca189e72de469661306810f4e", - "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/90/0a/621c8f2bc888e93581b4100ef857", - "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/2b/24/e9fd7c975d93ce57707b5ddd01f1", - "build/prefab/full/windows_x86/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/a6/f8/3bcda19fe1c92de4114b0096a807", - "build/prefab/full/windows_x86/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/d4/7b/22b7570f138f58ff88b219ff2586", - "build/prefab/full/windows_x86_server/debug/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/99/54/0a026dbab2d2e6e44d89f8242f4f", - "build/prefab/full/windows_x86_server/release/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/79/63/76dd15496bdedc116a02fc7a5df3", - "build/prefab/lib/linux_arm64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/95/48/ad90969b34d9166d32eae56ea9e4", - "build/prefab/lib/linux_arm64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/b4/5a/0515721b7e4ce334c0fabbeb4376", - "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/d5/7f/9d46d20545a97b9f3b65ce25880a", - "build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/66/bd/5b9723fab837270b875da9f9d91e", - "build/prefab/lib/linux_x86_64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/34/80/166ae132364a8d788ddc66b6b8fe", - "build/prefab/lib/linux_x86_64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/88/14/b63a6887474340f9ea5aecd861c7", - "build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/01/b8/9b18a2d624f5251c1d3d57a9abb8", - "build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/18/8a/d5f35a9938e4cfc21f26338b487a", - "build/prefab/lib/mac_arm64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/2f/c5/891774c681b68e350cca570a7936", - "build/prefab/lib/mac_arm64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ef/96/a0e88328f90dc079c84bc0791f7f", - "build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/c6/30/6446116fbb8ab3d97602a90ae99b", - "build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/40/75/633d1a8d826ecf7417519e7d39eb", - "build/prefab/lib/mac_x86_64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/81/da/43f897aec8a5140ac1ef35b193e9", - "build/prefab/lib/mac_x86_64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/94/90/fefc90daa043e388604ea79ef4f0", - "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/12/cb/521fa56c5954c40be151704fd77e", - "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/53/a7/da3c0ac70e103a8a3a31b50bc41e" + "build/prefab/full/linux_arm64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/fe/8e/2d088fc700f5082e38c5905c62f9", + "build/prefab/full/linux_arm64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/a3/bc/bbd49ff7fdc1e368e505fc13dc05", + "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/15/90/aac271a2f2ce680065e77b004aef", + "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/df/75/bfbb15dbb2e58d8b8417c916e8f4", + "build/prefab/full/linux_x86_64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/b7/b3/2f36b4c8dfaf2d889ace6bed8997", + "build/prefab/full/linux_x86_64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/f8/0b/69392c0662bc27b261190f9b18c2", + "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/23/55/3abe51e53f08d0c49d8cda499bd4", + "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/94/e4/bf1c4727c463890db8c2370c9add", + "build/prefab/full/mac_arm64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/b5/cf/1c2eed82ae6a59caf38e0a99db3f", + "build/prefab/full/mac_arm64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/a9/b5/938d8d57e898901dd09e01e0558e", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/77/77/3a3be11fec9168018287cb8318e4", + "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/9a/e4/2bf5b9b80d1a449f6615f567cb74", + "build/prefab/full/mac_x86_64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/be/d7/29cd656c83b4d0aaecda25f9ae71", + "build/prefab/full/mac_x86_64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/40/d4/4252bf6dc9ffefe8195c16a243fb", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/b6/e4/f8b2ccefb907c24fdae5a503687f", + "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/2b/41/03403d2112be6aa3c97ece97b6ad", + "build/prefab/full/windows_x86/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/3e/32/5647116c2fdbdf9e7bf9c51a59c2", + "build/prefab/full/windows_x86/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/d5/9d/f912c7a8b8297a63b5074f4611b6", + "build/prefab/full/windows_x86_server/debug/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/8e/a7/a65f979fb283ab33292bdff7c187", + "build/prefab/full/windows_x86_server/release/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/65/fe/0eab9c08daeed85ba65020bb1497", + "build/prefab/lib/linux_arm64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/46/63/ddb89ceddbe7f7e0194686b1f9fd", + "build/prefab/lib/linux_arm64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/8a/19/bff3a13ca376d9f3fe6c74be6655", + "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/da/1b/0d4c818d4646a4bb7a37ab6201c8", + "build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/78/21/d2789bd9343f01b944d0246c43ef", + "build/prefab/lib/linux_x86_64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/f9/e5/602243f370562f553d1b7a8ea10f", + "build/prefab/lib/linux_x86_64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/1d/fd/1284817f08d90c2f9ddb6bea35a4", + "build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/84/00/da93ec1c6eb292ce0f914bae4c73", + "build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/fd/ce/f2d635f25f9af9b72b49f6bd7ac7", + "build/prefab/lib/mac_arm64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/7f/ed/e915949aab7ff8f7751cea7e7c27", + "build/prefab/lib/mac_arm64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/cc/0e/9f736c2a548cdcc1d66e12df6989", + "build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/24/9d/8748b562e9534db9696227ce1f2d", + "build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/2b/24/7cb7aa32b353587b63c9a7094ad1", + "build/prefab/lib/mac_x86_64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/01/b2/f50629fb6513240ef49b2ced2226", + "build/prefab/lib/mac_x86_64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/e8/b1/c5222a3c3d05614f175e3526a460", + "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/41/0d/87732dd64bca0c72f16087864602", + "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/9a/58/7363f022504a97b34e076f9eac53" } \ No newline at end of file diff --git a/.idea/dictionaries/ericf.xml b/.idea/dictionaries/ericf.xml index c7099f2d..1312a27e 100644 --- a/.idea/dictionaries/ericf.xml +++ b/.idea/dictionaries/ericf.xml @@ -165,6 +165,7 @@ ballisticacore ballisticacorecb bamaster + bamasteraddr barcolor barebones baseh @@ -205,6 +206,7 @@ bindvals bisectmodule bitcode + blarg blas blastos bldtp @@ -621,6 +623,7 @@ elapsedf elementtree elim + embconnect emitfx emoji emojis @@ -1906,6 +1909,7 @@ serverget servermanager servermode + servernodequery servernodes serverput serverutils diff --git a/assets/.asset_manifest_public.json b/assets/.asset_manifest_public.json index c5603603..fd6e671c 100644 --- a/assets/.asset_manifest_public.json +++ b/assets/.asset_manifest_public.json @@ -40,7 +40,7 @@ "ba_data/python/ba/__pycache__/_meta.cpython-38.opt-1.pyc", "ba_data/python/ba/__pycache__/_multiteamsession.cpython-38.opt-1.pyc", "ba_data/python/ba/__pycache__/_music.cpython-38.opt-1.pyc", - "ba_data/python/ba/__pycache__/_netutils.cpython-38.opt-1.pyc", + "ba_data/python/ba/__pycache__/_net.cpython-38.opt-1.pyc", "ba_data/python/ba/__pycache__/_nodeactor.cpython-38.opt-1.pyc", "ba_data/python/ba/__pycache__/_player.cpython-38.opt-1.pyc", "ba_data/python/ba/__pycache__/_playlist.cpython-38.opt-1.pyc", @@ -102,7 +102,7 @@ "ba_data/python/ba/_meta.py", "ba_data/python/ba/_multiteamsession.py", "ba_data/python/ba/_music.py", - "ba_data/python/ba/_netutils.py", + "ba_data/python/ba/_net.py", "ba_data/python/ba/_nodeactor.py", "ba_data/python/ba/_player.py", "ba_data/python/ba/_playlist.py", diff --git a/assets/Makefile b/assets/Makefile index ac33b73b..024edb6c 100644 --- a/assets/Makefile +++ b/assets/Makefile @@ -171,7 +171,7 @@ SCRIPT_TARGETS_PY_PUBLIC = \ build/ba_data/python/ba/_meta.py \ build/ba_data/python/ba/_multiteamsession.py \ build/ba_data/python/ba/_music.py \ - build/ba_data/python/ba/_netutils.py \ + build/ba_data/python/ba/_net.py \ build/ba_data/python/ba/_nodeactor.py \ build/ba_data/python/ba/_player.py \ build/ba_data/python/ba/_playlist.py \ @@ -415,7 +415,7 @@ SCRIPT_TARGETS_PYC_PUBLIC = \ build/ba_data/python/ba/__pycache__/_meta.cpython-38.opt-1.pyc \ build/ba_data/python/ba/__pycache__/_multiteamsession.cpython-38.opt-1.pyc \ build/ba_data/python/ba/__pycache__/_music.cpython-38.opt-1.pyc \ - build/ba_data/python/ba/__pycache__/_netutils.cpython-38.opt-1.pyc \ + build/ba_data/python/ba/__pycache__/_net.cpython-38.opt-1.pyc \ build/ba_data/python/ba/__pycache__/_nodeactor.cpython-38.opt-1.pyc \ build/ba_data/python/ba/__pycache__/_player.cpython-38.opt-1.pyc \ build/ba_data/python/ba/__pycache__/_playlist.cpython-38.opt-1.pyc \ diff --git a/assets/src/ba_data/python/_ba.py b/assets/src/ba_data/python/_ba.py index 363d5302..01776ff3 100644 --- a/assets/src/ba_data/python/_ba.py +++ b/assets/src/ba_data/python/_ba.py @@ -2145,8 +2145,8 @@ def get_low_level_config_value(key: str, default_value: int) -> int: return int() -def get_master_server_address(source: int = -1) -> str: - """get_master_server_address(source: int = -1) -> str +def get_master_server_address(source: int = -1, version: int = 1) -> str: + """get_master_server_address(source: int = -1, version: int = 1) -> str (internal) diff --git a/assets/src/ba_data/python/ba/_apputils.py b/assets/src/ba_data/python/ba/_apputils.py index f3698a4e..8e3767c6 100644 --- a/assets/src/ba_data/python/ba/_apputils.py +++ b/assets/src/ba_data/python/ba/_apputils.py @@ -56,7 +56,7 @@ def handle_log() -> None: When this happens, we can upload our log to the server after a short bit if desired. """ - from ba._netutils import master_server_post + from ba._net import master_server_post from ba._enums import TimeType app = _ba.app app.log_have_new = True @@ -121,7 +121,7 @@ def handle_leftover_log_file() -> None: """Handle an un-uploaded log from a previous run.""" try: import json - from ba._netutils import master_server_post + from ba._net import master_server_post if os.path.exists(_ba.get_log_file_path()): with open(_ba.get_log_file_path()) as infile: diff --git a/assets/src/ba_data/python/ba/_assetmanager.py b/assets/src/ba_data/python/ba/_assetmanager.py index 118f2306..c23624a4 100644 --- a/assets/src/ba_data/python/ba/_assetmanager.py +++ b/assets/src/ba_data/python/ba/_assetmanager.py @@ -158,6 +158,7 @@ def fetch_url(url: str, filename: Path, asset_gather: AssetGather) -> None: """Fetch a given url to a given filename for a given AssetGather. """ + # pylint: disable=consider-using-with import socket diff --git a/assets/src/ba_data/python/ba/_netutils.py b/assets/src/ba_data/python/ba/_net.py similarity index 62% rename from assets/src/ba_data/python/ba/_netutils.py rename to assets/src/ba_data/python/ba/_net.py index 5f5e0883..39c3642d 100644 --- a/assets/src/ba_data/python/ba/_netutils.py +++ b/assets/src/ba_data/python/ba/_net.py @@ -15,7 +15,42 @@ if TYPE_CHECKING: from typing import Any, Dict, Union, Callable, Optional import socket import ba - ServerCallbackType = Callable[[Union[None, Dict[str, Any]]], None] + MasterServerCallback = Callable[[Union[None, Dict[str, Any]]], None] + +# Timeout for standard functions talking to the master-server/etc. +DEFAULT_REQUEST_TIMEOUT_SECONDS = 60 + + +def is_urllib_network_error(exc: BaseException) -> bool: + """Is the provided exception a network-related error? + + This should be passed any exception which resulted from opening or + reading a urllib Request. It should return True for any errors that + could conceivably arise due to unavailable/poor network connections, + firewall/connectivity issues, etc. These issues can often be safely + ignored or presented to the user as general 'network-unavailable' + states. + """ + import urllib.request + import urllib.error + import http.client + import errno + import socket + if isinstance( + exc, + (urllib.error.URLError, ConnectionError, http.client.IncompleteRead, + http.client.BadStatusLine, socket.timeout)): + return True + if isinstance(exc, OSError): + if exc.errno == 10051: # Windows unreachable network error. + return True + if exc.errno in { + errno.ETIMEDOUT, + errno.EHOSTUNREACH, + errno.ENETUNREACH, + }: + return True + return False def get_ip_address_type(addr: str) -> socket.AddressFamily: @@ -42,26 +77,26 @@ def get_ip_address_type(addr: str) -> socket.AddressFamily: return socket_type -class ServerResponseType(Enum): - """How to interpret responses from the server.""" +class MasterServerResponseType(Enum): + """How to interpret responses from the master-server.""" JSON = 0 -class ServerCallThread(threading.Thread): - """Thread to communicate with the master server.""" +class MasterServerCallThread(threading.Thread): + """Thread to communicate with the master-server.""" def __init__(self, request: str, request_type: str, data: Optional[Dict[str, Any]], - callback: Optional[ServerCallbackType], - response_type: ServerResponseType): + callback: Optional[MasterServerCallback], + response_type: MasterServerResponseType): super().__init__() self._request = request self._request_type = request_type - if not isinstance(response_type, ServerResponseType): + if not isinstance(response_type, MasterServerResponseType): raise TypeError(f'Invalid response type: {response_type}') self._response_type = response_type self._data = {} if data is None else copy.deepcopy(data) - self._callback: Optional[ServerCallbackType] = callback + self._callback: Optional[MasterServerCallback] = callback self._context = _ba.Context('current') # Save and restore the context we were created from. @@ -87,11 +122,10 @@ class ServerCallThread(threading.Thread): self._callback(arg) def run(self) -> None: - # pylint: disable=too-many-branches + # pylint: disable=too-many-branches, consider-using-with import urllib.request import urllib.error import json - import http.client from ba import _general try: self._data = _general.utf8_all(self._data) @@ -102,54 +136,43 @@ class ServerCallThread(threading.Thread): urllib.request.Request( (_ba.get_master_server_address() + '/' + self._request + '?' + parse.urlencode(self._data)), - None, {'User-Agent': _ba.app.user_agent_string})) + None, {'User-Agent': _ba.app.user_agent_string}), + timeout=DEFAULT_REQUEST_TIMEOUT_SECONDS) elif self._request_type == 'post': response = urllib.request.urlopen( urllib.request.Request( _ba.get_master_server_address() + '/' + self._request, parse.urlencode(self._data).encode(), - {'User-Agent': _ba.app.user_agent_string})) + {'User-Agent': _ba.app.user_agent_string}), + timeout=DEFAULT_REQUEST_TIMEOUT_SECONDS) else: raise TypeError('Invalid request_type: ' + self._request_type) # If html request failed. if response.getcode() != 200: response_data = None - elif self._response_type == ServerResponseType.JSON: + elif self._response_type == MasterServerResponseType.JSON: raw_data = response.read() # Empty string here means something failed server side. if raw_data == b'': response_data = None else: - # Json.loads requires str in python < 3.6. - raw_data_s = raw_data.decode() - response_data = json.loads(raw_data_s) + response_data = json.loads(raw_data) else: raise TypeError(f'invalid responsetype: {self._response_type}') except Exception as exc: - import errno do_print = False response_data = None # Ignore common network errors; note unexpected ones. - if isinstance( - exc, - (urllib.error.URLError, ConnectionError, - http.client.IncompleteRead, http.client.BadStatusLine)): + if is_urllib_network_error(exc): pass - elif isinstance(exc, OSError): - if exc.errno == 10051: # Windows unreachable network error. - pass - elif exc.errno in [ - errno.ETIMEDOUT, errno.EHOSTUNREACH, errno.ENETUNREACH - ]: - pass - else: - do_print = True - elif (self._response_type == ServerResponseType.JSON + elif (self._response_type == MasterServerResponseType.JSON and isinstance(exc, json.decoder.JSONDecodeError)): + # FIXME: should handle this better; could mean either the + # server sent us bad data or it got corrupted along the way. pass else: do_print = True @@ -157,7 +180,7 @@ class ServerCallThread(threading.Thread): if do_print: # Any other error here is unexpected, # so let's make a note of it, - print(f'Error in ServerCallThread' + print(f'Error in MasterServerCallThread' f' (response-type={self._response_type},' f' response-data={response_data}):') import traceback @@ -169,18 +192,22 @@ class ServerCallThread(threading.Thread): def master_server_get( - request: str, - data: Dict[str, Any], - callback: Optional[ServerCallbackType] = None, - response_type: ServerResponseType = ServerResponseType.JSON) -> None: + request: str, + data: Dict[str, Any], + callback: Optional[MasterServerCallback] = None, + response_type: MasterServerResponseType = MasterServerResponseType.JSON +) -> None: """Make a call to the master server via a http GET.""" - ServerCallThread(request, 'get', data, callback, response_type).start() + MasterServerCallThread(request, 'get', data, callback, + response_type).start() def master_server_post( - request: str, - data: Dict[str, Any], - callback: Optional[ServerCallbackType] = None, - response_type: ServerResponseType = ServerResponseType.JSON) -> None: + request: str, + data: Dict[str, Any], + callback: Optional[MasterServerCallback] = None, + response_type: MasterServerResponseType = MasterServerResponseType.JSON +) -> None: """Make a call to the master server via a http POST.""" - ServerCallThread(request, 'post', data, callback, response_type).start() + MasterServerCallThread(request, 'post', data, callback, + response_type).start() diff --git a/assets/src/ba_data/python/ba/_servermode.py b/assets/src/ba_data/python/ba/_servermode.py index ec540d3b..245fd9e0 100644 --- a/assets/src/ba_data/python/ba/_servermode.py +++ b/assets/src/ba_data/python/ba/_servermode.py @@ -186,7 +186,7 @@ class ServerController: def _run_access_check(self) -> None: """Check with the master server to see if we're likely joinable.""" - from ba._netutils import master_server_get + from ba._net import master_server_get master_server_get( 'bsAccessCheck', { diff --git a/assets/src/ba_data/python/ba/internal.py b/assets/src/ba_data/python/ba/internal.py index 1d852ee1..c2286f1c 100644 --- a/assets/src/ba_data/python/ba/internal.py +++ b/assets/src/ba_data/python/ba/internal.py @@ -25,8 +25,9 @@ from ba._campaign import getcampaign from ba._messages import PlayerProfilesChangedMessage from ba._multiteamsession import DEFAULT_TEAM_COLORS, DEFAULT_TEAM_NAMES from ba._music import do_play_music -from ba._netutils import (master_server_get, master_server_post, - get_ip_address_type) +from ba._net import (master_server_get, master_server_post, + get_ip_address_type, is_urllib_network_error, + DEFAULT_REQUEST_TIMEOUT_SECONDS) from ba._powerup import get_default_powerup_distribution from ba._profile import (get_player_profile_colors, get_player_profile_icon, get_player_colors) diff --git a/assets/src/ba_data/python/bastd/ui/confirm.py b/assets/src/ba_data/python/bastd/ui/confirm.py index fc65aaf6..82e2ac48 100644 --- a/assets/src/ba_data/python/bastd/ui/confirm.py +++ b/assets/src/ba_data/python/bastd/ui/confirm.py @@ -34,8 +34,7 @@ class ConfirmWindow: if cancel_text is None: cancel_text = ba.Lstr(resource='cancelText') height += 40 - if width < 360: - width = 360 + width = max(width, 360) self._action = action # if they provided an origin-widget, scale up from that diff --git a/assets/src/ba_data/python/bastd/ui/gather/publictab.py b/assets/src/ba_data/python/bastd/ui/gather/publictab.py index b1a326ba..fc07f836 100644 --- a/assets/src/ba_data/python/bastd/ui/gather/publictab.py +++ b/assets/src/ba_data/python/bastd/ui/gather/publictab.py @@ -1261,10 +1261,7 @@ class PublicGatherTab(GatherTab): self._have_user_selected_row = True def _on_max_public_party_size_minus_press(self) -> None: - val = _ba.get_public_party_max_size() - val -= 1 - if val < 1: - val = 1 + val = max(1, _ba.get_public_party_max_size() - 1) _ba.set_public_party_max_size(val) ba.textwidget(edit=self._host_max_party_size_value, text=str(val)) diff --git a/assets/src/server/ballisticacore_server.py b/assets/src/server/ballisticacore_server.py index d2a7c53f..49101783 100755 --- a/assets/src/server/ballisticacore_server.py +++ b/assets/src/server/ballisticacore_server.py @@ -549,6 +549,7 @@ class ServerManagerApp: def _run_server_cycle(self) -> None: """Spin up the server subprocess and run it until exit.""" + # pylint: disable=consider-using-with # Reload our config, and update our overall behavior based on it. # We do non-strict this time to give the user repeated attempts if diff --git a/ballisticacore-cmake/.idea/dictionaries/ericf.xml b/ballisticacore-cmake/.idea/dictionaries/ericf.xml index c02c1bfa..2055a422 100644 --- a/ballisticacore-cmake/.idea/dictionaries/ericf.xml +++ b/ballisticacore-cmake/.idea/dictionaries/ericf.xml @@ -66,6 +66,7 @@ backtraces ballistica ballisticacore + bamasteraddr barebones basetype basicsize @@ -88,6 +89,7 @@ bitmask bitpos bitval + blarg blitters blitting blockadr @@ -271,6 +273,7 @@ elems elevenbase elevenbits + embconnect emitfx emojis enablexinput @@ -822,6 +825,7 @@ seqtypestr serv serverget + servernodequery servernodes serverput sessiondata diff --git a/docs/ba_module.md b/docs/ba_module.md index 3d3a842e..e248e6bd 100644 --- a/docs/ba_module.md +++ b/docs/ba_module.md @@ -1,5 +1,5 @@ -

last updated on 2021-04-19 for Ballistica version 1.6.0 build 20347

+

last updated on 2021-04-25 for Ballistica version 1.6.0 build 20349

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 let me know. Happy modding!


diff --git a/src/ballistica/ballistica.cc b/src/ballistica/ballistica.cc index 252e796a..aa8029b7 100644 --- a/src/ballistica/ballistica.cc +++ b/src/ballistica/ballistica.cc @@ -21,7 +21,7 @@ namespace ballistica { // These are set automatically via script; don't change here. -const int kAppBuildNumber = 20347; +const int kAppBuildNumber = 20349; const char* kAppVersion = "1.6.0"; // Our standalone globals. diff --git a/src/ballistica/config/config_common.h b/src/ballistica/config/config_common.h index 664b7cb2..45764edd 100644 --- a/src/ballistica/config/config_common.h +++ b/src/ballistica/config/config_common.h @@ -10,9 +10,9 @@ // Universal sanity checks. #if !BA_DEBUG_BUILD -#if !NDEBUG +#ifndef NDEBUG #error NDEBUG should be defined for all non-debug builds. -#endif // !NDEBUG +#endif // NDEBUG #endif // !BA_DEBUG_BUILD // This header should be included at the very END of each platform config diff --git a/tools/batools/build.py b/tools/batools/build.py index cf7e7d09..7514b488 100644 --- a/tools/batools/build.py +++ b/tools/batools/build.py @@ -29,11 +29,11 @@ class PipRequirement: PIP_REQUIREMENTS = [ - PipRequirement(modulename='pylint', minversion=[2, 7, 0]), + PipRequirement(modulename='pylint', minversion=[2, 8, 1]), PipRequirement(modulename='mypy', minversion=[0, 812]), - PipRequirement(modulename='yapf', minversion=[0, 30, 0]), + PipRequirement(modulename='yapf', minversion=[0, 31, 0]), PipRequirement(modulename='cpplint', minversion=[1, 5, 4]), - PipRequirement(modulename='pytest', minversion=[6, 2, 2]), + PipRequirement(modulename='pytest', minversion=[6, 2, 3]), PipRequirement(modulename='typing_extensions'), PipRequirement(modulename='pytz'), PipRequirement(modulename='ansiwrap'), diff --git a/tools/efro/entity/_entity.py b/tools/efro/entity/_entity.py index 6a3d3942..b866964c 100644 --- a/tools/efro/entity/_entity.py +++ b/tools/efro/entity/_entity.py @@ -151,7 +151,7 @@ class EntityMixin: cls=ExtendedJSONEncoder) @staticmethod - def json_loads(s: str) -> Any: + def json_loads(s: Union[str, bytes]) -> Any: """Load a json string using our special extended decoder. Note that this simply returns loaded json data; no @@ -159,7 +159,9 @@ class EntityMixin: """ return json.loads(s, cls=ExtendedJSONDecoder) - def load_from_json_str(self, s: str, error: bool = True) -> None: + def load_from_json_str(self, + s: Union[str, bytes], + error: bool = True) -> None: """Set the entity's data in-place from a json string. The 'error' argument determines whether Exceptions will be raised @@ -171,7 +173,9 @@ class EntityMixin: self.set_data(data, error=error) @classmethod - def from_json_str(cls: Type[T], s: str, error: bool = True) -> T: + def from_json_str(cls: Type[T], + s: Union[str, bytes], + error: bool = True) -> T: """Instantiate a new instance with provided json string. The 'error' argument determines whether exceptions will be raised diff --git a/tools/efrotools/code.py b/tools/efrotools/code.py index 59531160..29c13fdb 100644 --- a/tools/efrotools/code.py +++ b/tools/efrotools/code.py @@ -629,6 +629,7 @@ def _run_idea_inspections(projroot: Path, Throw an Exception if anything is found or goes wrong. """ # pylint: disable=too-many-locals + # pylint: disable=consider-using-with import tempfile import time import datetime @@ -778,22 +779,21 @@ def check_pycharm(projroot: Path, full: bool, verbose: bool) -> None: # work that way. if bool(False): print('Launching GUI PyCharm to rebuild caches...', flush=True) - process = subprocess.Popen(str(pycharmbin)) + with subprocess.Popen(str(pycharmbin)) as process: - # Wait a bit and ask it nicely to die. - # We need to make sure it has enough time to do its cache updating - # thing even if the system is fully under load. - time.sleep(5 * 60) + # Wait a bit and ask it nicely to die. + # We need to make sure it has enough time to do its + # cache updating thing even if the system is fully under load. + time.sleep(5 * 60) - # Seems killing it via applescript is more likely to leave it - # in a working state for offline inspections than TERM signal.. - subprocess.run( - "osascript -e 'tell application \"PyCharm CE\" to quit'", - shell=True, - check=False) - # process.terminate() - print('Waiting for GUI PyCharm to quit...', flush=True) - process.wait() + # Seems killing it via applescript is more likely to leave it + # in a working state for offline inspections than TERM signal.. + subprocess.run( + "osascript -e 'tell application \"PyCharm CE\" to quit'", + shell=True, + check=False) + print('Waiting for GUI PyCharm to quit...', flush=True) + process.wait() _run_idea_inspections_cached(cachepath=cachepath, filenames=filenames, diff --git a/tools/efrotools/statictest.py b/tools/efrotools/statictest.py index c2ed794b..8a9456a0 100644 --- a/tools/efrotools/statictest.py +++ b/tools/efrotools/statictest.py @@ -29,6 +29,7 @@ class StaticTestFile: def __init__(self, filename: str): # pylint: disable=global-statement, invalid-name + # pylint: disable=consider-using-with global _tempdir, _nextfilenum # pylint: enable=global-statement, invalid-name