diff --git a/.efrocachemap b/.efrocachemap index 160b35c7..bae283d1 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -4132,16 +4132,16 @@ "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/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/c8/9c/ea45597789b0b0ef00b3868dfd4b", - "build/prefab/linux-server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/87/46/d99ad97bed02f7dbd8a22acfddea", - "build/prefab/linux/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/0b/22/78866aed7517959f4e340318cc7c", - "build/prefab/linux/release/ballisticacore": "https://files.ballistica.net/cache/ba1/88/87/2a6cbc9558ff7a8244b77419055b", - "build/prefab/mac-server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/06/72/e400773b3e2765f764192acd67ac", - "build/prefab/mac-server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/41/c7/c9aafa0d4f9c83561f355495f50b", - "build/prefab/mac/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/db/a1/a5c09c8ee119acd9276862726fb1", - "build/prefab/mac/release/ballisticacore": "https://files.ballistica.net/cache/ba1/ba/5f/4043991774fe98e496945c3c85fd", - "build/prefab/windows-server/debug/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/a8/8f/953a7085c724a49ac8598819c09b", - "build/prefab/windows-server/release/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/30/95/822b29da86c0f8b0196f18723fe3", - "build/prefab/windows/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/1f/9c/61ccc896b0c6f74910af629fc6ff", - "build/prefab/windows/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/d6/c2/0708d5b471ad22ccee64de7a61e3" + "build/prefab/linux-server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/c3/0a/88aac36a9fc3fd22655330620f94", + "build/prefab/linux-server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/88/24/292978d4c30e1ecd870eed435d28", + "build/prefab/linux/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/e8/f9/b7a3e4e3f4ff262804c14747ad11", + "build/prefab/linux/release/ballisticacore": "https://files.ballistica.net/cache/ba1/3c/55/c1005d5da5b7fc2fec10c4c5a5ba", + "build/prefab/mac-server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/68/4f/8a47768eaac63d56706489076fe9", + "build/prefab/mac-server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/5f/15/231c0b5530fb193bf43d1d424c55", + "build/prefab/mac/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/f7/c6/de3932a656e27f7f21a54380f62c", + "build/prefab/mac/release/ballisticacore": "https://files.ballistica.net/cache/ba1/b6/d7/d00e68f088c6ff72963231730648", + "build/prefab/windows-server/debug/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/83/93/99e8eb67cdaa7f64ccb66ba7fa9e", + "build/prefab/windows-server/release/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/d1/05/b7b47978e93db2f65cf172ff28b3", + "build/prefab/windows/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/74/f2/a754439742dd96c00aa57b6b036c", + "build/prefab/windows/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/f2/91/7e1fd943727c3bd78e48f405b6c5" } \ No newline at end of file diff --git a/.idea/dictionaries/ericf.xml b/.idea/dictionaries/ericf.xml index d4fe14f7..f2845589 100644 --- a/.idea/dictionaries/ericf.xml +++ b/.idea/dictionaries/ericf.xml @@ -89,6 +89,7 @@ archs argh argparse + argtypes argval armeabi arraymodule @@ -360,6 +361,7 @@ configparser configpath connectattr + conout containerwidget contentmanager contextlib @@ -627,6 +629,7 @@ fdata fdesc fdict + fdout fecfc feedparser ffaeff @@ -884,6 +887,7 @@ homebook homebrew hometest + hout howtoplay hpos hscrollwidget @@ -1100,6 +1104,7 @@ loofa loosey losecount + lpdword lpos lprop lsbo @@ -1360,6 +1365,7 @@ palmos pandoc pandroid + parallelized parsermodule partyqueue partyval diff --git a/CHANGELOG.md b/CHANGELOG.md index 424485c4..2c5bb2cc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,9 @@ +### 1.5.1 (20062) +- Windows server now properly displays color when run by double clicking the .bat file. +- Misc bug fixes. + ### 1.5.0 (20001) +- This build contains about 2 years worth of MAJOR internal refactoring to prepare for the future of BombSquad. As a player this should not (yet) look different from 1.4, but for modders there is a lot new. See the rest of these change entries or visit ballistica.net for more info. - Ported the entire scripting layer from Python 2 to to Python 3 (currently at 3.7, and I intend to keep this updated to the latest widely-available release). There's some significant changes going from python 2 to 3 (new print statement, string behavior, etc), but these are well documented online, so please read up as needed. This should provide us some nice benefits and future-proofs everything. (my janky 2.7 custom Python builds were getting a little long in the tooth). - Refactored all script code to be PEP8 compliant (Python coding standards). Basically, this means that stuff that was camel-case (fooBar) is now a single word or underscores (foobar / foo_bar). There are a few minor exceptions such as existing resource and media filenames, but in general old code can be ported by taking a pass through and killing the camel-case. I know this is a bit of a pain in the ass, but it'll let us use things like Pylint and just be more consistent with the rest of the Python world. - On a related note, I'm now using 'yapf' to keep my Python code formatted nicely (using pep8 style); I'd recommend checking it out if you're doing a lot of scripting as its a great time-saver. @@ -48,7 +53,7 @@ - bs.NodeActor is no more (it can simply be replaced with ba.Actor()) - bs.playMusic() is now ba.setmusic() which better fits its functionality (it sometimes just continues playing or stops playing). - The bs.Vector class is no more; in its place is a shiny new ba.Vec3 which is implemented internally in C++ so its nice and speedy. Will probably update certain things like vector node attrs to support this class in the future since it makes vector math nice and convenient. -- Ok you get the point.. +- Ok you get the point.. see ballistica.net for more info on these changes. ### 1.4.155 (14377) - Added protection against a repeated-input attack in lobbies. diff --git a/assets/src/ba_data/python/_ba.py b/assets/src/ba_data/python/_ba.py index a12c6430..13993284 100644 --- a/assets/src/ba_data/python/_ba.py +++ b/assets/src/ba_data/python/_ba.py @@ -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) -# SOURCES_HASH=188869443842417703663502065018427831709 +# SOURCES_HASH=328357141536767746382612764132666300753 # I'm sorry Pylint. I know this file saddens you. Be strong. # pylint: disable=useless-suppression diff --git a/assets/src/ba_data/python/ba/_servermode.py b/assets/src/ba_data/python/ba/_servermode.py index a8c75328..47beb6c9 100644 --- a/assets/src/ba_data/python/ba/_servermode.py +++ b/assets/src/ba_data/python/ba/_servermode.py @@ -321,9 +321,11 @@ class ServerController: if self._first_run: curtimestr = time.strftime('%c') - print(f'{Clr.BLD}{Clr.BLU}{_ba.appnameupper()} {app.version}' - f' ({app.build_number})' - f' entering server-mode {curtimestr}{Clr.RST}') + _ba.log( + f'{Clr.BLD}{Clr.BLU}{_ba.appnameupper()} {app.version}' + f' ({app.build_number})' + f' entering server-mode {curtimestr}{Clr.RST}', + to_server=False) if sessiontype is FreeForAllSession: appcfg['Free-for-All Playlist Selection'] = self._playlist_name @@ -354,6 +356,7 @@ class ServerController: # And here we go. _ba.new_host_session(sessiontype) - if not self._ran_access_check: + # Run an access check if we're trying to make a public party. + if not self._ran_access_check and self._config.party_is_public: self._run_access_check() self._ran_access_check = True diff --git a/assets/src/ba_data/python/bastd/ui/gather.py b/assets/src/ba_data/python/bastd/ui/gather.py index 288f3f62..98b122a0 100644 --- a/assets/src/ba_data/python/bastd/ui/gather.py +++ b/assets/src/ba_data/python/bastd/ui/gather.py @@ -1720,6 +1720,10 @@ class GatherWindow(ba.Window): # Ignore harmless errors. if exc.errno == errno.EHOSTUNREACH: pass + elif exc.errno == 10051: + # Windows 'a socket operation was attempted + # to an unreachable network' error. + pass elif exc.errno == errno.EADDRNOTAVAIL: if self._port == 0: # This has happened. Ignore. diff --git a/assets/src/server/README.txt b/assets/src/server/README.txt index afc5f770..674c999a 100644 --- a/assets/src/server/README.txt +++ b/assets/src/server/README.txt @@ -2,8 +2,8 @@ To run this, simply cd into this directory and run ./ballisticacore_server (on mac or linux) or launch_ballisticacore_server.bat (on windows). You'll need to open a UDP port (43210 by default) so that the world can communicate with your server. -You can configure your server by creating a config.yaml file -(see config_template.yaml as a starting point) +You can configure your server by editing the config.yaml file. +(if you only see config_template.yaml, you can copy/rename that to config.yaml) Platform-Specific Notes: @@ -16,7 +16,7 @@ Mac: Linux (x86_64): - Server binaries are currently compiled against Ubuntu 18 LTS. They depend on Python 3.7, so you may need to install that. - This should just be something like "sudo apt install python3" + This should just be something like "sudo apt install python3.7" Raspberry Pi: - The server binary was compiled on a Raspberry Pi 4 running Raspbian Buster. @@ -25,7 +25,8 @@ Windows: - You may need to run dist/Vc_redist.x64.exe to install support libraries if the app quits with complaints of missing DLLs -Please give me a holler at support@froemling.net if you run into any problems. +Please give me a holler at support@froemling.net or check out +ballistica.net/wiki if you run into any problems. Enjoy! -Eric diff --git a/assets/src/server/launch_ballisticacore_server.bat b/assets/src/server/launch_ballisticacore_server.bat index 134ebd52..a5315816 100644 --- a/assets/src/server/launch_ballisticacore_server.bat +++ b/assets/src/server/launch_ballisticacore_server.bat @@ -1,2 +1,4 @@ -:: All this does is run the ballisticacore_server script with the included python interpreter -dist\\python.exe ballisticacore_server.py +:: Simply run the ballisticacore_server.py script with the bundled +:: python interpreter. Run in opt-mode so we pick up all the +:: bundled .opt-1.pyc files too. +dist\\python.exe -O ballisticacore_server.py diff --git a/docs/ba_module.md b/docs/ba_module.md index 15c8d134..aad68617 100644 --- a/docs/ba_module.md +++ b/docs/ba_module.md @@ -1,5 +1,5 @@ -

last updated on 2020-06-08 for Ballistica version 1.5.0 build 20060

+

last updated on 2020-06-09 for Ballistica version 1.5.1 build 20062

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/tools/efro/terminal.py b/tools/efro/terminal.py index 727331f3..7f8acb8c 100644 --- a/tools/efro/terminal.py +++ b/tools/efro/terminal.py @@ -27,7 +27,7 @@ from enum import Enum, unique from typing import TYPE_CHECKING if TYPE_CHECKING: - pass + from typing import Any @unique @@ -85,6 +85,76 @@ class TerminalColor(Enum): STRONG_BG_WHITE = '\033[107m' +def _default_color_enabled() -> bool: + """Return whether we should enable ANSI color codes by default.""" + import platform + + # If we're not attached to a terminal, go with no-color. + if not sys.__stdout__.isatty(): + return False + + # On windows, try to enable ANSI color mode. + if platform.system() == 'Windows': + return _windows_enable_color() + + # We seem to be a terminal with color support; let's do it! + return True + + +# noinspection PyPep8Naming +def _windows_enable_color() -> bool: + """Attempt to enable ANSI color on windows terminal; return success.""" + # pylint: disable=invalid-name, import-error, undefined-variable + # Pulled from: https://bugs.python.org/issue30075 + import msvcrt + import ctypes + from ctypes import wintypes + kernel32 = ctypes.WinDLL('kernel32', use_last_error=True) # type: ignore + + ERROR_INVALID_PARAMETER = 0x0057 + ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004 + + def _check_bool(result: Any, _func: Any, args: Any) -> Any: + if not result: + raise ctypes.WinError(ctypes.get_last_error()) # type: ignore + return args + + LPDWORD = ctypes.POINTER(wintypes.DWORD) + kernel32.GetConsoleMode.errcheck = _check_bool + kernel32.GetConsoleMode.argtypes = (wintypes.HANDLE, LPDWORD) + kernel32.SetConsoleMode.errcheck = _check_bool + kernel32.SetConsoleMode.argtypes = (wintypes.HANDLE, wintypes.DWORD) + + def set_conout_mode(new_mode: int, mask: int = 0xffffffff) -> int: + # don't assume StandardOutput is a console. + # open CONOUT$ instead + fdout = os.open('CONOUT$', os.O_RDWR) + try: + hout = msvcrt.get_osfhandle(fdout) + old_mode = wintypes.DWORD() + kernel32.GetConsoleMode(hout, ctypes.byref(old_mode)) + mode = (new_mode & mask) | (old_mode.value & ~mask) + kernel32.SetConsoleMode(hout, mode) + return old_mode.value + finally: + os.close(fdout) + + def enable_vt_mode() -> int: + mode = mask = ENABLE_VIRTUAL_TERMINAL_PROCESSING + try: + return set_conout_mode(mode, mask) + except WindowsError as exc: + if exc.winerror == ERROR_INVALID_PARAMETER: + raise NotImplementedError + raise + + try: + enable_vt_mode() + return True + except NotImplementedError: + return False + + class Clr: """Convenience class for color terminal output. @@ -96,7 +166,7 @@ class Clr: """ _envval = os.environ.get('EFRO_TERMCOLORS') color_enabled = (True if _envval == '1' else - False if _envval == '0' else sys.__stdout__.isatty()) + False if _envval == '0' else _default_color_enabled()) if color_enabled: # Styles