mirror of
https://github.com/bombsquad-community/plugin-manager.git
synced 2025-10-08 14:54:36 +00:00
608 lines
23 KiB
Python
608 lines
23 KiB
Python
# -*- coding: utf-8 -*-
|
|
# ba_meta require api 7
|
|
|
|
# ===============================================
|
|
# EasyConnect by Mr.Smoothy |
|
|
# verion 1.2 |
|
|
# https://discord.gg/ucyaesh |
|
|
# Serverconnector X IPPORTRevealer |
|
|
# for bombsquad v1.7 + |
|
|
# ===============================================
|
|
|
|
|
|
# .................___________________________________________
|
|
# WATCH IN ACTION https://www.youtube.com/watch?v=jwi2wKwZblQ
|
|
# .................___________________________________________
|
|
|
|
# Have any idea/suggestion/bug report > send message on discord mr.smoothy#5824
|
|
|
|
# Discord:-
|
|
# mr.smoothy#5824
|
|
|
|
|
|
# DONT EDIT ANYTHING WITHOUT PERMISSION
|
|
|
|
# join Bombspot - bombsquad biggest modding community .... open for everyone https://discord.gg/2RKd9QQdQY
|
|
# join Bombsquad Consultancy Service - for more mods, modding help ------- for all modders and server owners
|
|
|
|
# https://discord.gg/2RKd9QQdQY
|
|
# https://discord.gg/ucyaesh
|
|
|
|
# REQUIREMENTS
|
|
# built for bs 1.7 and above
|
|
|
|
# by Mr.Smoothy for Bombsquad version 1.7
|
|
|
|
import _ba
|
|
import ba
|
|
import bastd
|
|
import threading
|
|
from bastd.ui.gather import manualtab, publictab
|
|
from bastd.ui import popup
|
|
from dataclasses import dataclass
|
|
import random
|
|
from enum import Enum
|
|
from bastd.ui.popup import PopupMenuWindow, PopupWindow
|
|
from typing import Any, Optional, Dict, List, Tuple, Type, Union, Callable
|
|
from bastd.ui.gather.publictab import PublicGatherTab
|
|
|
|
|
|
class _HostLookupThread(threading.Thread):
|
|
"""Thread to fetch an addr."""
|
|
|
|
def __init__(self, name: str, port: int,
|
|
call: Callable[[Optional[str], int], Any]):
|
|
super().__init__()
|
|
self._name = name
|
|
self._port = port
|
|
self._call = call
|
|
|
|
def run(self) -> None:
|
|
result: Optional[str]
|
|
try:
|
|
import socket
|
|
result = socket.gethostbyname(self._name)
|
|
except Exception:
|
|
result = None
|
|
ba.pushcall(lambda: self._call(result, self._port),
|
|
from_other_thread=True)
|
|
|
|
|
|
def new_build_favorites_tab(self, region_height: float) -> None:
|
|
c_height = region_height - 20
|
|
v = c_height - 35 - 25 - 30
|
|
self.retry_inter = 0.0
|
|
uiscale = ba.app.ui.uiscale
|
|
self._width = 1240 if uiscale is ba.UIScale.SMALL else 1040
|
|
x_inset = 100 if uiscale is ba.UIScale.SMALL else 0
|
|
self._height = (578 if uiscale is ba.UIScale.SMALL else
|
|
670 if uiscale is ba.UIScale.MEDIUM else 800)
|
|
|
|
self._scroll_width = self._width - 130 + 2 * x_inset
|
|
self._scroll_height = self._height - 180
|
|
x_inset = 100 if uiscale is ba.UIScale.SMALL else 0
|
|
|
|
c_height = self._scroll_height - 20
|
|
sub_scroll_height = c_height - 63
|
|
self._favorites_scroll_width = sub_scroll_width = (
|
|
680 if uiscale is ba.UIScale.SMALL else 640)
|
|
|
|
v = c_height - 30
|
|
|
|
b_width = 140 if uiscale is ba.UIScale.SMALL else 178
|
|
b_height = (90 if uiscale is ba.UIScale.SMALL else
|
|
142 if uiscale is ba.UIScale.MEDIUM else 130)
|
|
b_space_extra = (0 if uiscale is ba.UIScale.SMALL else
|
|
-2 if uiscale is ba.UIScale.MEDIUM else -5)
|
|
|
|
btnv = (c_height - (48 if uiscale is ba.UIScale.SMALL else
|
|
45 if uiscale is ba.UIScale.MEDIUM else 40) -
|
|
b_height)
|
|
# ================= smoothy =============
|
|
|
|
ba.textwidget(parent=self._container,
|
|
position=(90 if uiscale is ba.UIScale.SMALL else 120, btnv +
|
|
120 if uiscale is ba.UIScale.SMALL else btnv+90),
|
|
size=(0, 0),
|
|
h_align='center',
|
|
color=(0.8, 0.8, 0.8),
|
|
v_align='top',
|
|
text="Auto")
|
|
btnv += 50 if uiscale is ba.UIScale.SMALL else 0
|
|
|
|
ba.buttonwidget(parent=self._container,
|
|
size=(30, 30),
|
|
position=(25 if uiscale is ba.UIScale.SMALL else 40,
|
|
btnv+10),
|
|
|
|
color=(0.6, 0.53, 0.63),
|
|
textcolor=(0.75, 0.7, 0.8),
|
|
on_activate_call=self.auto_retry_dec,
|
|
text_scale=1.3 if uiscale is ba.UIScale.SMALL else 1.2,
|
|
label="-",
|
|
autoselect=True)
|
|
self.retry_inter_text = ba.textwidget(parent=self._container,
|
|
position=(
|
|
90 if uiscale is ba.UIScale.SMALL else 120, btnv+25),
|
|
size=(0, 0),
|
|
h_align='center',
|
|
color=(0.8, 0.8, 0.8),
|
|
v_align='center',
|
|
text=str(self.retry_inter) if self.retry_inter > 0.0 else 'off')
|
|
ba.buttonwidget(parent=self._container,
|
|
size=(30, 30),
|
|
position=(125 if uiscale is ba.UIScale.SMALL else 155,
|
|
btnv+10),
|
|
|
|
color=(0.6, 0.53, 0.63),
|
|
textcolor=(0.75, 0.7, 0.8),
|
|
on_activate_call=self.auto_retry_inc,
|
|
text_scale=1.3 if uiscale is ba.UIScale.SMALL else 1.2,
|
|
label="+",
|
|
autoselect=True)
|
|
|
|
btnv -= b_height + b_space_extra
|
|
|
|
self._favorites_connect_button = btn1 = ba.buttonwidget(
|
|
parent=self._container,
|
|
size=(b_width, b_height),
|
|
position=(25 if uiscale is ba.UIScale.SMALL else 40, btnv),
|
|
button_type='square',
|
|
color=(0.6, 0.53, 0.63),
|
|
textcolor=(0.75, 0.7, 0.8),
|
|
on_activate_call=self._on_favorites_connect_press,
|
|
text_scale=1.0 if uiscale is ba.UIScale.SMALL else 1.2,
|
|
label=ba.Lstr(resource='gatherWindow.manualConnectText'),
|
|
autoselect=True)
|
|
if uiscale is ba.UIScale.SMALL and ba.app.ui.use_toolbars:
|
|
ba.widget(edit=btn1,
|
|
left_widget=ba_internal.get_special_widget('back_button'))
|
|
btnv -= b_height + b_space_extra
|
|
ba.buttonwidget(parent=self._container,
|
|
size=(b_width, b_height),
|
|
position=(25 if uiscale is ba.UIScale.SMALL else 40,
|
|
btnv),
|
|
button_type='square',
|
|
color=(0.6, 0.53, 0.63),
|
|
textcolor=(0.75, 0.7, 0.8),
|
|
on_activate_call=self._on_favorites_edit_press,
|
|
text_scale=1.0 if uiscale is ba.UIScale.SMALL else 1.2,
|
|
label=ba.Lstr(resource='editText'),
|
|
autoselect=True)
|
|
btnv -= b_height + b_space_extra
|
|
ba.buttonwidget(parent=self._container,
|
|
size=(b_width, b_height),
|
|
position=(25 if uiscale is ba.UIScale.SMALL else 40,
|
|
btnv),
|
|
button_type='square',
|
|
color=(0.6, 0.53, 0.63),
|
|
textcolor=(0.75, 0.7, 0.8),
|
|
on_activate_call=self._on_favorite_delete_press,
|
|
text_scale=1.0 if uiscale is ba.UIScale.SMALL else 1.2,
|
|
label=ba.Lstr(resource='deleteText'),
|
|
autoselect=True)
|
|
|
|
v -= sub_scroll_height + 23
|
|
self._scrollwidget = scrlw = ba.scrollwidget(
|
|
parent=self._container,
|
|
position=(190 if uiscale is ba.UIScale.SMALL else 225, v),
|
|
size=(sub_scroll_width, sub_scroll_height),
|
|
claims_left_right=True)
|
|
ba.widget(edit=self._favorites_connect_button,
|
|
right_widget=self._scrollwidget)
|
|
self._columnwidget = ba.columnwidget(parent=scrlw,
|
|
left_border=10,
|
|
border=2,
|
|
margin=0,
|
|
claims_left_right=True)
|
|
|
|
self._favorite_selected = None
|
|
self._refresh_favorites()
|
|
|
|
|
|
def new_on_favorites_connect_press(self) -> None:
|
|
if self._favorite_selected is None:
|
|
self._no_favorite_selected_error()
|
|
|
|
else:
|
|
config = ba.app.config['Saved Servers'][self._favorite_selected]
|
|
_HostLookupThread(name=config['addr'],
|
|
port=config['port'],
|
|
call=ba.WeakCall(
|
|
self._host_lookup_result)).start()
|
|
|
|
if self.retry_inter > 0 and (ba_internal.get_connection_to_host_info() == {} or ba_internal.get_connection_to_host_info()['build_number'] == 0):
|
|
ba.screenmessage("Server full or unreachable, Retrying....")
|
|
self._retry_timer = ba.Timer(self.retry_inter, ba.Call(
|
|
self._on_favorites_connect_press), timetype=ba.TimeType.REAL)
|
|
|
|
|
|
def auto_retry_inc(self):
|
|
|
|
self.retry_inter += 0.5
|
|
ba.textwidget(edit=self.retry_inter_text, text='%.1f' % self.retry_inter)
|
|
|
|
|
|
def auto_retry_dec(self):
|
|
if self.retry_inter > 0.0:
|
|
self.retry_inter -= 0.5
|
|
|
|
if self.retry_inter == 0.0:
|
|
ba.textwidget(edit=self.retry_inter_text, text='off')
|
|
else:
|
|
ba.textwidget(edit=self.retry_inter_text, text='%.1f' % self.retry_inter)
|
|
|
|
|
|
@dataclass
|
|
class PartyEntry:
|
|
"""Info about a public party."""
|
|
address: str
|
|
index: int
|
|
queue: Optional[str] = None
|
|
port: int = -1
|
|
name: str = ''
|
|
size: int = -1
|
|
size_max: int = -1
|
|
claimed: bool = False
|
|
ping: Optional[float] = None
|
|
ping_interval: float = -1.0
|
|
next_ping_time: float = -1.0
|
|
ping_attempts: int = 0
|
|
ping_responses: int = 0
|
|
stats_addr: Optional[str] = None
|
|
clean_display_index: Optional[int] = None
|
|
|
|
def get_key(self) -> str:
|
|
"""Return the key used to store this party."""
|
|
return f'{self.address}_{self.port}'
|
|
|
|
|
|
class SelectionComponent(Enum):
|
|
"""Describes what part of an entry is selected."""
|
|
NAME = 'name'
|
|
STATS_BUTTON = 'stats_button'
|
|
|
|
|
|
@dataclass
|
|
class Selection:
|
|
"""Describes the currently selected list element."""
|
|
entry_key: str
|
|
component: SelectionComponent
|
|
|
|
|
|
def _clear(self) -> None:
|
|
for widget in [
|
|
self._name_widget, self._size_widget, self._ping_widget,
|
|
self._stats_button
|
|
]:
|
|
if widget:
|
|
try:
|
|
widget.delete()
|
|
except:
|
|
pass
|
|
|
|
|
|
def update(self, index: int, party: PartyEntry, sub_scroll_width: float,
|
|
sub_scroll_height: float, lineheight: float,
|
|
columnwidget: ba.Widget, join_text: ba.Widget,
|
|
filter_text: ba.Widget, existing_selection: Optional[Selection],
|
|
tab: PublicGatherTab) -> None:
|
|
"""Update for the given data."""
|
|
# pylint: disable=too-many-locals
|
|
|
|
# Quick-out: if we've been marked clean for a certain index and
|
|
# we're still at that index, we're done.
|
|
if party.clean_display_index == index:
|
|
return
|
|
|
|
ping_good = ba_internal.get_v1_account_misc_read_val('pingGood', 100)
|
|
ping_med = ba_internal.get_v1_account_misc_read_val('pingMed', 500)
|
|
|
|
self._clear()
|
|
hpos = 20
|
|
vpos = sub_scroll_height - lineheight * index - 50
|
|
self._name_widget = ba.textwidget(
|
|
text=ba.Lstr(value=party.name),
|
|
parent=columnwidget,
|
|
size=(sub_scroll_width * 0.63, 20),
|
|
position=(0 + hpos, 4 + vpos),
|
|
selectable=True,
|
|
on_select_call=ba.WeakCall(
|
|
tab.set_public_party_selection,
|
|
Selection(party.get_key(), SelectionComponent.NAME)),
|
|
on_activate_call=ba.WeakCall(tab.on_public_party_activate, party),
|
|
click_activate=True,
|
|
maxwidth=sub_scroll_width * 0.45,
|
|
corner_scale=1.4,
|
|
autoselect=True,
|
|
color=(1, 1, 1, 0.3 if party.ping is None else 1.0),
|
|
h_align='left',
|
|
v_align='center')
|
|
ba.widget(edit=self._name_widget,
|
|
left_widget=join_text,
|
|
show_buffer_top=64.0,
|
|
show_buffer_bottom=64.0)
|
|
if existing_selection == Selection(party.get_key(),
|
|
SelectionComponent.NAME):
|
|
ba.containerwidget(edit=columnwidget,
|
|
selected_child=self._name_widget)
|
|
if party.stats_addr or True:
|
|
url = party.stats_addr.replace(
|
|
'${ACCOUNT}',
|
|
ba_internal.get_v1_account_misc_read_val_2('resolvedAccountID',
|
|
'UNKNOWN'))
|
|
self._stats_button = ba.buttonwidget(
|
|
color=(0.5, 0.8, 0.8),
|
|
textcolor=(1.0, 1.0, 1.0),
|
|
label='....',
|
|
parent=columnwidget,
|
|
autoselect=True,
|
|
|
|
on_select_call=ba.WeakCall(
|
|
tab.set_public_party_selection,
|
|
Selection(party.get_key(),
|
|
SelectionComponent.STATS_BUTTON)),
|
|
size=(100, 40),
|
|
position=(sub_scroll_width * 0.66 + hpos, 1 + vpos),
|
|
scale=0.9)
|
|
ba.buttonwidget(edit=self._stats_button, on_activate_call=ba.Call(
|
|
self.on_stats_click, self._stats_button, party))
|
|
if existing_selection == Selection(
|
|
party.get_key(), SelectionComponent.STATS_BUTTON):
|
|
ba.containerwidget(edit=columnwidget,
|
|
selected_child=self._stats_button)
|
|
|
|
self._size_widget = ba.textwidget(
|
|
text=str(party.size) + '/' + str(party.size_max),
|
|
parent=columnwidget,
|
|
size=(0, 0),
|
|
position=(sub_scroll_width * 0.86 + hpos, 20 + vpos),
|
|
scale=0.7,
|
|
color=(0.8, 0.8, 0.8),
|
|
h_align='right',
|
|
v_align='center')
|
|
|
|
if index == 0:
|
|
ba.widget(edit=self._name_widget, up_widget=filter_text)
|
|
if self._stats_button:
|
|
ba.widget(edit=self._stats_button, up_widget=filter_text)
|
|
|
|
self._ping_widget = ba.textwidget(parent=columnwidget,
|
|
size=(0, 0),
|
|
position=(sub_scroll_width * 0.94 +
|
|
hpos, 20 + vpos),
|
|
scale=0.7,
|
|
h_align='right',
|
|
v_align='center')
|
|
if party.ping is None:
|
|
ba.textwidget(edit=self._ping_widget,
|
|
text='-',
|
|
color=(0.5, 0.5, 0.5))
|
|
else:
|
|
ba.textwidget(edit=self._ping_widget,
|
|
text=str(int(party.ping)),
|
|
color=(0, 1, 0) if party.ping <= ping_good else
|
|
(1, 1, 0) if party.ping <= ping_med else (1, 0, 0))
|
|
|
|
party.clean_display_index = index
|
|
|
|
|
|
def _get_popup_window_scale() -> float:
|
|
uiscale = ba.app.ui.uiscale
|
|
return (2.3 if uiscale is ba.UIScale.SMALL else
|
|
1.65 if uiscale is ba.UIScale.MEDIUM else 1.23)
|
|
|
|
|
|
_party = None
|
|
|
|
|
|
def on_stats_click(self, widget, party):
|
|
global _party
|
|
_party = party
|
|
choices = ['connect', 'copyqueue', "save"]
|
|
DisChoices = [ba.Lstr(resource="ipp", fallback_value="Connect by IP"), ba.Lstr(
|
|
resource="copy id", fallback_value="Copy Queue ID"), ba.Lstr(value="Save")]
|
|
if party.stats_addr:
|
|
choices.append('stats')
|
|
if 'discord' in party.stats_addr:
|
|
txt = "Discord"
|
|
elif 'yout' in party.stats_addr:
|
|
txt = "Youtube"
|
|
else:
|
|
txt = party.stats_addr[0:13]
|
|
DisChoices.append(ba.Lstr(value=txt))
|
|
PopupMenuWindow(
|
|
position=widget.get_screen_space_center(),
|
|
scale=_get_popup_window_scale(),
|
|
choices=choices,
|
|
choices_display=DisChoices,
|
|
current_choice="stats",
|
|
delegate=self)
|
|
|
|
|
|
def popup_menu_closing(self, popup_window: popup.PopupWindow) -> None:
|
|
pass
|
|
|
|
|
|
def popup_menu_selected_choice(self, window: popup.PopupMenu,
|
|
choice: str) -> None:
|
|
"""Called when a menu entry is selected."""
|
|
# Unused arg.
|
|
|
|
if choice == 'stats':
|
|
url = _party.stats_addr.replace(
|
|
'${ACCOUNT}',
|
|
ba_internal.get_v1_account_misc_read_val_2('resolvedAccountID',
|
|
'UNKNOWN'))
|
|
ba.open_url(url)
|
|
elif choice == 'connect':
|
|
|
|
PartyQuickConnect(_party.address, _party.port)
|
|
elif choice == 'save':
|
|
config = ba.app.config
|
|
ip_add = _party.address
|
|
p_port = _party.port
|
|
title = _party.name
|
|
if not isinstance(config.get('Saved Servers'), dict):
|
|
config['Saved Servers'] = {}
|
|
config['Saved Servers'][f'{ip_add}@{p_port}'] = {
|
|
'addr': ip_add,
|
|
'port': p_port,
|
|
'name': title
|
|
}
|
|
config.commit()
|
|
ba.screenmessage("Server saved to manual")
|
|
ba.playsound(ba.getsound('gunCocking'))
|
|
elif choice == "copyqueue":
|
|
ba.clipboard_set_text(_party.queue)
|
|
ba.playsound(ba.getsound('gunCocking'))
|
|
|
|
|
|
def is_game_version_lower_than(version):
|
|
"""
|
|
Returns a boolean value indicating whether the current game
|
|
version is lower than the passed version. Useful for addressing
|
|
any breaking changes within game versions.
|
|
"""
|
|
game_version = tuple(map(int, ba.app.version.split(".")))
|
|
version = tuple(map(int, version.split(".")))
|
|
return game_version < version
|
|
|
|
|
|
def replace():
|
|
global ba_internal
|
|
if is_game_version_lower_than("1.7.7"):
|
|
ba_internal = _ba
|
|
else:
|
|
ba_internal = ba.internal
|
|
manualtab.ManualGatherTab._build_favorites_tab = new_build_favorites_tab
|
|
manualtab.ManualGatherTab._on_favorites_connect_press = new_on_favorites_connect_press
|
|
manualtab.ManualGatherTab.auto_retry_dec = auto_retry_dec
|
|
manualtab.ManualGatherTab.auto_retry_inc = auto_retry_inc
|
|
publictab.UIRow.update = update
|
|
publictab.UIRow._clear = _clear
|
|
publictab.UIRow.on_stats_click = on_stats_click
|
|
publictab.UIRow.popup_menu_closing = popup_menu_closing
|
|
publictab.UIRow.popup_menu_selected_choice = popup_menu_selected_choice
|
|
|
|
|
|
class PartyQuickConnect(ba.Window):
|
|
def __init__(self, address: str, port: int):
|
|
self._width = 800
|
|
self._height = 400
|
|
self._white_tex = ba.gettexture('white')
|
|
self.lineup_tex = ba.gettexture('playerLineup')
|
|
self.lineup_1_transparent_model = ba.getmodel(
|
|
'playerLineup1Transparent')
|
|
self.eyes_model = ba.getmodel('plasticEyesTransparent')
|
|
uiscale = ba.app.ui.uiscale
|
|
super().__init__(root_widget=ba.containerwidget(
|
|
size=(self._width, self._height),
|
|
color=(0.45, 0.63, 0.15),
|
|
transition='in_scale',
|
|
scale=(1.4 if uiscale is ba.UIScale.SMALL else
|
|
1.2 if uiscale is ba.UIScale.MEDIUM else 1.0)))
|
|
self._cancel_button = ba.buttonwidget(parent=self._root_widget,
|
|
scale=1.0,
|
|
position=(60, self._height - 80),
|
|
size=(50, 50),
|
|
label='',
|
|
on_activate_call=self.close,
|
|
autoselect=True,
|
|
color=(0.45, 0.63, 0.15),
|
|
icon=ba.gettexture('crossOut'),
|
|
iconscale=1.2)
|
|
ba.containerwidget(edit=self._root_widget,
|
|
cancel_button=self._cancel_button)
|
|
|
|
self.IP = ba.textwidget(
|
|
parent=self._root_widget,
|
|
position=(self._width * 0.5, self._height * 0.55 + 60),
|
|
size=(0, 0),
|
|
color=(1.0, 3.0, 1.0),
|
|
scale=1.3,
|
|
h_align='center',
|
|
v_align='center',
|
|
text="IP: "+address + " PORT: "+str(port),
|
|
maxwidth=self._width * 0.65)
|
|
self._title_text = ba.textwidget(
|
|
parent=self._root_widget,
|
|
position=(self._width * 0.5, self._height * 0.55),
|
|
size=(0, 0),
|
|
color=(1.0, 3.0, 1.0),
|
|
scale=1.3,
|
|
h_align='center',
|
|
v_align='center',
|
|
text="Retrying....",
|
|
maxwidth=self._width * 0.65)
|
|
self._line_image = ba.imagewidget(
|
|
parent=self._root_widget,
|
|
color=(0.0, 0.0, 0.0),
|
|
opacity=0.2,
|
|
position=(40.0, 120),
|
|
size=(800-190+80, 4.0),
|
|
texture=self._white_tex)
|
|
self.dude_x = 60
|
|
self._body_image_target = ba.buttonwidget(
|
|
parent=self._root_widget,
|
|
size=(1 * 60, 1 * 80),
|
|
color=(random.random(), random.random(), random.random()),
|
|
label='',
|
|
texture=self.lineup_tex,
|
|
position=(40, 110),
|
|
model_transparent=self.lineup_1_transparent_model)
|
|
self._eyes_image = ba.imagewidget(
|
|
parent=self._root_widget,
|
|
size=(1 * 36, 1 * 18),
|
|
texture=self.lineup_tex,
|
|
color=(1, 1, 1),
|
|
position=(40, 165),
|
|
model_transparent=self.eyes_model)
|
|
# self._body_image_target2 = ba.imagewidget(
|
|
# parent=self._root_widget,
|
|
# size=(1* 60, 1 * 80),
|
|
# color=(1,0.3,0.4),
|
|
# texture=self.lineup_tex,
|
|
# position=(700,130),
|
|
# model_transparent=self.lineup_1_transparent_model)
|
|
self.closed = False
|
|
self.retry_count = 1
|
|
self.direction = "right"
|
|
self.connect(address, port)
|
|
self.move_R = ba.Timer(0.01, ba.Call(self.move_right),
|
|
timetype=ba.TimeType.REAL, repeat=True)
|
|
|
|
def move_right(self):
|
|
if self._body_image_target and self._eyes_image:
|
|
ba.buttonwidget(edit=self._body_image_target, position=(self.dude_x, 110))
|
|
ba.imagewidget(edit=self._eyes_image, position=(self.dude_x+10, 165))
|
|
else:
|
|
self.move_R = None
|
|
if self.direction == "right":
|
|
self.dude_x += 2
|
|
if self.dude_x >= 650:
|
|
self.direction = "left"
|
|
else:
|
|
self.dude_x -= 2
|
|
if self.dude_x <= 50:
|
|
self.direction = "right"
|
|
|
|
def connect(self, address, port):
|
|
if not self.closed and (ba_internal.get_connection_to_host_info() == {} or ba_internal.get_connection_to_host_info()['build_number'] == 0):
|
|
ba.textwidget(edit=self._title_text, text="Retrying....("+str(self.retry_count)+")")
|
|
self.retry_count += 1
|
|
ba_internal.connect_to_party(address, port=port)
|
|
self._retry_timer = ba.Timer(1.5, ba.Call(
|
|
self.connect, address, port), timetype=ba.TimeType.REAL)
|
|
|
|
def close(self) -> None:
|
|
"""Close the ui."""
|
|
self.closed = True
|
|
ba.containerwidget(edit=self._root_widget, transition='out_scale')
|
|
|
|
# ba_meta export plugin
|
|
|
|
|
|
class InitalRun(ba.Plugin):
|
|
def __init__(self):
|
|
replace()
|