Revert "updated server switch"

oop
This reverts commit c2832136aa.
This commit is contained in:
Ayush Saini 2023-07-08 15:44:27 +05:30
parent c2832136aa
commit 4eb520fa19
8 changed files with 873 additions and 355 deletions

View file

@ -40,8 +40,14 @@ There are two different ways the plugin manager can be installed:
1. [Download plugin_manager.py][DownloadLink] to your mods directory (check it out by going into your game's
Settings -> Advanced -> Show Mods Folder). This is the recommended way (read next method to know why).
If you're on a newer version of Android (11 or above) and not rooted, it probably won't be possible to copy
mods to game's mods folder. In this case, you can connect your Android phone to a computer and push `plugin_manager.py`
[using `adb`](https://www.xda-developers.com/install-adb-windows-macos-linux/):
```bash
$ adb push plugin_manager.py /sdcard/Android/data/net.froemling.bombsquad/files/mods/plugin_manager.py
```
2. Another way is to add
3. Another way is to add
[plugin_manager.py](https://raw.githubusercontent.com/bombsquad-community/plugin-manager/main/plugin_manager.py)
to your workspace. However, plugin manager self-updates will fail when installed using this way since the game
will overrwrite the updated plugin manager, with the older version from workspace on the next sync. However, you can
@ -193,7 +199,8 @@ That's it! Now you can make a [pull request](../../compare) with both the update
will also help us to notify the maintainers of any future breaking changes in plugin manager that could affect 3rd party
plugin sources.
[rikkolovescats/sahilp-plugins](https://github.com/rikkolovescats/sahilp-plugins)
- [rikkolovescats/sahilp-plugins](https://github.com/rikkolovescats/sahilp-plugins)
- [Aeliux/arcane](https://github.com/Aeliux/arcane)
## Tests

View file

@ -166,6 +166,12 @@
}
],
"versions": {
"2.0.0": {
"api_version": 8,
"commit_sha": "1b14789",
"released_on": "02-07-2023",
"md5sum": "cb2a7700dd13febe6f68c3cd979b8b19"
},
"1.1.0": {
"api_version": 7,
"commit_sha": "40b70fe",

View file

@ -2,23 +2,25 @@
#
"""Elimination mini-game."""
# ba_meta require api 7
# ba_meta require api 8
# (see https://ballistica.net/wiki/meta-tag-system)
from __future__ import annotations
from typing import TYPE_CHECKING
import ba
from bastd.actor.spazfactory import SpazFactory
from bastd.actor.scoreboard import Scoreboard
import babase
import bauiv1 as bui
import bascenev1 as bs
from bascenev1lib.actor.spazfactory import SpazFactory
from bascenev1lib.actor.scoreboard import Scoreboard
if TYPE_CHECKING:
from typing import (Any, Tuple, Type, List, Sequence, Optional,
Union)
class Icon(ba.Actor):
class Icon(bs.Actor):
"""Creates in in-game icon on screen."""
def __init__(self,
@ -37,10 +39,10 @@ class Icon(ba.Actor):
self._show_lives = show_lives
self._show_death = show_death
self._name_scale = name_scale
self._outline_tex = ba.gettexture('characterIconMask')
self._outline_tex = bs.gettexture('characterIconMask')
icon = player.get_icon()
self.node = ba.newnode('image',
self.node = bs.newnode('image',
delegate=self,
attrs={
'texture': icon['texture'],
@ -53,12 +55,12 @@ class Icon(ba.Actor):
'absolute_scale': True,
'attach': 'bottomCenter'
})
self._name_text = ba.newnode(
self._name_text = bs.newnode(
'text',
owner=self.node,
attrs={
'text': ba.Lstr(value=player.getname()),
'color': ba.safecolor(player.team.color),
'text': babase.Lstr(value=player.getname()),
'color': babase.safecolor(player.team.color),
'h_align': 'center',
'v_align': 'center',
'vr_depth': 410,
@ -69,7 +71,7 @@ class Icon(ba.Actor):
'v_attach': 'bottom'
})
if self._show_lives:
self._lives_text = ba.newnode('text',
self._lives_text = bs.newnode('text',
owner=self.node,
attrs={
'text': 'x0',
@ -125,7 +127,7 @@ class Icon(ba.Actor):
if not self.node:
return
if self._show_death:
ba.animate(
bs.animate(
self.node, 'opacity', {
0.00: 1.0,
0.05: 0.0,
@ -142,16 +144,16 @@ class Icon(ba.Actor):
})
lives = self._player.lives
if lives == 0:
ba.timer(0.6, self.update_for_lives)
bs.timer(0.6, self.update_for_lives)
def handlemessage(self, msg: Any) -> Any:
if isinstance(msg, ba.DieMessage):
if isinstance(msg, bs.DieMessage):
self.node.delete()
return None
return super().handlemessage(msg)
class Player(ba.Player['Team']):
class Player(bs.Player['Team']):
"""Our player type for this game."""
def __init__(self) -> None:
@ -159,7 +161,7 @@ class Player(ba.Player['Team']):
self.icons: List[Icon] = []
class Team(ba.Team[Player]):
class Team(bs.Team[Player]):
"""Our team type for this game."""
def __init__(self) -> None:
@ -167,14 +169,14 @@ class Team(ba.Team[Player]):
self.spawn_order: List[Player] = []
# ba_meta export game
class AllianceEliminationGame(ba.TeamGameActivity[Player, Team]):
# ba_meta export bascenev1.GameActivity
class AllianceEliminationGame(bs.TeamGameActivity[Player, Team]):
"""Game type where last player(s) left alive win."""
name = 'Alliance Elimination'
description = 'Fight in groups of duo, trio, or more.\nLast remaining alive wins.'
scoreconfig = ba.ScoreConfig(label='Survived',
scoretype=ba.ScoreType.SECONDS,
scoreconfig = bs.ScoreConfig(label='Survived',
scoretype=bs.ScoreType.SECONDS,
none_is_winner=True)
# Show messages when players die since it's meaningful here.
announce_player_deaths = True
@ -183,23 +185,23 @@ class AllianceEliminationGame(ba.TeamGameActivity[Player, Team]):
@classmethod
def get_available_settings(
cls, sessiontype: Type[ba.Session]) -> List[ba.Setting]:
cls, sessiontype: Type[bs.Session]) -> List[babase.Setting]:
settings = [
ba.IntSetting(
bs.IntSetting(
'Lives Per Player',
default=1,
min_value=1,
max_value=10,
increment=1,
),
ba.IntSetting(
bs.IntSetting(
'Players Per Team In Arena',
default=2,
min_value=2,
max_value=10,
increment=1,
),
ba.IntChoiceSetting(
bs.IntChoiceSetting(
'Time Limit',
choices=[
('None', 0),
@ -211,7 +213,7 @@ class AllianceEliminationGame(ba.TeamGameActivity[Player, Team]):
],
default=0,
),
ba.FloatChoiceSetting(
bs.FloatChoiceSetting(
'Respawn Times',
choices=[
('Shorter', 0.25),
@ -222,27 +224,27 @@ class AllianceEliminationGame(ba.TeamGameActivity[Player, Team]):
],
default=1.0,
),
ba.BoolSetting('Epic Mode', default=False),
bs.BoolSetting('Epic Mode', default=False),
]
if issubclass(sessiontype, ba.DualTeamSession):
if issubclass(sessiontype, bs.DualTeamSession):
settings.append(
ba.BoolSetting('Balance Total Lives', default=False))
bs.BoolSetting('Balance Total Lives', default=False))
return settings
@classmethod
def supports_session_type(cls, sessiontype: Type[ba.Session]) -> bool:
return issubclass(sessiontype, ba.DualTeamSession)
def supports_session_type(cls, sessiontype: Type[bs.Session]) -> bool:
return issubclass(sessiontype, bs.DualTeamSession)
@classmethod
def get_supported_maps(cls, sessiontype: Type[ba.Session]) -> List[str]:
return ba.getmaps('melee')
def get_supported_maps(cls, sessiontype: Type[bs.Session]) -> List[str]:
return bs.app.classic.getmaps('melee')
def __init__(self, settings: dict):
super().__init__(settings)
self._scoreboard = Scoreboard()
self._start_time: Optional[float] = None
self._vs_text: Optional[ba.Actor] = None
self._round_end_timer: Optional[ba.Timer] = None
self._vs_text: Optional[bs.Actor] = None
self._round_end_timer: Optional[bs.Timer] = None
self._epic_mode = bool(settings['Epic Mode'])
self._lives_per_player = int(settings['Lives Per Player'])
self._time_limit = float(settings['Time Limit'])
@ -253,16 +255,16 @@ class AllianceEliminationGame(ba.TeamGameActivity[Player, Team]):
# Base class overrides:
self.slow_motion = self._epic_mode
self.default_music = (ba.MusicType.EPIC
if self._epic_mode else ba.MusicType.SURVIVAL)
self.default_music = (bs.MusicType.EPIC
if self._epic_mode else bs.MusicType.SURVIVAL)
def get_instance_description(self) -> Union[str, Sequence]:
return 'Last team standing wins.' if isinstance(
self.session, ba.DualTeamSession) else 'Last one standing wins.'
self.session, bs.DualTeamSession) else 'Last one standing wins.'
def get_instance_description_short(self) -> Union[str, Sequence]:
return 'last team standing wins' if isinstance(
self.session, ba.DualTeamSession) else 'last one standing wins'
self.session, bs.DualTeamSession) else 'last one standing wins'
def on_player_join(self, player: Player) -> None:
@ -275,9 +277,9 @@ class AllianceEliminationGame(ba.TeamGameActivity[Player, Team]):
if (self._get_total_team_lives(player.team) == 0
and player.team.survival_seconds is None):
player.team.survival_seconds = 0
ba.screenmessage(
ba.Lstr(resource='playerDelayedJoinText',
subs=[('${PLAYER}', player.getname(full=True))]),
bs.broadcastmessage(
babase.Lstr(resource='playerDelayedJoinText',
subs=[('${PLAYER}', player.getname(full=True))]),
color=(0, 1, 0),
)
return
@ -293,11 +295,11 @@ class AllianceEliminationGame(ba.TeamGameActivity[Player, Team]):
def on_begin(self) -> None:
super().on_begin()
self._start_time = ba.time()
self._start_time = bs.time()
self.setup_standard_time_limit(self._time_limit)
self.setup_standard_powerup_drops()
self._vs_text = ba.NodeActor(
ba.newnode('text',
self._vs_text = bs.NodeActor(
bs.newnode('text',
attrs={
'position': (0, 92),
'h_attach': 'center',
@ -308,12 +310,12 @@ class AllianceEliminationGame(ba.TeamGameActivity[Player, Team]):
'scale': 0.6,
'v_attach': 'bottom',
'color': (0.8, 0.8, 0.3, 1.0),
'text': ba.Lstr(resource='vsText')
'text': babase.Lstr(resource='vsText')
}))
# If balance-team-lives is on, add lives to the smaller team until
# total lives match.
if (isinstance(self.session, ba.DualTeamSession)
if (isinstance(self.session, bs.DualTeamSession)
and self._balance_total_lives and self.teams[0].players
and self.teams[1].players):
if self._get_total_team_lives(
@ -333,7 +335,7 @@ class AllianceEliminationGame(ba.TeamGameActivity[Player, Team]):
# We could check game-over conditions at explicit trigger points,
# but lets just do the simple thing and poll it.
ba.timer(1.0, self._update, repeat=True)
bs.timer(1.0, self._update, repeat=True)
def _update_alliance_mode(self) -> None:
# For both teams, find the first player on the spawn order list with
@ -391,10 +393,10 @@ class AllianceEliminationGame(ba.TeamGameActivity[Player, Team]):
nplayers -= 1
test_lives += 1
def _get_spawn_point(self, player: Player) -> Optional[ba.Vec3]:
def _get_spawn_point(self, player: Player) -> Optional[babase.Vec3]:
return None
def spawn_player(self, player: Player) -> ba.Actor:
def spawn_player(self, player: Player) -> bs.Actor:
actor = self.spawn_player_spaz(player, self._get_spawn_point(player))
# If we have any icons, update their state.
@ -403,7 +405,7 @@ class AllianceEliminationGame(ba.TeamGameActivity[Player, Team]):
return actor
def _print_lives(self, player: Player) -> None:
from bastd.actor import popuptext
from bascenev1lib.actor import popuptext
# We get called in a timer so it's possible our player has left/etc.
if not player or not player.is_alive() or not player.node:
@ -426,20 +428,20 @@ class AllianceEliminationGame(ba.TeamGameActivity[Player, Team]):
# Update icons in a moment since our team will be gone from the
# list then.
ba.timer(0, self._update_icons)
bs.timer(0, self._update_icons)
# If the player to leave was the last in spawn order and had
# their final turn currently in-progress, mark the survival time
# for their team.
if self._get_total_team_lives(player.team) == 0:
assert self._start_time is not None
player.team.survival_seconds = int(ba.time() - self._start_time)
player.team.survival_seconds = int(bs.time() - self._start_time)
def _get_total_team_lives(self, team: Team) -> int:
return sum(player.lives for player in team.players)
def handlemessage(self, msg: Any) -> Any:
if isinstance(msg, ba.PlayerDiedMessage):
if isinstance(msg, bs.PlayerDiedMessage):
# Augment standard behavior.
super().handlemessage(msg)
@ -447,7 +449,7 @@ class AllianceEliminationGame(ba.TeamGameActivity[Player, Team]):
player.lives -= 1
if player.lives < 0:
ba.print_error(
babase.print_error(
"Got lives < 0 in Alliance Elimination; this shouldn't happen.")
player.lives = 0
@ -458,14 +460,14 @@ class AllianceEliminationGame(ba.TeamGameActivity[Player, Team]):
# Play big death sound on our last death
# or for every one.
if player.lives == 0:
ba.playsound(SpazFactory.get().single_player_death_sound)
SpazFactory.get().single_player_death_sound.play()
# If we hit zero lives, we're dead (and our team might be too).
if player.lives == 0:
# If the whole team is now dead, mark their survival time.
if self._get_total_team_lives(player.team) == 0:
assert self._start_time is not None
player.team.survival_seconds = int(ba.time() -
player.team.survival_seconds = int(bs.time() -
self._start_time)
# Put ourself at the back of the spawn order.
@ -493,7 +495,7 @@ class AllianceEliminationGame(ba.TeamGameActivity[Player, Team]):
# the game (allows the dust to settle and draws to occur if deaths
# are close enough).
if len(self._get_living_teams()) < 2:
self._round_end_timer = ba.Timer(0.5, self.end_game)
self._round_end_timer = bs.Timer(0.5, self.end_game)
def _get_living_teams(self) -> List[Team]:
return [
@ -505,7 +507,7 @@ class AllianceEliminationGame(ba.TeamGameActivity[Player, Team]):
def end_game(self) -> None:
if self.has_ended():
return
results = ba.GameResults()
results = bs.GameResults()
self._vs_text = None # Kill our 'vs' if its there.
for team in self.teams:
results.set_team_score(team, team.survival_seconds)

View file

@ -335,7 +335,12 @@
}
],
"versions": {
"2.0.0":null,
"2.0.0": {
"api_version": 8,
"commit_sha": "0c5ce76",
"released_on": "02-07-2023",
"md5sum": "8b05407fda379d853f5c75677b19fd85"
},
"1.2.1": {
"api_version": 7,
"commit_sha": "64e8a5c",
@ -417,7 +422,12 @@
}
],
"versions": {
"2.0.0":null,
"2.0.0": {
"api_version": 8,
"commit_sha": "bf3e61b",
"released_on": "04-07-2023",
"md5sum": "289cc852b7f0ec1b254d08267c9921c2"
},
"1.0.1": {
"api_version": 7,
"commit_sha": "64e8a5c",
@ -443,7 +453,12 @@
}
],
"versions": {
"2.0.0": null,
"2.0.0": {
"api_version": 8,
"commit_sha": "0c5ce76",
"released_on": "02-07-2023",
"md5sum": "bb5d85fb528020e809eaebb17a388e32"
},
"1.0.0": {
"api_version": 7,
"commit_sha": "ff4de19",
@ -507,7 +522,12 @@
}
],
"versions": {
"2.0.0":null,
"2.0.0": {
"api_version": 8,
"commit_sha": "a0239a9",
"released_on": "04-07-2023",
"md5sum": "187a9894158721c8fa1ecee9e3e38e73"
},
"1.0.0": {
"api_version": 7,
"commit_sha": "41e239c",

View file

@ -55,7 +55,6 @@ from bascenev1 import _lobby
from bascenev1lib.actor.spazappearance import *
def __init__(self, vpos: float, sessionplayer: bs.SessionPlayer,
lobby: 'Lobby') -> None:
self._deek_sound = bs.getsound('deek')
@ -113,25 +112,25 @@ def __init__(self, vpos: float, sessionplayer: bs.SessionPlayer,
self._profilename = self._profilenames[self._profileindex]
self._text_node = bs.newnode('text',
delegate=self,
attrs={
'position': (-100, self._vpos),
'maxwidth': 190,
'shadow': 0.5,
'vr_depth': -20,
'h_align': 'left',
'v_align': 'center',
'v_attach': 'top'
})
delegate=self,
attrs={
'position': (-100, self._vpos),
'maxwidth': 190,
'shadow': 0.5,
'vr_depth': -20,
'h_align': 'left',
'v_align': 'center',
'v_attach': 'top'
})
bs.animate(self._text_node, 'scale', {0: 0, 0.1: 1.0})
self.icon = bs.newnode('image',
owner=self._text_node,
attrs={
'position': (-130, self._vpos + 20),
'mask_texture': self._mask_texture,
'vr_depth': -10,
'attach': 'topCenter'
})
owner=self._text_node,
attrs={
'position': (-130, self._vpos + 20),
'mask_texture': self._mask_texture,
'vr_depth': -10,
'attach': 'topCenter'
})
bs.animate_array(self.icon, 'scale', 2, {0: (0, 0), 0.1: (45, 45)})

View file

@ -15,13 +15,13 @@
# .................___________________________________________
# Have any idea/suggestion/bug report > send message on discord mr.smoothy#5824
# Download modshttps://bombsquad-community.web.app/mods
# Download modshttps://bombsquad-community.web.app/mods
# Discord:-
# mr.smoothy#5824
# DONT EDIT ANYTHING WITHOUT PERMISSION
# join Bombsquad Community Server -
# join Bombsquad Community Server -
# https://discord.gg/ucyaesh
@ -73,7 +73,6 @@ def is_game_version_lower_than(version):
return game_version < version
def updateBannedServersCache():
response = None
config = babase.app.config
@ -112,7 +111,7 @@ class _HostLookupThread(threading.Thread):
except Exception:
result = None
babase.pushcall(lambda: self._call(result, self._port),
from_other_thread=True)
from_other_thread=True)
def newbuild_favorites_tab(self, region_height: float) -> None:
@ -148,45 +147,45 @@ def newbuild_favorites_tab(self, region_height: float) -> None:
# ================= smoothy =============
bui.textwidget(parent=self._container,
position=(90 if uiscale is babase.UIScale.SMALL else 120, btnv +
120 if uiscale is babase.UIScale.SMALL else btnv+90),
size=(0, 0),
h_align='center',
color=(0.8, 0.8, 0.8),
v_align='top',
text="Auto")
position=(90 if uiscale is babase.UIScale.SMALL else 120, btnv +
120 if uiscale is babase.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 babase.UIScale.SMALL else 0
bui.buttonwidget(parent=self._container,
size=(30, 30),
position=(25 if uiscale is babase.UIScale.SMALL else 40,
btnv+10),
size=(30, 30),
position=(25 if uiscale is babase.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 babase.UIScale.SMALL else 1.2,
label="-",
autoselect=True)
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 babase.UIScale.SMALL else 1.2,
label="-",
autoselect=True)
self.retry_inter_text = bui.textwidget(parent=self._container,
position=(
90 if uiscale is babase.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')
position=(
90 if uiscale is babase.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')
bui.buttonwidget(parent=self._container,
size=(30, 30),
position=(125 if uiscale is babase.UIScale.SMALL else 155,
btnv+10),
size=(30, 30),
position=(125 if uiscale is babase.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 babase.UIScale.SMALL else 1.2,
label="+",
autoselect=True)
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 babase.UIScale.SMALL else 1.2,
label="+",
autoselect=True)
btnv -= b_height + b_space_extra
@ -203,31 +202,31 @@ def newbuild_favorites_tab(self, region_height: float) -> None:
autoselect=True)
if uiscale is babase.UIScale.SMALL and bui.app.ui_v1.use_toolbars:
bui.widget(edit=btn1,
left_widget=bui.get_special_widget('back_button'))
left_widget=bui.get_special_widget('back_button'))
btnv -= b_height + b_space_extra
bui.buttonwidget(parent=self._container,
size=(b_width, b_height),
position=(25 if uiscale is babase.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 babase.UIScale.SMALL else 1.2,
label=babase.Lstr(resource='editText'),
autoselect=True)
size=(b_width, b_height),
position=(25 if uiscale is babase.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 babase.UIScale.SMALL else 1.2,
label=babase.Lstr(resource='editText'),
autoselect=True)
btnv -= b_height + b_space_extra
bui.buttonwidget(parent=self._container,
size=(b_width, b_height),
position=(25 if uiscale is babase.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 babase.UIScale.SMALL else 1.2,
label=babase.Lstr(resource='deleteText'),
autoselect=True)
size=(b_width, b_height),
position=(25 if uiscale is babase.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 babase.UIScale.SMALL else 1.2,
label=babase.Lstr(resource='deleteText'),
autoselect=True)
v -= sub_scroll_height + 23
self._scrollwidget = scrlw = bui.scrollwidget(
@ -236,12 +235,12 @@ def newbuild_favorites_tab(self, region_height: float) -> None:
size=(sub_scroll_width, sub_scroll_height),
claims_left_right=True)
bui.widget(edit=self._favorites_connect_button,
right_widget=self._scrollwidget)
right_widget=self._scrollwidget)
self._columnwidget = bui.columnwidget(parent=scrlw,
left_border=10,
border=2,
margin=0,
claims_left_right=True)
left_border=10,
border=2,
margin=0,
claims_left_right=True)
self._favorite_selected = None
self._refresh_favorites()
@ -323,9 +322,8 @@ def _clear(self) -> None:
self._stats_button
]:
if widget:
widget.delete()
def update(self, index: int, party: PartyEntry, sub_scroll_width: float,
@ -333,127 +331,128 @@ def update(self, index: int, party: PartyEntry, sub_scroll_width: float,
columnwidget: bui.Widget, join_text: bui.Widget,
filter_text: bui.Widget, existing_selection: Optional[Selection],
tab: PublicGatherTab) -> None:
"""Update for the given data."""
# pylint: disable=too-many-locals
"""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.
plus = bui.app.plus
assert plus is not None
# Quick-out: if we've been marked clean for a certain index and
# we're still at that index, we're done.
plus = bui.app.plus
assert plus is not None
# 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
# 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 = plus.get_v1_account_misc_read_val('pingGood', 100)
ping_med = plus.get_v1_account_misc_read_val('pingMed', 500)
ping_good = plus.get_v1_account_misc_read_val('pingGood', 100)
ping_med = plus.get_v1_account_misc_read_val('pingMed', 500)
self._clear()
hpos = 20
vpos = sub_scroll_height - lineheight * index - 50
self._name_widget = bui.textwidget(
text=bui.Lstr(value=party.name),
self._clear()
hpos = 20
vpos = sub_scroll_height - lineheight * index - 50
self._name_widget = bui.textwidget(
text=bui.Lstr(value=party.name),
parent=columnwidget,
size=(sub_scroll_width * 0.63, 20),
position=(0 + hpos, 4 + vpos),
selectable=True,
on_select_call=bui.WeakCall(
tab.set_public_party_selection,
Selection(party.get_key(), SelectionComponent.NAME),
),
on_activate_call=bui.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',
)
bui.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
):
bui.containerwidget(
edit=columnwidget, selected_child=self._name_widget
)
if party.stats_addr or True:
url = party.stats_addr.replace(
'${ACCOUNT}',
plus.get_v1_account_misc_read_val_2(
'resolvedAccountID', 'UNKNOWN'
),
)
self._stats_button = bui.buttonwidget(
color=(0.3, 0.6, 0.94),
textcolor=(1.0, 1.0, 1.0),
label='....',
parent=columnwidget,
size=(sub_scroll_width * 0.63, 20),
position=(0 + hpos, 4 + vpos),
selectable=True,
autoselect=True,
on_activate_call=bui.Call(bui.open_url, url),
on_select_call=bui.WeakCall(
tab.set_public_party_selection,
Selection(party.get_key(), SelectionComponent.NAME),
Selection(party.get_key(), SelectionComponent.STATS_BUTTON),
),
on_activate_call=bui.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',
)
bui.widget(
edit=self._name_widget,
left_widget=join_text,
show_buffer_top=64.0,
show_buffer_bottom=64.0,
size=(120, 40),
position=(sub_scroll_width * 0.66 + hpos, 1 + vpos),
scale=0.9,
)
bui.buttonwidget(edit=self._stats_button, on_activate_call=bui.WeakCall(
self.on_stats_click, self._stats_button, party))
if existing_selection == Selection(
party.get_key(), SelectionComponent.NAME
party.get_key(), SelectionComponent.STATS_BUTTON
):
bui.containerwidget(
edit=columnwidget, selected_child=self._name_widget
edit=columnwidget, selected_child=self._stats_button
)
if party.stats_addr or True:
url = party.stats_addr.replace(
'${ACCOUNT}',
plus.get_v1_account_misc_read_val_2(
'resolvedAccountID', 'UNKNOWN'
),
)
self._stats_button = bui.buttonwidget(
color=(0.3, 0.6, 0.94),
textcolor=(1.0, 1.0, 1.0),
label='....',
parent=columnwidget,
autoselect=True,
on_activate_call=bui.Call(bui.open_url, url),
on_select_call=bui.WeakCall(
tab.set_public_party_selection,
Selection(party.get_key(), SelectionComponent.STATS_BUTTON),
),
size=(120, 40),
position=(sub_scroll_width * 0.66 + hpos, 1 + vpos),
scale=0.9,
)
bui.buttonwidget(edit=self._stats_button, on_activate_call=bui.WeakCall(
self.on_stats_click, self._stats_button, party))
if existing_selection == Selection(
party.get_key(), SelectionComponent.STATS_BUTTON
):
bui.containerwidget(
edit=columnwidget, selected_child=self._stats_button
)
self._size_widget = bui.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',
self._size_widget = bui.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:
bui.widget(edit=self._name_widget, up_widget=filter_text)
if self._stats_button:
bui.widget(edit=self._stats_button, up_widget=filter_text)
self._ping_widget = bui.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:
bui.textwidget(
edit=self._ping_widget, text='-', color=(0.5, 0.5, 0.5)
)
else:
bui.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),
)
if index == 0:
bui.widget(edit=self._name_widget, up_widget=filter_text)
if self._stats_button:
bui.widget(edit=self._stats_button, up_widget=filter_text)
party.clean_display_index = index
self._ping_widget = bui.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:
bui.textwidget(
edit=self._ping_widget, text='-', color=(0.5, 0.5, 0.5)
)
else:
bui.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 = bui.app.ui_v1.uiscale
@ -501,7 +500,7 @@ def popup_menu_selected_choice(self, window: popup.PopupMenu,
url = _party.stats_addr.replace(
'${ACCOUNT}',
plus.get_v1_account_misc_read_val_2('resolvedAccountID',
'UNKNOWN'))
'UNKNOWN'))
bui.open_url(url)
elif choice == 'connect':
PartyQuickConnect(_party.address, _party.port)
@ -614,17 +613,17 @@ class PartyQuickConnect(bui.Window):
scale=(1.4 if uiscale is babase.UIScale.SMALL else
1.2 if uiscale is babase.UIScale.MEDIUM else 1.0)))
self._cancel_button = bui.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=bui.gettexture('crossOut'),
iconscale=1.2)
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=bui.gettexture('crossOut'),
iconscale=1.2)
bui.containerwidget(edit=self._root_widget,
cancel_button=self._cancel_button)
cancel_button=self._cancel_button)
self.IP = bui.textwidget(
parent=self._root_widget,

View file

@ -4,8 +4,23 @@ import _baplus
import babase
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, babase.app.version.split(".")))
version = tuple(map(int, version.split(".")))
return game_version < version
if is_game_version_lower_than("1.7.20"):
original_get_purchased = _baplus.get_purchased
else:
assert bs.app.plus is not None
original_get_purchased = bs.app.plus.get_purchased
original_get_purchased = _baplus.get_purchased
def get_purchased(item):
if item.startswith('characters.') or item.startswith('icons.'):
@ -17,5 +32,8 @@ def get_purchased(item):
class Unlock(babase.Plugin):
def on_app_running(self):
babase.app.classic.accounts.have_pro = lambda: True
_baplus.get_purchased = get_purchased
if is_game_version_lower_than("1.7.20"):
_baplus.get_purchased = get_purchased
else:
assert bs.app.plus is not None
bs.app.plus.get_purchased = get_purchased

View file

@ -1,108 +1,575 @@
# -*- coding: utf-8 -*-
# ba_meta require api 8
'''
Server Switch Plugin by My.Smoothy
Let you switch recently joined servers very quickly
+ Added button to quicky look into public server list without leaving current game.
# discord @mr.smoothy#5824
# ba_meta require api 8
from __future__ import annotations
import copy
import time
from typing import TYPE_CHECKING
discord: mr.smoothy
https://discord.gg/ucyaesh
Youtube : Hey Smoothy
Download more mods from
https://bombsquad-community.web.app/mods
'''
import babase
import bauiv1lib.mainmenu as bastd_ui_mainmenu
import bauiv1 as bui
import bascenev1 as bs
current_server_ip = "127.0.0.1"
current_server_port = 43210
servers = []
def _refresh_in_game(func):
def wrapper(self, *args, **kwargs):
returnValue = func(self, *args, **kwargs)
uiscale = bui.app.ui_v1.uiscale
bui.containerwidget(
edit=self._root_widget,
size=(self._width*2, self._height), # double the width
scale=(
2.15
if uiscale is bui.UIScale.SMALL
else 1.6
if uiscale is bui.UIScale.MEDIUM
else 1.0
),
)
h = 125
v = self._height - 60.0
bui.textwidget(
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: "+current_server_ip+" PORT: "+str(current_server_port),
position=(h-self._button_width/2 + 130 , v+60),
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)
self._public_servers = bui.buttonwidget(
color=(0.8, 0.45, 1),
parent=self._root_widget,
position=(h+self._button_width-10, v+60+20),
size=(self._button_width/4, self._button_height/2),
scale=1.0,
autoselect=self._use_autoselect,
label="~~~",
on_activate_call=bs.Call(public_servers))
for server in servers:
self._server_button = bui.buttonwidget(
color=(0.8, 0, 1),
parent=self._root_widget,
position=( (h- self._button_width / 2 ) + self._button_width + 20, v),
size=(self._button_width, self._button_height),
scale=1.0,
autoselect=self._use_autoselect,
label=server["name"][0:22],
on_activate_call=bs.Call(bs.connect_to_party, server["ip"], server["port"]))
v -= 50
return returnValue
return wrapper
v_h = v
connect = bs.connect_to_party
def connect_to_party(address, port=43210, print_progress=False):
global current_server_ip
global current_server_port
if (bs.get_connection_to_host_info() != {}):
bs.disconnect_from_host()
current_server_ip = address
current_server_port = port
connect(address, port, print_progress)
babase.apptimer(1, check_connect_status)
def check_connect_status():
global servers
global current_server_ip
global current_server_port
if (bs.get_connection_to_host_info() != {}):
if (not bs.get_connection_to_host_info()['name']):
babase.apptimer(1, check_connect_status)
return
new_server = {"name": bs.get_connection_to_host_info()['name'], "ip": current_server_ip, "port": current_server_port}
if new_server not in servers:
servers.append(new_server)
servers = servers[-3:]
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:
print("connection failed falling back to gather window")
public_servers()
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)
def public_servers(origin = None):
from bauiv1lib.gather import GatherWindow
bui.app.ui_v1.set_main_menu_window( GatherWindow(origin_widget=origin).get_root_widget())
# ba_meta export plugin
class bySmoothy(babase.Plugin):
def __init__(self):
bastd_ui_mainmenu.MainMenuWindow._refresh_in_game = _refresh_in_game(bastd_ui_mainmenu.MainMenuWindow._refresh_in_game)
bs.connect_to_party = connect_to_party
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")