mirror of
https://github.com/imayushsaini/Bombsquad-Ballistica-Modded-Server.git
synced 2025-10-20 00:00:39 +00:00
added push notification subscription service
This commit is contained in:
parent
59667ede11
commit
a070124d1d
8 changed files with 278 additions and 29 deletions
40
dist/ba_root/mods/custom_hooks.py
vendored
40
dist/ba_root/mods/custom_hooks.py
vendored
|
|
@ -35,6 +35,7 @@ from features import votingmachine
|
||||||
from features import text_on_map, announcement
|
from features import text_on_map, announcement
|
||||||
from features import map_fun
|
from features import map_fun
|
||||||
from spazmod import modifyspaz
|
from spazmod import modifyspaz
|
||||||
|
from tools import notification_manager
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from typing import Optional, Any
|
from typing import Optional, Any
|
||||||
|
|
||||||
|
|
@ -46,6 +47,8 @@ def filter_chat_message(msg: str, client_id: int) -> str | None:
|
||||||
return handlechat.filter_chat_message(msg, client_id)
|
return handlechat.filter_chat_message(msg, client_id)
|
||||||
|
|
||||||
# ba_meta export plugin
|
# ba_meta export plugin
|
||||||
|
|
||||||
|
|
||||||
class modSetup(ba.Plugin):
|
class modSetup(ba.Plugin):
|
||||||
def on_app_running(self):
|
def on_app_running(self):
|
||||||
"""Runs when app is launched."""
|
"""Runs when app is launched."""
|
||||||
|
|
@ -69,8 +72,11 @@ class modSetup(ba.Plugin):
|
||||||
ba.internal.sign_in_v1('Local')
|
ba.internal.sign_in_v1('Local')
|
||||||
ba.timer(60, playlist.flush_playlists)
|
ba.timer(60, playlist.flush_playlists)
|
||||||
|
|
||||||
def on_app_shutdown(self):
|
def on_app_shutdown(self): # TODO not working, fix this, also dump server logs
|
||||||
pass
|
print("Server shutting down , lets save cache")
|
||||||
|
pdata.dump_cache()
|
||||||
|
notification_manager.dump_cache()
|
||||||
|
print("Done dumping memory")
|
||||||
|
|
||||||
|
|
||||||
def score_screen_on_begin(_stats: ba.Stats) -> None:
|
def score_screen_on_begin(_stats: ba.Stats) -> None:
|
||||||
|
|
@ -99,6 +105,7 @@ def bootstraping():
|
||||||
_thread.start_new_thread(mystats.refreshStats, ())
|
_thread.start_new_thread(mystats.refreshStats, ())
|
||||||
pdata.load_cache()
|
pdata.load_cache()
|
||||||
_thread.start_new_thread(pdata.dump_cache, ())
|
_thread.start_new_thread(pdata.dump_cache, ())
|
||||||
|
_thread.start_new_thread(notification_manager.dump_cache, ())
|
||||||
|
|
||||||
# import plugins
|
# import plugins
|
||||||
if settings["elPatronPowerups"]["enable"]:
|
if settings["elPatronPowerups"]["enable"]:
|
||||||
|
|
@ -124,8 +131,7 @@ def bootstraping():
|
||||||
from plugins import colorfulmaps2
|
from plugins import colorfulmaps2
|
||||||
try:
|
try:
|
||||||
pass
|
pass
|
||||||
# from tools import healthcheck
|
# from tools import healthcheck
|
||||||
# healthcheck.main() spamming logs , will increase log interval later
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
print(e)
|
||||||
try:
|
try:
|
||||||
|
|
@ -283,24 +289,25 @@ def on_map_init():
|
||||||
text_on_map.textonmap()
|
text_on_map.textonmap()
|
||||||
modifyspaz.setTeamCharacter()
|
modifyspaz.setTeamCharacter()
|
||||||
|
|
||||||
|
|
||||||
def shutdown(func) -> None:
|
def shutdown(func) -> None:
|
||||||
"""Set the app to quit either now or at the next clean opportunity."""
|
"""Set the app to quit either now or at the next clean opportunity."""
|
||||||
def wrapper(*args, **kwargs):
|
def wrapper(*args, **kwargs):
|
||||||
# add screen text and tell players we are going to restart soon.
|
# add screen text and tell players we are going to restart soon.
|
||||||
ba.internal.chatmessage(
|
ba.internal.chatmessage(
|
||||||
"Server will restart on next opportunity. (series end)")
|
"Server will restart on next opportunity. (series end)")
|
||||||
_ba.restart_scheduled = True
|
_ba.restart_scheduled = True
|
||||||
_ba.get_foreground_host_activity().restart_msg = _ba.newnode('text',
|
_ba.get_foreground_host_activity().restart_msg = _ba.newnode('text',
|
||||||
attrs={
|
attrs={
|
||||||
'text': "Server going to restart after this series.",
|
'text': "Server going to restart after this series.",
|
||||||
'flatness': 1.0,
|
'flatness': 1.0,
|
||||||
'h_align': 'right',
|
'h_align': 'right',
|
||||||
'v_attach': 'bottom',
|
'v_attach': 'bottom',
|
||||||
'h_attach': 'right',
|
'h_attach': 'right',
|
||||||
'scale': 0.5,
|
'scale': 0.5,
|
||||||
'position': (-25, 54),
|
'position': (-25, 54),
|
||||||
'color': (1, 0.5, 0.7)
|
'color': (1, 0.5, 0.7)
|
||||||
})
|
})
|
||||||
func(*args, **kwargs)
|
func(*args, **kwargs)
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
|
|
@ -318,7 +325,8 @@ def on_player_request(func) -> bool:
|
||||||
if current_player.get_v1_account_id() == player.get_v1_account_id():
|
if current_player.get_v1_account_id() == player.get_v1_account_id():
|
||||||
count += 1
|
count += 1
|
||||||
if count >= settings["maxPlayersPerDevice"]:
|
if count >= settings["maxPlayersPerDevice"]:
|
||||||
_ba.screenmessage("Reached max players limit per device", clients=[player.inputdevice.client_id], transient=True,)
|
_ba.screenmessage("Reached max players limit per device", clients=[
|
||||||
|
player.inputdevice.client_id], transient=True,)
|
||||||
return False
|
return False
|
||||||
return func(*args, **kwargs)
|
return func(*args, **kwargs)
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
|
||||||
37
dist/ba_root/mods/playersData/blacklist.json
vendored
37
dist/ba_root/mods/playersData/blacklist.json
vendored
|
|
@ -1,11 +1,34 @@
|
||||||
{
|
{
|
||||||
"ban": {
|
"ban": {
|
||||||
"ids": [
|
"ids": {
|
||||||
],
|
"pb-234": {
|
||||||
"ips": [
|
"till": "2023-06-07 21:59:20",
|
||||||
],
|
"reason": "auto ban for spam"
|
||||||
"deviceids": [
|
}
|
||||||
]
|
},
|
||||||
|
"ips": {
|
||||||
|
"19.168.0.0.1": {
|
||||||
|
"till": "2023-06-07 21:59:20",
|
||||||
|
"reason": "auto ban for spam"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deviceids": {
|
||||||
|
"sdfdsfwr3": {
|
||||||
|
"till": "2023-06-07 21:59:20",
|
||||||
|
"reason": "auto ban for spam"
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"muted-ids": []
|
"muted-ids": {
|
||||||
|
"pb-IF4iU0QaEw==": {
|
||||||
|
"till": "2023-06-19 19:44:47",
|
||||||
|
"reason": "manually from website"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"kick-vote-disabled": {
|
||||||
|
"pb-JiNJARBaXEFBVF9HFkNXXF1EF0ZaRlZE": {
|
||||||
|
"till": "2023-06-12 19:37:48",
|
||||||
|
"reason": "manually from website"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
31
dist/ba_root/mods/playersData/subscribed_players.json
vendored
Normal file
31
dist/ba_root/mods/playersData/subscribed_players.json
vendored
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
{
|
||||||
|
"pb-IF41U2scIg==": {
|
||||||
|
"subscribers": [
|
||||||
|
"jrz6Rg"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"pb-IF4IVFkKNA==": {
|
||||||
|
"subscribers": [
|
||||||
|
"jrz6Rg"
|
||||||
|
],
|
||||||
|
"name": "\ue063ATTITUDEB2"
|
||||||
|
},
|
||||||
|
"pb-IF4CKhYn": {
|
||||||
|
"subscribers": [
|
||||||
|
"jrz6Rg"
|
||||||
|
],
|
||||||
|
"name": "\ue032Rico Un\u2122\u00a9\u00ae"
|
||||||
|
},
|
||||||
|
"pb-IF4jF1NY": {
|
||||||
|
"subscribers": [
|
||||||
|
"jrz6Rg"
|
||||||
|
],
|
||||||
|
"name": "\ue01eHoemaster"
|
||||||
|
},
|
||||||
|
"pb-IF4wVVk8Jg==": {
|
||||||
|
"subscribers": [
|
||||||
|
"jrz6Rg"
|
||||||
|
],
|
||||||
|
"name": "\ue063Homulilly"
|
||||||
|
}
|
||||||
|
}
|
||||||
10
dist/ba_root/mods/playersData/subscriptions.json
vendored
Normal file
10
dist/ba_root/mods/playersData/subscriptions.json
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"jrz6Rg": {
|
||||||
|
"endpoint": "https://wns2-pn1p.notify.windows.com/w/?token=8nmgbauneNBqKw7H6IGl",
|
||||||
|
"expirationTime": null,
|
||||||
|
"keys": {
|
||||||
|
"p256dh": "BOG4rFeziA",
|
||||||
|
"auth": "yNIDrg"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
18
dist/ba_root/mods/plugins/bcs_plugin.py
vendored
18
dist/ba_root/mods/plugins/bcs_plugin.py
vendored
|
|
@ -18,7 +18,7 @@ os.environ['FLASK_ENV'] = 'development'
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
app.config["DEBUG"] = False
|
app.config["DEBUG"] = False
|
||||||
SECRET_KEY = "my_secret_key"
|
SECRET_KEY = "my_secret_key2"
|
||||||
|
|
||||||
|
|
||||||
@app.after_request
|
@app.after_request
|
||||||
|
|
@ -56,6 +56,19 @@ def get_top200():
|
||||||
return jsonify(bombsquad_service.get_top_200()), 200
|
return jsonify(bombsquad_service.get_top_200()), 200
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/api/subscribe', methods=['POST'])
|
||||||
|
def subscribe_player():
|
||||||
|
try:
|
||||||
|
data = request.get_json()
|
||||||
|
bombsquad_service.subscribe_player(
|
||||||
|
data["subscription"], data["player_id"], data["name"])
|
||||||
|
response = {
|
||||||
|
'message': f'Subscribed {data["name"]} successfully , will send confirmation notification to test'}
|
||||||
|
return jsonify(response), 201
|
||||||
|
except Exception as e:
|
||||||
|
return jsonify({'message': 'Error processing request', 'error': str(e)}), 400
|
||||||
|
|
||||||
|
|
||||||
# ============ Admin only =========
|
# ============ Admin only =========
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -250,7 +263,8 @@ def update_server_config():
|
||||||
|
|
||||||
|
|
||||||
def enable():
|
def enable():
|
||||||
flask_run = _thread.start_new_thread(app.run, ("0.0.0.0", _ba.get_game_port(), False))
|
flask_run = _thread.start_new_thread(
|
||||||
|
app.run, ("0.0.0.0", _ba.get_game_port(), False))
|
||||||
# uvicorn_thread = threading.Thread(target=start_uvicorn)
|
# uvicorn_thread = threading.Thread(target=start_uvicorn)
|
||||||
# uvicorn_thread.start()
|
# uvicorn_thread.start()
|
||||||
# options = {
|
# options = {
|
||||||
|
|
|
||||||
13
dist/ba_root/mods/plugins/bombsquad_service.py
vendored
13
dist/ba_root/mods/plugins/bombsquad_service.py
vendored
|
|
@ -1,3 +1,6 @@
|
||||||
|
import ecdsa
|
||||||
|
import base64
|
||||||
|
import json
|
||||||
import ba
|
import ba
|
||||||
import _ba
|
import _ba
|
||||||
import ba.internal
|
import ba.internal
|
||||||
|
|
@ -6,7 +9,7 @@ from typing import Optional, Any, Dict, List, Type, Sequence
|
||||||
from ba._gameactivity import GameActivity
|
from ba._gameactivity import GameActivity
|
||||||
from playersData import pdata
|
from playersData import pdata
|
||||||
from serverData import serverdata
|
from serverData import serverdata
|
||||||
from tools import servercheck, logger
|
from tools import servercheck, logger, notification_manager
|
||||||
import setting
|
import setting
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import _thread
|
import _thread
|
||||||
|
|
@ -15,7 +18,7 @@ import yaml
|
||||||
stats = {}
|
stats = {}
|
||||||
leaderboard = {}
|
leaderboard = {}
|
||||||
top200 = {}
|
top200 = {}
|
||||||
|
vapidkeys = {}
|
||||||
serverinfo = {}
|
serverinfo = {}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -24,7 +27,7 @@ class BsDataThread(object):
|
||||||
global stats
|
global stats
|
||||||
stats["name"] = _ba.app.server._config.party_name
|
stats["name"] = _ba.app.server._config.party_name
|
||||||
stats["discord"] = "https://discord.gg/ucyaesh"
|
stats["discord"] = "https://discord.gg/ucyaesh"
|
||||||
stats["vapidKey"] = "sjfbsdjfdsf"
|
stats["vapidKey"] = notification_manager.get_vapid_keys()["public_key"]
|
||||||
|
|
||||||
self.refresh_stats_cache_timer = ba.Timer(8, ba.Call(self.refreshStats),
|
self.refresh_stats_cache_timer = ba.Timer(8, ba.Call(self.refreshStats),
|
||||||
timetype=ba.TimeType.REAL, repeat=True)
|
timetype=ba.TimeType.REAL, repeat=True)
|
||||||
|
|
@ -255,3 +258,7 @@ def do_action(action, value):
|
||||||
_ba.pushcall(ba.Call(_ba.chatmessage, value), from_other_thread=True)
|
_ba.pushcall(ba.Call(_ba.chatmessage, value), from_other_thread=True)
|
||||||
elif action == "quit":
|
elif action == "quit":
|
||||||
_ba.pushcall(ba.Call(_ba.quit), from_other_thread=True)
|
_ba.pushcall(ba.Call(_ba.quit), from_other_thread=True)
|
||||||
|
|
||||||
|
|
||||||
|
def subscribe_player(sub, account_id, name):
|
||||||
|
notification_manager.subscribe(sub, account_id, name)
|
||||||
|
|
|
||||||
154
dist/ba_root/mods/tools/notification_manager.py
vendored
Normal file
154
dist/ba_root/mods/tools/notification_manager.py
vendored
Normal file
|
|
@ -0,0 +1,154 @@
|
||||||
|
import time
|
||||||
|
import shutil
|
||||||
|
import random
|
||||||
|
import string
|
||||||
|
from pywebpush import webpush
|
||||||
|
import json
|
||||||
|
import base64
|
||||||
|
import ecdsa
|
||||||
|
import os
|
||||||
|
import _ba
|
||||||
|
from datetime import datetime
|
||||||
|
vapidkeys = {}
|
||||||
|
subscriptions = {}
|
||||||
|
subscribed_players = {}
|
||||||
|
PLAYERS_DATA_PATH = os.path.join(
|
||||||
|
_ba.env()["python_directory_user"], "playersData" + os.sep
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def get_vapid_keys():
|
||||||
|
global vapidkeys
|
||||||
|
if vapidkeys != {}:
|
||||||
|
return vapidkeys
|
||||||
|
try:
|
||||||
|
f = open(".keys", "r")
|
||||||
|
vapidkeys = json.load(f)
|
||||||
|
f.close()
|
||||||
|
return vapidkeys
|
||||||
|
except:
|
||||||
|
pk = ecdsa.SigningKey.generate(curve=ecdsa.NIST256p)
|
||||||
|
vk = pk.get_verifying_key()
|
||||||
|
vapidkeys = {
|
||||||
|
'private_key': base64.urlsafe_b64encode(pk.to_string()).rstrip(b'=').decode('utf-8'),
|
||||||
|
'public_key': base64.urlsafe_b64encode(b'\x04' + vk.to_string()).rstrip(b'=').decode('utf-8')
|
||||||
|
}
|
||||||
|
f = open(".keys", "w")
|
||||||
|
json.dump(vapidkeys, f)
|
||||||
|
f.close()
|
||||||
|
return vapidkeys
|
||||||
|
|
||||||
|
|
||||||
|
def send_push_notification(subscription, payload):
|
||||||
|
# try:
|
||||||
|
# Send the push notification using the subscription and payload
|
||||||
|
print(subscription)
|
||||||
|
print(payload)
|
||||||
|
print(get_vapid_keys()["private_key"])
|
||||||
|
|
||||||
|
webpush(subscription_info=subscription, data=json.dumps(payload),
|
||||||
|
vapid_private_key=get_vapid_keys()["private_key"], vapid_claims={
|
||||||
|
'sub': 'mailto:{}'.format("test@ballistica.net"),
|
||||||
|
})
|
||||||
|
print("Push notification sent successfully")
|
||||||
|
# except Exception as e:
|
||||||
|
# print("Error sending push notification:", str(e))
|
||||||
|
|
||||||
|
|
||||||
|
# if we already have that browser subscription saved get id or generate new one
|
||||||
|
def get_subscriber_id(sub):
|
||||||
|
subscriber_id = None
|
||||||
|
|
||||||
|
for key, value in subscriptions.items():
|
||||||
|
if value["endpoint"] == sub["endpoint"]:
|
||||||
|
subscriber_id = key
|
||||||
|
break
|
||||||
|
|
||||||
|
if not subscriber_id:
|
||||||
|
subscriber_id = generate_random_string(6)
|
||||||
|
subscriptions[subscriber_id] = sub
|
||||||
|
return subscriber_id
|
||||||
|
|
||||||
|
|
||||||
|
def generate_random_string(length):
|
||||||
|
letters = string.ascii_letters + string.digits
|
||||||
|
return ''.join(random.choice(letters) for _ in range(length))
|
||||||
|
|
||||||
|
|
||||||
|
def subscribe(sub, account_id, name):
|
||||||
|
|
||||||
|
id = get_subscriber_id(sub)
|
||||||
|
if account_id in subscribed_players:
|
||||||
|
if id not in subscribed_players[account_id]["subscribers"]:
|
||||||
|
subscribed_players[account_id]["subscribers"].append(id)
|
||||||
|
subscribed_players[account_id]["name"] = name
|
||||||
|
else:
|
||||||
|
subscribed_players[account_id] = {"subscribers": [id], "name": name}
|
||||||
|
send_push_notification(sub, {"notification": {
|
||||||
|
"title": "Notification working !", "body": f'subscribed {name}'}})
|
||||||
|
|
||||||
|
|
||||||
|
def player_joined(pb_id):
|
||||||
|
now = datetime.now()
|
||||||
|
if pb_id in subscribed_players:
|
||||||
|
if "last_notification" in subscribed_players[pb_id] and (now - subscribed_players[pb_id]["last_notification"]).seconds < 15 * 60:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
subscribed_players[pb_id]["last_notification"] = now
|
||||||
|
subscribes = subscribed_players[pb_id]["subscribers"]
|
||||||
|
for subscriber_id in subscribes:
|
||||||
|
sub = subscriptions[subscriber_id]
|
||||||
|
send_push_notification(
|
||||||
|
sub, {
|
||||||
|
"notification": {
|
||||||
|
"title": f'{subscribed_players[pb_id]["name"] } is playing now',
|
||||||
|
"body": f'Join {_ba.app.server._config.party_name} server {subscribed_players[pb_id]["name"]} is waiting for you ',
|
||||||
|
"icon": "assets/icons/icon-96x96.png",
|
||||||
|
"vibrate": [100, 50, 100],
|
||||||
|
"requireInteraction": True,
|
||||||
|
"data": {"dateOfArrival": datetime.now().strftime("%Y-%m-%d %H:%M:%S")},
|
||||||
|
"actions": [{"action": "nothing", "title": "Launch Bombsquad"}],
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
def loadCache():
|
||||||
|
global subscriptions
|
||||||
|
global subscribed_players
|
||||||
|
try:
|
||||||
|
f = open(PLAYERS_DATA_PATH+"subscriptions.json", "r")
|
||||||
|
subscriptions = json.load(f)
|
||||||
|
f.close()
|
||||||
|
except:
|
||||||
|
f = open(PLAYERS_DATA_PATH+"subscriptions.json.backup", "r")
|
||||||
|
subscriptions = json.load(f)
|
||||||
|
f.close()
|
||||||
|
try:
|
||||||
|
f = open(PLAYERS_DATA_PATH+"subscribed_players.json", "r")
|
||||||
|
subscribed_players = json.load(f)
|
||||||
|
f.close()
|
||||||
|
except:
|
||||||
|
f = open(PLAYERS_DATA_PATH+"subscribed_players.json.backup", "r")
|
||||||
|
subscribed_players = json.load(f)
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
|
||||||
|
def dump_cache():
|
||||||
|
if subscriptions != {}:
|
||||||
|
shutil.copyfile(PLAYERS_DATA_PATH + "subscriptions.json",
|
||||||
|
PLAYERS_DATA_PATH + "subscriptions.json.backup")
|
||||||
|
|
||||||
|
with open(PLAYERS_DATA_PATH + "subscriptions.json", "w") as f:
|
||||||
|
json.dump(subscriptions, f, indent=4)
|
||||||
|
if subscribed_players != {}:
|
||||||
|
shutil.copyfile(PLAYERS_DATA_PATH + "subscribed_players.json",
|
||||||
|
PLAYERS_DATA_PATH + "subscribed_players.json.backup")
|
||||||
|
|
||||||
|
with open(PLAYERS_DATA_PATH + "subscribed_players.json", "w") as f:
|
||||||
|
json.dump(subscribed_players, f, indent=4)
|
||||||
|
|
||||||
|
time.sleep(60)
|
||||||
|
dump_cache()
|
||||||
|
|
||||||
|
|
||||||
|
loadCache()
|
||||||
4
dist/ba_root/mods/tools/servercheck.py
vendored
4
dist/ba_root/mods/tools/servercheck.py
vendored
|
|
@ -17,7 +17,7 @@ import _thread
|
||||||
from tools import logger
|
from tools import logger
|
||||||
from features import profanity
|
from features import profanity
|
||||||
from playersData import pdata
|
from playersData import pdata
|
||||||
|
from . import notification_manager
|
||||||
blacklist = pdata.get_blacklist()
|
blacklist = pdata.get_blacklist()
|
||||||
|
|
||||||
settings = setting.get_settings_data()
|
settings = setting.get_settings_data()
|
||||||
|
|
@ -191,6 +191,7 @@ def on_player_join_server(pbid, player_data, ip, 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])
|
||||||
|
notification_manager.player_joined(pbid)
|
||||||
else:
|
else:
|
||||||
# fetch id for first time.
|
# fetch id for first time.
|
||||||
thread = FetchThread(
|
thread = FetchThread(
|
||||||
|
|
@ -203,6 +204,7 @@ def on_player_join_server(pbid, player_data, ip, device_id):
|
||||||
thread.start()
|
thread.start()
|
||||||
_ba.screenmessage(settings["firstTimeJoinMsg"], color=(0.6, 0.8, 0.6),
|
_ba.screenmessage(settings["firstTimeJoinMsg"], color=(0.6, 0.8, 0.6),
|
||||||
transient=True, clients=[clid])
|
transient=True, clients=[clid])
|
||||||
|
notification_manager.player_joined(pbid)
|
||||||
|
|
||||||
# pdata.add_profile(pbid,d_string,d_string)
|
# pdata.add_profile(pbid,d_string,d_string)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue