mirror of
https://github.com/hypervortex/VH-Bombsquad-Modded-Server-Files
synced 2025-11-07 17:36:08 +00:00
532 lines
13 KiB
Python
532 lines
13 KiB
Python
# Released under the MIT License. See LICENSE for details.
|
|
#
|
|
"""Snippets of code for use by the internal layer.
|
|
|
|
History: originally the engine would dynamically compile/eval various Python
|
|
code from within C++ code, but the major downside there was that none of it
|
|
was type-checked so if names or arguments changed it would go unnoticed
|
|
until it broke at runtime. By instead defining such snippets here and then
|
|
capturing references to them all at launch it is possible to allow linting
|
|
and type-checking magic to happen and most issues will be caught immediately.
|
|
"""
|
|
# (most of these are self-explanatory)
|
|
# pylint: disable=missing-function-docstring
|
|
from __future__ import annotations
|
|
|
|
from typing import TYPE_CHECKING
|
|
|
|
import _ba
|
|
from ba import _internal
|
|
|
|
if TYPE_CHECKING:
|
|
from typing import Sequence, Any
|
|
import ba
|
|
|
|
|
|
def finish_bootstrapping() -> None:
|
|
"""Do final bootstrapping related bits."""
|
|
assert _ba.in_logic_thread()
|
|
|
|
# Ok, low level bootstrapping is done; time to get Python stuff started.
|
|
_ba.app.on_bootstrapping_completed()
|
|
|
|
|
|
def reset_to_main_menu() -> None:
|
|
"""Reset the game to the main menu gracefully."""
|
|
_ba.app.return_to_main_menu_session_gracefully()
|
|
|
|
|
|
def set_config_fullscreen_on() -> None:
|
|
"""The app has set fullscreen on its own and we should note it."""
|
|
_ba.app.config['Fullscreen'] = True
|
|
_ba.app.config.commit()
|
|
|
|
|
|
def set_config_fullscreen_off() -> None:
|
|
"""The app has set fullscreen on its own and we should note it."""
|
|
_ba.app.config['Fullscreen'] = False
|
|
_ba.app.config.commit()
|
|
|
|
|
|
def not_signed_in_screen_message() -> None:
|
|
from ba._language import Lstr
|
|
|
|
_ba.screenmessage(Lstr(resource='notSignedInErrorText'))
|
|
|
|
|
|
def connecting_to_party_message() -> None:
|
|
from ba._language import Lstr
|
|
|
|
_ba.screenmessage(
|
|
Lstr(resource='internal.connectingToPartyText'), color=(1, 1, 1)
|
|
)
|
|
|
|
|
|
def rejecting_invite_already_in_party_message() -> None:
|
|
from ba._language import Lstr
|
|
|
|
_ba.screenmessage(
|
|
Lstr(resource='internal.rejectingInviteAlreadyInPartyText'),
|
|
color=(1, 0.5, 0),
|
|
)
|
|
|
|
|
|
def connection_failed_message() -> None:
|
|
from ba._language import Lstr
|
|
|
|
_ba.screenmessage(
|
|
Lstr(resource='internal.connectionFailedText'), color=(1, 0.5, 0)
|
|
)
|
|
|
|
|
|
def temporarily_unavailable_message() -> None:
|
|
from ba._language import Lstr
|
|
|
|
_ba.playsound(_ba.getsound('error'))
|
|
_ba.screenmessage(
|
|
Lstr(resource='getTicketsWindow.unavailableTemporarilyText'),
|
|
color=(1, 0, 0),
|
|
)
|
|
|
|
|
|
def in_progress_message() -> None:
|
|
from ba._language import Lstr
|
|
|
|
_ba.playsound(_ba.getsound('error'))
|
|
_ba.screenmessage(
|
|
Lstr(resource='getTicketsWindow.inProgressText'), color=(1, 0, 0)
|
|
)
|
|
|
|
|
|
def error_message() -> None:
|
|
from ba._language import Lstr
|
|
|
|
_ba.playsound(_ba.getsound('error'))
|
|
_ba.screenmessage(Lstr(resource='errorText'), color=(1, 0, 0))
|
|
|
|
|
|
def purchase_not_valid_error() -> None:
|
|
from ba._language import Lstr
|
|
|
|
_ba.playsound(_ba.getsound('error'))
|
|
_ba.screenmessage(
|
|
Lstr(
|
|
resource='store.purchaseNotValidError',
|
|
subs=[('${EMAIL}', 'support@froemling.net')],
|
|
),
|
|
color=(1, 0, 0),
|
|
)
|
|
|
|
|
|
def purchase_already_in_progress_error() -> None:
|
|
from ba._language import Lstr
|
|
|
|
_ba.playsound(_ba.getsound('error'))
|
|
_ba.screenmessage(
|
|
Lstr(resource='store.purchaseAlreadyInProgressText'), color=(1, 0, 0)
|
|
)
|
|
|
|
|
|
def gear_vr_controller_warning() -> None:
|
|
from ba._language import Lstr
|
|
|
|
_ba.playsound(_ba.getsound('error'))
|
|
_ba.screenmessage(
|
|
Lstr(resource='usesExternalControllerText'), color=(1, 0, 0)
|
|
)
|
|
|
|
|
|
def uuid_str() -> str:
|
|
import uuid
|
|
|
|
return str(uuid.uuid4())
|
|
|
|
|
|
def orientation_reset_cb_message() -> None:
|
|
from ba._language import Lstr
|
|
|
|
_ba.screenmessage(
|
|
Lstr(resource='internal.vrOrientationResetCardboardText'),
|
|
color=(0, 1, 0),
|
|
)
|
|
|
|
|
|
def orientation_reset_message() -> None:
|
|
from ba._language import Lstr
|
|
|
|
_ba.screenmessage(
|
|
Lstr(resource='internal.vrOrientationResetText'), color=(0, 1, 0)
|
|
)
|
|
|
|
|
|
def on_app_pause() -> None:
|
|
_ba.app.on_app_pause()
|
|
|
|
|
|
def on_app_resume() -> None:
|
|
_ba.app.on_app_resume()
|
|
|
|
|
|
def launch_main_menu_session() -> None:
|
|
from bastd.mainmenu import MainMenuSession
|
|
|
|
_ba.new_host_session(MainMenuSession)
|
|
|
|
|
|
def language_test_toggle() -> None:
|
|
_ba.app.lang.setlanguage(
|
|
'Gibberish' if _ba.app.lang.language == 'English' else 'English'
|
|
)
|
|
|
|
|
|
def award_in_control_achievement() -> None:
|
|
_ba.app.ach.award_local_achievement('In Control')
|
|
|
|
|
|
def award_dual_wielding_achievement() -> None:
|
|
_ba.app.ach.award_local_achievement('Dual Wielding')
|
|
|
|
|
|
def play_gong_sound() -> None:
|
|
_ba.playsound(_ba.getsound('gong'))
|
|
|
|
|
|
def launch_coop_game(name: str) -> None:
|
|
_ba.app.launch_coop_game(name)
|
|
|
|
|
|
def purchases_restored_message() -> None:
|
|
from ba._language import Lstr
|
|
|
|
_ba.screenmessage(
|
|
Lstr(resource='getTicketsWindow.purchasesRestoredText'), color=(0, 1, 0)
|
|
)
|
|
|
|
|
|
def dismiss_wii_remotes_window() -> None:
|
|
call = _ba.app.ui.dismiss_wii_remotes_window_call
|
|
if call is not None:
|
|
call()
|
|
|
|
|
|
def unavailable_message() -> None:
|
|
from ba._language import Lstr
|
|
|
|
_ba.screenmessage(
|
|
Lstr(resource='getTicketsWindow.unavailableText'), color=(1, 0, 0)
|
|
)
|
|
|
|
|
|
def submit_analytics_counts(sval: str) -> None:
|
|
_internal.add_transaction({'type': 'ANALYTICS_COUNTS', 'values': sval})
|
|
_internal.run_transactions()
|
|
|
|
|
|
def set_last_ad_network(sval: str) -> None:
|
|
import time
|
|
|
|
_ba.app.ads.last_ad_network = sval
|
|
_ba.app.ads.last_ad_network_set_time = time.time()
|
|
|
|
|
|
def no_game_circle_message() -> None:
|
|
from ba._language import Lstr
|
|
|
|
_ba.screenmessage(Lstr(resource='noGameCircleText'), color=(1, 0, 0))
|
|
|
|
|
|
def google_play_purchases_not_available_message() -> None:
|
|
from ba._language import Lstr
|
|
|
|
_ba.screenmessage(
|
|
Lstr(resource='googlePlayPurchasesNotAvailableText'), color=(1, 0, 0)
|
|
)
|
|
|
|
|
|
def google_play_services_not_available_message() -> None:
|
|
from ba._language import Lstr
|
|
|
|
_ba.screenmessage(
|
|
Lstr(resource='googlePlayServicesNotAvailableText'), color=(1, 0, 0)
|
|
)
|
|
|
|
|
|
def empty_call() -> None:
|
|
pass
|
|
|
|
|
|
def level_icon_press() -> None:
|
|
print('LEVEL ICON PRESSED')
|
|
|
|
|
|
def trophy_icon_press() -> None:
|
|
print('TROPHY ICON PRESSED')
|
|
|
|
|
|
def coin_icon_press() -> None:
|
|
print('COIN ICON PRESSED')
|
|
|
|
|
|
def ticket_icon_press() -> None:
|
|
from bastd.ui.resourcetypeinfo import ResourceTypeInfoWindow
|
|
|
|
ResourceTypeInfoWindow(
|
|
origin_widget=_ba.get_special_widget('tickets_info_button')
|
|
)
|
|
|
|
|
|
def back_button_press() -> None:
|
|
_ba.back_press()
|
|
|
|
|
|
def friends_button_press() -> None:
|
|
print('FRIEND BUTTON PRESSED!')
|
|
|
|
|
|
def print_trace() -> None:
|
|
import traceback
|
|
|
|
print('Python Traceback (most recent call last):')
|
|
traceback.print_stack()
|
|
|
|
|
|
def toggle_fullscreen() -> None:
|
|
cfg = _ba.app.config
|
|
cfg['Fullscreen'] = not cfg.resolve('Fullscreen')
|
|
cfg.apply_and_commit()
|
|
|
|
|
|
def party_icon_activate(origin: Sequence[float]) -> None:
|
|
import weakref
|
|
from bastd.ui.party import PartyWindow
|
|
|
|
app = _ba.app
|
|
_ba.playsound(_ba.getsound('swish'))
|
|
|
|
# If it exists, dismiss it; otherwise make a new one.
|
|
if app.ui.party_window is not None and app.ui.party_window() is not None:
|
|
app.ui.party_window().close()
|
|
else:
|
|
app.ui.party_window = weakref.ref(PartyWindow(origin=origin))
|
|
|
|
|
|
def read_config() -> None:
|
|
_ba.app.read_config()
|
|
|
|
|
|
def ui_remote_press() -> None:
|
|
"""Handle a press by a remote device that is only usable for nav."""
|
|
from ba._language import Lstr
|
|
|
|
# Can be called without a context; need a context for getsound.
|
|
with _ba.Context('ui'):
|
|
_ba.screenmessage(
|
|
Lstr(resource='internal.controllerForMenusOnlyText'),
|
|
color=(1, 0, 0),
|
|
)
|
|
_ba.playsound(_ba.getsound('error'))
|
|
|
|
|
|
def quit_window() -> None:
|
|
from bastd.ui.confirm import QuitWindow
|
|
|
|
QuitWindow()
|
|
|
|
|
|
def remove_in_game_ads_message() -> None:
|
|
_ba.app.ads.do_remove_in_game_ads_message()
|
|
|
|
|
|
def telnet_access_request() -> None:
|
|
from bastd.ui.telnet import TelnetAccessRequestWindow
|
|
|
|
TelnetAccessRequestWindow()
|
|
|
|
|
|
def do_quit() -> None:
|
|
_ba.quit()
|
|
|
|
|
|
def shutdown() -> None:
|
|
_ba.app.on_app_shutdown()
|
|
|
|
|
|
def gc_disable() -> None:
|
|
import gc
|
|
|
|
gc.disable()
|
|
|
|
|
|
def device_menu_press(device: ba.InputDevice) -> None:
|
|
from bastd.ui.mainmenu import MainMenuWindow
|
|
|
|
in_main_menu = _ba.app.ui.has_main_menu_window()
|
|
if not in_main_menu:
|
|
_ba.set_ui_input_device(device)
|
|
_ba.playsound(_ba.getsound('swish'))
|
|
_ba.app.ui.set_main_menu_window(MainMenuWindow().get_root_widget())
|
|
|
|
|
|
def show_url_window(address: str) -> None:
|
|
from bastd.ui.url import ShowURLWindow
|
|
|
|
ShowURLWindow(address)
|
|
|
|
|
|
def party_invite_revoke(invite_id: str) -> None:
|
|
# If there's a confirm window up for joining this particular
|
|
# invite, kill it.
|
|
for winref in _ba.app.invite_confirm_windows:
|
|
win = winref()
|
|
if win is not None and win.ew_party_invite_id == invite_id:
|
|
_ba.containerwidget(
|
|
edit=win.get_root_widget(), transition='out_right'
|
|
)
|
|
|
|
import custom_hooks as chooks
|
|
def filter_chat_message(msg: str, client_id: int) -> str | None:
|
|
|
|
"""Intercept/filter chat messages.
|
|
|
|
Called for all chat messages while hosting.
|
|
Messages originating from the host will have clientID -1.
|
|
Should filter and return the string to be displayed, or return None
|
|
to ignore the message.
|
|
"""
|
|
if not msg or not msg.strip():
|
|
return None
|
|
import coinSystem
|
|
if (coinSystem.correctAnswer is not None) and (msg.lower() in coinSystem.correctAnswer):
|
|
coinSystem.checkAnswer(msg,client_id)
|
|
return msg
|
|
if True:
|
|
return chooks.filter_chat_message(msg,client_id)
|
|
else:
|
|
if True:
|
|
return msg
|
|
|
|
def on_client_request(ip):
|
|
chooks.on_join_request(ip)
|
|
|
|
def kick_vote_started(by:str,to:str) -> None:
|
|
"""
|
|
get account ids of who started kick vote for whom ,
|
|
do what ever u want logging to files , whatever.
|
|
"""
|
|
chooks.kick_vote_started(by,to)
|
|
|
|
def on_kicked(account_id:str) -> None:
|
|
chooks.on_kicked(account_id)
|
|
|
|
def on_kick_vote_end() -> None:
|
|
chooks.on_kick_vote_end()
|
|
|
|
def on_player_join(pb_id:str)-> None:
|
|
# not integrated yet
|
|
pass
|
|
|
|
def on_player_leave(pb_id:str)-> None:
|
|
# not integrated yet
|
|
pass
|
|
|
|
|
|
def local_chat_message(msg: str) -> None:
|
|
if (
|
|
_ba.app.ui.party_window is not None
|
|
and _ba.app.ui.party_window() is not None
|
|
):
|
|
_ba.app.ui.party_window().on_chat_message(msg)
|
|
|
|
|
|
def get_player_icon(sessionplayer: ba.SessionPlayer) -> dict[str, Any]:
|
|
info = sessionplayer.get_icon_info()
|
|
return {
|
|
'texture': _ba.gettexture(info['texture']),
|
|
'tint_texture': _ba.gettexture(info['tint_texture']),
|
|
'tint_color': info['tint_color'],
|
|
'tint2_color': info['tint2_color'],
|
|
}
|
|
|
|
|
|
def hash_strings(inputs: list[str]) -> str:
|
|
"""Hash provided strings into a short output string."""
|
|
import hashlib
|
|
|
|
sha = hashlib.sha1()
|
|
for inp in inputs:
|
|
sha.update(inp.encode())
|
|
|
|
return sha.hexdigest()
|
|
|
|
|
|
def have_account_v2_credentials() -> bool:
|
|
"""Do we have primary account-v2 credentials set?"""
|
|
return _ba.app.accounts_v2.have_primary_credentials()
|
|
|
|
|
|
def implicit_sign_in(
|
|
login_type_str: str, login_id: str, display_name: str
|
|
) -> None:
|
|
"""An implicit login happened."""
|
|
from bacommon.login import LoginType
|
|
|
|
_ba.app.accounts_v2.on_implicit_sign_in(
|
|
login_type=LoginType(login_type_str),
|
|
login_id=login_id,
|
|
display_name=display_name,
|
|
)
|
|
|
|
|
|
def implicit_sign_out(login_type_str: str) -> None:
|
|
"""An implicit logout happened."""
|
|
from bacommon.login import LoginType
|
|
|
|
_ba.app.accounts_v2.on_implicit_sign_out(
|
|
login_type=LoginType(login_type_str)
|
|
)
|
|
|
|
|
|
def login_adapter_get_sign_in_token_response(
|
|
login_type_str: str, attempt_id_str: str, result_str: str
|
|
) -> None:
|
|
"""Login adapter do-sign-in completed."""
|
|
from bacommon.login import LoginType
|
|
from ba._login import LoginAdapterNative
|
|
|
|
login_type = LoginType(login_type_str)
|
|
attempt_id = int(attempt_id_str)
|
|
result = None if result_str == '' else result_str
|
|
with _ba.Context('ui'):
|
|
adapter = _ba.app.accounts_v2.login_adapters[login_type]
|
|
assert isinstance(adapter, LoginAdapterNative)
|
|
adapter.on_sign_in_complete(attempt_id=attempt_id, result=result)
|
|
|
|
|
|
def show_client_too_old_error() -> None:
|
|
"""Called at launch if the server tells us we're too old to talk to it."""
|
|
from ba._language import Lstr
|
|
|
|
# If you are using an old build of the app and would like to stop
|
|
# seeing this error at launch, do:
|
|
# ba.app.config['SuppressClientTooOldErrorForBuild'] = ba.app.build_number
|
|
# ba.app.config.commit()
|
|
# Note that you will have to do that again later if you update to
|
|
# a newer build.
|
|
if (
|
|
_ba.app.config.get('SuppressClientTooOldErrorForBuild')
|
|
== _ba.app.build_number
|
|
):
|
|
return
|
|
|
|
_ba.playsound(_ba.getsound('error'))
|
|
_ba.screenmessage(
|
|
Lstr(
|
|
translate=(
|
|
'serverResponses',
|
|
'Server functionality is no longer supported'
|
|
' in this version of the game;\n'
|
|
'Please update to a newer version.',
|
|
)
|
|
),
|
|
color=(1, 0, 0),
|
|
)
|