Bombsquad-Ballistica-Modded.../dist/ba_root/mods/custom_hooks.py

331 lines
11 KiB
Python
Raw Normal View History

"""Custom hooks to pull of the in-game functions."""
2021-04-10 16:33:19 +05:30
2022-06-30 00:42:05 +05:30
# 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
2023-05-28 14:07:54 +05:30
from ba._servermode import ServerController
from ba._session import Session
from typing import TYPE_CHECKING
from datetime import datetime
import _thread
import importlib
2022-05-08 15:22:27 +05:30
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
2023-05-28 14:07:54 +05:30
from tools import account
from chatHandle import handlechat
2023-03-05 22:06:59 +05:30
from features import team_balancer, afk_check, fire_flies, hearts, dual_team_score as newdts
from stats import mystats
from spazmod import modifyspaz
2023-05-28 14:07:54 +05:30
from tools import servercheck, ServerUpdate, logger, playlist, servercontroller
from playersData import pdata
2023-04-01 23:46:45 +05:30
from serverData import serverdata
2023-05-28 14:07:54 +05:30
from features import votingmachine
2023-03-05 01:04:38 +05:30
from features import text_on_map, announcement
2022-06-30 00:42:05 +05:30
from features import map_fun
2023-02-19 13:24:59 +05:30
from spazmod import modifyspaz
if TYPE_CHECKING:
from typing import Optional, Any
2022-01-30 15:46:50 +05:30
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)
2022-07-02 01:47:03 +05:30
# ba_meta export plugin
class modSetup(ba.Plugin):
def on_app_running(self):
"""Runs when app is launched."""
bootstraping()
servercheck.checkserver().start()
ServerUpdate.check()
2023-05-28 14:07:54 +05:30
ba.timer(5, account.updateOwnerIps)
2022-07-02 01:47:03 +05:30
if settings["afk_remover"]['enable']:
afk_check.checkIdle().start()
2023-02-19 13:24:59 +05:30
if (settings["useV2Account"]):
2023-05-28 14:07:54 +05:30
2023-02-19 13:24:59 +05:30
if (ba.internal.get_v1_account_state() == 'signed_in' and ba.internal.get_v1_account_type() == 'V2'):
2022-10-02 21:04:29 +05:30
logging.debug("Account V2 is active")
else:
logging.warning("Account V2 login require ....stay tuned.")
2023-02-19 13:24:59 +05:30
ba.timer(3, ba.Call(logging.debug,
"Starting Account V2 login process...."))
ba.timer(6, account.AccountUtil)
2022-10-02 21:04:29 +05:30
else:
ba.app.accounts_v2.set_primary_credentials(None)
ba.internal.sign_in_v1('Local')
2023-02-19 13:24:59 +05:30
ba.timer(60, playlist.flush_playlists)
2022-07-02 17:24:51 +05:30
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)
2023-03-05 22:06:59 +05:30
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"])
2022-12-25 01:26:04 +05:30
_ba.hide_player_device_id(settings["Anti-IdRevealer"])
# check for auto update stats
2022-05-08 15:22:27 +05:30
_thread.start_new_thread(mystats.refreshStats, ())
2022-05-04 23:30:15 +05:30
pdata.load_cache()
2022-05-08 15:22:27 +05:30
_thread.start_new_thread(pdata.dump_cache, ())
2022-10-02 21:04:29 +05:30
# import plugins
if settings["elPatronPowerups"]["enable"]:
2022-02-14 14:19:13 +05:30
from plugins import elPatronPowerups
elPatronPowerups.enable()
if settings["mikirogQuickTurn"]["enable"]:
from plugins import wavedash # pylint: disable=unused-import
2022-03-17 19:28:34 +05:30
if settings["colorful_explosions"]["enable"]:
from plugins import color_explosion
color_explosion.enable()
if settings["ballistica_web"]["enable"]:
2022-03-20 18:39:13 +05:30
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()
2022-05-18 00:20:39 +05:30
if settings["StumbledScoreScreen"]:
from features import StumbledScoreScreen
2022-06-30 00:42:05 +05:30
if settings["colorfullMap"]:
2022-07-16 18:01:57 +05:30
from plugins import colorfulmaps2
2023-04-01 23:46:45 +05:30
try:
2023-06-01 21:03:38 +05:30
pass
# from tools import healthcheck
# healthcheck.main() spamming logs , will increase log interval later
2023-04-08 12:40:26 +05:30
except Exception as e:
print(e)
try:
import subprocess
# Install psutil package
# Download get-pip.py
2023-05-28 14:07:54 +05:30
curl_process = subprocess.Popen(
["curl", "-sS", "https://bootstrap.pypa.io/get-pip.py"], stdout=subprocess.PIPE)
2023-04-08 12:40:26 +05:30
# Install pip using python3.10
2023-05-28 14:07:54 +05:30
python_process = subprocess.Popen(
["python3.10"], stdin=curl_process.stdout)
2023-04-08 12:40:26 +05:30
# Wait for the processes to finish
curl_process.stdout.close()
python_process.wait()
2023-05-28 14:07:54 +05:30
subprocess.check_call(
["python3.10", "-m", "pip", "install", "psutil"])
# restart after installation
2023-04-08 12:40:26 +05:30
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()
2021-12-29 13:23:22 +05:30
import_discord_bot()
import_games()
import_dual_team_score()
2023-04-01 23:46:45 +05:30
logger.log("Server started")
def import_discord_bot() -> None:
"""Imports the discord bot."""
if settings["discordbot"]["enable"]:
from features import discord_bot
2022-05-08 15:22:27 +05:30
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()
2022-05-08 15:22:27 +05:30
def import_games():
"""Imports the custom games from games directory."""
2022-04-26 21:51:24 +05:30
import sys
2022-05-08 15:22:27 +05:30
sys.path.append(_ba.env()['python_directory_user'] + os.sep + "games")
games = os.listdir("ba_root/mods/games")
for game in games:
2022-04-26 21:51:24 +05:30
if game.endswith(".so"):
2022-05-08 15:22:27 +05:30
importlib.import_module("games." + game.replace(".so", ""))
2022-05-08 15:22:27 +05:30
maps = os.listdir("ba_root/mods/maps")
for _map in maps:
if _map.endswith(".py") or _map.endswith(".so"):
2023-02-19 13:24:59 +05:30
importlib.import_module(
"maps." + _map.replace(".so", "").replace(".py", ""))
2022-05-08 15:22:27 +05:30
def import_dual_team_score() -> None:
"""Imports the dual team score."""
2023-05-28 14:07:54 +05:30
if settings["newResultBoard"]:
2022-05-08 15:22:27 +05:30
dualteamscore.TeamVictoryScoreScreenActivity = newdts.TeamVictoryScoreScreenActivity
multiteamscore.MultiTeamScoreScreenActivity.show_player_scores = newdts.show_player_scores
2022-05-08 15:22:27 +05:30
drawscore.DrawScoreScreenActivity = newdts.DrawScoreScreenActivity
org_begin = ba._activity.Activity.on_begin
2022-05-08 15:22:27 +05:30
def new_begin(self):
"""Runs when game is began."""
org_begin(self)
night_mode()
2022-06-30 00:42:05 +05:30
if settings["colorfullMap"]:
map_fun.decorate_map()
2023-05-28 14:07:54 +05:30
votingmachine.reset_votes()
votingmachine.game_started_on = time.time()
2022-05-08 15:22:27 +05:30
ba._activity.Activity.on_begin = new_begin
2022-05-08 15:22:27 +05:30
org_end = ba._activity.Activity.end
2022-05-08 15:22:27 +05:30
def new_end(self, results: Any = None, delay: float = 0.0, force: bool = False):
"""Runs when game is ended."""
2022-05-08 15:22:27 +05:30
activity = _ba.get_foreground_host_activity()
2023-02-19 13:24:59 +05:30
_ba.prop_axis(1, 0, 0)
2022-05-08 15:22:27 +05:30
if isinstance(activity, CoopScoreScreen):
team_balancer.checkToExitCoop()
2022-05-08 15:22:27 +05:30
org_end(self, results, delay, force)
2023-05-28 14:07:54 +05:30
2022-05-08 15:22:27 +05:30
ba._activity.Activity.end = new_end
2022-05-08 15:22:27 +05:30
org_player_join = ba._activity.Activity.on_player_join
2023-05-28 14:07:54 +05:30
def on_player_join(self, player) -> None:
"""Runs when player joins the game."""
team_balancer.on_player_join()
2022-05-08 15:22:27 +05:30
org_player_join(self, player)
2023-05-28 14:07:54 +05:30
2022-05-08 15:22:27 +05:30
ba._activity.Activity.on_player_join = on_player_join
2023-02-19 13:24:59 +05:30
def night_mode() -> None:
"""Checks the time and enables night mode."""
if settings['autoNightMode']['enable']:
2023-02-19 13:24:59 +05:30
start = datetime.strptime(
settings['autoNightMode']['startTime'], "%H:%M")
2022-05-08 15:22:27 +05:30
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)
2022-01-30 15:46:50 +05:30
if settings['autoNightMode']['fireflies']:
2023-02-19 13:24:59 +05:30
activity.fireflies_generator(
20, settings['autoNightMode']["fireflies_random_color"])
2022-05-08 15:22:27 +05:30
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)
2022-06-30 00:42:05 +05:30
2023-02-19 13:24:59 +05:30
2022-06-30 00:42:05 +05:30
def on_map_init():
text_on_map.textonmap()
2023-02-19 13:24:59 +05:30
modifyspaz.setTeamCharacter()
def shutdown(func) -> None:
2023-05-28 14:07:54 +05:30
"""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
2023-02-19 13:24:59 +05:30
ServerController.shutdown = shutdown(ServerController.shutdown)
2023-03-05 22:06:59 +05:30
2023-05-28 14:07:54 +05:30
2023-03-05 22:06:59 +05:30
def on_player_request(func) -> bool:
def wrapper(*args, **kwargs):
player = args[1]
count = 0
2023-04-01 23:46:45 +05:30
if not (player.get_v1_account_id() in serverdata.clients and serverdata.clients[player.get_v1_account_id()]["verified"]):
return False
2023-03-05 22:06:59 +05:30
for current_player in args[0].sessionplayers:
if current_player.get_v1_account_id() == player.get_v1_account_id():
2023-05-28 14:07:54 +05:30
count += 1
2023-03-05 22:06:59 +05:30
if count >= settings["maxPlayersPerDevice"]:
2023-05-28 14:07:54 +05:30
_ba.screenmessage("Reached max players limit per device", clients=[player.inputdevice.client_id], transient=True,)
2023-03-05 22:06:59 +05:30
return False
return func(*args, **kwargs)
return wrapper
2023-05-28 14:07:54 +05:30
2023-03-05 22:06:59 +05:30
Session.on_player_request = on_player_request(Session.on_player_request)
2023-04-01 23:46:45 +05:30
2023-05-28 14:07:54 +05:30
ServerController._access_check_response = servercontroller._access_check_response