Bombsquad-Ballistica-Modded.../dist/ba_root/mods/custom_hooks.py
2023-05-28 14:07:54 +05:30

329 lines
11 KiB
Python

"""Custom hooks to pull of the in-game functions."""
# ba_meta require api 7
# (see https://ballistica.net/wiki/meta-tag-system)
# pylint: disable=import-error
# pylint: disable=import-outside-toplevel
# pylint: disable=protected-access
from __future__ import annotations
from ba._servermode import ServerController
from ba._session import Session
from typing import TYPE_CHECKING
from datetime import datetime
import _thread
import importlib
import time
import os
import ba
import _ba
import logging
from bastd.activity import dualteamscore, multiteamscore, drawscore
from bastd.activity.coopscore import CoopScoreScreen
import setting
from tools import account
from chatHandle import handlechat
from features import team_balancer, afk_check, fire_flies, hearts, dual_team_score as newdts
from stats import mystats
from spazmod import modifyspaz
from tools import servercheck, ServerUpdate, logger, playlist, servercontroller
from playersData import pdata
from serverData import serverdata
from features import votingmachine
from features import text_on_map, announcement
from features import map_fun
from spazmod import modifyspaz
if TYPE_CHECKING:
from typing import Optional, Any
settings = setting.get_settings_data()
def filter_chat_message(msg: str, client_id: int) -> str | None:
"""Returns all in game messages or None (ignore's message)."""
return handlechat.filter_chat_message(msg, client_id)
# ba_meta export plugin
class modSetup(ba.Plugin):
def on_app_running(self):
"""Runs when app is launched."""
bootstraping()
servercheck.checkserver().start()
ServerUpdate.check()
ba.timer(5, account.updateOwnerIps)
if settings["afk_remover"]['enable']:
afk_check.checkIdle().start()
if (settings["useV2Account"]):
if (ba.internal.get_v1_account_state() == 'signed_in' and ba.internal.get_v1_account_type() == 'V2'):
logging.debug("Account V2 is active")
else:
logging.warning("Account V2 login require ....stay tuned.")
ba.timer(3, ba.Call(logging.debug,
"Starting Account V2 login process...."))
ba.timer(6, account.AccountUtil)
else:
ba.app.accounts_v2.set_primary_credentials(None)
ba.internal.sign_in_v1('Local')
ba.timer(60, playlist.flush_playlists)
def on_app_shutdown(self):
pass
def score_screen_on_begin(_stats: ba.Stats) -> None:
"""Runs when score screen is displayed."""
team_balancer.balanceTeams()
mystats.update(_stats)
announcement.showScoreScreenAnnouncement()
def playerspaz_init(playerspaz: ba.Player, node: ba.Node, player: ba.Player):
"""Runs when player is spawned on map."""
modifyspaz.main(playerspaz, node, player)
def bootstraping():
"""Bootstarps the server."""
logging.warning("Bootstraping mods...")
# server related
_ba.set_server_device_name(settings["HostDeviceName"])
_ba.set_server_name(settings["HostName"])
_ba.set_transparent_kickvote(settings["ShowKickVoteStarterName"])
_ba.set_kickvote_msg_type(settings["KickVoteMsgType"])
_ba.hide_player_device_id(settings["Anti-IdRevealer"])
# check for auto update stats
_thread.start_new_thread(mystats.refreshStats, ())
pdata.load_cache()
_thread.start_new_thread(pdata.dump_cache, ())
# import plugins
if settings["elPatronPowerups"]["enable"]:
from plugins import elPatronPowerups
elPatronPowerups.enable()
if settings["mikirogQuickTurn"]["enable"]:
from plugins import wavedash # pylint: disable=unused-import
if settings["colorful_explosions"]["enable"]:
from plugins import color_explosion
color_explosion.enable()
if settings["ballistica_web"]["enable"]:
from plugins import bcs_plugin
bcs_plugin.enable()
if settings["character_chooser"]["enable"]:
from plugins import CharacterChooser
CharacterChooser.enable()
if settings["custom_characters"]["enable"]:
from plugins import importcustomcharacters
importcustomcharacters.enable()
if settings["StumbledScoreScreen"]:
from features import StumbledScoreScreen
if settings["colorfullMap"]:
from plugins import colorfulmaps2
try:
from tools import healthcheck
healthcheck.main()
except Exception as e:
print(e)
try:
import subprocess
# Install psutil package
# Download get-pip.py
curl_process = subprocess.Popen(
["curl", "-sS", "https://bootstrap.pypa.io/get-pip.py"], stdout=subprocess.PIPE)
# Install pip using python3.10
python_process = subprocess.Popen(
["python3.10"], stdin=curl_process.stdout)
# Wait for the processes to finish
curl_process.stdout.close()
python_process.wait()
subprocess.check_call(
["python3.10", "-m", "pip", "install", "psutil"])
# restart after installation
print("dependency installed , restarting server")
_ba.quit()
from tools import healthcheck
healthcheck.main()
except:
logging.warning("please install psutil to enable system monitor.")
# import features
if settings["whitelist"]:
pdata.load_white_list()
import_discord_bot()
import_games()
import_dual_team_score()
logger.log("Server started")
def import_discord_bot() -> None:
"""Imports the discord bot."""
if settings["discordbot"]["enable"]:
from features import discord_bot
discord_bot.token = settings["discordbot"]["token"]
discord_bot.liveStatsChannelID = settings["discordbot"]["liveStatsChannelID"]
discord_bot.logsChannelID = settings["discordbot"]["logsChannelID"]
discord_bot.liveChat = settings["discordbot"]["liveChat"]
discord_bot.BsDataThread()
discord_bot.init()
def import_games():
"""Imports the custom games from games directory."""
import sys
sys.path.append(_ba.env()['python_directory_user'] + os.sep + "games")
games = os.listdir("ba_root/mods/games")
for game in games:
if game.endswith(".so"):
importlib.import_module("games." + game.replace(".so", ""))
maps = os.listdir("ba_root/mods/maps")
for _map in maps:
if _map.endswith(".py") or _map.endswith(".so"):
importlib.import_module(
"maps." + _map.replace(".so", "").replace(".py", ""))
def import_dual_team_score() -> None:
"""Imports the dual team score."""
if settings["newResultBoard"]:
dualteamscore.TeamVictoryScoreScreenActivity = newdts.TeamVictoryScoreScreenActivity
multiteamscore.MultiTeamScoreScreenActivity.show_player_scores = newdts.show_player_scores
drawscore.DrawScoreScreenActivity = newdts.DrawScoreScreenActivity
org_begin = ba._activity.Activity.on_begin
def new_begin(self):
"""Runs when game is began."""
org_begin(self)
night_mode()
if settings["colorfullMap"]:
map_fun.decorate_map()
votingmachine.reset_votes()
votingmachine.game_started_on = time.time()
ba._activity.Activity.on_begin = new_begin
org_end = ba._activity.Activity.end
def new_end(self, results: Any = None, delay: float = 0.0, force: bool = False):
"""Runs when game is ended."""
activity = _ba.get_foreground_host_activity()
_ba.prop_axis(1, 0, 0)
if isinstance(activity, CoopScoreScreen):
team_balancer.checkToExitCoop()
org_end(self, results, delay, force)
ba._activity.Activity.end = new_end
org_player_join = ba._activity.Activity.on_player_join
def on_player_join(self, player) -> None:
"""Runs when player joins the game."""
team_balancer.on_player_join()
org_player_join(self, player)
ba._activity.Activity.on_player_join = on_player_join
def night_mode() -> None:
"""Checks the time and enables night mode."""
if settings['autoNightMode']['enable']:
start = datetime.strptime(
settings['autoNightMode']['startTime'], "%H:%M")
end = datetime.strptime(settings['autoNightMode']['endTime'], "%H:%M")
now = datetime.now()
if now.time() > start.time() or now.time() < end.time():
activity = _ba.get_foreground_host_activity()
activity.globalsnode.tint = (0.5, 0.7, 1.0)
if settings['autoNightMode']['fireflies']:
activity.fireflies_generator(
20, settings['autoNightMode']["fireflies_random_color"])
def kick_vote_started(started_by: str, started_to: str) -> None:
"""Logs the kick vote."""
logger.log(f"{started_by} started kick vote for {started_to}.")
def on_kicked(account_id: str) -> None:
"""Runs when someone is kicked by kickvote."""
logger.log(f"{account_id} kicked by kickvotes.")
def on_kick_vote_end():
"""Runs when kickvote is ended."""
logger.log("Kick vote End")
def on_join_request(ip):
servercheck.on_join_request(ip)
def on_map_init():
text_on_map.textonmap()
modifyspaz.setTeamCharacter()
def shutdown(func) -> None:
"""Set the app to quit either now or at the next clean opportunity."""
def wrapper(*args, **kwargs):
# add screen text and tell players we are going to restart soon.
ba.internal.chatmessage(
"Server will restart on next opportunity. (series end)")
_ba.restart_scheduled = True
_ba.get_foreground_host_activity().restart_msg = _ba.newnode('text',
attrs={
'text': "Server going to restart after this series.",
'flatness': 1.0,
'h_align': 'right',
'v_attach': 'bottom',
'h_attach': 'right',
'scale': 0.5,
'position': (-25, 54),
'color': (1, 0.5, 0.7)
})
func(*args, **kwargs)
return wrapper
ServerController.shutdown = shutdown(ServerController.shutdown)
def on_player_request(func) -> bool:
def wrapper(*args, **kwargs):
player = args[1]
count = 0
if not (player.get_v1_account_id() in serverdata.clients and serverdata.clients[player.get_v1_account_id()]["verified"]):
return False
for current_player in args[0].sessionplayers:
if current_player.get_v1_account_id() == player.get_v1_account_id():
count += 1
if count >= settings["maxPlayersPerDevice"]:
_ba.screenmessage("Reached max players limit per device", clients=[player.inputdevice.client_id], transient=True,)
return False
return func(*args, **kwargs)
return wrapper
Session.on_player_request = on_player_request(Session.on_player_request)
ServerController._access_check_response = servercontroller._access_check_response