diff --git a/.efrocachemap b/.efrocachemap
index 719098f5..fbd821e4 100644
--- a/.efrocachemap
+++ b/.efrocachemap
@@ -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"
}
\ No newline at end of file
diff --git a/.idea/dictionaries/ericf.xml b/.idea/dictionaries/ericf.xml
index d50ebee8..9d6534a6 100644
--- a/.idea/dictionaries/ericf.xml
+++ b/.idea/dictionaries/ericf.xml
@@ -15,6 +15,7 @@
aarch
abcdefghijklmnopqrstuvwxyz
abeb
+ abishort
abot
abtn
accesstime
@@ -433,6 +434,7 @@
daynum
dayoffset
dbapi
+ dbase
dbpath
dcls
dcmake
@@ -1046,6 +1048,7 @@
lfval
libcrypto
libegl
+ libext
libgen
libinst
liblzma
@@ -2087,6 +2090,7 @@
unranked
unstaged
unstripped
+ unstrl
unsubscriptable
untracked
upcase
diff --git a/assets/src/ba_data/python/ba/_apputils.py b/assets/src/ba_data/python/ba/_apputils.py
index dcecd42c..d98cea00 100644
--- a/assets/src/ba_data/python/ba/_apputils.py
+++ b/assets/src/ba_data/python/ba/_apputils.py
@@ -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())
diff --git a/assets/src/ba_data/python/ba/_netutils.py b/assets/src/ba_data/python/ba/_netutils.py
index 08a41f82..ea138d01 100644
--- a/assets/src/ba_data/python/ba/_netutils.py
+++ b/assets/src/ba_data/python/ba/_netutils.py
@@ -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,
diff --git a/assets/src/ba_data/python/ba/_servermode.py b/assets/src/ba_data/python/ba/_servermode.py
index 47beb6c9..653a1510 100644
--- a/assets/src/ba_data/python/ba/_servermode.py
+++ b/assets/src/ba_data/python/ba/_servermode.py
@@ -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(),
diff --git a/assets/src/ba_data/python/ba/internal.py b/assets/src/ba_data/python/ba/internal.py
index 958a2580..4ac5d01b 100644
--- a/assets/src/ba_data/python/ba/internal.py
+++ b/assets/src/ba_data/python/ba/internal.py
@@ -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)
diff --git a/assets/src/ba_data/python/bastd/ui/account/viewer.py b/assets/src/ba_data/python/bastd/ui/account/viewer.py
index 7bc137f9..5a61b9db 100644
--- a/assets/src/ba_data/python/bastd/ui/account/viewer.py
+++ b/assets/src/ba_data/python/bastd/ui/account/viewer.py
@@ -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:
diff --git a/assets/src/ba_data/python/bastd/ui/gather.py b/assets/src/ba_data/python/bastd/ui/gather.py
index 8edcdd24..a9b93207 100644
--- a/assets/src/ba_data/python/bastd/ui/gather.py
+++ b/assets/src/ba_data/python/bastd/ui/gather.py
@@ -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
diff --git a/assets/src/ba_data/python/bastd/ui/getcurrency.py b/assets/src/ba_data/python/bastd/ui/getcurrency.py
index b25457cb..429cd52b 100644
--- a/assets/src/ba_data/python/bastd/ui/getcurrency.py
+++ b/assets/src/ba_data/python/bastd/ui/getcurrency.py
@@ -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:
diff --git a/assets/src/ba_data/python/bastd/ui/profile/upgrade.py b/assets/src/ba_data/python/bastd/ui/profile/upgrade.py
index 86ccaf07..62cebcf0 100644
--- a/assets/src/ba_data/python/bastd/ui/profile/upgrade.py
+++ b/assets/src/ba_data/python/bastd/ui/profile/upgrade.py
@@ -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,
diff --git a/assets/src/ba_data/python/bastd/ui/settings/advanced.py b/assets/src/ba_data/python/bastd/ui/settings/advanced.py
index da5c35f3..f9205206 100644
--- a/assets/src/ba_data/python/bastd/ui/settings/advanced.py
+++ b/assets/src/ba_data/python/bastd/ui/settings/advanced.py
@@ -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:
diff --git a/assets/src/ba_data/python/bastd/ui/settings/gamepad.py b/assets/src/ba_data/python/bastd/ui/settings/gamepad.py
index 62545869..406bee3d 100644
--- a/assets/src/ba_data/python/bastd/ui/settings/gamepad.py
+++ b/assets/src/ba_data/python/bastd/ui/settings/gamepad.py
@@ -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,
diff --git a/assets/src/ba_data/python/bastd/ui/settings/keyboard.py b/assets/src/ba_data/python/bastd/ui/settings/keyboard.py
index 340a5446..407b4d56 100644
--- a/assets/src/ba_data/python/bastd/ui/settings/keyboard.py
+++ b/assets/src/ba_data/python/bastd/ui/settings/keyboard.py
@@ -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,
diff --git a/assets/src/ba_data/python/bastd/ui/specialoffer.py b/assets/src/ba_data/python/bastd/ui/specialoffer.py
index 6c9169e7..80c6bf20 100644
--- a/assets/src/ba_data/python/bastd/ui/specialoffer.py
+++ b/assets/src/ba_data/python/bastd/ui/specialoffer.py
@@ -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),
diff --git a/assets/src/ba_data/python/bastd/ui/store/browser.py b/assets/src/ba_data/python/bastd/ui/store/browser.py
index 59ad1d34..d8677e7b 100644
--- a/assets/src/ba_data/python/bastd/ui/store/browser.py
+++ b/assets/src/ba_data/python/bastd/ui/store/browser.py
@@ -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,
diff --git a/docs/ba_module.md b/docs/ba_module.md
index 90607238..4465d271 100644
--- a/docs/ba_module.md
+++ b/docs/ba_module.md
@@ -1,5 +1,5 @@
-
last updated on 2020-06-24 for Ballistica version 1.5.12 build 20088
+last updated on 2020-06-25 for Ballistica version 1.5.12 build 20089
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/batools/snippets.py b/tools/batools/snippets.py
index 7324cc21..57e11240 100644
--- a/tools/batools/snippets.py
+++ b/tools/batools/snippets.py
@@ -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)
diff --git a/tools/efrotools/snippets.py b/tools/efrotools/snippets.py
index a68005c4..da95b003 100644
--- a/tools/efrotools/snippets.py
+++ b/tools/efrotools/snippets.py
@@ -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:
diff --git a/tools/snippets b/tools/snippets
index 7a5d17eb..ebe46596 100755
--- a/tools/snippets
+++ b/tools/snippets
@@ -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: