mirror of
https://github.com/imayushsaini/Bombsquad-Ballistica-Modded-Server.git
synced 2025-11-14 17:46:03 +00:00
rework on player restriction , exposing rest apis
This commit is contained in:
parent
af7fb5a586
commit
bf4c01c291
10 changed files with 883 additions and 361 deletions
|
|
@ -11,8 +11,8 @@ import _thread
|
||||||
import random
|
import random
|
||||||
from tools import playlist
|
from tools import playlist
|
||||||
from tools import logger
|
from tools import logger
|
||||||
Commands = ['recents','info','createteam', 'showid', 'hideid', 'lm', 'gp', 'party', 'quit', 'kickvote', 'maxplayers', 'playlist', 'ban', 'kick', 'remove', 'end', 'quit', 'mute', 'unmute', 'slowmo', 'nv', 'dv', 'pause',
|
Commands = ['recents', 'info', 'createteam', 'showid', 'hideid', 'lm', 'gp', 'party', 'quit', 'kickvote', 'maxplayers', 'playlist', 'ban', 'kick', 'remove', 'end', 'quit', 'mute', 'unmute', 'slowmo', 'nv', 'dv', 'pause',
|
||||||
'cameramode', 'createrole', 'addrole', 'removerole', 'addcommand', 'addcmd', 'removecommand', 'getroles', 'removecmd', 'changetag', 'customtag', 'customeffect','removeeffect','removetag' 'add', 'spectators', 'lobbytime']
|
'cameramode', 'createrole', 'addrole', 'removerole', 'addcommand', 'addcmd', 'removecommand', 'getroles', 'removecmd', 'changetag', 'customtag', 'customeffect', 'removeeffect', 'removetag' 'add', 'spectators', 'lobbytime']
|
||||||
CommandAliases = ['max', 'rm', 'next', 'restart', 'mutechat', 'unmutechat', 'sm',
|
CommandAliases = ['max', 'rm', 'next', 'restart', 'mutechat', 'unmutechat', 'sm',
|
||||||
'slow', 'night', 'day', 'pausegame', 'camera_mode', 'rotate_camera', 'effect']
|
'slow', 'night', 'day', 'pausegame', 'camera_mode', 'rotate_camera', 'effect']
|
||||||
|
|
||||||
|
|
@ -136,7 +136,7 @@ def create_team(arguments):
|
||||||
ba.internal.chatmessage("enter team name")
|
ba.internal.chatmessage("enter team name")
|
||||||
else:
|
else:
|
||||||
from ba._team import SessionTeam
|
from ba._team import SessionTeam
|
||||||
_ba.get_foreground_host_session().sessionteams.append(SessionTeam(team_id=len(_ba.get_foreground_host_session().sessionteams) +1, name=str(arguments[0]), color=(random.uniform(0, 1.2), random.uniform(
|
_ba.get_foreground_host_session().sessionteams.append(SessionTeam(team_id=len(_ba.get_foreground_host_session().sessionteams) + 1, name=str(arguments[0]), color=(random.uniform(0, 1.2), random.uniform(
|
||||||
0, 1.2), random.uniform(0, 1.2))))
|
0, 1.2), random.uniform(0, 1.2))))
|
||||||
from ba._lobby import Lobby
|
from ba._lobby import Lobby
|
||||||
_ba.get_foreground_host_session().lobby = Lobby()
|
_ba.get_foreground_host_session().lobby = Lobby()
|
||||||
|
|
@ -157,9 +157,12 @@ def get_player_info(arguments, client_id):
|
||||||
if account['client_id'] == int(arguments[0]):
|
if account['client_id'] == int(arguments[0]):
|
||||||
send(pdata.get_detailed_info(account["pbid"]), client_id)
|
send(pdata.get_detailed_info(account["pbid"]), client_id)
|
||||||
|
|
||||||
|
|
||||||
def get_recents(client_id):
|
def get_recents(client_id):
|
||||||
for players in serverdata.recents:
|
for players in serverdata.recents:
|
||||||
send(f"{players['client_id']} {players['deviceId']} {players['pbid']}", client_id)
|
send(
|
||||||
|
f"{players['client_id']} {players['deviceId']} {players['pbid']}", client_id)
|
||||||
|
|
||||||
|
|
||||||
def changepartysize(arguments):
|
def changepartysize(arguments):
|
||||||
if len(arguments) == 0:
|
if len(arguments) == 0:
|
||||||
|
|
@ -184,7 +187,7 @@ def kick(arguments):
|
||||||
cl_id = int(arguments[0])
|
cl_id = int(arguments[0])
|
||||||
for ros in ba.internal.get_game_roster():
|
for ros in ba.internal.get_game_roster():
|
||||||
if ros["client_id"] == cl_id:
|
if ros["client_id"] == cl_id:
|
||||||
logger.log("kicked "+ ros["display_string"])
|
logger.log("kicked " + ros["display_string"])
|
||||||
ba.internal.disconnect_client(int(arguments[0]))
|
ba.internal.disconnect_client(int(arguments[0]))
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
@ -201,11 +204,11 @@ def kikvote(arguments, clientid):
|
||||||
cl_id = int(arguments[1])
|
cl_id = int(arguments[1])
|
||||||
for ros in ba.internal.get_game_roster():
|
for ros in ba.internal.get_game_roster():
|
||||||
if ros["client_id"] == cl_id:
|
if ros["client_id"] == cl_id:
|
||||||
if ros["account_id"] in serverdata.clients:
|
pdata.enable_kick_vote(ros["account_id"])
|
||||||
serverdata.clients[ros["account_id"]
|
logger.log(
|
||||||
]["canStartKickVote"] = True
|
f'kick vote enabled for {ros["account_id"]} {ros["display_string"]}')
|
||||||
send(
|
send(
|
||||||
"Upon server restart, Kick-vote will be enabled for this person", clientid)
|
"Upon server restart, Kick-vote will be enabled for this person", clientid)
|
||||||
return
|
return
|
||||||
except:
|
except:
|
||||||
return
|
return
|
||||||
|
|
@ -220,9 +223,10 @@ def kikvote(arguments, clientid):
|
||||||
if ros["client_id"] == cl_id:
|
if ros["client_id"] == cl_id:
|
||||||
_ba.disable_kickvote(ros["account_id"])
|
_ba.disable_kickvote(ros["account_id"])
|
||||||
send("Kick-vote disabled for this person", clientid)
|
send("Kick-vote disabled for this person", clientid)
|
||||||
if ros["account_id"] in serverdata.clients:
|
logger.log(
|
||||||
serverdata.clients[ros["account_id"]
|
f'kick vote disabled for {ros["account_id"]} {ros["display_string"]}')
|
||||||
]["canStartKickVote"] = False
|
pdata.disable_kick_vote(
|
||||||
|
ros["account_id"], 2, "by chat command")
|
||||||
return
|
return
|
||||||
except:
|
except:
|
||||||
return
|
return
|
||||||
|
|
@ -272,17 +276,19 @@ def end(arguments):
|
||||||
def ban(arguments):
|
def ban(arguments):
|
||||||
try:
|
try:
|
||||||
cl_id = int(arguments[0])
|
cl_id = int(arguments[0])
|
||||||
ac_id = ""
|
duration = int(arguments[1]) if len(arguments) >= 2 else 0.5
|
||||||
for ros in ba.internal.get_game_roster():
|
for ros in ba.internal.get_game_roster():
|
||||||
if ros["client_id"] == cl_id:
|
if ros["client_id"] == cl_id:
|
||||||
ac_id = ros['account_id']
|
pdata.ban_player(ros['account_id'], duration,
|
||||||
pdata.ban_player(ros['account_id'])
|
"by chat command")
|
||||||
logger.log("banned "+ros["display_string"])
|
logger.log(f'banned {ros["display_string"]} by chat command')
|
||||||
if ac_id in serverdata.clients:
|
|
||||||
serverdata.clients[ac_id]["isBan"] = True
|
for account in serverdata.recents: # backup case if player left the server
|
||||||
for account in serverdata.recents: # backup case if player left the server
|
|
||||||
if account['client_id'] == int(arguments[0]):
|
if account['client_id'] == int(arguments[0]):
|
||||||
pdata.ban_player(account["pbid"])
|
pdata.ban_player(
|
||||||
|
account["pbid"], duration, "by chat command")
|
||||||
|
logger.log(
|
||||||
|
f'banned {ros["display_string"]} by chat command, recents')
|
||||||
kick(arguments)
|
kick(arguments)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
@ -298,17 +304,18 @@ def mute(arguments):
|
||||||
serverdata.muted = True
|
serverdata.muted = True
|
||||||
try:
|
try:
|
||||||
cl_id = int(arguments[0])
|
cl_id = int(arguments[0])
|
||||||
ac_id = ""
|
duration = int(arguments[1]) if len(arguments) >= 2 else 0.5
|
||||||
for ros in ba.internal.get_game_roster():
|
for ros in ba.internal.get_game_roster():
|
||||||
if ros["client_id"] == cl_id:
|
if ros["client_id"] == cl_id:
|
||||||
pdata.mute(ros['account_id'])
|
pdata.mute(ros['account_id'])
|
||||||
ac_id = ros['account_id']
|
ac_id = ros['account_id']
|
||||||
logger.log("muted "+ros["display_string"])
|
logger.log(f'muted {ros["display_string"]}')
|
||||||
if ac_id in serverdata.clients:
|
pdata.mute(ac_id, duration, "muted by chat command")
|
||||||
serverdata.clients[ac_id]["isMuted"] = True
|
return
|
||||||
for account in serverdata.recents: # backup case if player left the server
|
for account in serverdata.recents: # backup case if player left the server
|
||||||
if account['client_id'] == int(arguments[0]):
|
if account['client_id'] == int(arguments[0]):
|
||||||
pdata.mute(account["pbid"])
|
pdata.mute(account["pbid"], duration,
|
||||||
|
"muted by chat command, from recents")
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
return
|
return
|
||||||
|
|
@ -319,14 +326,16 @@ def un_mute(arguments):
|
||||||
serverdata.muted = False
|
serverdata.muted = False
|
||||||
try:
|
try:
|
||||||
cl_id = int(arguments[0])
|
cl_id = int(arguments[0])
|
||||||
ac_id = ""
|
|
||||||
for ros in ba.internal.get_game_roster():
|
for ros in ba.internal.get_game_roster():
|
||||||
if ros["client_id"] == cl_id:
|
if ros["client_id"] == cl_id:
|
||||||
pdata.unmute(ros['account_id'])
|
pdata.unmute(ros['account_id'])
|
||||||
ac_id = ros['account_id']
|
logger.log(f'unmuted {ros["display_string"]} by chat command')
|
||||||
if ac_id in serverdata.clients:
|
return
|
||||||
serverdata.clients[ac_id]["isMuted"] = False
|
for account in serverdata.recents: # backup case if player left the server
|
||||||
return
|
if account['client_id'] == int(arguments[0]):
|
||||||
|
pdata.unmute(account["pbid"])
|
||||||
|
logger.log(
|
||||||
|
f'unmuted {ros["display_string"]} by chat command, recents')
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
@ -485,24 +494,27 @@ def set_custom_tag(arguments):
|
||||||
except:
|
except:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def remove_custom_tag(arguments):
|
def remove_custom_tag(arguments):
|
||||||
try:
|
try:
|
||||||
session = ba.internal.get_foreground_host_session()
|
session = ba.internal.get_foreground_host_session()
|
||||||
for i in session.sessionplayers:
|
for i in session.sessionplayers:
|
||||||
if i.inputdevice.client_id == int(arguments[0]):
|
if i.inputdevice.client_id == int(arguments[0]):
|
||||||
pdata.remove_tag( i.get_v1_account_id())
|
pdata.remove_tag(i.get_v1_account_id())
|
||||||
except:
|
except:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def remove_custom_effect(arguments):
|
def remove_custom_effect(arguments):
|
||||||
try:
|
try:
|
||||||
session = ba.internal.get_foreground_host_session()
|
session = ba.internal.get_foreground_host_session()
|
||||||
for i in session.sessionplayers:
|
for i in session.sessionplayers:
|
||||||
if i.inputdevice.client_id == int(arguments[0]):
|
if i.inputdevice.client_id == int(arguments[0]):
|
||||||
pdata.remove_effect( i.get_v1_account_id())
|
pdata.remove_effect(i.get_v1_account_id())
|
||||||
except:
|
except:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def set_custom_effect(arguments):
|
def set_custom_effect(arguments):
|
||||||
try:
|
try:
|
||||||
session = ba.internal.get_foreground_host_session()
|
session = ba.internal.get_foreground_host_session()
|
||||||
|
|
|
||||||
26
dist/ba_root/mods/chatHandle/handlechat.py
vendored
26
dist/ba_root/mods/chatHandle/handlechat.py
vendored
|
|
@ -6,19 +6,22 @@ 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 votingmachine
|
from features import votingmachine
|
||||||
import ba, _ba
|
from playersData import pdata
|
||||||
|
import ba
|
||||||
|
import _ba
|
||||||
import ba.internal
|
import ba.internal
|
||||||
import setting
|
import setting
|
||||||
|
from datetime import datetime
|
||||||
settings = setting.get_settings_data()
|
settings = setting.get_settings_data()
|
||||||
|
|
||||||
|
|
||||||
def filter_chat_message(msg, client_id):
|
def filter_chat_message(msg, client_id):
|
||||||
|
now = datetime.now()
|
||||||
if client_id == -1:
|
if client_id == -1:
|
||||||
if msg.startswith("/"):
|
if msg.startswith("/"):
|
||||||
Main.Command(msg, client_id)
|
Main.Command(msg, client_id)
|
||||||
return None
|
return None
|
||||||
logger.log(f"Host msg: | {msg}" , "chat")
|
logger.log(f"Host msg: | {msg}", "chat")
|
||||||
return msg
|
return msg
|
||||||
acid = ""
|
acid = ""
|
||||||
displaystring = ""
|
displaystring = ""
|
||||||
|
|
@ -42,21 +45,23 @@ def filter_chat_message(msg, client_id):
|
||||||
if msg == None:
|
if msg == None:
|
||||||
return
|
return
|
||||||
|
|
||||||
if msg in ["end","dv","nv","sm"] and settings["allowVotes"]:
|
if msg in ["end", "dv", "nv", "sm"] and settings["allowVotes"]:
|
||||||
votingmachine.vote(acid, client_id, msg)
|
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"]:
|
||||||
|
|
||||||
if serverdata.muted:
|
if serverdata.muted:
|
||||||
_ba.screenmessage("Server on mute", transient=True, clients=[client_id])
|
_ba.screenmessage("Server on mute",
|
||||||
|
transient=True, clients=[client_id])
|
||||||
return
|
return
|
||||||
|
|
||||||
elif serverdata.clients[acid]["isMuted"]:
|
elif acid in pdata.get_blacklist()["muted-ids"] and now < datetime.strptime(pdata.get_blacklist()["muted-ids"][acid]["till"], "%Y-%m-%d %H:%M:%S"):
|
||||||
_ba.screenmessage("You are on mute", transient=True, clients=[client_id])
|
_ba.screenmessage(
|
||||||
|
"You are on mute, maybe try after some time", transient=True, clients=[client_id])
|
||||||
return None
|
return None
|
||||||
elif servercheck.get_account_age(serverdata.clients[acid]["accountAge"]) < settings['minAgeToChatInHours']:
|
elif servercheck.get_account_age(serverdata.clients[acid]["accountAge"]) < settings['minAgeToChatInHours']:
|
||||||
_ba.screenmessage("New accounts not allowed to chat here", transient=True, clients=[client_id])
|
_ba.screenmessage("New accounts not allowed to chat here",
|
||||||
|
transient=True, clients=[client_id])
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
if msg.startswith(",") and settings["allowTeamChat"]:
|
if msg.startswith(",") and settings["allowTeamChat"]:
|
||||||
|
|
@ -66,5 +71,6 @@ def filter_chat_message(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
|
||||||
|
|
|
||||||
243
dist/ba_root/mods/playersData/pdata.py
vendored
243
dist/ba_root/mods/playersData/pdata.py
vendored
|
|
@ -4,6 +4,8 @@
|
||||||
# (see https://ballistica.net/wiki/meta-tag-system)
|
# (see https://ballistica.net/wiki/meta-tag-system)
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
import shutil
|
||||||
|
import copy
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
import time
|
import time
|
||||||
|
|
@ -17,13 +19,13 @@ import _ba
|
||||||
import ba.internal
|
import ba.internal
|
||||||
import json
|
import json
|
||||||
import datetime
|
import datetime
|
||||||
from tools.ServerUpdate import contributeData , checkSpammer
|
from tools.ServerUpdate import checkSpammer
|
||||||
import setting
|
import setting
|
||||||
|
from datetime import datetime, timedelta
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
setti=setting.get_settings_data()
|
settings = setting.get_settings_data()
|
||||||
|
|
||||||
PLAYERS_DATA_PATH = os.path.join(
|
PLAYERS_DATA_PATH = os.path.join(
|
||||||
_ba.env()["python_directory_user"], "playersData" + os.sep
|
_ba.env()["python_directory_user"], "playersData" + os.sep
|
||||||
|
|
@ -54,7 +56,7 @@ def get_info(account_id: str) -> dict | None:
|
||||||
dict | None
|
dict | None
|
||||||
information of client
|
information of client
|
||||||
"""
|
"""
|
||||||
profiles=get_profiles()
|
profiles = get_profiles()
|
||||||
if account_id in profiles:
|
if account_id in profiles:
|
||||||
return profiles[account_id]
|
return profiles[account_id]
|
||||||
return None
|
return None
|
||||||
|
|
@ -68,54 +70,69 @@ def get_profiles() -> dict:
|
||||||
dict
|
dict
|
||||||
profiles of the players
|
profiles of the players
|
||||||
"""
|
"""
|
||||||
if CacheData.profiles=={}:
|
if CacheData.profiles == {}:
|
||||||
try:
|
try:
|
||||||
if os.stat(PLAYERS_DATA_PATH+"profiles.json").st_size > 1000000:
|
if os.stat(PLAYERS_DATA_PATH+"profiles.json").st_size > 1000000:
|
||||||
newpath = PLAYERS_DATA_PATH + "profiles.json"+str(datetime.datetime.now())
|
newpath = f'{PLAYERS_DATA_PATH}profiles-{str(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))}.json'
|
||||||
shutil.copyfile(PLAYERS_DATA_PATH + "profiles.json", newpath)
|
shutil.copyfile(PLAYERS_DATA_PATH + "profiles.json", newpath)
|
||||||
if setti["contributeData"]:
|
profiles = {"pb-sdf": {}}
|
||||||
contributeData(newpath)
|
|
||||||
profiles = {"pb-sdf":{}}
|
|
||||||
print("resetting profiles")
|
print("resetting profiles")
|
||||||
else:
|
else:
|
||||||
f=open(PLAYERS_DATA_PATH + "profiles.json","r")
|
f = open(PLAYERS_DATA_PATH + "profiles.json", "r")
|
||||||
profiles = json.load(f)
|
profiles = json.load(f)
|
||||||
f.close()
|
f.close()
|
||||||
print("loading old proiles.json")
|
print("loading old proiles.json")
|
||||||
CacheData.profiles=profiles
|
CacheData.profiles = profiles
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
f=open(PLAYERS_DATA_PATH + "profiles.json.backup","r")
|
f = open(PLAYERS_DATA_PATH + "profiles.json.backup", "r")
|
||||||
profiles = json.load(f)
|
profiles = json.load(f)
|
||||||
print(e)
|
print(e)
|
||||||
print("exception happened , falling back to profiles.json.backup")
|
print("exception happened , falling back to profiles.json.backup")
|
||||||
CacheData.profiles=profiles
|
CacheData.profiles = profiles
|
||||||
f.close()
|
f.close()
|
||||||
return profiles
|
return profiles
|
||||||
else:
|
else:
|
||||||
return CacheData.profiles
|
return CacheData.profiles
|
||||||
|
|
||||||
|
|
||||||
|
def get_profiles_archive_index():
|
||||||
|
return [x for x in os.listdir(PLAYERS_DATA_PATH) if x.startswith("profiles")]
|
||||||
|
|
||||||
|
|
||||||
|
def get_old_profiles(filename):
|
||||||
|
try:
|
||||||
|
f = open(PLAYERS_DATA_PATH + filename, "r")
|
||||||
|
profiles = json.load(f)
|
||||||
|
return profiles
|
||||||
|
except:
|
||||||
|
return {}
|
||||||
|
|
||||||
|
|
||||||
def get_blacklist() -> dict:
|
def get_blacklist() -> dict:
|
||||||
if CacheData.blacklist == {}:
|
if CacheData.blacklist == {}:
|
||||||
try:
|
try:
|
||||||
f = open(PLAYERS_DATA_PATH + "blacklist.json","r")
|
f = open(PLAYERS_DATA_PATH + "blacklist.json", "r")
|
||||||
CacheData.blacklist = json.load(f)
|
CacheData.blacklist = json.load(f)
|
||||||
except:
|
except:
|
||||||
print('error opening blacklist json')
|
print('error opening blacklist json')
|
||||||
return {
|
return {
|
||||||
"ban":{
|
"ban": {
|
||||||
"ids":[],
|
"ids": {},
|
||||||
"ips":[],
|
"ips": {},
|
||||||
"deviceids":[]
|
"deviceids": {}
|
||||||
},
|
},
|
||||||
"muted-ids":[]
|
"muted-ids": {},
|
||||||
}
|
"kick-vote-disabled": {}
|
||||||
|
}
|
||||||
|
|
||||||
return CacheData.blacklist
|
return CacheData.blacklist
|
||||||
|
|
||||||
|
|
||||||
def update_blacklist():
|
def update_blacklist():
|
||||||
with open(PLAYERS_DATA_PATH + "blacklist.json","w") as f:
|
with open(PLAYERS_DATA_PATH + "blacklist.json", "w") as f:
|
||||||
json.dump(CacheData.blacklist,f,indent=4)
|
json.dump(CacheData.blacklist, f, indent=4)
|
||||||
|
|
||||||
|
|
||||||
def commit_profiles(data={}) -> None:
|
def commit_profiles(data={}) -> None:
|
||||||
"""Commits the given profiles in the database.
|
"""Commits the given profiles in the database.
|
||||||
|
|
@ -127,6 +144,7 @@ def commit_profiles(data={}) -> None:
|
||||||
# with OpenJson(PLAYERS_DATA_PATH + "profiles.json") as profiles_file:
|
# with OpenJson(PLAYERS_DATA_PATH + "profiles.json") as profiles_file:
|
||||||
# profiles_file.dump(CacheData.profiles, indent=4)
|
# profiles_file.dump(CacheData.profiles, indent=4)
|
||||||
|
|
||||||
|
|
||||||
def get_detailed_info(pbid):
|
def get_detailed_info(pbid):
|
||||||
main_account = get_info(pbid)
|
main_account = get_info(pbid)
|
||||||
if main_account == None:
|
if main_account == None:
|
||||||
|
|
@ -164,19 +182,16 @@ def add_profile(
|
||||||
"""
|
"""
|
||||||
profiles = get_profiles()
|
profiles = get_profiles()
|
||||||
profiles[account_id] = {
|
profiles[account_id] = {
|
||||||
"display_string": display_string,
|
"display_string": display_string,
|
||||||
"profiles": [],
|
"profiles": [],
|
||||||
"name": current_name,
|
"name": current_name,
|
||||||
"isBan": False,
|
"accountAge": account_age,
|
||||||
"isMuted": False,
|
"registerOn": time.time(),
|
||||||
"accountAge": account_age,
|
"spamCount": 0,
|
||||||
"registerOn": time.time(),
|
"lastSpam": time.time(),
|
||||||
"canStartKickVote": True,
|
"totaltimeplayer": 0,
|
||||||
"spamCount": 0,
|
}
|
||||||
"lastSpam": time.time(),
|
CacheData.profiles = profiles
|
||||||
"totaltimeplayer": 0,
|
|
||||||
}
|
|
||||||
CacheData.profiles=profiles
|
|
||||||
|
|
||||||
serverdata.clients[account_id] = profiles[account_id]
|
serverdata.clients[account_id] = profiles[account_id]
|
||||||
serverdata.clients[account_id]["warnCount"] = 0
|
serverdata.clients[account_id]["warnCount"] = 0
|
||||||
|
|
@ -190,14 +205,15 @@ def add_profile(
|
||||||
cid = ros['client_id']
|
cid = ros['client_id']
|
||||||
ip = _ba.get_client_ip(cid)
|
ip = _ba.get_client_ip(cid)
|
||||||
serverdata.clients[account_id]["lastIP"] = ip
|
serverdata.clients[account_id]["lastIP"] = ip
|
||||||
serverdata.recents.append({"client_id":cid,"deviceId":display_string,"pbid": account_id})
|
serverdata.recents.append(
|
||||||
|
{"client_id": cid, "deviceId": display_string, "pbid": account_id})
|
||||||
serverdata.recents = serverdata.recents[-20:]
|
serverdata.recents = serverdata.recents[-20:]
|
||||||
device_id = _ba.get_client_public_device_uuid(cid)
|
device_id = _ba.get_client_public_device_uuid(cid)
|
||||||
if(device_id==None):
|
if (device_id == None):
|
||||||
device_id = _ba.get_client_device_uuid(cid)
|
device_id = _ba.get_client_device_uuid(cid)
|
||||||
checkSpammer({'id':account_id,'display':display_string,'ip':ip,'device':device_id})
|
checkSpammer({'id': account_id, 'display': display_string,
|
||||||
if device_id in get_blacklist()["ban"]["deviceids"]:
|
'ip': ip, 'device': device_id})
|
||||||
serverdata.clients[account_id]["isBan"]=True
|
if device_id in get_blacklist()["ban"]["deviceids"] or account_id in get_blacklist()["ban"]["ids"]:
|
||||||
ba.internal.disconnect_client(cid)
|
ba.internal.disconnect_client(cid)
|
||||||
serverdata.clients[account_id]["deviceUUID"] = device_id
|
serverdata.clients[account_id]["deviceUUID"] = device_id
|
||||||
|
|
||||||
|
|
@ -215,7 +231,7 @@ def update_display_string(account_id: str, display_string: str) -> None:
|
||||||
profiles = get_profiles()
|
profiles = get_profiles()
|
||||||
if account_id in profiles:
|
if account_id in profiles:
|
||||||
profiles[account_id]["display_string"] = display_string
|
profiles[account_id]["display_string"] = display_string
|
||||||
CacheData.profiles=profiles
|
CacheData.profiles = profiles
|
||||||
commit_profiles()
|
commit_profiles()
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -255,11 +271,11 @@ def update_profile(
|
||||||
|
|
||||||
if name is not None:
|
if name is not None:
|
||||||
profiles[account_id]["name"] = name
|
profiles[account_id]["name"] = name
|
||||||
CacheData.profiles=profiles
|
CacheData.profiles = profiles
|
||||||
commit_profiles()
|
commit_profiles()
|
||||||
|
|
||||||
|
|
||||||
def ban_player(account_id: str) -> None:
|
def ban_player(account_id: str, duration_in_days: float, reason: str) -> None:
|
||||||
"""Bans the player.
|
"""Bans the player.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
|
|
@ -267,27 +283,51 @@ def ban_player(account_id: str) -> None:
|
||||||
account_id : str
|
account_id : str
|
||||||
account id of the player to be banned
|
account id of the player to be banned
|
||||||
"""
|
"""
|
||||||
profiles = get_profiles()
|
current_profiles = get_profiles()
|
||||||
if account_id in profiles:
|
ip = ""
|
||||||
profiles[account_id]["isBan"] = True
|
device_id = ""
|
||||||
CacheData.profiles=profiles
|
if account_id in current_profiles:
|
||||||
# _thread.start_new_thread(commit_profiles, (profiles,))
|
ip = current_profiles[account_id]["lastIP"]
|
||||||
cid = -1
|
device_id = current_profiles[account_id]["deviceUUID"]
|
||||||
for ros in ba.internal.get_game_roster():
|
|
||||||
if ros['account_id'] == account_id:
|
|
||||||
cid = ros['client_id']
|
|
||||||
ip = _ba.get_client_ip(cid)
|
|
||||||
|
|
||||||
device_id = _ba.get_client_public_device_uuid(cid)
|
ban_time = datetime.now() + timedelta(days=duration_in_days)
|
||||||
if(device_id==None):
|
|
||||||
device_id = _ba.get_client_device_uuid(cid)
|
|
||||||
CacheData.blacklist["ban"]["ips"].append(ip)
|
|
||||||
|
|
||||||
CacheData.blacklist["ban"]["ids"].append(account_id)
|
CacheData.blacklist["ban"]["ips"][ip] = {"till": ban_time.strftime(
|
||||||
CacheData.blacklist["ban"]["deviceids"].append(device_id)
|
"%Y-%m-%d %H:%M:%S"), "reason": f'linked with account {account_id}'}
|
||||||
_thread.start_new_thread(update_blacklist,())
|
CacheData.blacklist["ban"]["ids"][account_id] = {
|
||||||
|
"till": ban_time.strftime("%Y-%m-%d %H:%M:%S"), "reason": reason}
|
||||||
|
CacheData.blacklist["ban"]["deviceids"][device_id] = {"till": ban_time.strftime(
|
||||||
|
"%Y-%m-%d %H:%M:%S"), "reason": f'linked with account {account_id}'}
|
||||||
|
_thread.start_new_thread(update_blacklist, ())
|
||||||
|
|
||||||
def mute(account_id: str) -> None:
|
|
||||||
|
def unban_player(account_id):
|
||||||
|
current_profiles = get_profiles()
|
||||||
|
ip = ""
|
||||||
|
device_id = ""
|
||||||
|
if account_id in current_profiles:
|
||||||
|
ip = current_profiles[account_id]["lastIP"]
|
||||||
|
device_id = current_profiles[account_id]["deviceUUID"]
|
||||||
|
|
||||||
|
CacheData.blacklist["ban"]["ips"].pop(ip, None)
|
||||||
|
CacheData.blacklist["ban"]["deviceids"].pop(device_id, None)
|
||||||
|
CacheData.blacklist["ban"]["ids"].pop(account_id, None)
|
||||||
|
_thread.start_new_thread(update_blacklist, ())
|
||||||
|
|
||||||
|
|
||||||
|
def disable_kick_vote(account_id, duration, reason):
|
||||||
|
ban_time = datetime.now() + timedelta(days=duration)
|
||||||
|
CacheData.blacklist["kick-vote-disabled"][account_id] = {"till": ban_time.strftime(
|
||||||
|
"%Y-%m-%d %H:%M:%S"), "reason": reason}
|
||||||
|
_thread.start_new_thread(update_blacklist, ())
|
||||||
|
|
||||||
|
|
||||||
|
def enable_kick_vote(account_id):
|
||||||
|
CacheData.blacklist["kick-vote-disabled"].pop(account_id, None)
|
||||||
|
_thread.start_new_thread(update_blacklist, ())
|
||||||
|
|
||||||
|
|
||||||
|
def mute(account_id: str, duration_in_days: float, reason: str) -> None:
|
||||||
"""Mutes the player.
|
"""Mutes the player.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
|
|
@ -295,11 +335,11 @@ def mute(account_id: str) -> None:
|
||||||
account_id : str
|
account_id : str
|
||||||
acccount id of the player to be muted
|
acccount id of the player to be muted
|
||||||
"""
|
"""
|
||||||
profiles = get_profiles()
|
ban_time = datetime.now() + timedelta(days=duration_in_days)
|
||||||
if account_id in profiles:
|
|
||||||
profiles[account_id]["isMuted"] = True
|
|
||||||
CacheData.profiles=profiles
|
|
||||||
|
|
||||||
|
CacheData.blacklist["muted-ids"][account_id] = {"till": ban_time.strftime(
|
||||||
|
"%Y-%m-%d %H:%M:%S"), "reason": reason}
|
||||||
|
_thread.start_new_thread(update_blacklist, ())
|
||||||
|
|
||||||
|
|
||||||
def unmute(account_id: str) -> None:
|
def unmute(account_id: str) -> None:
|
||||||
|
|
@ -310,11 +350,8 @@ def unmute(account_id: str) -> None:
|
||||||
account_id : str
|
account_id : str
|
||||||
acccount id of the player to be unmuted
|
acccount id of the player to be unmuted
|
||||||
"""
|
"""
|
||||||
profiles = get_profiles()
|
CacheData.blacklist["muted-ids"].pop(account_id, None)
|
||||||
if account_id in profiles:
|
_thread.start_new_thread(update_blacklist, ())
|
||||||
profiles[account_id]["isMuted"] = False
|
|
||||||
CacheData.profiles=profiles
|
|
||||||
_thread.start_new_thread(commit_profiles, (profiles,))
|
|
||||||
|
|
||||||
|
|
||||||
def update_spam(account_id: str, spam_count: int, last_spam: float) -> None:
|
def update_spam(account_id: str, spam_count: int, last_spam: float) -> None:
|
||||||
|
|
@ -333,7 +370,7 @@ def update_spam(account_id: str, spam_count: int, last_spam: float) -> None:
|
||||||
if account_id in profiles:
|
if account_id in profiles:
|
||||||
profiles[account_id]["spamCount"] = spam_count
|
profiles[account_id]["spamCount"] = spam_count
|
||||||
profiles[account_id]["lastSpam"] = last_spam
|
profiles[account_id]["lastSpam"] = last_spam
|
||||||
CacheData.profiles=profiles
|
CacheData.profiles = profiles
|
||||||
commit_profiles(profiles)
|
commit_profiles(profiles)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -549,15 +586,19 @@ def get_custom() -> dict:
|
||||||
"""
|
"""
|
||||||
if CacheData.custom == {}:
|
if CacheData.custom == {}:
|
||||||
try:
|
try:
|
||||||
f=open(PLAYERS_DATA_PATH + "custom.json","r")
|
f = open(PLAYERS_DATA_PATH + "custom.json", "r")
|
||||||
custom = json.load(f)
|
custom = json.load(f)
|
||||||
f.close()
|
f.close()
|
||||||
CacheData.custom=custom
|
CacheData.custom = custom
|
||||||
except:
|
except:
|
||||||
f=open(PLAYERS_DATA_PATH + "custom.json.backup","r")
|
f = open(PLAYERS_DATA_PATH + "custom.json.backup", "r")
|
||||||
custom = json.load(f)
|
custom = json.load(f)
|
||||||
f.close()
|
f.close()
|
||||||
CacheData.custom=custom
|
CacheData.custom = custom
|
||||||
|
for account_id in custom["customeffects"]:
|
||||||
|
custom["customeffects"][account_id] = [custom["customeffects"][account_id]] if type(
|
||||||
|
custom["customeffects"][account_id]) is str else custom["customeffects"][account_id]
|
||||||
|
|
||||||
return CacheData.custom
|
return CacheData.custom
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -573,7 +614,8 @@ def set_effect(effect: str, account_id: str) -> None:
|
||||||
"""
|
"""
|
||||||
custom = get_custom()
|
custom = get_custom()
|
||||||
if account_id in custom["customeffects"]:
|
if account_id in custom["customeffects"]:
|
||||||
effects = [custom["customeffects"][account_id]] if type(custom["customeffects"][account_id]) is str else custom["customeffects"][account_id]
|
effects = [custom["customeffects"][account_id]] if type(
|
||||||
|
custom["customeffects"][account_id]) is str else custom["customeffects"][account_id]
|
||||||
effects.append(effect)
|
effects.append(effect)
|
||||||
custom["customeffects"][account_id] = effects
|
custom["customeffects"][account_id] = effects
|
||||||
else:
|
else:
|
||||||
|
|
@ -598,6 +640,22 @@ def set_tag(tag: str, account_id: str) -> None:
|
||||||
commit_c()
|
commit_c()
|
||||||
|
|
||||||
|
|
||||||
|
def get_roles():
|
||||||
|
return CacheData.roles
|
||||||
|
|
||||||
|
|
||||||
|
def update_roles(roles):
|
||||||
|
CacheData.roles = roles
|
||||||
|
|
||||||
|
|
||||||
|
def get_custom_perks():
|
||||||
|
return CacheData.custom
|
||||||
|
|
||||||
|
|
||||||
|
def update_custom_perks(custom):
|
||||||
|
CacheData.custom = custom
|
||||||
|
|
||||||
|
|
||||||
def remove_effect(account_id: str) -> None:
|
def remove_effect(account_id: str) -> None:
|
||||||
"""Removes the effect from player.
|
"""Removes the effect from player.
|
||||||
|
|
||||||
|
|
@ -609,7 +667,6 @@ def remove_effect(account_id: str) -> None:
|
||||||
custom = get_custom()
|
custom = get_custom()
|
||||||
custom["customeffects"].pop(account_id)
|
custom["customeffects"].pop(account_id)
|
||||||
CacheData.custom = custom
|
CacheData.custom = custom
|
||||||
commit_c()
|
|
||||||
|
|
||||||
|
|
||||||
def remove_tag(account_id: str) -> None:
|
def remove_tag(account_id: str) -> None:
|
||||||
|
|
@ -623,7 +680,6 @@ def remove_tag(account_id: str) -> None:
|
||||||
custom = get_custom()
|
custom = get_custom()
|
||||||
custom["customtag"].pop(account_id)
|
custom["customtag"].pop(account_id)
|
||||||
CacheData.custom = custom
|
CacheData.custom = custom
|
||||||
commit_c()
|
|
||||||
|
|
||||||
|
|
||||||
def commit_c():
|
def commit_c():
|
||||||
|
|
@ -654,28 +710,31 @@ def load_white_list() -> None:
|
||||||
for account_id in data:
|
for account_id in data:
|
||||||
CacheData.whitelist.append(account_id)
|
CacheData.whitelist.append(account_id)
|
||||||
|
|
||||||
|
|
||||||
def load_cache():
|
def load_cache():
|
||||||
""" to be called on server boot"""
|
""" to be called on server boot"""
|
||||||
get_profiles()
|
get_profiles()
|
||||||
get_custom()
|
get_custom()
|
||||||
get_roles()
|
get_roles()
|
||||||
|
|
||||||
import shutil
|
|
||||||
import copy
|
|
||||||
def dump_cache():
|
def dump_cache():
|
||||||
if CacheData.profiles!={}:
|
if CacheData.profiles != {}:
|
||||||
shutil.copyfile(PLAYERS_DATA_PATH + "profiles.json",PLAYERS_DATA_PATH + "profiles.json.backup")
|
shutil.copyfile(PLAYERS_DATA_PATH + "profiles.json",
|
||||||
profiles= copy.deepcopy(CacheData.profiles)
|
PLAYERS_DATA_PATH + "profiles.json.backup")
|
||||||
with open(PLAYERS_DATA_PATH + "profiles.json","w") as f:
|
profiles = copy.deepcopy(CacheData.profiles)
|
||||||
json.dump(profiles,f,indent=4)
|
with open(PLAYERS_DATA_PATH + "profiles.json", "w") as f:
|
||||||
if CacheData.roles!={}:
|
json.dump(profiles, f, indent=4)
|
||||||
shutil.copyfile(PLAYERS_DATA_PATH + "roles.json",PLAYERS_DATA_PATH + "roles.json.backup")
|
if CacheData.roles != {}:
|
||||||
roles= copy.deepcopy(CacheData.roles)
|
shutil.copyfile(PLAYERS_DATA_PATH + "roles.json",
|
||||||
|
PLAYERS_DATA_PATH + "roles.json.backup")
|
||||||
|
roles = copy.deepcopy(CacheData.roles)
|
||||||
with open(PLAYERS_DATA_PATH + "roles.json", "w") as f:
|
with open(PLAYERS_DATA_PATH + "roles.json", "w") as f:
|
||||||
json.dump(roles, f, indent=4)
|
json.dump(roles, f, indent=4)
|
||||||
if CacheData.custom!={}:
|
if CacheData.custom != {}:
|
||||||
shutil.copyfile(PLAYERS_DATA_PATH + "custom.json",PLAYERS_DATA_PATH + "custom.json.backup")
|
shutil.copyfile(PLAYERS_DATA_PATH + "custom.json",
|
||||||
custom= copy.deepcopy(CacheData.custom)
|
PLAYERS_DATA_PATH + "custom.json.backup")
|
||||||
|
custom = copy.deepcopy(CacheData.custom)
|
||||||
with open(PLAYERS_DATA_PATH + "custom.json", "w") as f:
|
with open(PLAYERS_DATA_PATH + "custom.json", "w") as f:
|
||||||
json.dump(custom, f, indent=4)
|
json.dump(custom, f, indent=4)
|
||||||
time.sleep(60)
|
time.sleep(60)
|
||||||
|
|
|
||||||
363
dist/ba_root/mods/plugins/bcs_plugin.py
vendored
363
dist/ba_root/mods/plugins/bcs_plugin.py
vendored
|
|
@ -2,119 +2,43 @@
|
||||||
# coding: utf-8
|
# coding: utf-8
|
||||||
|
|
||||||
# ba_meta require api 7
|
# ba_meta require api 7
|
||||||
from typing import Optional, Any, Dict, List, Type, Sequence
|
# from gunicorn.app.base import BaseApplication
|
||||||
from ba._gameactivity import GameActivity
|
# from gunicorn.workers import ggevent as gevent_worker
|
||||||
import ba,_ba
|
|
||||||
import ba.internal
|
from flask import Flask, request, jsonify
|
||||||
import json
|
from functools import wraps
|
||||||
import os
|
import os
|
||||||
|
|
||||||
import _thread
|
import _thread
|
||||||
# from stats import mystats
|
# import uvicorn
|
||||||
|
from . import bombsquad_service
|
||||||
|
|
||||||
os.environ['FLASK_APP'] = 'bombsquadflaskapi.py'
|
os.environ['FLASK_APP'] = 'bombsquadflaskapi.py'
|
||||||
os.environ['FLASK_ENV'] = 'development'
|
os.environ['FLASK_ENV'] = 'development'
|
||||||
from stats import mystats
|
|
||||||
|
|
||||||
stats={}
|
app = Flask(__name__)
|
||||||
leaderboard={}
|
|
||||||
top200={}
|
|
||||||
|
|
||||||
class BsDataThread(object):
|
|
||||||
def __init__(self):
|
|
||||||
self.Timer = ba.Timer( 8,ba.Call(self.refreshStats),timetype = ba.TimeType.REAL,repeat = True)
|
|
||||||
self.Timerr = ba.Timer( 10,ba.Call(self.startThread),timetype = ba.TimeType.REAL,repeat = True)
|
|
||||||
|
|
||||||
def startThread(self):
|
|
||||||
_thread.start_new_thread(self.refreshLeaderboard,())
|
|
||||||
|
|
||||||
def refreshLeaderboard(self):
|
|
||||||
global leaderboard
|
|
||||||
global top200
|
|
||||||
_t200={}
|
|
||||||
|
|
||||||
lboard=mystats.get_all_stats()
|
|
||||||
leaderboard=lboard
|
|
||||||
try:
|
|
||||||
entries = [(a['scores'], a['kills'], a['deaths'], a['games'], a['name'], a['aid'],a['last_seen']) for a in lboard.values()]
|
|
||||||
except:
|
|
||||||
print("stats reset is required , please clear out stats.json records , or download fresh stats.json from github")
|
|
||||||
import _ba
|
|
||||||
_ba.quit()
|
|
||||||
entries.sort(key=lambda x: x[1] or 0, reverse=True)
|
|
||||||
rank=0
|
|
||||||
for entry in entries:
|
|
||||||
rank+=1
|
|
||||||
if rank >201:
|
|
||||||
break
|
|
||||||
_t200[entry[5]]={"rank":rank,"scores":int(entry[0]),"games":int(entry[3]),"kills":int(entry[1]),"deaths":int(entry[2]),"name_html":entry[4],"last_seen":entry[6]}
|
|
||||||
top200=_t200
|
|
||||||
|
|
||||||
def refreshStats(self):
|
|
||||||
|
|
||||||
liveplayers={}
|
|
||||||
nextMap=''
|
|
||||||
currentMap=''
|
|
||||||
global stats
|
|
||||||
for i in ba.internal.get_game_roster():
|
|
||||||
|
|
||||||
|
|
||||||
try:
|
|
||||||
liveplayers[i['account_id']]={'name':i['players'][0]['name_full'],'client_id':i['client_id'],'device_id':i['display_string']}
|
|
||||||
except:
|
|
||||||
liveplayers[i['account_id']]={'name':"<in-lobby>",'clientid':i['client_id'],'device_id':i['display_string']}
|
|
||||||
try:
|
|
||||||
nextMap=ba.internal.get_foreground_host_session().get_next_game_description().evaluate()
|
|
||||||
|
|
||||||
current_game_spec=ba.internal.get_foreground_host_session()._current_game_spec
|
|
||||||
gametype: Type[GameActivity] =current_game_spec['resolved_type']
|
|
||||||
|
|
||||||
currentMap=gametype.get_settings_display_string(current_game_spec).evaluate()
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
minigame={'current':currentMap,'next':nextMap}
|
|
||||||
# system={'cpu':"p.cpu_percent()",'ram':p.virtual_memory().percent}
|
|
||||||
system={'cpu':"null",'ram':'null'}
|
|
||||||
stats['system']=system
|
|
||||||
stats['roster']=liveplayers
|
|
||||||
stats['chats']=ba.internal.get_chat_messages()
|
|
||||||
stats['playlist']=minigame
|
|
||||||
stats['teamInfo']=self.getTeamInfo()
|
|
||||||
|
|
||||||
#print(self.getTeamInfo());
|
|
||||||
|
|
||||||
def getTeamInfo(self):
|
|
||||||
data={}
|
|
||||||
|
|
||||||
session=ba.internal.get_foreground_host_session()
|
|
||||||
data['sessionType']=type(session).__name__
|
|
||||||
teams=session.sessionteams
|
|
||||||
for team in teams:
|
|
||||||
data[team.id]={'name':team.name.evaluate(),
|
|
||||||
'color':list(team.color),
|
|
||||||
'score':team.customdata['score'],
|
|
||||||
'players':[]
|
|
||||||
}
|
|
||||||
for player in team.players:
|
|
||||||
teamplayer={'name':player.getname(),
|
|
||||||
'device_id':player.inputdevice.get_v1_account_name(True),
|
|
||||||
'inGame':player.in_game,
|
|
||||||
'character':player.character,
|
|
||||||
'account_id':player.get_v1_account_id()
|
|
||||||
}
|
|
||||||
data[team.id]['players'].append(teamplayer)
|
|
||||||
|
|
||||||
return data
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BsDataThread()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import flask
|
|
||||||
from flask import request, jsonify
|
|
||||||
|
|
||||||
app = flask.Flask(__name__)
|
|
||||||
app.config["DEBUG"] = False
|
app.config["DEBUG"] = False
|
||||||
|
SECRET_KEY = "my_secret_key"
|
||||||
|
|
||||||
|
|
||||||
|
@app.after_request
|
||||||
|
def add_cors_headers(response):
|
||||||
|
# Allow requests from any origin
|
||||||
|
response.headers['Access-Control-Allow-Origin'] = '*'
|
||||||
|
# Allow specific headers
|
||||||
|
response.headers['Access-Control-Allow-Headers'] = 'Content-Type,Authorization,Secret-Key'
|
||||||
|
# Allow specific HTTP methods
|
||||||
|
response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE'
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
def check_admin(func):
|
||||||
|
@wraps(func)
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
if "Secret-Key" not in request.headers or request.headers["Secret-Key"] != SECRET_KEY:
|
||||||
|
return jsonify({"message": "Invalid secret key provided."}), 401
|
||||||
|
return func(*args, **kwargs)
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
@app.route('/', methods=['GET'])
|
@app.route('/', methods=['GET'])
|
||||||
|
|
@ -122,26 +46,219 @@ def home():
|
||||||
return '''Nothing here :)'''
|
return '''Nothing here :)'''
|
||||||
|
|
||||||
|
|
||||||
# A route to return all of the available entries in our catalog.
|
@app.route('/api/live-stats', methods=['GET'])
|
||||||
@app.route('/getStats', methods=['GET'])
|
def get_live_stats():
|
||||||
def api_all():
|
return jsonify(bombsquad_service.get_stats()), 200
|
||||||
return json.dumps(stats)
|
|
||||||
|
|
||||||
@app.route('/getLeaderboard',methods=['GET'])
|
|
||||||
def get_l():
|
|
||||||
return json.dumps(leaderboard)
|
|
||||||
|
|
||||||
@app.route('/getTop200',methods=['GET'])
|
@app.route('/api/top-200', methods=['GET'])
|
||||||
def get_top200():
|
def get_top200():
|
||||||
return json.dumps(top200)
|
return jsonify(bombsquad_service.get_top_200()), 200
|
||||||
|
|
||||||
|
|
||||||
class InitalRun:
|
# ============ Admin only =========
|
||||||
def __init__(self):
|
|
||||||
print("start flask")
|
|
||||||
flask_run = _thread.start_new_thread(app.run, ("0.0.0.0",5000,False ))
|
@app.route('/api/login', methods=['POST'])
|
||||||
|
@check_admin
|
||||||
|
def login():
|
||||||
|
return jsonify({"message": "Successful"}), 200
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/api/current-leaderboard', methods=['GET'])
|
||||||
|
@check_admin
|
||||||
|
def get_complete_leaderboard():
|
||||||
|
return jsonify(bombsquad_service.get_complete_leaderboard()), 200
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/api/server-settings', methods=['GET'])
|
||||||
|
@check_admin
|
||||||
|
def get_server_settings():
|
||||||
|
return jsonify(bombsquad_service.get_server_settings()), 200
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/api/roles', methods=['GET'])
|
||||||
|
@check_admin
|
||||||
|
def get_roles():
|
||||||
|
return jsonify(bombsquad_service.get_roles()), 200
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/api/roles', methods=['POST'])
|
||||||
|
@check_admin
|
||||||
|
def update_roles():
|
||||||
|
try:
|
||||||
|
data = request.get_json()
|
||||||
|
bombsquad_service.update_roles(data)
|
||||||
|
response = {
|
||||||
|
'message': 'Roles updated successfully'}
|
||||||
|
return jsonify(response), 201
|
||||||
|
except Exception as e:
|
||||||
|
return jsonify({'message': 'Error processing request', 'error': str(e)}), 400
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/api/perks', methods=['GET'])
|
||||||
|
@check_admin
|
||||||
|
def get_perks():
|
||||||
|
return jsonify(bombsquad_service.get_perks()), 200
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/api/perks', methods=['POST'])
|
||||||
|
@check_admin
|
||||||
|
def update_perks():
|
||||||
|
try:
|
||||||
|
data = request.get_json()
|
||||||
|
bombsquad_service.update_perks(data)
|
||||||
|
response = {
|
||||||
|
'message': 'Custom perks updated successfully'}
|
||||||
|
return jsonify(response), 201
|
||||||
|
except Exception as e:
|
||||||
|
return jsonify({'message': 'Error processing request', 'error': str(e)}), 400
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/api/server-settings', methods=['POST'])
|
||||||
|
@check_admin
|
||||||
|
def update_server_settings():
|
||||||
|
try:
|
||||||
|
data = request.get_json()
|
||||||
|
bombsquad_service.update_server_settings(data)
|
||||||
|
response = {
|
||||||
|
'message': 'Settings updated successfully, server may need restart'}
|
||||||
|
return jsonify(response), 201
|
||||||
|
except Exception as e:
|
||||||
|
return jsonify({'message': 'Error processing request', 'error': str(e)}), 400
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/api/db-list', methods=['GET'])
|
||||||
|
@check_admin
|
||||||
|
def fetch_dB_list():
|
||||||
|
key = request.args.get('type')
|
||||||
|
if key is None:
|
||||||
|
return "type required", 400
|
||||||
|
if key == "logs":
|
||||||
|
return jsonify(bombsquad_service.get_logs_db_list()), 200
|
||||||
|
elif key == "players":
|
||||||
|
return jsonify(bombsquad_service.get_profiles_db_list()), 200
|
||||||
|
else:
|
||||||
|
return jsonify({"message": "Invalid db type"}), 400
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/api/search-logs', methods=['GET'])
|
||||||
|
@check_admin
|
||||||
|
def search_logs():
|
||||||
|
key = request.args.get('key')
|
||||||
|
db = request.args.get('db')
|
||||||
|
if key is None or db is None:
|
||||||
|
return jsonify({"message": "key and db required"}), 400
|
||||||
|
return jsonify(bombsquad_service.get_matching_logs(key, db)), 200
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/api/search-player', methods=['GET'])
|
||||||
|
@check_admin
|
||||||
|
def search_players():
|
||||||
|
key = request.args.get('key')
|
||||||
|
db = request.args.get('db')
|
||||||
|
if key is None or db is None:
|
||||||
|
return jsonify({"message": "key and db required"}), 400
|
||||||
|
return jsonify(bombsquad_service.search_player_profile(key, db)), 200
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/api/get-player-info', methods=['GET'])
|
||||||
|
@check_admin
|
||||||
|
def get_player():
|
||||||
|
account_id = request.args.get('account-id')
|
||||||
|
if account_id is None:
|
||||||
|
return jsonify({"message": "account-id required"}), 400
|
||||||
|
return jsonify(bombsquad_service.get_player_details(account_id)), 200
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/api/update-player', methods=['POST'])
|
||||||
|
@check_admin
|
||||||
|
def update_player():
|
||||||
|
account_id = request.args.get('account-id')
|
||||||
|
action = request.args.get('action')
|
||||||
|
duration = int(request.args.get('duration'))
|
||||||
|
if account_id is None or action is None:
|
||||||
|
return "account-id and action required", 400
|
||||||
|
if action == "ban":
|
||||||
|
bombsquad_service.ban_player(account_id, duration)
|
||||||
|
elif action == "unban":
|
||||||
|
bombsquad_service.unban_player(account_id)
|
||||||
|
elif action == "mute":
|
||||||
|
bombsquad_service.mute_player(account_id, duration)
|
||||||
|
elif action == "unmute":
|
||||||
|
bombsquad_service.unmute_player(account_id)
|
||||||
|
elif action == "disable-kick-vote":
|
||||||
|
bombsquad_service.disable_kick_vote(account_id, duration)
|
||||||
|
elif action == "enable-kick-vote":
|
||||||
|
bombsquad_service.enable_kick_vote(account_id)
|
||||||
|
else:
|
||||||
|
return jsonify({"message": "Invalid Action"}), 400
|
||||||
|
return jsonify({"message": f"{action} done"}), 201
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/api/config', methods=['GET'])
|
||||||
|
@check_admin
|
||||||
|
def get_config():
|
||||||
|
return jsonify(bombsquad_service.get_server_config()), 200
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/api/action', methods=['POST'])
|
||||||
|
@check_admin
|
||||||
|
def do_action():
|
||||||
|
action = request.args.get('action')
|
||||||
|
value = request.args.get('value')
|
||||||
|
bombsquad_service.do_action(action, value)
|
||||||
|
return jsonify({"message": f'{action} done'}), 200
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/api/config', methods=['POST'])
|
||||||
|
@check_admin
|
||||||
|
def update_server_config():
|
||||||
|
try:
|
||||||
|
data = request.get_json()
|
||||||
|
bombsquad_service.update_server_config(data)
|
||||||
|
response = {
|
||||||
|
'message': 'config updated successfully, server will restart'}
|
||||||
|
return jsonify(response), 201
|
||||||
|
except Exception as e:
|
||||||
|
return jsonify({'message': 'Error processing request', 'error': str(e)}), 400
|
||||||
|
|
||||||
|
# from flask_asgi import FlaskASGI
|
||||||
|
# asgi_app = FlaskASGI(app)
|
||||||
|
|
||||||
|
|
||||||
|
# class FlaskApplication(BaseApplication):
|
||||||
|
# def __init__(self, app, options=None):
|
||||||
|
# self.options = options or {}
|
||||||
|
# self.application = app
|
||||||
|
# super(FlaskApplication, self).__init__()
|
||||||
|
|
||||||
|
# def load_config(self):
|
||||||
|
# config = {key: value for key, value in self.options.items(
|
||||||
|
# ) if key in self.cfg.settings and value is not None}
|
||||||
|
# for key, value in config.items():
|
||||||
|
# self.cfg.set(key.lower(), value)
|
||||||
|
|
||||||
|
# def load(self):
|
||||||
|
# return self.application
|
||||||
|
|
||||||
|
|
||||||
|
# def start_uvicorn():
|
||||||
|
# uvicorn.run("main:app", host='0.0.0.0', port=5000,
|
||||||
|
# reload=False, log_level="debug", workers=3, use_colors=True, no_signal=True)
|
||||||
|
# flask_run = _thread.start_new_thread(app.run, ("0.0.0.0", 5000, False))
|
||||||
|
|
||||||
|
|
||||||
def enable():
|
def enable():
|
||||||
InitalRun()
|
flask_run = _thread.start_new_thread(app.run, ("0.0.0.0", 5000, False))
|
||||||
# SAMPLE OUTPUT
|
# uvicorn_thread = threading.Thread(target=start_uvicorn)
|
||||||
# {'system': {'cpu': 80, 'ram': 34}, 'roster': {}, 'chats': [], 'playlist': {'current': 'Meteor Shower @ Rampage', 'next': 'Assault @ Step Right Up'}, 'teamInfo': {'sessionType': 'DualTeamSession', 0: {'name': 'Blue', 'color': (0.1, 0.25, 1.0), 'score': 1, 'players': [{'name': 'Jolly', 'device_id': '\ue030PC295588', 'inGame': True, 'character': 'xmas', 'account_id': 'pb-IF4TVWwZUQ=='}]}, 1: {'name': 'Red', 'color': (1.0, 0.25, 0.2), 'score': 0, 'players': []}}}
|
# uvicorn_thread.start()
|
||||||
|
# options = {
|
||||||
|
# 'bind': '0.0.0.0:8000',
|
||||||
|
# 'workers': 4,
|
||||||
|
# 'worker_class': 'gevent'
|
||||||
|
# }
|
||||||
|
|
||||||
|
# flask_app = FlaskApplication(app, options)
|
||||||
|
# gevent_worker.GeventWorker(app.wsgi_app).init_process()
|
||||||
|
# flask_app.run()
|
||||||
|
|
|
||||||
257
dist/ba_root/mods/plugins/bombsquad_service.py
vendored
Normal file
257
dist/ba_root/mods/plugins/bombsquad_service.py
vendored
Normal file
|
|
@ -0,0 +1,257 @@
|
||||||
|
import ba
|
||||||
|
import _ba
|
||||||
|
import ba.internal
|
||||||
|
from stats import mystats
|
||||||
|
from typing import Optional, Any, Dict, List, Type, Sequence
|
||||||
|
from ba._gameactivity import GameActivity
|
||||||
|
from playersData import pdata
|
||||||
|
from serverData import serverdata
|
||||||
|
from tools import servercheck, logger
|
||||||
|
import setting
|
||||||
|
from datetime import datetime
|
||||||
|
import _thread
|
||||||
|
import os
|
||||||
|
import yaml
|
||||||
|
stats = {}
|
||||||
|
leaderboard = {}
|
||||||
|
top200 = {}
|
||||||
|
|
||||||
|
serverinfo = {}
|
||||||
|
|
||||||
|
|
||||||
|
class BsDataThread(object):
|
||||||
|
def __init__(self):
|
||||||
|
global stats
|
||||||
|
stats["name"] = _ba.app.server._config.party_name
|
||||||
|
stats["discord"] = "https://discord.gg/ucyaesh"
|
||||||
|
stats["vapidKey"] = "sjfbsdjfdsf"
|
||||||
|
|
||||||
|
self.refresh_stats_cache_timer = ba.Timer(8, ba.Call(self.refreshStats),
|
||||||
|
timetype=ba.TimeType.REAL, repeat=True)
|
||||||
|
self.refresh_leaderboard_cache_timer = ba.Timer(10, ba.Call(
|
||||||
|
self.refreshLeaderboard), timetype=ba.TimeType.REAL, repeat=True)
|
||||||
|
|
||||||
|
def startThread(self):
|
||||||
|
_thread.start_new_thread(self.refreshLeaderboard, ())
|
||||||
|
|
||||||
|
def refreshLeaderboard(self):
|
||||||
|
global leaderboard
|
||||||
|
global top200
|
||||||
|
|
||||||
|
lboard = mystats.get_cached_stats()
|
||||||
|
leaderboard = lboard
|
||||||
|
sorted_data = sorted(lboard.values(), key=lambda x: x["rank"])
|
||||||
|
top_200_players = sorted_data[:200]
|
||||||
|
|
||||||
|
top200 = {player["aid"]: player for player in top_200_players}
|
||||||
|
|
||||||
|
def refreshStats(self):
|
||||||
|
global stats
|
||||||
|
global serverinfo
|
||||||
|
liveplayers = {}
|
||||||
|
nextMap = ''
|
||||||
|
currentMap = ''
|
||||||
|
|
||||||
|
for i in ba.internal.get_game_roster():
|
||||||
|
try:
|
||||||
|
liveplayers[i['account_id']] = {
|
||||||
|
'name': i['players'][0]['name_full'], 'client_id': i['client_id'], 'device_id': i['display_string']}
|
||||||
|
except:
|
||||||
|
liveplayers[i['account_id']] = {
|
||||||
|
'name': "<in-lobby>", 'client_id': i['client_id'], 'device_id': i['display_string']}
|
||||||
|
try:
|
||||||
|
nextMap = ba.internal.get_foreground_host_session(
|
||||||
|
).get_next_game_description().evaluate()
|
||||||
|
|
||||||
|
current_game_spec = ba.internal.get_foreground_host_session()._current_game_spec
|
||||||
|
gametype: Type[GameActivity] = current_game_spec['resolved_type']
|
||||||
|
|
||||||
|
currentMap = gametype.get_settings_display_string(
|
||||||
|
current_game_spec).evaluate()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
current_games = {'current': currentMap, 'next': nextMap}
|
||||||
|
# system={'cpu':"p.cpu_percent()",'ram':p.virtual_memory().percent}
|
||||||
|
system = {'cpu': "null", 'ram': 'null'}
|
||||||
|
stats['system'] = system
|
||||||
|
stats['roster'] = liveplayers
|
||||||
|
stats['chats'] = ba.internal.get_chat_messages()
|
||||||
|
stats['playlist'] = current_games
|
||||||
|
stats['teamInfo'] = self.getTeamInfo()
|
||||||
|
stats["sessionType"] = type(
|
||||||
|
ba.internal.get_foreground_host_session()).__name__
|
||||||
|
|
||||||
|
# print(self.getTeamInfo());
|
||||||
|
|
||||||
|
def getTeamInfo(self):
|
||||||
|
data = {}
|
||||||
|
session = ba.internal.get_foreground_host_session()
|
||||||
|
if session:
|
||||||
|
teams = session.sessionteams
|
||||||
|
for team in teams:
|
||||||
|
data[str(team.id)] = {'name': team.name if isinstance(team.name, str) else team.name.evaluate(),
|
||||||
|
'color': list(team.color),
|
||||||
|
'score': team.customdata['score'],
|
||||||
|
'players': []
|
||||||
|
}
|
||||||
|
for player in team.players:
|
||||||
|
teamplayer = {'name': player.getname(),
|
||||||
|
'device_id': player.inputdevice.get_v1_account_name(True),
|
||||||
|
'inGame': player.in_game,
|
||||||
|
'character': player.character,
|
||||||
|
'account_id': player.get_v1_account_id()
|
||||||
|
}
|
||||||
|
data[str(team.id)]['players'].append(teamplayer)
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
BsDataThread()
|
||||||
|
|
||||||
|
|
||||||
|
def get_stats():
|
||||||
|
return stats
|
||||||
|
|
||||||
|
|
||||||
|
def get_complete_leaderboard():
|
||||||
|
return leaderboard
|
||||||
|
|
||||||
|
|
||||||
|
def get_top_200():
|
||||||
|
return top200
|
||||||
|
|
||||||
|
|
||||||
|
def get_server_settings():
|
||||||
|
return setting.get_settings_data()
|
||||||
|
|
||||||
|
|
||||||
|
def update_server_settings(settings):
|
||||||
|
logger.log(f'updating server settings, request from web')
|
||||||
|
setting.commit(settings)
|
||||||
|
|
||||||
|
|
||||||
|
def get_roles():
|
||||||
|
return pdata.get_roles()
|
||||||
|
|
||||||
|
|
||||||
|
def get_perks():
|
||||||
|
# TODO wire with spaz_effects to fetch list of effects.
|
||||||
|
return {"perks": pdata.get_custom_perks(), "availableEffects": ["spark", "glow", "fairydust"]}
|
||||||
|
|
||||||
|
|
||||||
|
def update_perks(custom):
|
||||||
|
logger.log(f'updating custom perks, request from web')
|
||||||
|
pdata.update_custom_perks(custom)
|
||||||
|
|
||||||
|
|
||||||
|
def update_roles(roles):
|
||||||
|
logger.log("updated roles from web")
|
||||||
|
return pdata.update_roles(roles)
|
||||||
|
|
||||||
|
|
||||||
|
def get_profiles_db_list():
|
||||||
|
return pdata.get_profiles_archive_index()
|
||||||
|
|
||||||
|
|
||||||
|
def get_logs_db_list():
|
||||||
|
return serverdata.get_stats_index()
|
||||||
|
|
||||||
|
|
||||||
|
def get_matching_logs(key: str, filename: str):
|
||||||
|
logs = serverdata.read_logs(filename)
|
||||||
|
matching_lines = [line.strip() for line in logs.split('\n') if key in line]
|
||||||
|
return matching_lines
|
||||||
|
|
||||||
|
|
||||||
|
def search_player_profile(search_key: str, db: str):
|
||||||
|
selectedDB = {}
|
||||||
|
if db == "profiles.json":
|
||||||
|
selectedDB = pdata.get_profiles()
|
||||||
|
|
||||||
|
elif db in pdata.get_profiles_archive_index():
|
||||||
|
selectedDB = pdata.get_old_profiles(db)
|
||||||
|
|
||||||
|
matching_objects = {}
|
||||||
|
for key in selectedDB.keys():
|
||||||
|
if (search_key == key or
|
||||||
|
any(search_key.lower() in s.lower() for s in selectedDB[key].get("display_string", [])) or
|
||||||
|
search_key.lower() in selectedDB[key].get("name", "").lower()):
|
||||||
|
matching_objects[key] = selectedDB[key]
|
||||||
|
return matching_objects
|
||||||
|
|
||||||
|
|
||||||
|
def get_player_details(account_id: str):
|
||||||
|
current_time = datetime.now()
|
||||||
|
current_profiles = pdata.get_profiles()
|
||||||
|
ip = ""
|
||||||
|
device_id = ""
|
||||||
|
if account_id in current_profiles:
|
||||||
|
ip = current_profiles[account_id]["lastIP"]
|
||||||
|
device_id = current_profiles[account_id]["deviceUUID"]
|
||||||
|
extra_info = pdata.get_detailed_info(account_id)
|
||||||
|
isBanned = False
|
||||||
|
isMuted = False
|
||||||
|
isKickVoteDisabled = False
|
||||||
|
haveBanReason = servercheck.check_ban(ip, device_id, account_id, False)
|
||||||
|
if haveBanReason:
|
||||||
|
isBanned = True
|
||||||
|
extra_info += " , Banned for > " + haveBanReason
|
||||||
|
if account_id in pdata.get_blacklist()["muted-ids"] and current_time < datetime.strptime(pdata.get_blacklist()["muted-ids"][account_id]["till"], "%Y-%m-%d %H:%M:%S"):
|
||||||
|
isMuted = True
|
||||||
|
extra_info += f', Muted for > { pdata.get_blacklist()["muted-ids"][account_id]["reason"] } , till > {pdata.get_blacklist()["muted-ids"][account_id]["till"]} ,'
|
||||||
|
if account_id in pdata.get_blacklist()["kick-vote-disabled"] and current_time < datetime.strptime(pdata.get_blacklist()["kick-vote-disabled"][account_id]["till"], "%Y-%m-%d %H:%M:%S"):
|
||||||
|
isKickVoteDisabled = True
|
||||||
|
extra_info += f', Kick vote disabled for > { pdata.get_blacklist()["kick-vote-disabled"][account_id]["reason"] } , till > {pdata.get_blacklist()["kick-vote-disabled"][account_id]["till"]} '
|
||||||
|
|
||||||
|
return {"extra": extra_info, "isBan": isBanned, "isMuted": isMuted, "isKickVoteDisabled": isKickVoteDisabled}
|
||||||
|
|
||||||
|
|
||||||
|
def unban_player(account_id):
|
||||||
|
logger.log(f'unbanning {account_id} , request from web')
|
||||||
|
pdata.unban_player(account_id)
|
||||||
|
|
||||||
|
|
||||||
|
def unmute_player(account_id):
|
||||||
|
logger.log(f'unmuting {account_id} , request from web')
|
||||||
|
pdata.unmute(account_id)
|
||||||
|
|
||||||
|
|
||||||
|
def enable_kick_vote(account_id):
|
||||||
|
logger.log(f'enabling kick vote for {account_id} , request from web')
|
||||||
|
pdata.enable_kick_vote(account_id)
|
||||||
|
|
||||||
|
# TODO take duration input
|
||||||
|
|
||||||
|
|
||||||
|
def ban_player(account_id, duration):
|
||||||
|
logger.log(f'banning {account_id} , request from web')
|
||||||
|
pdata.ban_player(account_id, duration, "manually from website")
|
||||||
|
|
||||||
|
|
||||||
|
def mute_player(account_id, duration):
|
||||||
|
logger.log(f'muting {account_id} , request from web')
|
||||||
|
pdata.mute(account_id, duration, "manually from website")
|
||||||
|
|
||||||
|
|
||||||
|
def disable_kick_vote(account_id, duration):
|
||||||
|
logger.log(f'disable {account_id} , request from web')
|
||||||
|
pdata.disable_kick_vote(account_id, duration, "manually from website")
|
||||||
|
|
||||||
|
|
||||||
|
def get_server_config():
|
||||||
|
return _ba.app.server._config.__dict__
|
||||||
|
|
||||||
|
|
||||||
|
def update_server_config(config):
|
||||||
|
current_dir = os.getcwd()
|
||||||
|
file_path = os.path.join(current_dir, '..', 'config.yaml')
|
||||||
|
|
||||||
|
with open(file_path, "w") as f:
|
||||||
|
f.write(yaml.dump(config))
|
||||||
|
|
||||||
|
|
||||||
|
def do_action(action, value):
|
||||||
|
if action == "message":
|
||||||
|
_ba.pushcall(ba.Call(_ba.chatmessage, value), from_other_thread=True)
|
||||||
|
elif action == "quit":
|
||||||
|
_ba.pushcall(ba.Call(_ba.quit), from_other_thread=True)
|
||||||
41
dist/ba_root/mods/serverData/serverdata.py
vendored
41
dist/ba_root/mods/serverData/serverdata.py
vendored
|
|
@ -1,8 +1,37 @@
|
||||||
# Released under the MIT License. See LICENSE for details.
|
# Released under the MIT License. See LICENSE for details.
|
||||||
|
|
||||||
clients={}
|
import fcntl
|
||||||
cachedclients=[]
|
import _ba
|
||||||
muted=False
|
import os
|
||||||
coopmode=False
|
clients = {}
|
||||||
ips={}
|
cachedclients = []
|
||||||
recents=[]
|
muted = False
|
||||||
|
coopmode = False
|
||||||
|
ips = {}
|
||||||
|
recents = []
|
||||||
|
|
||||||
|
|
||||||
|
SERVER_DATA_PATH = os.path.join(
|
||||||
|
_ba.env()["python_directory_user"], "serverData" + os.sep
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def get_stats_index():
|
||||||
|
return [x for x in os.listdir(SERVER_DATA_PATH) if "log" in x]
|
||||||
|
|
||||||
|
|
||||||
|
def read_logs(filename):
|
||||||
|
file_path = SERVER_DATA_PATH+filename
|
||||||
|
if not os.path.exists(file_path):
|
||||||
|
return ""
|
||||||
|
file = open(file_path, "r")
|
||||||
|
fcntl.flock(file.fileno(), fcntl.LOCK_SH)
|
||||||
|
contents = ""
|
||||||
|
try:
|
||||||
|
contents = file.read()
|
||||||
|
|
||||||
|
finally:
|
||||||
|
fcntl.flock(file.fileno(), fcntl.LOCK_UN)
|
||||||
|
file.close()
|
||||||
|
|
||||||
|
return contents
|
||||||
|
|
|
||||||
6
dist/ba_root/mods/setting.py
vendored
6
dist/ba_root/mods/setting.py
vendored
|
|
@ -30,6 +30,10 @@ def get_settings_data() -> dict:
|
||||||
with open(SETTINGS_PATH, mode="r", encoding="utf-8") as data:
|
with open(SETTINGS_PATH, mode="r", encoding="utf-8") as data:
|
||||||
return json.load(data)
|
return json.load(data)
|
||||||
|
|
||||||
|
def refresh_cache() -> None:
|
||||||
|
get_settings_data.cache_clear()
|
||||||
|
# lets cache it again
|
||||||
|
get_settings_data()
|
||||||
|
|
||||||
def commit(data: dict) -> None:
|
def commit(data: dict) -> None:
|
||||||
"""Commits the data in setting file.
|
"""Commits the data in setting file.
|
||||||
|
|
@ -41,3 +45,5 @@ def commit(data: dict) -> None:
|
||||||
"""
|
"""
|
||||||
with open(SETTINGS_PATH, mode="w", encoding="utf-8") as setting_file:
|
with open(SETTINGS_PATH, mode="w", encoding="utf-8") as setting_file:
|
||||||
json.dump(data, setting_file, indent=4)
|
json.dump(data, setting_file, indent=4)
|
||||||
|
# settings updated ok now update the cache
|
||||||
|
refresh_cache()
|
||||||
|
|
|
||||||
44
dist/ba_root/mods/stats/mystats.py
vendored
44
dist/ba_root/mods/stats/mystats.py
vendored
|
|
@ -6,29 +6,17 @@ import os
|
||||||
import shutil
|
import shutil
|
||||||
import threading
|
import threading
|
||||||
import datetime
|
import datetime
|
||||||
import custom_hooks
|
|
||||||
import urllib.request
|
import urllib.request
|
||||||
from ba._activitytypes import *
|
from ba._activitytypes import *
|
||||||
from ba import _activitytypes as ba_actypes
|
|
||||||
from ba._lobby import JoinInfo
|
|
||||||
from typing import Any, Dict, Optional
|
|
||||||
from ba._team import EmptyTeam # pylint: disable=W0611
|
|
||||||
from ba._player import EmptyPlayer # pylint: disable=W0611
|
|
||||||
from ba._music import setmusic, MusicType
|
|
||||||
from ba._activity import Activity
|
|
||||||
damage_data = {}
|
damage_data = {}
|
||||||
# Don't touch the above line
|
|
||||||
"""
|
|
||||||
mystats module for BombSquad version 1.5.29
|
|
||||||
Provides functionality for dumping player stats to disk between rounds.
|
|
||||||
"""
|
|
||||||
ranks = []
|
ranks = []
|
||||||
top3Name = []
|
top3Name = []
|
||||||
# False-positive from pylint due to our class-generics-filter.
|
|
||||||
|
|
||||||
# variables
|
|
||||||
our_settings = setting.get_settings_data()
|
our_settings = setting.get_settings_data()
|
||||||
# where our stats file and pretty html output will go
|
|
||||||
base_path = os.path.join(_ba.env()['python_directory_user'], "stats" + os.sep)
|
base_path = os.path.join(_ba.env()['python_directory_user'], "stats" + os.sep)
|
||||||
statsfile = base_path + 'stats.json'
|
statsfile = base_path + 'stats.json'
|
||||||
cached_stats = {}
|
cached_stats = {}
|
||||||
|
|
@ -47,16 +35,14 @@ statsDefault = {
|
||||||
"last_seen": "2022-04-26 17:01:13.715014"
|
"last_seen": "2022-04-26 17:01:13.715014"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
# <th><b>Total Damage</b></th> #removed this line as it isn't crt data
|
|
||||||
|
|
||||||
# useful functions
|
|
||||||
seasonStartDate = None
|
seasonStartDate = None
|
||||||
|
|
||||||
|
|
||||||
def get_all_stats():
|
def get_all_stats():
|
||||||
global seasonStartDate
|
global seasonStartDate
|
||||||
if os.path.exists(statsfile):
|
if os.path.exists(statsfile):
|
||||||
renameFile = False
|
|
||||||
with open(statsfile, 'r', encoding='utf8') as f:
|
with open(statsfile, 'r', encoding='utf8') as f:
|
||||||
try:
|
try:
|
||||||
jsonData = json.loads(f.read())
|
jsonData = json.loads(f.read())
|
||||||
|
|
@ -83,7 +69,7 @@ def get_all_stats():
|
||||||
|
|
||||||
def backupStatsFile():
|
def backupStatsFile():
|
||||||
shutil.copy(statsfile, statsfile.replace(
|
shutil.copy(statsfile, statsfile.replace(
|
||||||
".json", "") + str(seasonStartDate) + ".json")
|
".json", "") + str(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")) + ".json")
|
||||||
|
|
||||||
|
|
||||||
def dump_stats(s: dict):
|
def dump_stats(s: dict):
|
||||||
|
|
@ -107,23 +93,27 @@ def get_stats_by_id(account_id: str):
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def get_cached_stats():
|
def get_cached_stats():
|
||||||
return cached_stats
|
return cached_stats
|
||||||
|
|
||||||
|
|
||||||
|
def get_sorted_stats(stats):
|
||||||
|
entries = [(a['scores'], a['kills'], a['deaths'], a['games'],
|
||||||
|
a['name'], a['aid']) for a in stats.values()]
|
||||||
|
# this gives us a list of kills/names sorted high-to-low
|
||||||
|
entries.sort(key=lambda x: x[1] or 0, reverse=True)
|
||||||
|
return entries
|
||||||
|
|
||||||
|
|
||||||
def refreshStats():
|
def refreshStats():
|
||||||
global cached_stats
|
global cached_stats
|
||||||
# lastly, write a pretty html version.
|
# lastly, write a pretty html version.
|
||||||
# our stats url could point at something like this...
|
# our stats url could point at something like this...
|
||||||
pStats = get_all_stats()
|
pStats = get_all_stats()
|
||||||
cached_stats = pStats
|
cached_stats = pStats
|
||||||
|
entries = get_sorted_stats(pStats)
|
||||||
|
|
||||||
entries = [(a['scores'], a['kills'], a['deaths'], a['games'],
|
|
||||||
a['name'], a['aid']) for a in pStats.values()]
|
|
||||||
# this gives us a list of kills/names sorted high-to-low
|
|
||||||
entries.sort(key=lambda x: x[1] or 0, reverse=True)
|
|
||||||
rank = 0
|
rank = 0
|
||||||
toppers = {}
|
|
||||||
toppersIDs = []
|
toppersIDs = []
|
||||||
_ranks = []
|
_ranks = []
|
||||||
for entry in entries:
|
for entry in entries:
|
||||||
|
|
|
||||||
39
dist/ba_root/mods/tools/logger.py
vendored
39
dist/ba_root/mods/tools/logger.py
vendored
|
|
@ -17,7 +17,7 @@ import shutil
|
||||||
import threading
|
import threading
|
||||||
import setting
|
import setting
|
||||||
import _ba
|
import _ba
|
||||||
|
import fcntl
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
@ -33,6 +33,7 @@ if SETTINGS["discordbot"]["enable"]:
|
||||||
|
|
||||||
WEBHOOK_URL = SETTINGS["discordWebHook"]["webhookURL"]
|
WEBHOOK_URL = SETTINGS["discordWebHook"]["webhookURL"]
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class RecentLogs:
|
class RecentLogs:
|
||||||
"""Saves the recent logs."""
|
"""Saves the recent logs."""
|
||||||
|
|
@ -54,7 +55,7 @@ def log(msg: str, mtype: str = "sys") -> None:
|
||||||
message = msg.replace("||", "|")
|
message = msg.replace("||", "|")
|
||||||
discord_bot.push_log("***" + mtype + ":***" + message)
|
discord_bot.push_log("***" + mtype + ":***" + message)
|
||||||
|
|
||||||
current_time = datetime.datetime.now()
|
current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||||
msg = f"{current_time} + : {msg} \n"
|
msg = f"{current_time} + : {msg} \n"
|
||||||
|
|
||||||
if SETTINGS["discordWebHook"]["enable"]:
|
if SETTINGS["discordWebHook"]["enable"]:
|
||||||
|
|
@ -102,14 +103,38 @@ class dumplogs(threading.Thread):
|
||||||
elif self.type == "cmndlog":
|
elif self.type == "cmndlog":
|
||||||
log_path = SERVER_DATA_PATH + "cmndusage.log"
|
log_path = SERVER_DATA_PATH + "cmndusage.log"
|
||||||
else:
|
else:
|
||||||
log_path = SERVER_DATA_PATH + "logs.log"
|
log_path = SERVER_DATA_PATH + "systemlogs.log"
|
||||||
if os.path.exists(log_path):
|
if os.path.exists(log_path):
|
||||||
if os.stat(log_path).st_size > 1000000:
|
if os.stat(log_path).st_size > 1000000:
|
||||||
shutil.copy(log_path, log_path+str(datetime.datetime.now()))
|
self.copy_file(
|
||||||
os.remove(log_path)
|
log_path, log_path+str(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")))
|
||||||
with open(log_path, mode="a+", encoding="utf-8") as file:
|
|
||||||
for msg in self.msg:
|
self.write_file(log_path, self.msg)
|
||||||
|
|
||||||
|
def write_file(self, file_path, data):
|
||||||
|
file = open(file_path, "a+", encoding="utf-8")
|
||||||
|
fcntl.flock(file.fileno(), fcntl.LOCK_EX)
|
||||||
|
|
||||||
|
try:
|
||||||
|
for msg in data:
|
||||||
file.write(msg)
|
file.write(msg)
|
||||||
|
finally:
|
||||||
|
fcntl.flock(file.fileno(), fcntl.LOCK_UN)
|
||||||
|
file.close()
|
||||||
|
|
||||||
|
def copy_file(self, file_path, dest_path):
|
||||||
|
lock_file = open(file_path, "r")
|
||||||
|
fcntl.flock(lock_file.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)
|
||||||
|
|
||||||
|
try:
|
||||||
|
shutil.copy(file_path, dest_path)
|
||||||
|
except Exception as e:
|
||||||
|
print("Error occurred while copying file:", str(e))
|
||||||
|
finally:
|
||||||
|
fcntl.flock(lock_file.fileno(), fcntl.LOCK_UN)
|
||||||
|
lock_file.close()
|
||||||
|
os.remove(lock_file)
|
||||||
|
|
||||||
|
|
||||||
def send_webhook_message():
|
def send_webhook_message():
|
||||||
global webhook_queue
|
global webhook_queue
|
||||||
|
|
|
||||||
145
dist/ba_root/mods/tools/servercheck.py
vendored
145
dist/ba_root/mods/tools/servercheck.py
vendored
|
|
@ -7,7 +7,7 @@ import _ba
|
||||||
import ba.internal
|
import ba.internal
|
||||||
import urllib.request
|
import urllib.request
|
||||||
import json
|
import json
|
||||||
import datetime
|
from datetime import datetime
|
||||||
import time
|
import time
|
||||||
import ba
|
import ba
|
||||||
from ba._general import Call
|
from ba._general import Call
|
||||||
|
|
@ -23,11 +23,13 @@ blacklist = pdata.get_blacklist()
|
||||||
settings = setting.get_settings_data()
|
settings = setting.get_settings_data()
|
||||||
ipjoin = {}
|
ipjoin = {}
|
||||||
|
|
||||||
|
|
||||||
class checkserver(object):
|
class checkserver(object):
|
||||||
def start(self):
|
def start(self):
|
||||||
self.players = []
|
self.players = []
|
||||||
|
|
||||||
self.t1 = ba.Timer(1, ba.Call(self.check), repeat=True, timetype=ba.TimeType.REAL)
|
self.t1 = ba.Timer(1, ba.Call(self.check),
|
||||||
|
repeat=True, timetype=ba.TimeType.REAL)
|
||||||
|
|
||||||
def check(self):
|
def check(self):
|
||||||
newPlayers = []
|
newPlayers = []
|
||||||
|
|
@ -36,33 +38,33 @@ 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"]:
|
if (device_id == None):
|
||||||
# logger.log(f'Player disconnected, None account Id || {ros["display_string"] } IP {ip} {device_id}' ,
|
device_id = _ba.get_client_device_uuid(ros["client_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:
|
||||||
deviceClientMap[device_id].append(ros["client_id"])
|
deviceClientMap[device_id].append(ros["client_id"])
|
||||||
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(f'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:
|
||||||
ipClientMap[ip] = [ros["client_id"]]
|
ipClientMap[ip] = [ros["client_id"]]
|
||||||
else:
|
else:
|
||||||
ipClientMap[ip].append(ros["client_id"])
|
ipClientMap[ip].append(ros["client_id"])
|
||||||
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(f'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'])
|
||||||
if ros['account_id'] not in self.players and ros[
|
if ros['account_id'] not in self.players and ros[
|
||||||
'client_id'] != -1:
|
'client_id'] != -1:
|
||||||
# new player joined lobby
|
# new player joined lobby
|
||||||
|
|
||||||
d_str = ros['display_string']
|
d_str = ros['display_string']
|
||||||
|
|
@ -92,7 +94,8 @@ 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(f'{d_str} || { ros["account_id"]} | kicked > not in whitelist')
|
logger.log(
|
||||||
|
f'{d_str} || { ros["account_id"]} | kicked > not in whitelist')
|
||||||
ba.internal.disconnect_client(ros['client_id'])
|
ba.internal.disconnect_client(ros['client_id'])
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
@ -101,14 +104,15 @@ class checkserver(object):
|
||||||
if ros['account_id'] in serverdata.clients:
|
if ros['account_id'] in serverdata.clients:
|
||||||
on_player_join_server(ros['account_id'],
|
on_player_join_server(ros['account_id'],
|
||||||
serverdata.clients[
|
serverdata.clients[
|
||||||
ros['account_id']], ip)
|
ros['account_id']], ip, device_id)
|
||||||
else:
|
else:
|
||||||
LoadProfile(ros['account_id'], ip).start() # from local cache, then call on_player_join_server
|
# from local cache, then call on_player_join_server
|
||||||
|
LoadProfile(ros['account_id'], ip, device_id).start()
|
||||||
|
|
||||||
self.players = newPlayers
|
self.players = newPlayers
|
||||||
|
|
||||||
|
|
||||||
def on_player_join_server(pbid, player_data, ip):
|
def on_player_join_server(pbid, player_data, ip, device_id):
|
||||||
global ipjoin
|
global ipjoin
|
||||||
now = time.time()
|
now = time.time()
|
||||||
# player_data=pdata.get_info(pbid)
|
# player_data=pdata.get_info(pbid)
|
||||||
|
|
@ -124,7 +128,7 @@ def on_player_join_server(pbid, player_data, ip):
|
||||||
if now - lastjoin < 15:
|
if now - lastjoin < 15:
|
||||||
joincount += 1
|
joincount += 1
|
||||||
if joincount > 2:
|
if joincount > 2:
|
||||||
_ba.screenmessage("Joining too fast , slow down dude",
|
_ba.screenmessage("Joining too fast , slow down dude", # its not possible now tho, network layer will catch it before reaching here
|
||||||
color=(1, 0, 1), transient=True,
|
color=(1, 0, 1), transient=True,
|
||||||
clients=[clid])
|
clients=[clid])
|
||||||
logger.log(f'{pbid} || kicked for joining too fast')
|
logger.log(f'{pbid} || kicked for joining too fast')
|
||||||
|
|
@ -137,52 +141,53 @@ def on_player_join_server(pbid, player_data, ip):
|
||||||
ipjoin[ip]["count"] = joincount
|
ipjoin[ip]["count"] = joincount
|
||||||
ipjoin[ip]["lastJoin"] = now
|
ipjoin[ip]["lastJoin"] = now
|
||||||
else:
|
else:
|
||||||
ipjoin[ip] = {"lastJoin":now,"count":0}
|
ipjoin[ip] = {"lastJoin": now, "count": 0}
|
||||||
if pbid in serverdata.clients:
|
if pbid in serverdata.clients:
|
||||||
serverdata.clients[pbid]["lastJoin"] = now
|
serverdata.clients[pbid]["lastJoin"] = now
|
||||||
|
|
||||||
if player_data != None: # player data not in serevrdata or in local.json cache
|
if player_data != None: # player data is in serevrdata or in local.json cache
|
||||||
serverdata.recents.append({"client_id":clid,"deviceId":device_string,"pbid":pbid})
|
serverdata.recents.append(
|
||||||
|
{"client_id": clid, "deviceId": device_string, "pbid": pbid})
|
||||||
serverdata.recents = serverdata.recents[-20:]
|
serverdata.recents = serverdata.recents[-20:]
|
||||||
if player_data["isBan"] or get_account_age(player_data["accountAge"]) < \
|
if check_ban(ip, device_id, pbid):
|
||||||
settings["minAgeToJoinInHours"]:
|
_ba.chatmessage(
|
||||||
|
'sad ,your account is flagged contact server owner for unban', clients=[clid])
|
||||||
|
ba.internal.disconnect_client(clid)
|
||||||
|
return
|
||||||
|
if get_account_age(player_data["accountAge"]) < \
|
||||||
|
settings["minAgeToJoinInHours"]:
|
||||||
for ros in ba.internal.get_game_roster():
|
for ros in ba.internal.get_game_roster():
|
||||||
if ros['account_id'] == pbid:
|
if ros['account_id'] == pbid:
|
||||||
if not player_data["isBan"]:
|
|
||||||
_ba.screenmessage(
|
|
||||||
"New Accounts not allowed here , come back later",
|
|
||||||
color=(1, 0, 0), transient=True,
|
|
||||||
clients=[ros['client_id']])
|
|
||||||
logger.log(pbid + " | kicked > reason:Banned account")
|
|
||||||
_ba.screenmessage(
|
_ba.screenmessage(
|
||||||
"Contact server owner, your account not allowed here",
|
"New Accounts not allowed here , come back later",
|
||||||
color=(1, 0, 0), transient=True,
|
color=(1, 0, 0), transient=True,
|
||||||
clients=[ros['client_id']])
|
clients=[ros['client_id']])
|
||||||
|
logger.log(pbid + " | kicked > reason:Banned account")
|
||||||
ba.internal.disconnect_client(ros['client_id'])
|
ba.internal.disconnect_client(ros['client_id'])
|
||||||
|
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
|
current_time = datetime.now()
|
||||||
if pbid not in serverdata.clients:
|
if pbid not in serverdata.clients:
|
||||||
if check_ban(clid,pbid):
|
# ahh , lets reset if plyer joining after some long time
|
||||||
return
|
|
||||||
serverdata.clients[pbid] = player_data
|
serverdata.clients[pbid] = player_data
|
||||||
serverdata.clients[pbid]["warnCount"] = 0
|
serverdata.clients[pbid]["warnCount"] = 0
|
||||||
serverdata.clients[pbid]["lastWarned"] = time.time()
|
serverdata.clients[pbid]["lastWarned"] = time.time()
|
||||||
serverdata.clients[pbid]["verified"] = False
|
serverdata.clients[pbid]["verified"] = False
|
||||||
serverdata.clients[pbid]["rejoincount"] = 1
|
serverdata.clients[pbid]["rejoincount"] = 1
|
||||||
serverdata.clients[pbid]["lastJoin"] = time.time()
|
serverdata.clients[pbid]["lastJoin"] = time.time()
|
||||||
if not player_data["canStartKickVote"]:
|
if pbid in blacklist["kick-vote-disabled"] and current_time < datetime.strptime(blacklist["kick-vote-disabled"][pbid]["till"], "%Y-%m-%d %H:%M:%S"):
|
||||||
_ba.disable_kickvote(pbid)
|
_ba.disable_kickvote(pbid)
|
||||||
|
|
||||||
|
|
||||||
serverdata.clients[pbid]["lastIP"] = ip
|
serverdata.clients[pbid]["lastIP"] = ip
|
||||||
|
|
||||||
device_id = _ba.get_client_public_device_uuid(clid)
|
device_id = _ba.get_client_public_device_uuid(clid)
|
||||||
if(device_id==None):
|
if (device_id == None):
|
||||||
device_id = _ba.get_client_device_uuid(clid)
|
device_id = _ba.get_client_device_uuid(clid)
|
||||||
serverdata.clients[pbid]["deviceUUID"] = device_id
|
serverdata.clients[pbid]["deviceUUID"] = device_id
|
||||||
verify_account(pbid, player_data) # checked for spoofed ids
|
verify_account(pbid, player_data) # checked for spoofed ids
|
||||||
logger.log(pbid+" ip: "+serverdata.clients[pbid]["lastIP"]+", Device id: "+device_id)
|
logger.log(
|
||||||
|
f'{pbid} ip: {serverdata.clients[pbid]["lastIP"]} , Device id: {device_id}')
|
||||||
_ba.screenmessage(settings["regularWelcomeMsg"] + " " + device_string,
|
_ba.screenmessage(settings["regularWelcomeMsg"] + " " + device_string,
|
||||||
color=(0.60, 0.8, 0.6), transient=True,
|
color=(0.60, 0.8, 0.6), transient=True,
|
||||||
clients=[clid])
|
clients=[clid])
|
||||||
|
|
@ -201,19 +206,33 @@ 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):
|
|
||||||
ip = _ba.get_client_ip(clid)
|
|
||||||
|
|
||||||
device_id = _ba.get_client_public_device_uuid(clid)
|
def check_ban(ip, device_id, pbid, log=True):
|
||||||
if(device_id==None):
|
current_time = datetime.now()
|
||||||
device_id = _ba.get_client_device_uuid(clid)
|
|
||||||
if (ip in blacklist["ban"]['ips'] or device_id in blacklist['ban']['deviceids'] or pbid in blacklist["ban"]["ids"]):
|
if ip in blacklist["ban"]['ips'] and current_time < datetime.strptime(blacklist["ban"]["ips"][ip]["till"], "%Y-%m-%d %H:%M:%S"):
|
||||||
_ba.chatmessage('sad ,your account is flagged contact server owner for unban',clients=[clid])
|
msg = f' reason: matched IP | {blacklist["ban"]["ips"][ip]["reason"]} , Till : {blacklist["ban"]["ips"][ip]["till"]}'
|
||||||
logger.log(pbid + " | kicked > reason: Banned account")
|
if log:
|
||||||
ba.internal.disconnect_client(clid)
|
logger.log(f'{pbid} | kicked > {msg}')
|
||||||
return True
|
return True
|
||||||
|
return msg
|
||||||
|
elif device_id in blacklist["ban"]["deviceids"] and current_time < datetime.strptime(blacklist["ban"]["deviceids"][device_id]["till"], "%Y-%m-%d %H:%M:%S"):
|
||||||
|
msg = f'reason: matched deviceId | {blacklist["ban"]["deviceids"][device_id]["reason"]}, Till : {blacklist["ban"]["deviceids"][device_id]["till"]}'
|
||||||
|
if log:
|
||||||
|
logger.log(
|
||||||
|
f'{pbid} | kicked > {msg}')
|
||||||
|
return True
|
||||||
|
return msg
|
||||||
|
elif pbid in blacklist["ban"]["ids"] and current_time < datetime.strptime(blacklist["ban"]["ids"][pbid]["till"], "%Y-%m-%d %H:%M:%S"):
|
||||||
|
msg = f'reason: matched ID | {blacklist["ban"]["ids"][pbid]["reason"]} , Till : {blacklist["ban"]["ids"][pbid]["till"]}'
|
||||||
|
if log:
|
||||||
|
logger.log(
|
||||||
|
f'{pbid} | kicked > {msg}')
|
||||||
|
return True
|
||||||
|
return msg
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def verify_account(pb_id, p_data):
|
def verify_account(pb_id, p_data):
|
||||||
d_string = ""
|
d_string = ""
|
||||||
for ros in ba.internal.get_game_roster():
|
for ros in ba.internal.get_game_roster():
|
||||||
|
|
@ -260,8 +279,8 @@ def get_account_creation_date(pb_id):
|
||||||
else:
|
else:
|
||||||
creation_time = account_creation["created"]
|
creation_time = account_creation["created"]
|
||||||
creation_time = map(str, creation_time)
|
creation_time = map(str, creation_time)
|
||||||
creation_time = datetime.datetime.strptime("/".join(creation_time),
|
creation_time = datetime.strptime("/".join(creation_time),
|
||||||
"%Y/%m/%d/%H/%M/%S")
|
"%Y/%m/%d/%H/%M/%S")
|
||||||
# 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)
|
||||||
|
|
@ -285,14 +304,15 @@ def get_device_accounts(pb_id):
|
||||||
# ============ file I/O =============
|
# ============ file I/O =============
|
||||||
|
|
||||||
class LoadProfile(threading.Thread):
|
class LoadProfile(threading.Thread):
|
||||||
def __init__(self, pb_id, ip):
|
def __init__(self, pb_id, ip, device_id):
|
||||||
threading.Thread.__init__(self)
|
threading.Thread.__init__(self)
|
||||||
self.pbid = pb_id
|
self.pbid = pb_id
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
|
self.device_id = device_id
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
player_data = pdata.get_info(self.pbid)
|
player_data = pdata.get_info(self.pbid)
|
||||||
_ba.pushcall(Call(on_player_join_server, self.pbid, player_data, self.ip),
|
_ba.pushcall(Call(on_player_join_server, self.pbid, player_data, self.ip, self.device_id),
|
||||||
from_other_thread=True)
|
from_other_thread=True)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -316,7 +336,8 @@ def my_acc_age(pb_id):
|
||||||
|
|
||||||
|
|
||||||
def save_age(age, pb_id, display_string):
|
def save_age(age, pb_id, display_string):
|
||||||
_ba.pushcall(Call(pdata.add_profile,pb_id, display_string,display_string, age), from_other_thread=True)
|
_ba.pushcall(Call(pdata.add_profile, pb_id, display_string,
|
||||||
|
display_string, age), from_other_thread=True)
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
thread2 = FetchThread(
|
thread2 = FetchThread(
|
||||||
target=get_device_accounts,
|
target=get_device_accounts,
|
||||||
|
|
@ -352,8 +373,8 @@ def kick_by_pb_id(pb_id, msg):
|
||||||
|
|
||||||
|
|
||||||
def get_account_age(ct):
|
def get_account_age(ct):
|
||||||
creation_time = datetime.datetime.strptime(ct, "%Y-%m-%d %H:%M:%S")
|
creation_time = datetime.strptime(ct, "%Y-%m-%d %H:%M:%S")
|
||||||
now = datetime.datetime.now()
|
now = datetime.now()
|
||||||
delta = now - creation_time
|
delta = now - creation_time
|
||||||
delta_hours = delta.total_seconds() / (60 * 60)
|
delta_hours = delta.total_seconds() / (60 * 60)
|
||||||
return delta_hours
|
return delta_hours
|
||||||
|
|
@ -364,18 +385,18 @@ def reportSpam(id):
|
||||||
profiles = pdata.get_profiles()
|
profiles = pdata.get_profiles()
|
||||||
if id in profiles:
|
if id in profiles:
|
||||||
count = profiles[id]["spamCount"]
|
count = profiles[id]["spamCount"]
|
||||||
|
|
||||||
if now - profiles[id]["lastSpam"] < 2 * 24 * 60 * 60:
|
if now - profiles[id]["lastSpam"] < 2 * 24 * 60 * 60:
|
||||||
count += 1
|
count += 1
|
||||||
if count > 3:
|
if count > 3:
|
||||||
logger.log(id+" auto banned for spamming")
|
logger.log(id+" auto banned for spamming")
|
||||||
profiles[id]["isBan"] = True
|
# by default ban for 1 day , change here if you want
|
||||||
|
pdata.ban_player(id, 1, "auto ban exceed warn count")
|
||||||
else:
|
else:
|
||||||
count = 0
|
count = 0
|
||||||
|
|
||||||
profiles[id]["spamCount"] = count
|
profiles[id]["spamCount"] = count
|
||||||
profiles[id]["lastSpam"] = now
|
profiles[id]["lastSpam"] = now
|
||||||
pdata.commit_profiles(profiles)
|
|
||||||
|
|
||||||
def on_join_request(ip):
|
def on_join_request(ip):
|
||||||
now = time.time()
|
now = time.time()
|
||||||
|
|
@ -383,11 +404,11 @@ def on_join_request(ip):
|
||||||
lastRequest = serverdata.ips[ip]["lastRequest"]
|
lastRequest = serverdata.ips[ip]["lastRequest"]
|
||||||
count = serverdata.ips[ip]["count"]
|
count = serverdata.ips[ip]["count"]
|
||||||
if now - lastRequest < 5:
|
if now - lastRequest < 5:
|
||||||
count +=1
|
count += 1
|
||||||
if count > 40:
|
if count > 40:
|
||||||
_ba.ban_ip(ip)
|
_ba.ban_ip(ip)
|
||||||
else:
|
else:
|
||||||
count = 0
|
count = 0
|
||||||
serverdata.ips[ip] = {"lastRequest":time.time(),"count":count}
|
serverdata.ips[ip] = {"lastRequest": time.time(), "count": count}
|
||||||
else:
|
else:
|
||||||
serverdata.ips[ip]={"lastRequest":time.time(),"count":0}
|
serverdata.ips[ip] = {"lastRequest": time.time(), "count": 0}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue