security patch and other bug fixes.

This commit is contained in:
Ayush Saini 2023-05-28 14:07:54 +05:30
parent 99352f0f84
commit cafc2e0225
20 changed files with 494 additions and 263 deletions

View file

@ -46,6 +46,10 @@
"77": { "77": {
"log": "system logs, security patch, discord webhook logs dump.", "log": "system logs, security patch, discord webhook logs dump.",
"time": "8 April 2023" "time": "8 April 2023"
},
"78": {
"log": "security update: auto handle server queue, fake accounts protection, allow owner to join houefull server. And other bug fixes. ",
"time": "28 May 2023"
} }
} }

View file

@ -5,9 +5,6 @@ import ba
import ba.internal import ba.internal
def clientid_to_accountid(clientid): def clientid_to_accountid(clientid):
""" """
Transform Clientid To Accountid Transform Clientid To Accountid
@ -24,9 +21,6 @@ def clientid_to_accountid(clientid):
return None return None
def check_permissions(accountid, command): def check_permissions(accountid, command):
""" """
Checks The Permission To Player To Executive Command Checks The Permission To Player To Executive Command
@ -54,5 +48,5 @@ def check_permissions(accountid, command):
def is_server(accid): def is_server(accid):
for i in ba.internal.get_game_roster(): for i in ba.internal.get_game_roster():
if i['account_id']==accid and i['client_id']==-1: if i['account_id'] == accid and i['client_id'] == -1:
return True return True

View file

@ -182,7 +182,8 @@ class Floater(ba.Actor):
pn = self.node.position pn = self.node.position
dist = self.distance(pn[0], pn[1], pn[2], px, py, pz) dist = self.distance(pn[0], pn[1], pn[2], px, py, pz)
self.node.velocity = ((px - pn[0]) / dist, (py - pn[1]) / dist, (pz - pn[2]) / dist) self.node.velocity = ((px - pn[0]) / dist, (py - pn[1]) / dist, (pz - pn[2]) / dist)
ba.timer(dist-1, ba.WeakCall(self.move), suppress_format_warning=True) t = dist - 1 if dist - 1 >= 0 else 0.1
ba.timer(t, ba.WeakCall(self.move), suppress_format_warning=True)
def handlemessage(self, msg): def handlemessage(self, msg):
if isinstance(msg, ba.DieMessage): if isinstance(msg, ba.DieMessage):

View file

@ -5,7 +5,7 @@ from serverData import serverdata
from chatHandle.ChatCommands import Main from chatHandle.ChatCommands import Main
from tools import logger, servercheck from tools import logger, servercheck
from chatHandle.chatFilter import ChatFilter from chatHandle.chatFilter import ChatFilter
from features import EndVote from features import votingmachine
import ba, _ba import ba, _ba
import ba.internal import ba.internal
import setting import setting
@ -18,7 +18,7 @@ def filter_chat_message(msg, client_id):
if msg.startswith("/"): if msg.startswith("/"):
Main.Command(msg, client_id) Main.Command(msg, client_id)
return None return None
logger.log("Host msg: | " + msg , "chat") logger.log(f"Host msg: | {msg}" , "chat")
return msg return msg
acid = "" acid = ""
displaystring = "" displaystring = ""
@ -36,14 +36,15 @@ def filter_chat_message(msg, client_id):
msg = ChatFilter.filter(msg, acid, client_id) msg = ChatFilter.filter(msg, acid, client_id)
if msg == None: if msg == None:
return return
logger.log(acid + " | " + displaystring + " | " + currentname + " | " + msg, "chat") logger.log(f'{acid} | {displaystring}| {currentname} | {msg}', "chat")
if msg.startswith("/"): if msg.startswith("/"):
msg = Main.Command(msg, client_id) msg = Main.Command(msg, client_id)
if msg == None: if msg == None:
return return
if msg == "end" and settings["allowEndVote"]: if msg in ["end","dv","nv","sm"] and settings["allowVotes"]:
EndVote.vote_end(acid, client_id) votingmachine.vote(acid, client_id, msg)
if acid in serverdata.clients and serverdata.clients[acid]["verified"]: if acid in serverdata.clients and serverdata.clients[acid]["verified"]:
@ -64,7 +65,6 @@ def filter_chat_message(msg, client_id):
return Main.QuickAccess(msg, client_id) return Main.QuickAccess(msg, client_id)
return msg return msg
else: else:
_ba.screenmessage("Fetching your account info , Wait a minute", transient=True, clients=[client_id]) _ba.screenmessage("Fetching your account info , Wait a minute", transient=True, clients=[client_id])
return None return None

View file

@ -8,10 +8,11 @@
# pylint: disable=protected-access # pylint: disable=protected-access
from __future__ import annotations from __future__ import annotations
from ba._servermode import ServerController
from ba._session import Session
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from datetime import datetime from datetime import datetime
import _thread import _thread
import importlib import importlib
import time import time
@ -19,19 +20,18 @@ import os
import ba import ba
import _ba import _ba
import logging import logging
from ba import _hooks
from bastd.activity import dualteamscore, multiteamscore, drawscore from bastd.activity import dualteamscore, multiteamscore, drawscore
from bastd.activity.coopscore import CoopScoreScreen from bastd.activity.coopscore import CoopScoreScreen
import setting import setting
from tools import account
from chatHandle import handlechat from chatHandle import handlechat
from features import team_balancer, afk_check, fire_flies, hearts, dual_team_score as newdts from features import team_balancer, afk_check, fire_flies, hearts, dual_team_score as newdts
from stats import mystats from stats import mystats
from spazmod import modifyspaz from spazmod import modifyspaz
from tools import servercheck, ServerUpdate, logger, playlist from tools import servercheck, ServerUpdate, logger, playlist, servercontroller
from playersData import pdata from playersData import pdata
from serverData import serverdata from serverData import serverdata
from features import EndVote from features import votingmachine
from features import text_on_map, announcement from features import text_on_map, announcement
from features import map_fun from features import map_fun
from spazmod import modifyspaz from spazmod import modifyspaz
@ -46,19 +46,17 @@ def filter_chat_message(msg: str, client_id: int) -> str | None:
return handlechat.filter_chat_message(msg, client_id) return handlechat.filter_chat_message(msg, client_id)
# ba_meta export plugin # ba_meta export plugin
class modSetup(ba.Plugin): class modSetup(ba.Plugin):
def on_app_running(self): def on_app_running(self):
"""Runs when app is launched.""" """Runs when app is launched."""
bootstraping() bootstraping()
servercheck.checkserver().start() servercheck.checkserver().start()
ServerUpdate.check() ServerUpdate.check()
ba.timer(5, account.updateOwnerIps)
if settings["afk_remover"]['enable']: if settings["afk_remover"]['enable']:
afk_check.checkIdle().start() afk_check.checkIdle().start()
if (settings["useV2Account"]): if (settings["useV2Account"]):
from tools import account
if (ba.internal.get_v1_account_state() == 'signed_in' and ba.internal.get_v1_account_type() == 'V2'): if (ba.internal.get_v1_account_state() == 'signed_in' and ba.internal.get_v1_account_type() == 'V2'):
logging.debug("Account V2 is active") logging.debug("Account V2 is active")
else: else:
@ -133,17 +131,20 @@ def bootstraping():
import subprocess import subprocess
# Install psutil package # Install psutil package
# Download get-pip.py # Download get-pip.py
curl_process = subprocess.Popen(["curl", "-sS", "https://bootstrap.pypa.io/get-pip.py"], stdout=subprocess.PIPE) curl_process = subprocess.Popen(
["curl", "-sS", "https://bootstrap.pypa.io/get-pip.py"], stdout=subprocess.PIPE)
# Install pip using python3.10 # Install pip using python3.10
python_process = subprocess.Popen(["python3.10"], stdin=curl_process.stdout) python_process = subprocess.Popen(
["python3.10"], stdin=curl_process.stdout)
# Wait for the processes to finish # Wait for the processes to finish
curl_process.stdout.close() curl_process.stdout.close()
python_process.wait() python_process.wait()
subprocess.check_call(["python3.10","-m","pip", "install", "psutil"]) subprocess.check_call(
#restart after installation ["python3.10", "-m", "pip", "install", "psutil"])
# restart after installation
print("dependency installed , restarting server") print("dependency installed , restarting server")
_ba.quit() _ba.quit()
from tools import healthcheck from tools import healthcheck
@ -155,8 +156,6 @@ def bootstraping():
if settings["whitelist"]: if settings["whitelist"]:
pdata.load_white_list() pdata.load_white_list()
#
import_discord_bot() import_discord_bot()
import_games() import_games()
import_dual_team_score() import_dual_team_score()
@ -193,7 +192,7 @@ def import_games():
def import_dual_team_score() -> None: def import_dual_team_score() -> None:
"""Imports the dual team score.""" """Imports the dual team score."""
if settings["newResultBoard"] and _ba.get_foreground_host_session().use_teams: if settings["newResultBoard"]:
dualteamscore.TeamVictoryScoreScreenActivity = newdts.TeamVictoryScoreScreenActivity dualteamscore.TeamVictoryScoreScreenActivity = newdts.TeamVictoryScoreScreenActivity
multiteamscore.MultiTeamScoreScreenActivity.show_player_scores = newdts.show_player_scores multiteamscore.MultiTeamScoreScreenActivity.show_player_scores = newdts.show_player_scores
drawscore.DrawScoreScreenActivity = newdts.DrawScoreScreenActivity drawscore.DrawScoreScreenActivity = newdts.DrawScoreScreenActivity
@ -208,8 +207,8 @@ def new_begin(self):
night_mode() night_mode()
if settings["colorfullMap"]: if settings["colorfullMap"]:
map_fun.decorate_map() map_fun.decorate_map()
EndVote.voters = [] votingmachine.reset_votes()
EndVote.game_started_on = time.time() votingmachine.game_started_on = time.time()
ba._activity.Activity.on_begin = new_begin ba._activity.Activity.on_begin = new_begin
@ -224,13 +223,19 @@ def new_end(self, results: Any = None, delay: float = 0.0, force: bool = False):
if isinstance(activity, CoopScoreScreen): if isinstance(activity, CoopScoreScreen):
team_balancer.checkToExitCoop() team_balancer.checkToExitCoop()
org_end(self, results, delay, force) org_end(self, results, delay, force)
ba._activity.Activity.end = new_end ba._activity.Activity.end = new_end
org_player_join = ba._activity.Activity.on_player_join org_player_join = ba._activity.Activity.on_player_join
def on_player_join(self, player) -> None: def on_player_join(self, player) -> None:
"""Runs when player joins the game.""" """Runs when player joins the game."""
team_balancer.on_player_join() team_balancer.on_player_join()
org_player_join(self, player) org_player_join(self, player)
ba._activity.Activity.on_player_join = on_player_join ba._activity.Activity.on_player_join = on_player_join
@ -277,30 +282,31 @@ def on_map_init():
text_on_map.textonmap() text_on_map.textonmap()
modifyspaz.setTeamCharacter() modifyspaz.setTeamCharacter()
from ba._servermode import ServerController
def shutdown(func) -> None: def shutdown(func) -> None:
"""Set the app to quit either now or at the next clean opportunity.""" """Set the app to quit either now or at the next clean opportunity."""
def wrapper(*args, **kwargs): def wrapper(*args, **kwargs):
# add screen text and tell players we are going to restart soon. # add screen text and tell players we are going to restart soon.
ba.internal.chatmessage("Server will restart on next opportunity. (series end)") ba.internal.chatmessage(
"Server will restart on next opportunity. (series end)")
_ba.restart_scheduled = True _ba.restart_scheduled = True
_ba.get_foreground_host_activity().restart_msg = _ba.newnode('text', _ba.get_foreground_host_activity().restart_msg = _ba.newnode('text',
attrs={ attrs={
'text':"Server going to restart after this series.", 'text': "Server going to restart after this series.",
'flatness':1.0, 'flatness': 1.0,
'h_align':'right', 'h_align': 'right',
'v_attach':'bottom', 'v_attach': 'bottom',
'h_attach':'right', 'h_attach': 'right',
'scale':0.5, 'scale': 0.5,
'position':(-25,54), 'position': (-25, 54),
'color':(1,0.5,0.7) 'color': (1, 0.5, 0.7)
}) })
func(*args, **kwargs) func(*args, **kwargs)
return wrapper return wrapper
ServerController.shutdown = shutdown(ServerController.shutdown) ServerController.shutdown = shutdown(ServerController.shutdown)
from ba._session import Session
def on_player_request(func) -> bool: def on_player_request(func) -> bool:
def wrapper(*args, **kwargs): def wrapper(*args, **kwargs):
player = args[1] player = args[1]
@ -309,11 +315,15 @@ def on_player_request(func) -> bool:
return False return False
for current_player in args[0].sessionplayers: for current_player in args[0].sessionplayers:
if current_player.get_v1_account_id() == player.get_v1_account_id(): if current_player.get_v1_account_id() == player.get_v1_account_id():
count +=1 count += 1
if count >= settings["maxPlayersPerDevice"]: if count >= settings["maxPlayersPerDevice"]:
_ba.screenmessage("Reached max players limit per device",clients=[player.inputdevice.client_id],transient=True,) _ba.screenmessage("Reached max players limit per device", clients=[player.inputdevice.client_id], transient=True,)
return False return False
return func(*args, **kwargs) return func(*args, **kwargs)
return wrapper return wrapper
Session.on_player_request = on_player_request(Session.on_player_request) Session.on_player_request = on_player_request(Session.on_player_request)
ServerController._access_check_response = servercontroller._access_check_response

View file

@ -46,17 +46,17 @@ class TeamVictoryScoreScreenActivity(MultiTeamScoreScreenActivity):
best_txt = ba.Lstr(resource='bestOfSeriesText', best_txt = ba.Lstr(resource='bestOfSeriesText',
subs=[('${COUNT}', subs=[('${COUNT}',
str(session.get_series_length()))]) str(session.get_series_length()))])
if len(self.teams) != 2:
# ZoomText(best_txt, ZoomText(best_txt,
# position=(0, 175), position=(0, 175),
# shiftposition=(-250, 175), shiftposition=(-250, 175),
# shiftdelay=2.5, shiftdelay=2.5,
# flash=False, flash=False,
# trail=False, trail=False,
# h_align='center', h_align='center',
# scale=0.25, scale=0.25,
# color=(0.5, 0.5, 0.5, 1.0), color=(0.5, 0.5, 0.5, 1.0),
# jitter=3.0).autoretain() jitter=3.0).autoretain()
for team in self.session.sessionteams: for team in self.session.sessionteams:
ba.timer( ba.timer(
i * 0.15 + 0.15, i * 0.15 + 0.15,
@ -86,6 +86,20 @@ class TeamVictoryScoreScreenActivity(MultiTeamScoreScreenActivity):
def _show_team_name(self, pos_v: float, team: ba.SessionTeam, def _show_team_name(self, pos_v: float, team: ba.SessionTeam,
kill_delay: float, shiftdelay: float) -> None: kill_delay: float, shiftdelay: float) -> None:
del kill_delay # Unused arg. del kill_delay # Unused arg.
if len(self.teams) != 2:
ZoomText(
ba.Lstr(value='${A}:', subs=[('${A}', team.name)]),
position=(100, pos_v),
shiftposition=(-150, pos_v),
shiftdelay=shiftdelay,
flash=False,
trail=False,
h_align='right',
maxwidth=300,
color=team.color,
jitter=1.0,
).autoretain()
else:
ZoomText(ba.Lstr(value='${A}', subs=[('${A}', team.name)]), ZoomText(ba.Lstr(value='${A}', subs=[('${A}', team.name)]),
position=(-250, 260) if pos_v == 65 else (250, 260), position=(-250, 260) if pos_v == 65 else (250, 260),
shiftposition=(-250, 260) if pos_v == 65 else (250, 260), shiftposition=(-250, 260) if pos_v == 65 else (250, 260),
@ -100,6 +114,22 @@ class TeamVictoryScoreScreenActivity(MultiTeamScoreScreenActivity):
def _show_team_old_score(self, pos_v: float, sessionteam: ba.SessionTeam, def _show_team_old_score(self, pos_v: float, sessionteam: ba.SessionTeam,
shiftdelay: float) -> None: shiftdelay: float) -> None:
if len(self.teams) != 2:
ZoomText(
str(sessionteam.customdata['score'] - 1),
position=(150, pos_v),
maxwidth=100,
color=(0.6, 0.6, 0.7),
shiftposition=(-100, pos_v),
shiftdelay=shiftdelay,
flash=False,
trail=False,
lifespan=1.0,
h_align='left',
jitter=1.0,
).autoretain()
else:
ZoomText(str(sessionteam.customdata['score'] - 1), ZoomText(str(sessionteam.customdata['score'] - 1),
position=(-250, 190) if pos_v == 65 else (250, 190), position=(-250, 190) if pos_v == 65 else (250, 190),
maxwidth=100, maxwidth=100,
@ -117,6 +147,21 @@ class TeamVictoryScoreScreenActivity(MultiTeamScoreScreenActivity):
scored: bool, kill_delay: float, scored: bool, kill_delay: float,
shiftdelay: float) -> None: shiftdelay: float) -> None:
del kill_delay # Unused arg. del kill_delay # Unused arg.
if len(self.teams) != 2:
ZoomText(
str(sessionteam.customdata['score']),
position=(150, pos_v),
maxwidth=100,
color=(1.0, 0.9, 0.5) if scored else (0.6, 0.6, 0.7),
shiftposition=(-100, pos_v),
shiftdelay=shiftdelay,
flash=scored,
trail=scored,
h_align='left',
jitter=1.0,
trailcolor=(1, 0.8, 0.0, 0),
).autoretain()
else:
ZoomText(str(sessionteam.customdata['score']), ZoomText(str(sessionteam.customdata['score']),
position=(-250, 190) if pos_v == 65 else (250, 190), position=(-250, 190) if pos_v == 65 else (250, 190),
maxwidth=100, maxwidth=100,
@ -241,6 +286,19 @@ def show_player_scores(self,
h_align=Text.HAlign.CENTER, h_align=Text.HAlign.CENTER,
extrascale=1.4, extrascale=1.4,
maxwidth=None) maxwidth=None)
else:
tval = ba.Lstr(
resource='gameLeadersText',
subs=[('${COUNT}', str(session.get_game_number()))],
)
_txt(
180,
43,
tval,
h_align=Text.HAlign.CENTER,
extrascale=1.4,
maxwidth=None,
)
_txt(-15, 4, ba.Lstr(resource='playerText'), h_align=Text.HAlign.LEFT) _txt(-15, 4, ba.Lstr(resource='playerText'), h_align=Text.HAlign.LEFT)
_txt(180, 4, ba.Lstr(resource='killsText')) _txt(180, 4, ba.Lstr(resource='killsText'))
_txt(280, 4, ba.Lstr(resource='deathsText'), maxwidth=100) _txt(280, 4, ba.Lstr(resource='deathsText'), maxwidth=100)

View file

@ -27,6 +27,7 @@ def balanceTeams():
teamBSize += 1 teamBSize += 1
except: except:
pass pass
if settings["autoTeamBalance"]:
if abs(teamBSize-teamASize) >= 0: if abs(teamBSize-teamASize) >= 0:
if teamBSize > teamASize and teamBSize != 0: if teamBSize > teamASize and teamBSize != 0:
movePlayers(1, 0, abs(teamBSize-teamASize)-1) movePlayers(1, 0, abs(teamBSize-teamASize)-1)
@ -40,7 +41,6 @@ def movePlayers(fromTeam, toTeam, count):
toTeam = session.sessionteams[toTeam] toTeam = session.sessionteams[toTeam]
for i in range(0, count): for i in range(0, count):
player = fromTeam.players.pop() player = fromTeam.players.pop()
print("moved"+player.get_v1_account_id())
broadCastShiftMsg(player.get_v1_account_id()) broadCastShiftMsg(player.get_v1_account_id())
player.setdata(team=toTeam, character=player.character, player.setdata(team=toTeam, character=player.character,
color=toTeam.color, highlight=player.highlight) color=toTeam.color, highlight=player.highlight)

View file

@ -21,6 +21,7 @@ class textonmap:
nextMap=ba.internal.get_foreground_host_session().get_next_game_description().evaluate() nextMap=ba.internal.get_foreground_host_session().get_next_game_description().evaluate()
except: except:
pass pass
top = top.replace("@IP", _ba.our_ip).replace("@PORT", _ba.our_port)
self.index = 0 self.index = 0
self.highlights = data['center highlights']["msg"] self.highlights = data['center highlights']["msg"]
self.left_watermark(left) self.left_watermark(left)

View file

@ -1,31 +1,40 @@
# EndVote by -mr.smoothy # Electronic Voting Machine (EVM) by -mr.smoothy
import _ba import _ba
import ba import ba
import ba.internal import ba.internal
import time import time
last_end_vote_start_time = 0
end_vote_duration = 50
game_started_on = 0 game_started_on = 0
min_game_duration_to_start_end_vote = 30
voters = []
def vote_end(pb_id, client_id): vote_machine = {"end": {"last_vote_start_time": 0, "vote_duration": 50,
global voters "min_game_duration_to_start_vote": 30, "voters": []},
global last_end_vote_start_time "sm": {"last_vote_start_time": 0, "vote_duration": 50,
"min_game_duration_to_start_vote": 1, "voters": []},
"nv": {"last_vote_start_time": 0, "vote_duration": 50,
"min_game_duration_to_start_vote": 1, "voters": []},
"dv": {"last_vote_start_time": 0, "vote_duration": 50,
"min_game_duration_to_start_vote": 1, "voters": []}}
def vote(pb_id, client_id, vote_type):
global vote_machine
voters = vote_machine[vote_type]["voters"]
last_vote_start_time = vote_machine[vote_type]["last_vote_start_time"]
vote_duration = vote_machine[vote_type]["vote_duration"]
min_game_duration_to_start_vote = vote_machine[vote_type]["min_game_duration_to_start_vote"]
now = time.time() now = time.time()
if now > last_end_vote_start_time + end_vote_duration: if now > last_vote_start_time + vote_duration:
voters = [] voters = []
last_end_vote_start_time = now last_vote_start_time = now
if now < game_started_on + min_game_duration_to_start_end_vote: if now < game_started_on + min_game_duration_to_start_vote:
_ba.screenmessage("Seems game just started, Try again after some time", transient=True, _ba.screenmessage("Seems game just started, Try again after some time", transient=True,
clients=[client_id]) clients=[client_id])
return return
if len(voters) == 0: if len(voters) == 0:
ba.internal.chatmessage("end vote started") ba.internal.chatmessage(f"{vote_type} vote started")
# clean up voters list # clean up voters list
active_players = [] active_players = []
@ -36,25 +45,34 @@ def vote_end(pb_id, client_id):
voters.remove(voter) voters.remove(voter)
if pb_id not in voters: if pb_id not in voters:
voters.append(pb_id) voters.append(pb_id)
_ba.screenmessage("Thanks for vote , encourage other players to type 'end' too.", transient=True, _ba.screenmessage(f'Thanks for vote , encourage other players to type {vote_type} too.', transient=True,
clients=[client_id]) clients=[client_id])
if vote_type == 'end':
update_vote_text(required_votes(len(active_players)) - len(voters)) update_vote_text(required_votes(len(active_players)) - len(voters))
if required_votes(len(active_players)) - len(
voters) == 3: # lets dont spam chat/screen message with votes required , only give message when only 3 votes left
ba.internal.chatmessage("3 more end votes required")
if len(voters) >= required_votes(len(active_players)): if len(voters) >= required_votes(len(active_players)):
ba.internal.chatmessage("end vote succeed") ba.internal.chatmessage(f"{vote_type} vote succeed")
if vote_type == "end":
try: try:
with _ba.Context(_ba.get_foreground_host_activity()): with _ba.Context(_ba.get_foreground_host_activity()):
_ba.get_foreground_host_activity().end_game() _ba.get_foreground_host_activity().end_game()
except: except:
pass pass
elif vote_type == "nv":
_ba.chatmessage("/nv")
elif vote_type == "dv":
_ba.chatmessage("/dv")
elif vote_type == "sm":
_ba.chatmessage("/sm")
def reset_votes():
global vote_machine
for value in vote_machine.values():
value["voters"] = []
def required_votes(players): def required_votes(players):
if players == 2: if players == 2:
return 1 return 2
elif players == 3: elif players == 3:
return 2 return 2
elif players == 4: elif players == 4:

View file

@ -11,7 +11,7 @@ CONFIGS = {
"AdaptivePos": True, "AdaptivePos": True,
"IgnoreOnMaps": [], "IgnoreOnMaps": [],
"Colors": { "Colors": {
"Intensity": 0.8, "Intensity": 0.5,
"Animate": True, "Animate": True,
"Random": True, "Random": True,
"LeftSide": (1, 0, 1), "LeftSide": (1, 0, 1),

View file

@ -6,7 +6,7 @@
"BrodcastCommand": true "BrodcastCommand": true
}, },
"textonmap": { "textonmap": {
"top watermark": "Welcome to server \nip 192.168.0.1", "top watermark": "Welcome to server \nIP @IP PORT @PORT",
"bottom left watermark": "Owner : <owner-name> \nEditor : <bablu>\nScripts : BCS1.7.13", "bottom left watermark": "Owner : <owner-name> \nEditor : <bablu>\nScripts : BCS1.7.13",
"center highlights":{ "center highlights":{
"color":[1,0,0], "color":[1,0,0],
@ -52,7 +52,7 @@
"minPlayerToExitCoop":0 "minPlayerToExitCoop":0
}, },
"mikirogQuickTurn":{ "mikirogQuickTurn":{
"enable":true "enable":false
}, },
"colorful_explosions":{ "colorful_explosions":{
"enable":true "enable":true
@ -102,14 +102,21 @@
"kick_idle_from_lobby":true, "kick_idle_from_lobby":true,
"lobby_idle_time_in_secs":10 "lobby_idle_time_in_secs":10
}, },
"playermod": {
"default_boxing_gloves": true,
"default_shield" : false,
"default_bomb" : "normal",
"default_bomb_count" : 1
},
"allowTeamChat":true, "allowTeamChat":true,
"allowEndVote":true, "allowVotes":true,
"allowInGameChat":true, "allowInGameChat":true,
"sameCharacterForTeam":false, "sameCharacterForTeam":false,
"newResultBoard":true, "newResultBoard":true,
"HostDeviceName":"v1.4", "HostDeviceName":"v1.4",
"HostName":"BCS", "HostName":"BCS",
"ShowKickVoteStarterName":true, "ShowKickVoteStarterName":true,
"autoTeamBalance": true,
"KickVoteMsgType":"chat", "KickVoteMsgType":"chat",
"minAgeToChatInHours":78, "minAgeToChatInHours":78,
"minAgeToJoinInHours":24, "minAgeToJoinInHours":24,

View file

@ -2,15 +2,17 @@ from spazmod import tag
import setting import setting
from random import randint from random import randint
from spazmod import hitmessage from spazmod import hitmessage
import _ba,ba import _ba
import ba
import ba.internal import ba.internal
_setting=setting.get_settings_data() _setting = setting.get_settings_data()
if _setting['enableeffects']: if _setting['enableeffects']:
from spazmod import spaz_effects from spazmod import spaz_effects
spaz_effects.apply() spaz_effects.apply()
def update_name(): def update_name():
import ba.internal import ba.internal
from stats import mystats from stats import mystats
@ -25,18 +27,25 @@ def update_name():
mystats.dump_stats(stat) mystats.dump_stats(stat)
# all activites related to modify spaz by any how will be here # all activites related to modify spaz by any how will be here
def main(spaz, node, player):
def main(spaz, node, player):
if _setting['enablehptag']: if _setting['enablehptag']:
tag.addhp(node, spaz) tag.addhp(node, spaz)
if _setting['enabletags']: if _setting['enabletags']:
tag.addtag(node,player) tag.addtag(node, player)
if _setting['enablerank']: if _setting['enablerank']:
tag.addrank(node,player) tag.addrank(node, player)
if _setting["playermod"]['default_boxing_gloves']:
spaz.equip_boxing_gloves()
if _setting['playermod']['default_shield']:
spaz.equip_shields()
spaz.bomb_type_default = _setting['playermod']['default_bomb']
spaz.bomb_count = _setting['playermod']['default_bomb_count']
# update_name() will add threading here later . it was adding delay on game start
#update_name() will add threading here later . it was adding delay on game start
def getCharacter(player,character): def getCharacter(player, character):
if _setting["sameCharacterForTeam"]: if _setting["sameCharacterForTeam"]:
@ -48,12 +57,13 @@ def getCharacter(player,character):
def getRandomCharacter(otherthen): def getRandomCharacter(otherthen):
characters=list(ba.app.spaz_appearances.keys()) characters = list(ba.app.spaz_appearances.keys())
invalid_characters=["Snake Shadow","Lee","Zola","Butch","Witch","Middle-Man","Alien","OldLady","Wrestler","Gretel","Robot"] invalid_characters = ["Snake Shadow", "Lee", "Zola", "Butch", "Witch",
"Middle-Man", "Alien", "OldLady", "Wrestler", "Gretel", "Robot"]
while True: while True:
val=randint(0,len(characters)-1) val = randint(0, len(characters)-1)
ch=characters[val] ch = characters[val]
if ch not in invalid_characters and ch not in otherthen: if ch not in invalid_characters and ch not in otherthen:
return ch return ch
@ -61,12 +71,11 @@ def getRandomCharacter(otherthen):
def setTeamCharacter(): def setTeamCharacter():
if not _setting["sameCharacterForTeam"]: if not _setting["sameCharacterForTeam"]:
return return
used=[] used = []
teams=ba.internal.get_foreground_host_session().sessionteams teams = ba.internal.get_foreground_host_session().sessionteams
if len(teams) < 10: if len(teams) < 10:
for team in teams: for team in teams:
character=getRandomCharacter(used) character = getRandomCharacter(used)
used.append(character) used.append(character)
team.name=character team.name = character
team.customdata["character"]=character team.customdata["character"] = character

View file

@ -105,10 +105,20 @@ class Rank(object):
'operation': 'add' 'operation': 'add'
}) })
self.node.connectattr('torso_position', mnode, 'input2') self.node.connectattr('torso_position', mnode, 'input2')
if (rank == 1):
rank = '\ue01f' + "#"+str(rank) +'\ue01f'
elif (rank ==2):
rank = '\ue01f' + "#"+str(rank) +'\ue01f'
elif (rank ==3):
rank = '\ue01f' + "#"+str(rank) +'\ue01f'
else:
rank = "#"+str(rank)
self.rank_text = ba.newnode('text', self.rank_text = ba.newnode('text',
owner=self.node, owner=self.node,
attrs={ attrs={
'text': "#"+str(rank), 'text': rank,
'in_world': True, 'in_world': True,
'shadow': 1.0, 'shadow': 1.0,
'flatness': 1.0, 'flatness': 1.0,

View file

@ -101,7 +101,7 @@ def dump_stats(s: dict):
def get_stats_by_id(account_id: str): def get_stats_by_id(account_id: str):
a = get_cached_stats a = get_cached_stats()
if account_id in a: if account_id in a:
return a[account_id] return a[account_id]
else: else:

View file

@ -6,7 +6,7 @@ from efro.terminal import Clr
import json import json
import requests import requests
import _ba import _ba
VERSION=77 VERSION=78
def check(): def check():

View file

@ -2,14 +2,16 @@
from __future__ import annotations from __future__ import annotations
import ba import ba
import _ba
import bacommon.cloud import bacommon.cloud
import logging import logging
from efro.error import CommunicationError from efro.error import CommunicationError
from playersData import pdata
STATUS_CHECK_INTERVAL_SECONDS = 2.0 STATUS_CHECK_INTERVAL_SECONDS = 2.0
class AccountUtil: class AccountUtil:
def __init__(self): def __init__(self):
self._proxyid: str | None = None self._proxyid: str | None = None
@ -26,7 +28,7 @@ class AccountUtil:
return return
address = ba.internal.get_master_server_address( address = ba.internal.get_master_server_address(
version=2) + response.url version=2) + response.url
logging.debug("Copy this URL to your browser : " +address) logging.debug("Copy this URL to your browser : " + address)
self._proxyid = response.proxyid self._proxyid = response.proxyid
self._proxykey = response.proxykey self._proxykey = response.proxykey
ba.timer(STATUS_CHECK_INTERVAL_SECONDS, ba.timer(STATUS_CHECK_INTERVAL_SECONDS,
@ -57,7 +59,7 @@ class AccountUtil:
assert response.credentials is not None assert response.credentials is not None
ba.app.accounts_v2.set_primary_credentials(response.credentials) ba.app.accounts_v2.set_primary_credentials(response.credentials)
ba.timer(3,self._logged_in) ba.timer(3, self._logged_in)
return return
@ -66,15 +68,19 @@ class AccountUtil:
or response.state is response.State.WAITING): or response.state is response.State.WAITING):
ba.timer(STATUS_CHECK_INTERVAL_SECONDS, ba.timer(STATUS_CHECK_INTERVAL_SECONDS,
ba.Call(self._ask_for_status)) ba.Call(self._ask_for_status))
def _logged_in(self):
logging.info("Logged in as: "+ba.internal.get_v1_account_display_string())
# #ba_meta export plugin def _logged_in(self):
# class AccountV2(ba.Plugin): logging.info("Logged in as: " +
# def __init__(self): ba.internal.get_v1_account_display_string())
# if(ba.internal.get_v1_account_state()=='signed_in' and ba.internal.get_v1_account_type()=='V2'):
# logging.debug("Account V2 is active")
# else: def updateOwnerIps():
# logging.warning("Account V2 login require ....stay tuned.") accountIds = pdata.get_roles()["owner"]["ids"]
# ba.timer(3, ba.Call(logging.debug,"Starting Account V2 login process....")) profiles = pdata.get_profiles()
# ba.timer(6,AccountUtil)
for account_id in accountIds:
if account_id in profiles:
profile = profiles[account_id]
if "lastIP" in profile:
ip = profile["lastIP"]
_ba.append_owner_ip(ip)

View file

@ -27,7 +27,7 @@ class checkserver(object):
def start(self): def start(self):
self.players = [] self.players = []
self.t1 = ba.timer(1, ba.Call(self.check), repeat=True) self.t1 = ba.Timer(1, ba.Call(self.check), repeat=True, timetype=ba.TimeType.REAL)
def check(self): def check(self):
newPlayers = [] newPlayers = []
@ -36,6 +36,10 @@ class checkserver(object):
for ros in ba.internal.get_game_roster(): for ros in ba.internal.get_game_roster():
ip = _ba.get_client_ip(ros["client_id"]) ip = _ba.get_client_ip(ros["client_id"])
device_id = _ba.get_client_public_device_uuid(ros["client_id"]) device_id = _ba.get_client_public_device_uuid(ros["client_id"])
# if not ros["account_id"]:
# logger.log(f'Player disconnected, None account Id || {ros["display_string"] } IP {ip} {device_id}' ,
# "playerjoin")
# ba.internal.disconnect_client(ros["client_id"], 0)
if device_id not in deviceClientMap: if device_id not in deviceClientMap:
deviceClientMap[device_id] = [ros["client_id"]] deviceClientMap[device_id] = [ros["client_id"]]
else: else:
@ -43,7 +47,7 @@ class checkserver(object):
if len(deviceClientMap[device_id]) >= settings['maxAccountPerIP']: if len(deviceClientMap[device_id]) >= settings['maxAccountPerIP']:
_ba.chatmessage(f"Only {settings['maxAccountPerIP']} player per IP allowed, disconnecting this device.", clients=[ros["client_id"]]) _ba.chatmessage(f"Only {settings['maxAccountPerIP']} player per IP allowed, disconnecting this device.", clients=[ros["client_id"]])
ba.internal.disconnect_client(ros["client_id"]) ba.internal.disconnect_client(ros["client_id"])
logger.log(" Player disconnected, reached max players per device ||"+ ros["account_id"] , logger.log(f'Player disconnected, reached max players per device || {ros["account_id"]}' ,
"playerjoin") "playerjoin")
continue continue
if ip not in ipClientMap: if ip not in ipClientMap:
@ -53,7 +57,7 @@ class checkserver(object):
if len(ipClientMap[ip]) >= settings['maxAccountPerIP']: if len(ipClientMap[ip]) >= settings['maxAccountPerIP']:
_ba.chatmessage(f"Only {settings['maxAccountPerIP']} player per IP allowed, disconnecting this device.", clients=[ros["client_id"]]) _ba.chatmessage(f"Only {settings['maxAccountPerIP']} player per IP allowed, disconnecting this device.", clients=[ros["client_id"]])
ba.internal.disconnect_client(ros["client_id"]) ba.internal.disconnect_client(ros["client_id"])
logger.log(" Player disconnected, reached max players per IP address ||"+ ros["account_id"] , logger.log(f'Player disconnected, reached max players per IP address || {ros["account_id"]}' ,
"playerjoin") "playerjoin")
continue continue
newPlayers.append(ros['account_id']) newPlayers.append(ros['account_id'])
@ -65,8 +69,9 @@ class checkserver(object):
d_str2 = profanity.censor(d_str) d_str2 = profanity.censor(d_str)
try: try:
logger.log( logger.log(
d_str + "||" + ros["account_id"] + "|| joined server", f'{d_str} || {ros["account_id"]} || joined server',
"playerjoin") "playerjoin")
logger.log(f'{ros["account_id"]} {ip} {device_id}')
except: except:
pass pass
if d_str2 != d_str: if d_str2 != d_str:
@ -75,8 +80,7 @@ class checkserver(object):
color=(1, 0, 0), transient=True, color=(1, 0, 0), transient=True,
clients=[ros['client_id']]) clients=[ros['client_id']])
try: try:
logger.log(d_str + "||" + ros[ logger.log(f'{d_str} || { ros["account_id"] } || kicked by profanity check',
"account_id"] + "|| kicked by profanity check",
"sys") "sys")
except: except:
pass pass
@ -88,8 +92,7 @@ class checkserver(object):
_ba.screenmessage("Not in whitelist,contact admin", _ba.screenmessage("Not in whitelist,contact admin",
color=(1, 0, 0), transient=True, color=(1, 0, 0), transient=True,
clients=[ros['client_id']]) clients=[ros['client_id']])
logger.log(d_str + "||" + ros[ logger.log(f'{d_str} || { ros["account_id"]} | kicked > not in whitelist')
"account_id"] + " | kicked > not in whitelist")
ba.internal.disconnect_client(ros['client_id']) ba.internal.disconnect_client(ros['client_id'])
return return
@ -124,7 +127,7 @@ def on_player_join_server(pbid, player_data, ip):
_ba.screenmessage("Joining too fast , slow down dude", _ba.screenmessage("Joining too fast , slow down dude",
color=(1, 0, 1), transient=True, color=(1, 0, 1), transient=True,
clients=[clid]) clients=[clid])
logger.log(pbid + "|| kicked for joining too fast") logger.log(f'{pbid} || kicked for joining too fast')
ba.internal.disconnect_client(clid) ba.internal.disconnect_client(clid)
_thread.start_new_thread(reportSpam, (pbid,)) _thread.start_new_thread(reportSpam, (pbid,))
return return
@ -198,7 +201,7 @@ def on_player_join_server(pbid, player_data, ip):
# pdata.add_profile(pbid,d_string,d_string) # pdata.add_profile(pbid,d_string,d_string)
def check_ban(clid,pbid): def check_ban(clid, pbid):
ip = _ba.get_client_ip(clid) ip = _ba.get_client_ip(clid)
device_id = _ba.get_client_public_device_uuid(clid) device_id = _ba.get_client_public_device_uuid(clid)
@ -230,7 +233,7 @@ def verify_account(pb_id, p_data):
serverdata.clients[pb_id]["verified"] = True serverdata.clients[pb_id]["verified"] = True
# ============== IGNORE BLOW CODE , ELSE DIE ======================= # ============== IGNORE BELOW CODE =======================
def _make_request_safe(request, retries=2, raise_err=True): def _make_request_safe(request, retries=2, raise_err=True):
try: try:
@ -262,10 +265,6 @@ def get_account_creation_date(pb_id):
# Convert to IST # Convert to IST
creation_time += datetime.timedelta(hours=5, minutes=30) creation_time += datetime.timedelta(hours=5, minutes=30)
return str(creation_time) return str(creation_time)
# now = datetime.datetime.now()
# delta = now - creation_time
# delta_hours = delta.total_seconds() / (60 * 60)
# return delta_hours
def get_device_accounts(pb_id): def get_device_accounts(pb_id):

View file

@ -0,0 +1,114 @@
from typing import TYPE_CHECKING
from efro.terminal import Clr
import _ba
import ba
if TYPE_CHECKING:
from typing import Any
def _access_check_response(self, data) -> None:
if data is None:
print('error on UDP port access check (internet down?)')
else:
addr = data['address']
port = data['port']
addrstr = f' {addr}'
poststr = ''
_ba.our_ip = addr
_ba.our_port = port
if data['accessible']:
# _fetch_public_servers()
_ba.queue_chcker_timer = ba.Timer(8, ba.Call(simple_queue_checker), repeat=True, timetype=ba.TimeType.REAL)
print(
f'{Clr.SBLU}Master server access check of{addrstr}'
f' udp port {port} succeeded.\n'
f'Your server appears to be'
f' joinable from the internet .{poststr}{Clr.RST}'
)
if self._config.party_is_public:
print(
f'{Clr.SBLU}Your party {self._config.party_name}'
f' visible in public party list.{Clr.RST}'
)
else:
print(
f'{Clr.SBLU}Your private party {self._config.party_name}'
f'can be joined by {addrstr} {port}.{Clr.RST}'
)
else:
print(
f'{Clr.SRED}Master server access check of{addrstr}'
f' udp port {port} failed.\n'
f'Your server does not appear to be'
f' joinable from the internet. Please check your firewall or instance security group.{poststr}{Clr.RST}'
)
def _fetch_public_servers():
ba.internal.add_transaction(
{
'type': 'PUBLIC_PARTY_QUERY',
'proto': ba.app.protocol_version,
'lang': ba.app.lang.language,
},
callback=ba.Call(_on_public_party_response),
)
ba.internal.run_transactions()
def _on_public_party_response(result):
if result is None:
return
parties_in = result['l']
queue_id = None
for party_in in parties_in:
addr = party_in['a']
assert isinstance(addr, str)
port = party_in['p']
assert isinstance(port, int)
if addr == _ba.our_ip and str(port) == str(_ba.our_port):
queue_id = party_in['q']
# aah sad , public party result dont include our own server
if queue_id:
_ba.our_queue_id = queue_id
_ba.queue_chcker_timer = ba.timer(6, ba.Call(check_queue), repeat=True)
else:
print("Something is wrong , why our server is not in public list.")
def check_queue():
ba.internal.add_transaction(
{'type': 'PARTY_QUEUE_QUERY', 'q': _ba.our_queue_id},
callback=ba.Call(on_update_response),
)
ba.internal.run_transactions()
# lets dont spam our own queue
ba.internal.add_transaction(
{'type': 'PARTY_QUEUE_REMOVE', 'q': _ba.our_queue_id}
)
ba.internal.run_transactions()
def on_update_response(response):
allowed_to_join = response["c"]
players_in_queue = response["e"]
max_allowed_in_server = _ba.app.server._config.max_party_size
current_players = len(_ba.get_game_roster())
# print(allowed_to_join)
if allowed_to_join:
# looks good , yipee
_ba.set_public_party_queue_enabled(True)
return
if not allowed_to_join and len(players_in_queue) > 1 and current_players < max_allowed_in_server:
# something is wrong , lets disable queue for some time
_ba.set_public_party_queue_enabled(False)
def simple_queue_checker():
max_allowed_in_server = _ba.app.server._config.max_party_size
current_players = len(_ba.get_game_roster())
if current_players < max_allowed_in_server:
_ba.set_public_party_queue_enabled(False)
else:
_ba.set_public_party_queue_enabled(True)

Binary file not shown.

Binary file not shown.