Work on error/crash reporting

This commit is contained in:
Eric Froemling 2020-06-25 20:27:15 -07:00
parent 9a12f02689
commit 6301b8ed0c
19 changed files with 120 additions and 66 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/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",
"build/prefab/linux-server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/4d/d2/45d06a8dfcde71da3200fd4d2821",
"build/prefab/linux-server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/38/87/34f9bf38be66b158c9a53536dc41",
"build/prefab/linux/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/26/59/925cf3b362cde408b96f78fd7b54",
"build/prefab/linux/release/ballisticacore": "https://files.ballistica.net/cache/ba1/ec/ad/0650df6bd220bc24ace2817098e8",
"build/prefab/mac-server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/12/89/ec265516675eccf129704a350730",
"build/prefab/mac-server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/0b/72/2afc2855b5f258849c7dc3fda768",
"build/prefab/mac/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/02/3b/5c9c860eee9be52abe1991534470",
"build/prefab/mac/release/ballisticacore": "https://files.ballistica.net/cache/ba1/fb/24/e19eca2f233d1f368e19cd3aa2ff",
"build/prefab/windows-server/debug/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/db/fa/5c3fb5069c67a71808927e0bd09e",
"build/prefab/windows-server/release/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/b3/32/09227cb81f307f0b30978c97b383",
"build/prefab/windows/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/ea/4d/df0cc0ef2649bd8e3fb8ffd658ba",
"build/prefab/windows/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/69/23/69b46627e812ff279bf761daf309"
"build/prefab/linux-server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/83/b0/c0963abb0e6f5628742e1de7b890",
"build/prefab/linux-server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/6a/63/fe355b556462b609f26cebc4a140",
"build/prefab/linux/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/68/0a/de33d78be9b5f7a31af4f5181d43",
"build/prefab/linux/release/ballisticacore": "https://files.ballistica.net/cache/ba1/4c/4e/a08641d6e81bbca74c24bf364f59",
"build/prefab/mac-server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/f7/b1/8648ef7e0060d0b1b3716893d389",
"build/prefab/mac-server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/41/b5/a5233e4efdf0420f43759e2c9f8e",
"build/prefab/mac/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/f6/62/ac74aa6cb053cdd0486826d580f1",
"build/prefab/mac/release/ballisticacore": "https://files.ballistica.net/cache/ba1/f0/21/817d17de9b85320710e57b3e8882",
"build/prefab/windows-server/debug/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/52/d6/2ba38ece384d512820ef64c8e748",
"build/prefab/windows-server/release/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/06/44/6daa364334ae5f7ac23ad565cd79",
"build/prefab/windows/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/b1/28/6ceb93f662ea36958b573ea6e761",
"build/prefab/windows/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/b4/34/81b1bb50eece76cfa2163a9fdcba"
}

View File

@ -15,6 +15,7 @@
<w>aarch</w>
<w>abcdefghijklmnopqrstuvwxyz</w>
<w>abeb</w>
<w>abishort</w>
<w>abot</w>
<w>abtn</w>
<w>accesstime</w>
@ -433,6 +434,7 @@
<w>daynum</w>
<w>dayoffset</w>
<w>dbapi</w>
<w>dbase</w>
<w>dbpath</w>
<w>dcls</w>
<w>dcmake</w>
@ -1046,6 +1048,7 @@
<w>lfval</w>
<w>libcrypto</w>
<w>libegl</w>
<w>libext</w>
<w>libgen</w>
<w>libinst</w>
<w>liblzma</w>
@ -2087,6 +2090,7 @@
<w>unranked</w>
<w>unstaged</w>
<w>unstripped</w>
<w>unstrl</w>
<w>unsubscriptable</w>
<w>untracked</w>
<w>upcase</w>

View File

@ -73,7 +73,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 serverput
from ba._netutils import master_server_post
from ba._enums import TimeType
app = _ba.app
app.log_have_new = True
@ -111,7 +111,7 @@ def handle_log() -> None:
app.log_have_new = False
_ba.mark_log_sent()
serverput('bsLog', info, response)
master_server_post('bsLog', info, response)
app.log_upload_timer_started = True
@ -138,7 +138,7 @@ def handle_leftover_log_file() -> None:
"""Handle an un-uploaded log from a previous run."""
try:
import json
from ba._netutils import serverput
from ba._netutils import master_server_post
if os.path.exists(_ba.get_log_file_path()):
with open(_ba.get_log_file_path()) as infile:
@ -159,7 +159,7 @@ def handle_leftover_log_file() -> None:
# killed it since. ¯\_(ツ)_/¯
pass
serverput('bsLog', info, response)
master_server_post('bsLog', info, response)
else:
# If they don't want logs uploaded just kill it.
os.remove(_ba.get_log_file_path())

View File

@ -114,8 +114,6 @@ class ServerCallThread(threading.Thread):
try:
self._data = _general.utf8_all(self._data)
_ba.set_thread_name('BA_ServerCallThread')
# Seems pycharm doesn't know about urllib.parse.
parse = urllib.parse
if self._request_type == 'get':
response = urllib.request.urlopen(
@ -181,7 +179,7 @@ class ServerCallThread(threading.Thread):
from_other_thread=True)
def serverget(
def master_server_get(
request: str,
data: Dict[str, Any],
callback: Optional[ServerCallbackType] = None,
@ -190,7 +188,7 @@ def serverget(
ServerCallThread(request, 'get', data, callback, response_type).start()
def serverput(
def master_server_post(
request: str,
data: Dict[str, Any],
callback: Optional[ServerCallbackType] = None,

View File

@ -204,8 +204,8 @@ class ServerController:
def _run_access_check(self) -> None:
"""Check with the master server to see if we're likely joinable."""
from ba._netutils import serverget
serverget(
from ba._netutils import master_server_get
master_server_get(
'bsAccessCheck',
{
'port': _ba.get_game_port(),

View File

@ -53,7 +53,8 @@ from ba._messages import PlayerProfilesChangedMessage
from ba._meta import get_game_types
from ba._multiteamsession import DEFAULT_TEAM_COLORS, DEFAULT_TEAM_NAMES
from ba._music import do_play_music
from ba._netutils import serverget, serverput, get_ip_address_type
from ba._netutils import (master_server_get, master_server_post,
get_ip_address_type)
from ba._powerup import get_default_powerup_distribution
from ba._profile import (get_player_profile_colors, get_player_profile_icon,
get_player_colors)

View File

@ -41,7 +41,7 @@ class AccountViewerWindow(popup.PopupWindow):
position: Tuple[float, float] = (0.0, 0.0),
scale: float = None,
offset: Tuple[float, float] = (0.0, 0.0)):
from ba.internal import is_browser_likely_available, serverget
from ba.internal import is_browser_likely_available, master_server_get
self._account_id = account_id
self._profile_id = profile_id
@ -124,12 +124,12 @@ class AccountViewerWindow(popup.PopupWindow):
ba.containerwidget(edit=self.root_widget,
cancel_button=self._cancel_button)
serverget('bsAccountInfo', {
master_server_get('bsAccountInfo', {
'buildNumber': ba.app.build_number,
'accountID': self._account_id,
'profileID': self._profile_id
},
callback=ba.WeakCall(self._on_query_response))
callback=ba.WeakCall(self._on_query_response))
def popup_menu_selected_choice(self, window: popup.PopupMenu,
choice: str) -> None:

View File

@ -1725,14 +1725,14 @@ class GatherWindow(ba.Window):
self._rebuild_public_party_list()
def _do_internet_status_check(self) -> None:
from ba.internal import serverget
from ba.internal import master_server_get
ba.textwidget(edit=self._internet_host_status_text,
color=(1, 1, 0),
text=ba.Lstr(resource=self._r +
'.partyStatusCheckingText'))
serverget('bsAccessCheck', {'b': ba.app.build_number},
callback=ba.WeakCall(
self._on_public_party_accessible_response))
master_server_get('bsAccessCheck', {'b': ba.app.build_number},
callback=ba.WeakCall(
self._on_public_party_accessible_response))
def _on_start_internet_advertizing_press(self) -> None:
from bastd.ui import account
@ -1843,7 +1843,7 @@ class GatherWindow(ba.Window):
def _access_check_update(self, t_addr: ba.Widget, t_accessible: ba.Widget,
t_accessible_extra: ba.Widget) -> None:
from ba.internal import serverget
from ba.internal import master_server_get
# If we don't have an outstanding query, start one..
assert self._doing_access_check is not None
@ -1854,8 +1854,9 @@ class GatherWindow(ba.Window):
self._t_addr = t_addr
self._t_accessible = t_accessible
self._t_accessible_extra = t_accessible_extra
serverget('bsAccessCheck', {'b': ba.app.build_number},
callback=ba.WeakCall(self._on_accessible_response))
master_server_get('bsAccessCheck', {'b': ba.app.build_number},
callback=ba.WeakCall(
self._on_accessible_response))
def _on_accessible_response(self, data: Optional[Dict[str, Any]]) -> None:
t_addr = self._t_addr

View File

@ -523,7 +523,7 @@ class GetCurrencyWindow(ba.Window):
def _purchase(self, item: str) -> None:
from bastd.ui import account
from bastd.ui import appinvite
from ba.internal import serverget
from ba.internal import master_server_get
if item == 'app_invite':
if _ba.get_account_state() != 'signed_in':
account.show_sign_in_prompt()
@ -533,14 +533,15 @@ class GetCurrencyWindow(ba.Window):
# here we ping the server to ask if it's valid for us to
# purchase this.. (better to fail now than after we've paid locally)
app = ba.app
serverget('bsAccountPurchaseCheck', {
master_server_get('bsAccountPurchaseCheck', {
'item': item,
'platform': app.platform,
'subplatform': app.subplatform,
'version': app.version,
'buildNumber': app.build_number
},
callback=ba.WeakCall(self._purchase_check_result, item))
callback=ba.WeakCall(self._purchase_check_result,
item))
def _purchase_check_result(self, item: str,
result: Optional[Dict[str, Any]]) -> None:

View File

@ -40,7 +40,7 @@ class ProfileUpgradeWindow(ba.Window):
def __init__(self,
edit_profile_window: EditProfileWindow,
transition: str = 'in_right'):
from ba.internal import serverget
from ba.internal import master_server_get
self._r = 'editProfileWindow'
self._width = 680
@ -138,11 +138,11 @@ class ProfileUpgradeWindow(ba.Window):
else:
self._tickets_text = None
serverget('bsGlobalProfileCheck', {
master_server_get('bsGlobalProfileCheck', {
'name': self._name,
'b': ba.app.build_number
},
callback=ba.WeakCall(self._profile_check_result))
callback=ba.WeakCall(self._profile_check_result))
self._cost = _ba.get_account_misc_read_val('price.global_profile', 500)
self._status: Optional[str] = 'waiting'
self._update_timer = ba.Timer(1.0,

View File

@ -39,7 +39,7 @@ class AdvancedSettingsWindow(ba.Window):
transition: str = 'in_right',
origin_widget: ba.Widget = None):
# pylint: disable=too-many-statements
from ba.internal import serverget
from ba.internal import master_server_get
app = ba.app
@ -151,8 +151,8 @@ class AdvancedSettingsWindow(ba.Window):
timetype=ba.TimeType.REAL)
# Fetch the list of completed languages.
serverget('bsLangGetCompleted', {'b': app.build_number},
callback=ba.WeakCall(self._completed_langs_cb))
master_server_get('bsLangGetCompleted', {'b': app.build_number},
callback=ba.WeakCall(self._completed_langs_cb))
def _update_lang_status(self) -> None:
if self._complete_langs_list is not None:

View File

@ -717,7 +717,7 @@ class GamepadSettingsWindow(ba.Window):
transition='in_left').get_root_widget())
def _save(self) -> None:
from ba.internal import (serverput, get_input_device_config,
from ba.internal import (master_server_post, get_input_device_config,
get_input_map_hash, should_submit_debug_info)
ba.containerwidget(edit=self._root_widget,
transition=self._transition_out)
@ -742,7 +742,7 @@ class GamepadSettingsWindow(ba.Window):
# generate more defaults in the future.
inputhash = get_input_map_hash(self._input)
if should_submit_debug_info():
serverput(
master_server_post(
'controllerConfig', {
'ua': ba.app.user_agent_string,
'b': ba.app.build_number,

View File

@ -230,7 +230,7 @@ class ConfigKeyboardWindow(ba.Window):
def _save(self) -> None:
from bastd.ui.settings.controls import ControlsSettingsWindow
from ba.internal import (get_input_device_config,
should_submit_debug_info, serverput)
should_submit_debug_info, master_server_post)
ba.containerwidget(edit=self._root_widget, transition='out_right')
ba.playsound(ba.getsound('gunCocking'))
@ -246,7 +246,7 @@ class ConfigKeyboardWindow(ba.Window):
# If we're allowed to phone home, send this config so we can generate
# more defaults in the future.
if should_submit_debug_info():
serverput(
master_server_post(
'controllerConfig', {
'ua': ba.app.user_agent_string,
'name': self._name,

View File

@ -56,11 +56,15 @@ class SpecialOfferWindow(ba.Window):
real_price = _ba.get_price('pro' if offer['item'] ==
'pro_fullprice' else 'pro_sale')
if real_price is None and ba.app.debug_build:
print('TEMP FAKING REAL PRICE')
print('NOTE: Faking prices for debug build.')
real_price = '$1.23'
zombie = real_price is None
elif isinstance(offer['price'], str): # a string price implies IAP id
elif isinstance(offer['price'], str):
# (a string price implies IAP id)
real_price = _ba.get_price(offer['price'])
if real_price is None and ba.app.debug_build:
print('NOTE: Faking price for debug build.')
real_price = '$1.23'
zombie = real_price is None
else:
real_price = None
@ -109,16 +113,25 @@ class SpecialOfferWindow(ba.Window):
self._is_bundle_sale = True
original_price = _ba.get_account_misc_read_val(
'price.' + self._offer_item, 9999)
new_price = offer['price']
tchar = ba.charstr(SpecialChar.TICKET)
original_price_str = tchar + str(original_price)
new_price_str = tchar + str(new_price)
percent_off = int(
round(100.0 - (float(new_price) / original_price) * 100.0))
percent_off_text = ' ' + ba.Lstr(
resource='store.salePercentText').evaluate().replace(
'${PERCENT}', str(percent_off))
# For pure ticket prices we can show a percent-off.
if isinstance(offer['price'], int):
new_price = offer['price']
tchar = ba.charstr(SpecialChar.TICKET)
original_price_str = tchar + str(original_price)
new_price_str = tchar + str(new_price)
percent_off = int(
round(100.0 -
(float(new_price) / original_price) * 100.0))
percent_off_text = ' ' + ba.Lstr(
resource='store.salePercentText').evaluate().replace(
'${PERCENT}', str(percent_off))
else:
original_price_str = new_price_str = '?'
percent_off_text = ''
except Exception:
print(f'Offer: {offer}')
ba.print_exception('Error setting up special-offer')
original_price_str = new_price_str = '?'
percent_off_text = ''
@ -211,8 +224,8 @@ class SpecialOfferWindow(ba.Window):
total_worth_item = offer.get('valueItem', None)
if total_worth_item is not None:
price = _ba.get_price(total_worth_item)
assert price is not None
total_worth_price = get_clean_price(price)
total_worth_price = (get_clean_price(price)
if price is not None else None)
if total_worth_price is not None:
total_worth_text = ba.Lstr(resource='store.totalWorthText',
subs=[('${TOTAL_WORTH}',
@ -246,7 +259,7 @@ class SpecialOfferWindow(ba.Window):
text=new_price_str)
# Add ticket button only if this is ticket-purchasable.
if offer['price'] is not None and isinstance(offer['price'], int):
if isinstance(offer.get('price'), int):
self._get_tickets_button = ba.buttonwidget(
parent=self._root_widget,
position=(self._width - 125, self._height - 68),

View File

@ -449,13 +449,13 @@ class StoreBrowserWindow(ba.Window):
def _do_purchase_check(self,
item: str,
is_ticket_purchase: bool = False) -> None:
from ba.internal import serverget
from ba.internal import master_server_get
# Here we ping the server to ask if it's valid for us to
# purchase this. Better to fail now than after we've
# paid locally.
app = ba.app
serverget(
master_server_get(
'bsAccountPurchaseCheck',
{
'item': item,

View File

@ -1,5 +1,5 @@
<!-- THIS FILE IS AUTO GENERATED; DO NOT EDIT BY HAND -->
<h4><em>last updated on 2020-06-24 for Ballistica version 1.5.12 build 20088</em></h4>
<h4><em>last updated on 2020-06-25 for Ballistica version 1.5.12 build 20089</em></h4>
<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>
<hr>

View File

@ -616,3 +616,38 @@ def lazybuild() -> None:
batools.build.lazybuild(target, category, command)
except subprocess.CalledProcessError as exc:
raise CleanError(exc)
def android_archive_unstripped_libs() -> None:
"""Copy libs to a build archive."""
import subprocess
from pathlib import Path
from efro.error import CleanError
from efro.terminal import Clr
if len(sys.argv) != 4:
raise CleanError('Expected 2 args; src-dir and dst-dir')
src = Path(sys.argv[2])
dst = Path(sys.argv[3])
if dst.exists():
subprocess.run(['rm', '-rf', dst], check=True)
dst.mkdir(parents=True, exist_ok=True)
if not src.is_dir():
raise CleanError(f"Source dir not found: '{src}'")
libname = 'libmain'
libext = '.so'
for abi, abishort in [
('armeabi-v7a', 'arm'),
('arm64-v8a', 'arm64'),
('x86', 'x86'),
('x86_64', 'x86-64'),
]:
srcpath = Path(src, abi, libname + libext)
dstname = f'{libname}_{abishort}{libext}'
dstpath = Path(dst, dstname)
if srcpath.exists():
print(f'Archiving unstripped library: {Clr.BLD}{dstname}{Clr.RST}')
subprocess.run(['cp', srcpath, dstpath], check=True)
subprocess.run(['tar', '-zcf', dstname + '.tgz', dstname],
cwd=dst,
check=True)
subprocess.run(['rm', dstpath], check=True)

View File

@ -79,8 +79,9 @@ def snippets_main(globs: Dict[str, Any]) -> None:
exc.pretty_print()
sys.exit(1)
else:
print('Unknown snippets command: "' + sys.argv[1] + '"',
file=sys.stderr)
print(
f'{Clr.RED}Unknown snippets command: "{sys.argv[1]}"{Clr.RST}',
file=sys.stderr)
retval = 255
if show_help:

View File

@ -54,7 +54,7 @@ from batools.snippets import (
python_gather, capitalize, efrocache_update, efrocache_get,
get_modern_make, warm_start_asset_build, update_docs_md, list_pip_reqs,
install_pip_reqs, checkenv, ensure_prefab_platform, prefab_run_var,
make_prefab, update_makebob, lazybuild)
make_prefab, update_makebob, lazybuild, android_archive_unstripped_libs)
# pylint: enable=unused-import
if TYPE_CHECKING: