Release 0.9.0
This commit is contained in:
79
bot/modules/players/actions/getadmins.py
Normal file
79
bot/modules/players/actions/getadmins.py
Normal file
@@ -0,0 +1,79 @@
|
||||
from bot import loaded_modules_dict
|
||||
from bot.constants import TELNET_TIMEOUT_VERY_SHORT
|
||||
from os import path, pardir
|
||||
from time import sleep, time
|
||||
import re
|
||||
|
||||
module_name = path.basename(path.normpath(path.join(path.abspath(__file__), pardir, pardir)))
|
||||
action_name = path.basename(path.abspath(__file__))[:-3]
|
||||
|
||||
|
||||
def main_function(module, event_data, dispatchers_steamid=None):
|
||||
timeout = TELNET_TIMEOUT_VERY_SHORT
|
||||
timeout_start = time()
|
||||
event_data[1]["action_identifier"] = action_name
|
||||
event_data[1]["fail_reason"] = []
|
||||
|
||||
if module.telnet.add_telnet_command_to_queue("admin list"):
|
||||
poll_is_finished = False
|
||||
# Updated regex for modern 7D2D server format (V 2.x+)
|
||||
# New format: "Defined User Permissions:" and SteamIDs have "Steam_" prefix
|
||||
# Timestamps are still present in "Executing command" lines
|
||||
regex = (
|
||||
r"(?P<datetime>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2})\s(?P<stardate>[-+]?\d*\.\d+|\d+)\s"
|
||||
r"INF Executing\scommand\s\'admin list\'\sby\sTelnet\sfrom\s(?P<called_by>.*?)\r?\n"
|
||||
r"(?P<raw_adminlist>Defined User Permissions:[\s\S]*?(?=Defined Group Permissions:))"
|
||||
)
|
||||
while not poll_is_finished and (time() < timeout_start + timeout):
|
||||
sleep(0.25)
|
||||
match = False
|
||||
for match in re.finditer(regex, module.telnet.telnet_buffer, re.DOTALL):
|
||||
poll_is_finished = True
|
||||
|
||||
if match:
|
||||
module.callback_success(callback_success, module, event_data, dispatchers_steamid, match)
|
||||
return
|
||||
|
||||
event_data[1]["fail_reason"].append("action timed out")
|
||||
else:
|
||||
event_data[1]["fail_reason"].append("action already queued up")
|
||||
|
||||
module.callback_fail(callback_fail, module, event_data, dispatchers_steamid)
|
||||
|
||||
|
||||
def callback_success(module, event_data, dispatchers_steamid, match=None):
|
||||
# Updated regex for modern format with "Steam_" prefix
|
||||
# Example: " 0: Steam_76561198040658370 (stored name: MOTKU)"
|
||||
regex = (
|
||||
r"(?:^\s{0,7})(?P<level>\d{1,2})\:\s+Steam_(?P<steamid>\d{17})"
|
||||
)
|
||||
raw_adminlist = match.group("raw_adminlist")
|
||||
admin_dict = {}
|
||||
for m in re.finditer(regex, raw_adminlist, re.MULTILINE):
|
||||
admin_dict[m.group("steamid")] = m.group("level")
|
||||
|
||||
module.dom.data.upsert({
|
||||
module.get_module_identifier(): {
|
||||
"admins": admin_dict
|
||||
}
|
||||
})
|
||||
|
||||
disable_after_success = event_data[1]["disable_after_success"]
|
||||
if disable_after_success:
|
||||
module.disable_action(action_name)
|
||||
|
||||
|
||||
def callback_fail(module, event_data, dispatchers_steamid):
|
||||
pass
|
||||
|
||||
|
||||
action_meta = {
|
||||
"description": "gets a list of all admins and mods",
|
||||
"main_function": main_function,
|
||||
"callback_success": callback_success,
|
||||
"callback_fail": callback_fail,
|
||||
"requires_telnet_connection": True,
|
||||
"enabled": True
|
||||
}
|
||||
|
||||
loaded_modules_dict["module_" + module_name].register_action(action_name, action_meta)
|
||||
246
bot/modules/players/actions/getplayers.py
Normal file
246
bot/modules/players/actions/getplayers.py
Normal file
@@ -0,0 +1,246 @@
|
||||
from bot import loaded_modules_dict
|
||||
from bot.constants import TELNET_TIMEOUT_SHORT
|
||||
from os import path, pardir
|
||||
from time import sleep, time
|
||||
import re
|
||||
|
||||
module_name = path.basename(path.normpath(path.join(path.abspath(__file__), pardir, pardir)))
|
||||
action_name = path.basename(path.abspath(__file__))[:-3]
|
||||
|
||||
|
||||
def _set_players_offline(players_dict):
|
||||
"""
|
||||
Helper function to mark all players in a dictionary as offline.
|
||||
|
||||
Creates a new dictionary with all players set to is_online=False and
|
||||
is_initialized=False. This is used when telnet commands fail or timeout.
|
||||
|
||||
Args:
|
||||
players_dict: Dictionary of player data keyed by steam_id
|
||||
|
||||
Returns:
|
||||
Dictionary with same players but marked as offline
|
||||
"""
|
||||
modified_players = {}
|
||||
for steam_id, player_data in players_dict.items():
|
||||
# Create a copy of the player dict
|
||||
updated_player = player_data.copy()
|
||||
updated_player["is_online"] = False
|
||||
updated_player["is_initialized"] = False
|
||||
modified_players[steam_id] = updated_player
|
||||
|
||||
return modified_players
|
||||
|
||||
|
||||
def main_function(module, event_data, dispatchers_steamid=None):
|
||||
timeout = TELNET_TIMEOUT_SHORT
|
||||
timeout_start = time()
|
||||
event_data[1]["action_identifier"] = action_name
|
||||
event_data[1]["fail_reason"] = []
|
||||
|
||||
if module.telnet.add_telnet_command_to_queue("lp"):
|
||||
poll_is_finished = False
|
||||
# Modern format - matches both empty and populated player lists
|
||||
regex = (
|
||||
r"Executing\scommand\s\'lp\'\sby\sTelnet\sfrom\s"
|
||||
r"(?P<called_by>.*?)\r?\n"
|
||||
r"(?P<raw_playerdata>[\s\S]*?)"
|
||||
r"Total\sof\s(?P<player_count>\d{1,2})\sin\sthe\sgame"
|
||||
)
|
||||
|
||||
while not poll_is_finished and (time() < timeout_start + timeout):
|
||||
sleep(0.25)
|
||||
match = False
|
||||
for match in re.finditer(regex, module.telnet.telnet_buffer):
|
||||
poll_is_finished = True
|
||||
|
||||
if match:
|
||||
module.callback_success(callback_success, module, event_data, dispatchers_steamid, match)
|
||||
return
|
||||
|
||||
event_data[1]["fail_reason"].append("timed out waiting for response")
|
||||
else:
|
||||
event_data[1]["fail_reason"].append("action already queued up")
|
||||
|
||||
module.callback_fail(callback_fail, module, event_data, dispatchers_steamid)
|
||||
|
||||
|
||||
def callback_success(module, event_data, dispatchers_steamid, match=None):
|
||||
""" without a place to store this, why bother """
|
||||
active_dataset = module.dom.data.get("module_game_environment", {}).get("active_dataset", None)
|
||||
player_count = int(match.group("player_count"))
|
||||
if all([
|
||||
active_dataset is None,
|
||||
player_count <= 0
|
||||
]):
|
||||
return False
|
||||
|
||||
""" get some basic stuff needed later """
|
||||
last_seen_gametime_string = module.game_environment.get_last_recorded_gametime_string()
|
||||
|
||||
""" lets extract all data the game provides!! """
|
||||
# Note: Modern regex doesn't capture datetime, using current time instead
|
||||
from datetime import datetime
|
||||
telnet_datetime = datetime.now().strftime("%Y-%m-%dT%H:%M:%S")
|
||||
raw_playerdata = match.group("raw_playerdata").lstrip()
|
||||
# Modern 7D2D format includes pltfmid (platform ID) and crossid (Epic cross-platform ID)
|
||||
# Format: pltfmid=Steam_76561198040658370, crossid=EOS_..., ip=..., ping=...
|
||||
regex = (
|
||||
r"\d{1,2}\. id=(?P<id>\d+), (?P<name>[^,]+), "
|
||||
r"pos=\((?P<pos_x>-?\d+\.\d+), (?P<pos_y>-?\d+\.\d+), (?P<pos_z>-?\d+\.\d+)\), "
|
||||
r"rot=\((?P<rot_x>-?\d+\.\d+), (?P<rot_y>-?\d+\.\d+), (?P<rot_z>-?\d+\.\d+)\), "
|
||||
r"remote=(?P<remote>\w+), "
|
||||
r"health=(?P<health>\d+), "
|
||||
r"deaths=(?P<deaths>\d+), "
|
||||
r"zombies=(?P<zombies>\d+), "
|
||||
r"players=(?P<players>\d+), "
|
||||
r"score=(?P<score>\d+), "
|
||||
r"level=(?P<level>\d+), "
|
||||
r"pltfmid=Steam_(?P<steamid>\d+), crossid=(?P<crossid>[\w_]+), "
|
||||
r"ip=(?P<ip>[^,]+), "
|
||||
r"ping=(?P<ping>\d+)"
|
||||
r"\r\n"
|
||||
)
|
||||
|
||||
all_players_dict = (
|
||||
module.dom.data.get(module.get_module_identifier(), {})
|
||||
.get("elements", {})
|
||||
.get(active_dataset, {})
|
||||
)
|
||||
|
||||
players_to_update_dict = {}
|
||||
for m in re.finditer(regex, raw_playerdata):
|
||||
in_limbo = int(m.group("health")) == 0
|
||||
player_dict = {
|
||||
# data the game provides
|
||||
"id": m.group("id"),
|
||||
"name": str(m.group("name")),
|
||||
"remote": bool(m.group("remote")),
|
||||
"health": int(m.group("health")),
|
||||
"deaths": int(m.group("deaths")),
|
||||
"zombies": int(m.group("zombies")),
|
||||
"players": int(m.group("players")),
|
||||
"score": int(m.group("score")),
|
||||
"level": int(m.group("level")),
|
||||
"steamid": m.group("steamid"),
|
||||
"ip": str(m.group("ip")),
|
||||
"ping": int(float(m.group("ping"))),
|
||||
"pos": {
|
||||
"x": int(float(m.group("pos_x"))),
|
||||
"y": int(float(m.group("pos_y"))),
|
||||
"z": int(float(m.group("pos_z")))
|
||||
},
|
||||
"rot": {
|
||||
"x": int(float(m.group("rot_x"))),
|
||||
"y": int(float(m.group("rot_y"))),
|
||||
"z": int(float(m.group("rot_z")))
|
||||
},
|
||||
# data invented by the bot
|
||||
"dataset": active_dataset,
|
||||
"in_limbo": in_limbo,
|
||||
"is_online": True,
|
||||
"is_initialized": True,
|
||||
"last_updated_servertime": telnet_datetime,
|
||||
"last_seen_gametime": last_seen_gametime_string,
|
||||
"owner": m.group("steamid")
|
||||
}
|
||||
players_to_update_dict[m.group("steamid")] = player_dict
|
||||
|
||||
""" players_to_update_dict now holds all game-data for all online players plus a few generated ones like last seen
|
||||
and is_initialized. Otherwise it's empty """
|
||||
|
||||
# set all players not currently online to offline
|
||||
online_players_list = list(players_to_update_dict.keys())
|
||||
for steamid, existing_player_dict in all_players_dict.items():
|
||||
if existing_player_dict["is_initialized"] is False:
|
||||
continue
|
||||
|
||||
if steamid not in online_players_list and existing_player_dict["is_online"] is True:
|
||||
# Create offline version of player using copy
|
||||
updated_player = existing_player_dict.copy()
|
||||
updated_player["is_online"] = False
|
||||
updated_player["is_initialized"] = False
|
||||
players_to_update_dict[steamid] = updated_player
|
||||
|
||||
if len(players_to_update_dict) >= 1:
|
||||
module.dom.data.upsert({
|
||||
module.get_module_identifier(): {
|
||||
"elements": {
|
||||
active_dataset: players_to_update_dict
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
if online_players_list != module.dom.data.get(module.get_module_identifier(), {}).get("online_players"):
|
||||
module.dom.data.upsert({
|
||||
module.get_module_identifier(): {
|
||||
"online_players": online_players_list
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
def callback_fail(module, event_data, dispatchers_steamid):
|
||||
active_dataset = module.dom.data.get("module_game_environment", {}).get("active_dataset", None)
|
||||
if active_dataset is None:
|
||||
return
|
||||
|
||||
all_existing_players_dict = (
|
||||
module.dom.data
|
||||
.get(module.get_module_identifier(), {})
|
||||
.get("elements", {})
|
||||
.get(active_dataset, {})
|
||||
)
|
||||
|
||||
# Mark all existing players as offline using helper function
|
||||
all_modified_players_dict = _set_players_offline(all_existing_players_dict)
|
||||
|
||||
module.dom.data.upsert({
|
||||
module.get_module_identifier(): {
|
||||
"elements": {
|
||||
active_dataset: all_modified_players_dict
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
module.dom.data.upsert({
|
||||
module.get_module_identifier(): {
|
||||
"online_players": []
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
def skip_it(module, event_data, dispatchers_steamid=None):
|
||||
active_dataset = module.dom.data.get("module_game_environment", {}).get("active_dataset", None)
|
||||
if active_dataset is None:
|
||||
return
|
||||
|
||||
all_existing_players_dict = (
|
||||
module.dom.data
|
||||
.get(module.get_module_identifier(), {})
|
||||
.get("elements", {})
|
||||
.get(active_dataset, {})
|
||||
)
|
||||
|
||||
# Mark all existing players as offline using helper function
|
||||
all_modified_players_dict = _set_players_offline(all_existing_players_dict)
|
||||
|
||||
module.dom.data.upsert({
|
||||
module.get_module_identifier(): {
|
||||
"elements": {
|
||||
active_dataset: all_modified_players_dict
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
action_meta = {
|
||||
"description": "gets a list of all currently logged in players and sets status-flags",
|
||||
"main_function": main_function,
|
||||
"callback_success": callback_success,
|
||||
"callback_fail": callback_fail,
|
||||
"skip_it": skip_it,
|
||||
"requires_telnet_connection": True,
|
||||
"enabled": True
|
||||
}
|
||||
|
||||
loaded_modules_dict["module_" + module_name].register_action(action_name, action_meta)
|
||||
107
bot/modules/players/actions/kick_player.py
Normal file
107
bot/modules/players/actions/kick_player.py
Normal file
@@ -0,0 +1,107 @@
|
||||
from bot import loaded_modules_dict
|
||||
from bot import telnet_prefixes
|
||||
from bot.logger import get_logger
|
||||
from os import path, pardir
|
||||
from time import time, sleep
|
||||
import re
|
||||
|
||||
module_name = path.basename(path.normpath(path.join(path.abspath(__file__), pardir, pardir)))
|
||||
action_name = path.basename(path.abspath(__file__))[:-3]
|
||||
logger = get_logger("players.kick_player")
|
||||
|
||||
|
||||
def main_function(module, event_data, dispatchers_steamid):
|
||||
action = event_data[1].get("action", None)
|
||||
event_data[1]["action_identifier"] = action_name
|
||||
action_is_confirmed = event_data[1].get("confirmed", "False")
|
||||
player_to_be_kicked = event_data[1].get("steamid", None)
|
||||
|
||||
if action == "kick_player":
|
||||
if action_is_confirmed == "True":
|
||||
timeout = 5 # [seconds]
|
||||
timeout_start = time()
|
||||
|
||||
reason = event_data[1].get("reason")
|
||||
|
||||
# Get player entity ID - game requires entity ID instead of steamid
|
||||
dataset = module.dom.data.get("module_game_environment", {}).get("active_dataset", None)
|
||||
player_dict = (
|
||||
module.dom.data
|
||||
.get("module_players", {})
|
||||
.get("elements", {})
|
||||
.get(dataset, {})
|
||||
.get(player_to_be_kicked, {})
|
||||
)
|
||||
player_entity_id = player_dict.get("id")
|
||||
|
||||
if not player_entity_id:
|
||||
module.callback_fail(callback_fail, module, event_data, dispatchers_steamid)
|
||||
return
|
||||
|
||||
command = "kick {} \"{}\"".format(player_entity_id, reason)
|
||||
"""
|
||||
i was trying re.escape, string replacements... the only thing that seems to work is all of them together
|
||||
Had some big trouble filtering out stuff like ^ and " and whatnot
|
||||
"""
|
||||
regex = (
|
||||
telnet_prefixes["telnet_log"]["timestamp"] +
|
||||
r"Executing\scommand\s\'" + re.escape(command) + r"\'\s"
|
||||
r"by\sTelnet\s"
|
||||
r"from\s(?P<called_by>.*)"
|
||||
).replace('"', '\\"')
|
||||
|
||||
logger.debug("kick_command_prepared",
|
||||
command=command,
|
||||
user=dispatchers_steamid,
|
||||
target=player_to_be_kicked,
|
||||
reason=reason)
|
||||
|
||||
if not module.telnet.add_telnet_command_to_queue(command):
|
||||
module.callback_fail(callback_fail, module, event_data, dispatchers_steamid)
|
||||
return
|
||||
|
||||
poll_is_finished = False
|
||||
while not poll_is_finished and (time() < timeout_start + timeout):
|
||||
sleep(0.25)
|
||||
match = False
|
||||
for match in re.finditer(regex, module.telnet.telnet_buffer, re.DOTALL):
|
||||
poll_is_finished = True
|
||||
|
||||
if match:
|
||||
module.callback_success(callback_success, module, event_data, dispatchers_steamid, match)
|
||||
return
|
||||
|
||||
else:
|
||||
module.set_current_view(dispatchers_steamid, {
|
||||
"current_view": "kick-modal",
|
||||
"current_view_steamid": player_to_be_kicked
|
||||
})
|
||||
return
|
||||
|
||||
elif action == "cancel_kick_player":
|
||||
module.callback_success(callback_success, module, event_data, dispatchers_steamid)
|
||||
return
|
||||
|
||||
module.callback_fail(callback_fail, module, event_data, dispatchers_steamid)
|
||||
|
||||
|
||||
def callback_success(module, event_data, dispatchers_steamid, match=None):
|
||||
module.set_current_view(dispatchers_steamid, {
|
||||
"current_view": "frontend",
|
||||
})
|
||||
|
||||
|
||||
def callback_fail(module, event_data, dispatchers_steamid):
|
||||
pass
|
||||
|
||||
|
||||
action_meta = {
|
||||
"description": "kicks a player",
|
||||
"main_function": main_function,
|
||||
"callback_success": callback_success,
|
||||
"callback_fail": callback_fail,
|
||||
"requires_telnet_connection": True,
|
||||
"enabled": True
|
||||
}
|
||||
|
||||
loaded_modules_dict["module_" + module_name].register_action(action_name, action_meta)
|
||||
74
bot/modules/players/actions/say_to_player.py
Normal file
74
bot/modules/players/actions/say_to_player.py
Normal file
@@ -0,0 +1,74 @@
|
||||
from bot import loaded_modules_dict, telnet_prefixes
|
||||
from os import path, pardir
|
||||
from time import sleep, time
|
||||
import re
|
||||
|
||||
module_name = path.basename(path.normpath(path.join(path.abspath(__file__), pardir, pardir)))
|
||||
action_name = path.basename(path.abspath(__file__))[:-3]
|
||||
|
||||
|
||||
def main_function(module, event_data, dispatchers_steamid=None):
|
||||
timeout = 5 # [seconds]
|
||||
timeout_start = time()
|
||||
event_data[1]["action_identifier"] = action_name
|
||||
|
||||
target_player_steamid = event_data[1].get("steamid", None)
|
||||
message = event_data[1].get("message", None)
|
||||
|
||||
# Get player entity ID - game requires entity ID instead of steamid
|
||||
dataset = module.dom.data.get("module_game_environment", {}).get("active_dataset", None)
|
||||
player_dict = (
|
||||
module.dom.data
|
||||
.get("module_players", {})
|
||||
.get("elements", {})
|
||||
.get(dataset, {})
|
||||
.get(target_player_steamid, {})
|
||||
)
|
||||
player_entity_id = player_dict.get("id")
|
||||
|
||||
if not player_entity_id:
|
||||
module.callback_fail(callback_fail, module, event_data, dispatchers_steamid)
|
||||
return
|
||||
|
||||
command = "sayplayer {} \"{}\"".format(player_entity_id, message)
|
||||
if not module.telnet.add_telnet_command_to_queue(command):
|
||||
module.callback_fail(callback_fail, module, event_data, dispatchers_steamid)
|
||||
return
|
||||
|
||||
poll_is_finished = False
|
||||
# Modern format: timestamps ARE present in "Executing command" lines
|
||||
regex = (
|
||||
telnet_prefixes["telnet_log"]["timestamp"] +
|
||||
r"Executing\scommand\s\'" + command + r"\'\sby\sTelnet\sfrom\s(?P<called_by>.*)"
|
||||
)
|
||||
while not poll_is_finished and (time() < timeout_start + timeout):
|
||||
sleep(0.25)
|
||||
match = False
|
||||
for match in re.finditer(regex, module.telnet.telnet_buffer, re.DOTALL):
|
||||
poll_is_finished = True
|
||||
|
||||
if match:
|
||||
module.callback_success(callback_success, module, event_data, dispatchers_steamid, match)
|
||||
return
|
||||
|
||||
module.callback_fail(callback_fail, module, event_data, dispatchers_steamid)
|
||||
|
||||
|
||||
def callback_success(module, event_data, dispatchers_steamid, match=None):
|
||||
pass
|
||||
|
||||
|
||||
def callback_fail(module, event_data, dispatchers_steamid):
|
||||
pass
|
||||
|
||||
|
||||
action_meta = {
|
||||
"description": "sends a message to any player",
|
||||
"main_function": main_function,
|
||||
"callback_success": callback_success,
|
||||
"callback_fail": callback_fail,
|
||||
"requires_telnet_connection": True,
|
||||
"enabled": True
|
||||
}
|
||||
|
||||
loaded_modules_dict["module_" + module_name].register_action(action_name, action_meta)
|
||||
114
bot/modules/players/actions/teleport_player.py
Normal file
114
bot/modules/players/actions/teleport_player.py
Normal file
@@ -0,0 +1,114 @@
|
||||
from bot import loaded_modules_dict
|
||||
from bot import telnet_prefixes
|
||||
from bot.logger import get_logger
|
||||
from os import path, pardir
|
||||
from time import sleep, time
|
||||
import re
|
||||
|
||||
module_name = path.basename(path.normpath(path.join(path.abspath(__file__), pardir, pardir)))
|
||||
action_name = path.basename(path.abspath(__file__))[:-3]
|
||||
logger = get_logger("players.teleport_player")
|
||||
|
||||
|
||||
def main_function(module, event_data, dispatchers_steamid=None):
|
||||
timeout = 6 # [seconds]
|
||||
timeout_start = time()
|
||||
event_data[1]["action_identifier"] = action_name
|
||||
|
||||
target_coordinates = event_data[1].get("coordinates", None)
|
||||
player_to_be_teleported_steamid = event_data[1].get("steamid", None)
|
||||
dataset = module.dom.data.get("module_game_environment", {}).get("active_dataset", None)
|
||||
player_to_be_teleported_dict = (
|
||||
module.dom.data
|
||||
.get("module_players", {})
|
||||
.get("elements", {})
|
||||
.get(dataset, {})
|
||||
.get(player_to_be_teleported_steamid, {})
|
||||
)
|
||||
player_coordinates = player_to_be_teleported_dict.get("pos", None)
|
||||
|
||||
if all([
|
||||
dataset is not None,
|
||||
target_coordinates is not None,
|
||||
player_coordinates is not None
|
||||
]) and all([
|
||||
# no sense in porting a player to a place they are already standing on ^^
|
||||
target_coordinates != player_coordinates
|
||||
]):
|
||||
# Use entity ID instead of steamid - game requires entity ID now
|
||||
player_entity_id = player_to_be_teleported_dict.get("id")
|
||||
if not player_entity_id:
|
||||
event_data[1]["fail_reason"] = "player entity ID not found"
|
||||
module.callback_fail(callback_fail, module, event_data, dispatchers_steamid)
|
||||
return
|
||||
|
||||
command = (
|
||||
"teleportplayer {player_to_be_teleported} {pos_x} {pos_y} {pos_z}"
|
||||
).format(
|
||||
player_to_be_teleported=player_entity_id,
|
||||
pos_x=int(float(target_coordinates["x"])),
|
||||
pos_y=int(float(target_coordinates["y"])),
|
||||
pos_z=int(float(target_coordinates["z"]))
|
||||
)
|
||||
|
||||
if not module.telnet.add_telnet_command_to_queue(command):
|
||||
event_data[1]["fail_reason"] = "duplicate command"
|
||||
module.callback_fail(callback_fail, module, event_data, dispatchers_steamid)
|
||||
return
|
||||
|
||||
poll_is_finished = False
|
||||
regex = (
|
||||
telnet_prefixes["telnet_log"]["timestamp"] +
|
||||
r"PlayerSpawnedInWorld\s"
|
||||
r"\("
|
||||
r"reason: (?P<command>.+?),\s"
|
||||
r"position: (?P<pos_x>.*),\s(?P<pos_y>.*),\s(?P<pos_z>.*)"
|
||||
r"\):\s"
|
||||
r"EntityID={entity_id},\s".format(entity_id=player_to_be_teleported_dict.get("id")) +
|
||||
r"PlayerID='{player_to_be_teleported}',\s".format(player_to_be_teleported=player_to_be_teleported_steamid) +
|
||||
r"OwnerID='{player_to_be_teleported}',\s".format(player_to_be_teleported=player_to_be_teleported_steamid) +
|
||||
r"PlayerName='(?P<player_name>.*)'"
|
||||
)
|
||||
|
||||
while not poll_is_finished and (time() < timeout_start + timeout):
|
||||
match = False
|
||||
for match in re.finditer(regex, module.telnet.telnet_buffer, re.DOTALL):
|
||||
poll_is_finished = True
|
||||
|
||||
if match:
|
||||
module.callback_success(callback_success, module, event_data, dispatchers_steamid, match)
|
||||
return
|
||||
|
||||
sleep(0.25)
|
||||
|
||||
event_data[1]["fail_reason"] = "action timed out"
|
||||
module.callback_fail(callback_fail, module, event_data, dispatchers_steamid)
|
||||
return
|
||||
|
||||
event_data[1]["fail_reason"] = "insufficient data for execution"
|
||||
module.callback_fail(callback_fail, module, event_data, dispatchers_steamid)
|
||||
return
|
||||
|
||||
|
||||
def callback_success(module, event_data, dispatchers_steamid, match=None):
|
||||
player_to_be_teleported = event_data[1].get("steamid", None)
|
||||
dataset = module.dom.data.get("module_game_environment", {}).get("active_dataset", None)
|
||||
|
||||
|
||||
def callback_fail(module, event_data, dispatchers_steamid):
|
||||
logger.error("teleport_failed",
|
||||
user=dispatchers_steamid,
|
||||
target=event_data[1].get("steamid"),
|
||||
reason=event_data[1].get("fail_reason", "no reason known"))
|
||||
|
||||
|
||||
action_meta = {
|
||||
"description": "teleports a player",
|
||||
"main_function": main_function,
|
||||
"callback_success": callback_success,
|
||||
"callback_fail": callback_fail,
|
||||
"requires_telnet_connection": True,
|
||||
"enabled": True
|
||||
}
|
||||
|
||||
loaded_modules_dict["module_" + module_name].register_action(action_name, action_meta)
|
||||
50
bot/modules/players/actions/toggle_player_authentication.py
Normal file
50
bot/modules/players/actions/toggle_player_authentication.py
Normal file
@@ -0,0 +1,50 @@
|
||||
from bot import loaded_modules_dict
|
||||
from os import path, pardir
|
||||
|
||||
module_name = path.basename(path.normpath(path.join(path.abspath(__file__), pardir, pardir)))
|
||||
action_name = path.basename(path.abspath(__file__))[:-3]
|
||||
|
||||
|
||||
def main_function(module, event_data, dispatchers_steamid=None):
|
||||
event_data[1]["action_identifier"] = action_name
|
||||
|
||||
target_player_steamid = event_data[1].get("steamid", None)
|
||||
auth_status = event_data[1].get("auth_status", None)
|
||||
active_dataset = event_data[1].get("dataset", None)
|
||||
|
||||
if all([target_player_steamid, auth_status is not None, active_dataset]):
|
||||
module.dom.data.upsert({
|
||||
"module_players": {
|
||||
"elements": {
|
||||
active_dataset: {
|
||||
target_player_steamid: {
|
||||
"is_authenticated": auth_status
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
module.callback_success(callback_success, module, event_data, dispatchers_steamid)
|
||||
return
|
||||
|
||||
module.callback_fail(callback_fail, module, event_data, dispatchers_steamid)
|
||||
|
||||
|
||||
def callback_success(module, event_data, dispatchers_steamid, match=None):
|
||||
pass
|
||||
|
||||
|
||||
def callback_fail(module, event_data, dispatchers_steamid):
|
||||
pass
|
||||
|
||||
|
||||
action_meta = {
|
||||
"description": "toggles a player's authentication status",
|
||||
"main_function": main_function,
|
||||
"callback_success": callback_success,
|
||||
"callback_fail": callback_fail,
|
||||
"requires_telnet_connection": False,
|
||||
"enabled": True
|
||||
}
|
||||
|
||||
loaded_modules_dict["module_" + module_name].register_action(action_name, action_meta)
|
||||
91
bot/modules/players/actions/toggle_player_mute.py
Normal file
91
bot/modules/players/actions/toggle_player_mute.py
Normal file
@@ -0,0 +1,91 @@
|
||||
from bot import loaded_modules_dict, telnet_prefixes
|
||||
from os import path, pardir
|
||||
from time import sleep, time
|
||||
import re
|
||||
|
||||
module_name = path.basename(path.normpath(path.join(path.abspath(__file__), pardir, pardir)))
|
||||
action_name = path.basename(path.abspath(__file__))[:-3]
|
||||
|
||||
|
||||
def main_function(module, event_data, dispatchers_steamid=None):
|
||||
timeout = 5 # [seconds]
|
||||
timeout_start = time()
|
||||
event_data[1]["action_identifier"] = action_name
|
||||
|
||||
target_player_steamid = event_data[1].get("steamid", None)
|
||||
mute_status = event_data[1].get("mute_status", None)
|
||||
|
||||
# Get player entity ID - game requires entity ID instead of steamid
|
||||
dataset = module.dom.data.get("module_game_environment", {}).get("active_dataset", None)
|
||||
player_dict = (
|
||||
module.dom.data
|
||||
.get("module_players", {})
|
||||
.get("elements", {})
|
||||
.get(dataset, {})
|
||||
.get(target_player_steamid, {})
|
||||
)
|
||||
player_entity_id = player_dict.get("id")
|
||||
|
||||
if not player_entity_id:
|
||||
module.callback_fail(callback_fail, module, event_data, dispatchers_steamid)
|
||||
return
|
||||
|
||||
command = "bc-mute {} {}".format(player_entity_id, mute_status)
|
||||
|
||||
if not module.telnet.add_telnet_command_to_queue(command):
|
||||
module.callback_fail(callback_fail, module, event_data, dispatchers_steamid)
|
||||
return
|
||||
|
||||
poll_is_finished = False
|
||||
# Modern format: timestamps ARE present in "Executing command" lines
|
||||
regex = (
|
||||
telnet_prefixes["telnet_log"]["timestamp"] +
|
||||
r"Executing\scommand\s\'" + command + r"\'\sby\sTelnet\sfrom\s(?P<called_by>.*)"
|
||||
)
|
||||
while not poll_is_finished and (time() < timeout_start + timeout):
|
||||
sleep(0.25)
|
||||
match = False
|
||||
for match in re.finditer(regex, module.telnet.telnet_buffer, re.DOTALL):
|
||||
poll_is_finished = True
|
||||
|
||||
if match:
|
||||
module.callback_success(callback_success, module, event_data, dispatchers_steamid, match)
|
||||
return
|
||||
|
||||
module.callback_fail(callback_fail, module, event_data, dispatchers_steamid)
|
||||
|
||||
|
||||
def callback_success(module, event_data, dispatchers_steamid, match=None):
|
||||
target_player_steamid = event_data[1].get("steamid", None)
|
||||
flag_player_to_be_muted = event_data[1].get("mute_status", None)
|
||||
active_dataset = event_data[1].get("dataset", None)
|
||||
|
||||
module.dom.data.upsert({
|
||||
"module_players": {
|
||||
"elements": {
|
||||
active_dataset: {
|
||||
target_player_steamid: {
|
||||
"is_muted": flag_player_to_be_muted
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
pass
|
||||
|
||||
|
||||
def callback_fail(module, event_data, dispatchers_steamid):
|
||||
pass
|
||||
|
||||
|
||||
action_meta = {
|
||||
"description": "mutes or unmutes a given player",
|
||||
"main_function": main_function,
|
||||
"callback_success": callback_success,
|
||||
"callback_fail": callback_fail,
|
||||
"requires_telnet_connection": True,
|
||||
"enabled": True
|
||||
}
|
||||
|
||||
loaded_modules_dict["module_" + module_name].register_action(action_name, action_meta)
|
||||
50
bot/modules/players/actions/toggle_players_widget_view.py
Normal file
50
bot/modules/players/actions/toggle_players_widget_view.py
Normal file
@@ -0,0 +1,50 @@
|
||||
from bot import loaded_modules_dict
|
||||
from os import path, pardir
|
||||
|
||||
module_name = path.basename(path.normpath(path.join(path.abspath(__file__), pardir, pardir)))
|
||||
action_name = path.basename(path.abspath(__file__))[:-3]
|
||||
|
||||
|
||||
def main_function(module, event_data, dispatchers_steamid):
|
||||
action = event_data[1].get("action", None)
|
||||
event_data[1]["action_identifier"] = action_name
|
||||
player_steamid = event_data[1].get("steamid", None)
|
||||
|
||||
if action == "show_options":
|
||||
current_view = "options"
|
||||
current_view_steamid = None
|
||||
elif action == "show_frontend":
|
||||
current_view = "frontend"
|
||||
current_view_steamid = None
|
||||
elif action == "show_info_view":
|
||||
current_view = "info"
|
||||
current_view_steamid = player_steamid
|
||||
else:
|
||||
module.callback_fail(callback_fail, module, event_data, dispatchers_steamid)
|
||||
return
|
||||
|
||||
module.set_current_view(dispatchers_steamid, {
|
||||
"current_view": current_view,
|
||||
"current_view_steamid": current_view_steamid
|
||||
})
|
||||
module.callback_success(callback_success, module, event_data, dispatchers_steamid)
|
||||
|
||||
|
||||
def callback_success(module, event_data, dispatchers_steamid, match=None):
|
||||
pass
|
||||
|
||||
|
||||
def callback_fail(module, event_data, dispatchers_steamid):
|
||||
pass
|
||||
|
||||
|
||||
action_meta = {
|
||||
"description": "manages player entries",
|
||||
"main_function": main_function,
|
||||
"callback_success": callback_success,
|
||||
"callback_fail": callback_fail,
|
||||
"requires_telnet_connection": False,
|
||||
"enabled": True
|
||||
}
|
||||
|
||||
loaded_modules_dict["module_" + module_name].register_action(action_name, action_meta)
|
||||
@@ -0,0 +1,64 @@
|
||||
from bot import loaded_modules_dict
|
||||
from os import path, pardir
|
||||
|
||||
module_name = path.basename(path.normpath(path.join(path.abspath(__file__), pardir, pardir)))
|
||||
action_name = path.basename(path.abspath(__file__))[:-3]
|
||||
|
||||
|
||||
def main_function(module, event_data, dispatchers_steamid=None):
|
||||
active_dataset = module.dom.data.get("module_game_environment", {}).get("active_dataset", None)
|
||||
player_to_be_updated_steamid = event_data[1].get("steamid", None)
|
||||
permission_level = event_data[1].get("level", 1000)
|
||||
|
||||
event_data[1]["action_identifier"] = action_name
|
||||
event_data[1]["fail_reason"] = []
|
||||
|
||||
player_to_be_updated = (
|
||||
module.dom.data
|
||||
.get("module_players", {})
|
||||
.get("elements", {})
|
||||
.get(active_dataset, {})
|
||||
.get(player_to_be_updated_steamid, None)
|
||||
)
|
||||
|
||||
if player_to_be_updated is not None:
|
||||
module.dom.data.upsert({
|
||||
"module_players": {
|
||||
"elements": {
|
||||
active_dataset: {
|
||||
player_to_be_updated_steamid: {
|
||||
"permission_level": permission_level
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
module.callback_success(callback_success, module, event_data, dispatchers_steamid)
|
||||
return
|
||||
else:
|
||||
event_data[1]["fail_reason"].append(
|
||||
"player does not exist on this server / has not logged in yet t create a file"
|
||||
)
|
||||
|
||||
module.callback_fail(callback_fail, module, event_data, dispatchers_steamid)
|
||||
|
||||
|
||||
def callback_success(module, event_data, dispatchers_steamid, match=None):
|
||||
pass
|
||||
|
||||
|
||||
def callback_fail(module, event_data, dispatchers_steamid):
|
||||
pass
|
||||
|
||||
|
||||
action_meta = {
|
||||
"description": "updates a players profiles permission data",
|
||||
"main_function": main_function,
|
||||
"callback_success": callback_success,
|
||||
"callback_fail": callback_fail,
|
||||
"requires_telnet_connection": True,
|
||||
"enabled": True
|
||||
}
|
||||
|
||||
loaded_modules_dict["module_" + module_name].register_action(action_name, action_meta)
|
||||
Reference in New Issue
Block a user