bombsquad-plugin-manager/plugins/utilities/server_switch.py
2023-07-04 11:57:58 +05:30

575 lines
21 KiB
Python

# discord @mr.smoothy#5824
# ba_meta require api 8
from __future__ import annotations
import copy
import time
from typing import TYPE_CHECKING
import babase
import bauiv1 as bui
import bascenev1 as bs
import _bascenev1 as _bs
import time
import threading
from enum import Enum
from dataclasses import dataclass
if TYPE_CHECKING:
from typing import Any, Optional, Dict, List, Tuple, Type
import bascenev1 as bs
from bauiv1lib.gather import GatherWindow
from bauiv1lib.confirm import ConfirmWindow
import bauiv1lib.mainmenu as bastd_ui_mainmenu
connect = bs.connect_to_party
disconnect = bs.disconnect_from_host
server = []
ip_add = "private"
p_port = 44444
p_name = "nothing here"
def newconnect_to_party(address, port=43210, print_progress=False):
global ip_add
global p_port
dd = _bs.get_connection_to_host_info()
if (dd != {}):
_bs.disconnect_from_host()
ip_add = address
p_port = port
connect(address, port, print_progress)
else:
ip_add = address
p_port = port
# print(ip_add,p_port)
connect(ip_add, port, print_progress)
def newdisconnect_from_host():
try:
name = _bs.get_connection_to_host_info()['name']
global server
global ip_add
global p_port
pojo = {"name": name, "ip": ip_add, "port": p_port}
if pojo not in server:
server.insert(0, pojo)
server = server[:3]
except:
pass
disconnect()
def printip():
bs.screenmessage("ip address is"+ip_add)
def new_refresh_in_game(
self, positions: List[Tuple[float, float,
float]]) -> Tuple[float, float, float]:
# pylint: disable=too-many-branches
# pylint: disable=too-many-locals
# pylint: disable=too-many-statements
custom_menu_entries: List[Dict[str, Any]] = []
session = _bs.get_foreground_host_session()
if session is not None:
try:
custom_menu_entries = session.get_custom_menu_entries()
for cme in custom_menu_entries:
if (not isinstance(cme, dict) or 'label' not in cme
or not isinstance(cme['label'], (str, bs.Lstr))
or 'call' not in cme or not callable(cme['call'])):
raise ValueError('invalid custom menu entry: ' +
str(cme))
except Exception:
custom_menu_entries = []
babase.print_exception(
f'Error getting custom menu entries for {session}')
self._width = 250.0
self._height = 250.0 if self._input_player else 180.0
if (self._is_demo or self._is_arcade) and self._input_player:
self._height -= 40
if not self._have_settings_button:
self._height -= 50
if self._connected_to_remote_player:
# In this case we have a leave *and* a disconnect button.
self._height += 50
self._height += 50 * (len(custom_menu_entries))
uiscale = bui.app.ui_v1.uiscale
bui.containerwidget(
edit=self._root_widget,
size=(self._width*2, self._height),
scale=(2.15 if uiscale is bui.UIScale.SMALL else
1.6 if uiscale is bui.UIScale.MEDIUM else 1.0))
h = 125.0
v = (self._height - 80.0 if self._input_player else self._height - 60)
h_offset = 0
d_h_offset = 0
v_offset = -50
for _i in range(6 + len(custom_menu_entries)):
positions.append((h, v, 1.0))
v += v_offset
h += h_offset
h_offset += d_h_offset
self._start_button = None
bui.app.pause()
h, v, scale = positions[self._p_index]
bui.textwidget(
parent=self._root_widget,
draw_controller=None,
text="IP: "+ip_add+" PORT: "+str(p_port),
position=(h+self._button_width-80, v+60),
h_align='center',
v_align='center',
size=(20, 60),
scale=0.6)
v_h = v
global server
def con(address, port):
global ip_add
global p_port
if (address == ip_add and port == p_port):
self._resume()
else:
_bs.disconnect_from_host()
_bs.connect_to_party(address, port)
if len(server) == 0:
bui.textwidget(
parent=self._root_widget,
draw_controller=None,
text="Nothing in \n recents",
position=(h + self._button_width * scale, v-30),
h_align='center',
v_align='center',
size=(20, 60),
scale=1)
for ser in server:
self._server_button = bui.buttonwidget(
color=(0.8, 0, 1),
parent=self._root_widget,
position=(h + self._button_width * scale - 80, v_h),
size=(self._button_width, self._button_height),
scale=scale,
autoselect=self._use_autoselect,
label=ser["name"][0:22],
on_activate_call=bs.Call(con, ser["ip"], ser["port"]))
v_h = v_h-50
# Player name if applicable.
if self._input_player:
player_name = self._input_player.getname()
h, v, scale = positions[self._p_index]
v += 35
bui.textwidget(parent=self._root_widget,
position=(h - self._button_width / 2, v),
size=(self._button_width, self._button_height),
color=(1, 1, 1, 0.5),
scale=0.7,
h_align='center',
text=bs.Lstr(value=player_name))
else:
player_name = ''
h, v, scale = positions[self._p_index]
self._p_index += 1
btn = bui.buttonwidget(parent=self._root_widget,
position=(h - self._button_width / 2, v),
size=(self._button_width, self._button_height),
scale=scale,
label=bs.Lstr(resource=self._r + '.resumeText'),
autoselect=self._use_autoselect,
on_activate_call=self._resume)
bui.containerwidget(edit=self._root_widget, cancel_button=btn)
# Add any custom options defined by the current game.
for entry in custom_menu_entries:
h, v, scale = positions[self._p_index]
self._p_index += 1
# Ask the entry whether we should resume when we call
# it (defaults to true).
resume = bool(entry.get('resume_on_call', True))
if resume:
call = bs.Call(self._resume_and_call, entry['call'])
else:
call = bs.Call(entry['call'], bs.WeakCall(self._resume))
bui.buttonwidget(parent=self._root_widget,
position=(h - self._button_width / 2, v),
size=(self._button_width, self._button_height),
scale=scale,
on_activate_call=call,
label=entry['label'],
autoselect=self._use_autoselect)
# Add a 'leave' button if the menu-owner has a player.
if ((self._input_player or self._connected_to_remote_player)
and not (self._is_demo or self._is_arcade)):
h, v, scale = positions[self._p_index]
self._p_index += 1
btn = bui.buttonwidget(parent=self._root_widget,
position=(h - self._button_width / 2, v),
size=(self._button_width,
self._button_height),
scale=scale,
on_activate_call=self._leave,
label='',
autoselect=self._use_autoselect)
if (player_name != '' and player_name[0] != '<'
and player_name[-1] != '>'):
txt = bs.Lstr(resource=self._r + '.justPlayerText',
subs=[('${NAME}', player_name)])
else:
txt = bs.Lstr(value=player_name)
bui.textwidget(parent=self._root_widget,
position=(h, v + self._button_height *
(0.64 if player_name != '' else 0.5)),
size=(0, 0),
text=bs.Lstr(resource=self._r + '.leaveGameText'),
scale=(0.83 if player_name != '' else 1.0),
color=(0.75, 1.0, 0.7),
h_align='center',
v_align='center',
draw_controller=btn,
maxwidth=self._button_width * 0.9)
bui.textwidget(parent=self._root_widget,
position=(h, v + self._button_height * 0.27),
size=(0, 0),
text=txt,
color=(0.75, 1.0, 0.7),
h_align='center',
v_align='center',
draw_controller=btn,
scale=0.45,
maxwidth=self._button_width * 0.9)
return h, v, scale
def new_refresh(self) -> None:
# pylint: disable=too-many-branches
# pylint: disable=too-many-locals
# pylint: disable=too-many-statements
global server
print(server)
from bauiv1lib.confirm import QuitWindow
from bauiv1lib.store.button import StoreButton
import bascenev1 as bs
import _bascenev1 as _bs
import bauiv1 as bui
import _baplus
# Clear everything that was there.
children = self._root_widget.get_children()
for child in children:
child.delete()
self._tdelay = 0.0
self._t_delay_inc = 0.0
self._t_delay_play = 0.0
self._button_width = 200.0
self._button_height = 45.0
self._r = 'mainMenu'
assert bs.app.classic is not None
app = bs.app.classic
self._have_quit_button = (bui.app.ui_v1.uiscale is bui.UIScale.LARGE
or (app.platform == 'windows'
and app.subplatform == 'oculus'))
self._have_store_button = not self._in_game
self._have_settings_button = (
(not self._in_game or not bui.app.toolbar_test)
and not (self._is_demo or self._is_arcade or self._is_iircade))
self._input_device = input_device = _bs.get_ui_input_device()
self._input_player = input_device.player if input_device else None
self._connected_to_remote_player = (
input_device.is_attached_to_player()
if input_device else False)
positions: List[Tuple[float, float, float]] = []
self._p_index = 0
if self._in_game:
h, v, scale = self._refresh_in_game(positions)
print("refreshing in GAME", ip_add)
# btn = bui.buttonwidget(parent=self._root_widget,
# position=(80,270),
# size=(100, 90),
# scale=1.2,
# label=ip_add,
# autoselect=None,
# on_activate_call=printip)
bui.textwidget(
parent=self._root_widget,
draw_controller=None,
text="IP: "+ip_add+" PORT: "+str(p_port),
position=(150, 270),
h_align='center',
v_align='center',
size=(20, 60),
scale=1)
self._server_button = bui.buttonwidget(
parent=self._root_widget,
position=(h * 3.2 + 20 - self._button_width * scale, v),
size=(self._button_width, self._button_height),
scale=scale,
autoselect=self._use_autoselect,
label=bs.Lstr(resource=self._r + '.settingsText'),
transition_delay=self._tdelay,
on_activate_call=self._settings)
self._server_button2 = bui.buttonwidget(
parent=self._root_widget,
position=(h * 3.2 + 20 - self._button_width * scale, v-50),
size=(self._button_width, self._button_height),
scale=scale,
autoselect=self._use_autoselect,
label=bs.Lstr(resource=self._r + '.settingsText'),
transition_delay=self._tdelay,
on_activate_call=self._settings)
self._server_button3 = bui.buttonwidget(
parent=self._root_widget,
position=(h * 3.2 + 20 - self._button_width * scale, v-100),
size=(self._button_width, self._button_height),
scale=scale,
autoselect=self._use_autoselect,
label=bs.Lstr(resource=self._r + '.settingsText'),
transition_delay=self._tdelay,
on_activate_call=self._settings)
else:
h, v, scale = self._refresh_not_in_game(positions)
if self._have_settings_button:
h, v, scale = positions[self._p_index]
self._p_index += 1
self._settings_button = bui.buttonwidget(
parent=self._root_widget,
position=(h - self._button_width * 0.5 * scale, v),
size=(self._button_width, self._button_height),
scale=scale,
autoselect=self._use_autoselect,
label=bs.Lstr(resource=self._r + '.settingsText'),
transition_delay=self._tdelay,
on_activate_call=self._settings)
# Scattered eggs on easter.
if _baplus.get_v1_account_misc_read_val('easter',
False) and not self._in_game:
icon_size = 34
bui.imagewidget(parent=self._root_widget,
position=(h - icon_size * 0.5 - 15,
v + self._button_height * scale -
icon_size * 0.24 + 1.5),
transition_delay=self._tdelay,
size=(icon_size, icon_size),
texture=bui.gettexture('egg3'),
tilt_scale=0.0)
self._tdelay += self._t_delay_inc
if self._in_game:
h, v, scale = positions[self._p_index]
self._p_index += 1
# If we're in a replay, we have a 'Leave Replay' button.
if _bs.is_in_replay():
bui.buttonwidget(parent=self._root_widget,
position=(h - self._button_width * 0.5 * scale,
v),
scale=scale,
size=(self._button_width, self._button_height),
autoselect=self._use_autoselect,
label=bs.Lstr(resource='replayEndText'),
on_activate_call=self._confirm_end_replay)
elif _bs.get_foreground_host_session() is not None:
bui.buttonwidget(
parent=self._root_widget,
position=(h - self._button_width * 0.5 * scale, v),
scale=scale,
size=(self._button_width, self._button_height),
autoselect=self._use_autoselect,
label=bs.Lstr(resource=self._r + '.endGameText'),
on_activate_call=self._confirm_end_game)
# Assume we're in a client-session.
else:
bui.buttonwidget(
parent=self._root_widget,
position=(h - self._button_width * 0.5 * scale, v),
scale=scale,
size=(self._button_width, self._button_height),
autoselect=self._use_autoselect,
label=bs.Lstr(resource=self._r + '.leavePartyText'),
on_activate_call=self._confirm_leave_party)
self._store_button: Optional[bui.Widget]
if self._have_store_button:
this_b_width = self._button_width
h, v, scale = positions[self._p_index]
self._p_index += 1
sbtn = self._store_button_instance = StoreButton(
parent=self._root_widget,
position=(h - this_b_width * 0.5 * scale, v),
size=(this_b_width, self._button_height),
scale=scale,
on_activate_call=bs.WeakCall(self._on_store_pressed),
sale_scale=1.3,
transition_delay=self._tdelay)
self._store_button = store_button = sbtn.get_button()
uiscale = bui.app.ui_v1.uiscale
icon_size = (55 if uiscale is bui.UIScale.SMALL else
55 if uiscale is bui.UIScale.MEDIUM else 70)
bui.imagewidget(
parent=self._root_widget,
position=(h - icon_size * 0.5,
v + self._button_height * scale - icon_size * 0.23),
transition_delay=self._tdelay,
size=(icon_size, icon_size),
texture=bui.gettexture(self._store_char_tex),
tilt_scale=0.0,
draw_controller=store_button)
self._tdelay += self._t_delay_inc
else:
self._store_button = None
self._quit_button: Optional[bui.Widget]
if not self._in_game and self._have_quit_button:
h, v, scale = positions[self._p_index]
self._p_index += 1
self._quit_button = quit_button = bui.buttonwidget(
parent=self._root_widget,
autoselect=self._use_autoselect,
position=(h - self._button_width * 0.5 * scale, v),
size=(self._button_width, self._button_height),
scale=scale,
label=bs.Lstr(resource=self._r +
('.quitText' if 'Mac' in
bs.app.classic.legacy_user_agent_string else '.exitGameText')),
on_activate_call=self._quit,
transition_delay=self._tdelay)
# Scattered eggs on easter.
if _baplus.get_v1_account_misc_read_val('easter', False):
icon_size = 30
bui.imagewidget(parent=self._root_widget,
position=(h - icon_size * 0.5 + 25,
v + self._button_height * scale -
icon_size * 0.24 + 1.5),
transition_delay=self._tdelay,
size=(icon_size, icon_size),
texture=bui.gettexture('egg1'),
tilt_scale=0.0)
bui.containerwidget(edit=self._root_widget,
cancel_button=quit_button)
self._tdelay += self._t_delay_inc
else:
self._quit_button = None
# If we're not in-game, have no quit button, and this is android,
# we want back presses to quit our activity.
if (not self._in_game and not self._have_quit_button
and bs.app.classic.platform == 'android'):
def _do_quit() -> None:
QuitWindow(swish=True, back=True)
bui.containerwidget(edit=self._root_widget,
on_cancel_call=_do_quit)
# Add speed-up/slow-down buttons for replays.
# (ideally this should be part of a fading-out playback bar like most
# media players but this works for now).
if _bs.is_in_replay():
b_size = 50.0
b_buffer = 10.0
t_scale = 0.75
uiscale = bui.app.ui_v1.uiscale
if uiscale is bui.UIScale.SMALL:
b_size *= 0.6
b_buffer *= 1.0
v_offs = -40
t_scale = 0.5
elif uiscale is bui.UIScale.MEDIUM:
v_offs = -70
else:
v_offs = -100
self._replay_speed_text = bui.textwidget(
parent=self._root_widget,
text=bs.Lstr(resource='watchWindow.playbackSpeedText',
subs=[('${SPEED}', str(1.23))]),
position=(h, v + v_offs + 7 * t_scale),
h_align='center',
v_align='center',
size=(0, 0),
scale=t_scale)
# Update to current value.
self._change_replay_speed(0)
# Keep updating in a timer in case it gets changed elsewhere.
self._change_replay_speed_timer = bs.Timer(
0.25,
bs.WeakCall(self._change_replay_speed, 0),
repeat=True)
btn = bui.buttonwidget(parent=self._root_widget,
position=(h - b_size - b_buffer,
v - b_size - b_buffer + v_offs),
button_type='square',
size=(b_size, b_size),
label='',
autoselect=True,
on_activate_call=bs.Call(
self._change_replay_speed, -1))
bui.textwidget(
parent=self._root_widget,
draw_controller=btn,
text='-',
position=(h - b_size * 0.5 - b_buffer,
v - b_size * 0.5 - b_buffer + 5 * t_scale + v_offs),
h_align='center',
v_align='center',
size=(0, 0),
scale=3.0 * t_scale)
btn = bui.buttonwidget(
parent=self._root_widget,
position=(h + b_buffer, v - b_size - b_buffer + v_offs),
button_type='square',
size=(b_size, b_size),
label='',
autoselect=True,
on_activate_call=bs.Call(self._change_replay_speed, 1))
bui.textwidget(
parent=self._root_widget,
draw_controller=btn,
text='+',
position=(h + b_size * 0.5 + b_buffer,
v - b_size * 0.5 - b_buffer + 5 * t_scale + v_offs),
h_align='center',
v_align='center',
size=(0, 0),
scale=3.0 * t_scale)
# ba_meta export plugin
class bySmoothy(babase.Plugin):
def __init__(self):
if babase.env().get("build_number", 0) >= 21140:
bastd_ui_mainmenu.MainMenuWindow._refresh_in_game = new_refresh_in_game
bs.connect_to_party = newconnect_to_party
bs.disconnect_from_host = newdisconnect_from_host
else:
print("Server Switch only works on bs 1.7.20 and above")