Release 0.9.0
This commit is contained in:
49
bot/modules/game_environment/actions/cancel_shutdown.py
Normal file
49
bot/modules/game_environment/actions/cancel_shutdown.py
Normal file
@@ -0,0 +1,49 @@
|
||||
from bot import loaded_modules_dict
|
||||
from os import path, pardir
|
||||
from time import time
|
||||
|
||||
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):
|
||||
active_dataset = module.dom.data.get("module_game_environment", {}).get("active_dataset", None)
|
||||
|
||||
module.dom.data.upsert({
|
||||
"module_game_environment": {
|
||||
active_dataset: {
|
||||
"cancel_shutdown": True,
|
||||
"shutdown_in_seconds": None,
|
||||
"force_shutdown": False
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
event_data = ['say_to_all', {
|
||||
'message': (
|
||||
'a [FF6666]scheduled shutdown[-] has been cancelled.'
|
||||
)
|
||||
}]
|
||||
module.trigger_action_hook(module, event_data=event_data)
|
||||
|
||||
""" stop the timer """
|
||||
|
||||
|
||||
def callback_success(module, event_data, dispatchers_steamid, match=None):
|
||||
pass
|
||||
|
||||
|
||||
def callback_fail(module, event_data, dispatchers_steamid):
|
||||
pass
|
||||
|
||||
|
||||
action_meta = {
|
||||
"description": "Set the (active) shutdown procedure to be cancelled",
|
||||
"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)
|
||||
52
bot/modules/game_environment/actions/force_shutdown.py
Normal file
52
bot/modules/game_environment/actions/force_shutdown.py
Normal file
@@ -0,0 +1,52 @@
|
||||
from bot import loaded_modules_dict
|
||||
from os import path, pardir
|
||||
from time import time
|
||||
|
||||
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):
|
||||
active_dataset = module.dom.data.get("module_game_environment", {}).get("active_dataset", None)
|
||||
|
||||
module.dom.data.upsert({
|
||||
"module_game_environment": {
|
||||
active_dataset: {
|
||||
"cancel_shutdown": False,
|
||||
"shutdown_in_seconds": None,
|
||||
"force_shutdown": True
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
event_data = ['say_to_all', {
|
||||
'message': (
|
||||
'[FF6666]FORCED SHUTDOWN INITIATED[-]'
|
||||
)
|
||||
}]
|
||||
module.trigger_action_hook(module, event_data=event_data)
|
||||
|
||||
""" stop the timer """
|
||||
|
||||
event_data = ['shutdown', {}]
|
||||
module.trigger_action_hook(module, event_data=event_data)
|
||||
|
||||
|
||||
def callback_success(module, event_data, dispatchers_steamid, match=None):
|
||||
pass
|
||||
|
||||
|
||||
def callback_fail(module, event_data, dispatchers_steamid):
|
||||
pass
|
||||
|
||||
|
||||
action_meta = {
|
||||
"description": "Set the (active) shutdown procedure to be force-completed!",
|
||||
"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)
|
||||
136
bot/modules/game_environment/actions/getentities.py
Normal file
136
bot/modules/game_environment/actions/getentities.py
Normal file
@@ -0,0 +1,136 @@
|
||||
from bot import loaded_modules_dict
|
||||
from bot.constants import TELNET_TIMEOUT_NORMAL
|
||||
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_NORMAL
|
||||
timeout_start = time()
|
||||
event_data[1]["action_identifier"] = action_name
|
||||
|
||||
if not module.telnet.add_telnet_command_to_queue("listents"):
|
||||
module.callback_fail(callback_fail, module, event_data, dispatchers_steamid)
|
||||
return
|
||||
|
||||
poll_is_finished = False
|
||||
# Modern format - matches both empty and populated entity lists
|
||||
regex = (
|
||||
r"Executing\scommand\s\'listents\'\sby\sTelnet\sfrom\s(?P<called_by>.*?)\r?\n"
|
||||
r"(?P<raw_entity_data>[\s\S]*?)"
|
||||
r"Total\sof\s(?P<entity_count>\d{1,3})\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
|
||||
|
||||
module.callback_fail(callback_fail, module, event_data, dispatchers_steamid)
|
||||
|
||||
|
||||
def callback_success(module, event_data, dispatchers_steamid, match=None):
|
||||
raw_entity_data = match.group("raw_entity_data").lstrip()
|
||||
if len(raw_entity_data) >= 1:
|
||||
regex = (
|
||||
r"\d{1,2}. id=(?P<id>\d+), \["
|
||||
r"type=(?P<type>.+), "
|
||||
r"name=(?P<name>.*), "
|
||||
r"id=(\d+)"
|
||||
r"\], "
|
||||
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"lifetime=(?P<lifetime>.+), "
|
||||
r"remote=(?P<remote>.+), "
|
||||
r"dead=(?P<dead>.+), "
|
||||
r"health=(?P<health>\d+)"
|
||||
r"\r\n"
|
||||
)
|
||||
entities_to_update_dict = {}
|
||||
|
||||
active_dataset = module.dom.data.get("module_game_environment", {}).get("active_dataset", None)
|
||||
if active_dataset is None:
|
||||
return
|
||||
|
||||
for m in re.finditer(regex, raw_entity_data):
|
||||
last_seen_gametime_string = module.game_environment.get_last_recorded_gametime_string()
|
||||
entity_dict = {
|
||||
"id": m.group("id"),
|
||||
"owner": m.group("id"),
|
||||
"identifier": m.group("id"),
|
||||
"type": str(m.group("type")),
|
||||
"name": str(m.group("name")),
|
||||
"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"))),
|
||||
},
|
||||
"lifetime": str(m.group("lifetime")),
|
||||
"remote": bool(m.group("remote")),
|
||||
"dead": bool(m.group("dead")),
|
||||
"health": int(m.group("health")),
|
||||
"dataset": active_dataset,
|
||||
"last_seen_gametime": last_seen_gametime_string
|
||||
}
|
||||
entities_to_update_dict[m.group("id")] = entity_dict
|
||||
|
||||
if len(entities_to_update_dict) >= 1:
|
||||
module.dom.data.upsert({
|
||||
module.get_module_identifier(): {
|
||||
"elements": {
|
||||
active_dataset: entities_to_update_dict
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
stuff_to_delete = []
|
||||
for path, dom_element_key, dom_element in module.dom.get_dom_element_by_query(
|
||||
target_module=module.get_module_identifier(),
|
||||
query="id"
|
||||
):
|
||||
# Delete entities that are no longer in the update or have health <= 0 (dead)
|
||||
entity_data = entities_to_update_dict.get(dom_element, {})
|
||||
health = entity_data.get("health", 0)
|
||||
if dom_element not in entities_to_update_dict or health <= 0:
|
||||
stuff_to_delete.append([module.get_module_identifier(), "elements"] + path)
|
||||
|
||||
for dom_element_to_delete in stuff_to_delete:
|
||||
module.dom.data.remove_key_by_path(
|
||||
dom_element_to_delete,
|
||||
dispatchers_steamid=dispatchers_steamid
|
||||
)
|
||||
|
||||
|
||||
def callback_fail(module, event_data, dispatchers_steamid):
|
||||
pass
|
||||
|
||||
|
||||
def skip_it(module, event_data, dispatchers_steamid=None):
|
||||
pass
|
||||
|
||||
|
||||
action_meta = {
|
||||
"description": "get game entities",
|
||||
"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)
|
||||
108
bot/modules/game_environment/actions/getgameprefs.py
Normal file
108
bot/modules/game_environment/actions/getgameprefs.py
Normal file
@@ -0,0 +1,108 @@
|
||||
from bot import loaded_modules_dict
|
||||
from bot.constants import TELNET_TIMEOUT_NORMAL
|
||||
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("game_environment.getgameprefs")
|
||||
|
||||
|
||||
def main_function(module, event_data, dispatchers_steamid=None):
|
||||
timeout = TELNET_TIMEOUT_NORMAL
|
||||
timeout_start = time()
|
||||
event_data[1]["action_identifier"] = action_name
|
||||
|
||||
if not module.telnet.add_telnet_command_to_queue("getgamepref"):
|
||||
module.callback_fail(callback_fail, module, event_data, dispatchers_steamid)
|
||||
return
|
||||
|
||||
# Modern format: timestamps ARE present in "Executing command" lines
|
||||
# Format: 2025-11-18T20:21:02 4854.528 INF Executing command 'getgamepref'...
|
||||
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\'getgamepref\'\sby\sTelnet\sfrom\s(?P<called_by>.*?)\r?\n"
|
||||
r"(?P<raw_gameprefs>(?:GamePref\..*?\r?\n)+)"
|
||||
)
|
||||
|
||||
match = None
|
||||
match_found = False
|
||||
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.MULTILINE):
|
||||
poll_is_finished = True
|
||||
match_found = True
|
||||
|
||||
if match_found:
|
||||
module.callback_success(callback_success, module, event_data, dispatchers_steamid, match)
|
||||
return
|
||||
|
||||
module.callback_fail(callback_fail, module, event_data, dispatchers_steamid)
|
||||
|
||||
|
||||
def validate_settings(regex, raw_gameprefs):
|
||||
gameprefs_dict = {}
|
||||
all_required_settings_are_available = False
|
||||
for m in re.finditer(regex, raw_gameprefs, re.MULTILINE):
|
||||
stripped_gameprefs = m.group("gamepref_value").rstrip()
|
||||
if all([
|
||||
len(stripped_gameprefs) >= 1, # we have settings
|
||||
m.group("gamepref_name") == "GameName" # the GameName setting is available!
|
||||
|
||||
]):
|
||||
all_required_settings_are_available = True
|
||||
|
||||
gameprefs_dict[m.group("gamepref_name")] = stripped_gameprefs
|
||||
|
||||
if all_required_settings_are_available:
|
||||
return gameprefs_dict
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def callback_success(module, event_data, dispatchers_steamid, match=None):
|
||||
regex = (
|
||||
r"GamePref\.(?P<gamepref_name>.*)\s\=\s(?P<gamepref_value>.*)\s"
|
||||
)
|
||||
raw_gameprefs = match.group("raw_gameprefs")
|
||||
|
||||
gameprefs_dict = validate_settings(regex, raw_gameprefs)
|
||||
if isinstance(gameprefs_dict, dict):
|
||||
current_game_name = gameprefs_dict.get("GameName", None)
|
||||
module.dom.data.upsert({
|
||||
module.get_module_identifier(): {
|
||||
current_game_name: {
|
||||
"gameprefs": gameprefs_dict
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
module.dom.data.upsert({
|
||||
module.get_module_identifier(): {
|
||||
"active_dataset": current_game_name
|
||||
}
|
||||
})
|
||||
|
||||
logger.info("active_dataset_set", dataset=current_game_name)
|
||||
else:
|
||||
logger.error("gameprefs_validation_failed", reason="required_settings_missing")
|
||||
|
||||
|
||||
def callback_fail(module, event_data, dispatchers_steamid):
|
||||
pass
|
||||
|
||||
|
||||
action_meta = {
|
||||
"description": "gets a list of all current game-preferences",
|
||||
"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)
|
||||
88
bot/modules/game_environment/actions/getgamestats.py
Normal file
88
bot/modules/game_environment/actions/getgamestats.py
Normal file
@@ -0,0 +1,88 @@
|
||||
from bot import loaded_modules_dict
|
||||
from bot.constants import TELNET_TIMEOUT_NORMAL
|
||||
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):
|
||||
# we can't save the gamestats without knowing the game-name, as each game can have different stats.
|
||||
active_dataset = module.dom.data.get("module_game_environment", {}).get("active_dataset", None)
|
||||
if active_dataset is None:
|
||||
module.callback_fail(callback_fail, module, event_data, dispatchers_steamid)
|
||||
|
||||
timeout = TELNET_TIMEOUT_NORMAL
|
||||
timeout_start = time()
|
||||
event_data[1]["action_identifier"] = action_name
|
||||
|
||||
if not module.telnet.add_telnet_command_to_queue("getgamestat"):
|
||||
module.callback_fail(callback_fail, module, event_data, dispatchers_steamid)
|
||||
return
|
||||
|
||||
# Modern format: timestamps ARE present in "Executing command" lines
|
||||
# Format: 2025-11-18T20:21:02 4854.528 INF Executing command 'getgamestat'...
|
||||
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\'getgamestat\'\sby\sTelnet\sfrom\s(?P<called_by>.*?)\r?\n"
|
||||
r"(?P<raw_gamestats>(?:GameStat\..*?\r?\n)+)"
|
||||
)
|
||||
|
||||
match = None
|
||||
match_found = False
|
||||
poll_is_finished = False
|
||||
while not poll_is_finished and (time() < timeout_start + timeout):
|
||||
sleep(0.25) # give the telnet a little time to respond so we have a chance to get the data at first try
|
||||
match = False
|
||||
for match in re.finditer(regex, module.telnet.telnet_buffer, re.MULTILINE):
|
||||
poll_is_finished = True
|
||||
match_found = True
|
||||
|
||||
if match_found:
|
||||
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):
|
||||
regex = (
|
||||
r"GameStat\.(?P<gamestat_name>.*)\s\=\s(?P<gamestat_value>.*)\s"
|
||||
)
|
||||
raw_gamestats = match.group("raw_gamestats")
|
||||
gamestats_dict = {}
|
||||
|
||||
for m in re.finditer(regex, raw_gamestats, re.MULTILINE):
|
||||
gamestats_dict[m.group("gamestat_name")] = m.group("gamestat_value").rstrip()
|
||||
|
||||
active_dataset = (
|
||||
module.dom.data
|
||||
.get(module.get_module_identifier())
|
||||
.get("active_dataset", None)
|
||||
)
|
||||
|
||||
module.dom.data.upsert({
|
||||
module.get_module_identifier(): {
|
||||
active_dataset: {
|
||||
"gamestats": gamestats_dict
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
def callback_fail(module, event_data, dispatchers_steamid):
|
||||
pass
|
||||
|
||||
|
||||
action_meta = {
|
||||
"description": "gets a list of all current game-stats",
|
||||
"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)
|
||||
151
bot/modules/game_environment/actions/gettime.py
Normal file
151
bot/modules/game_environment/actions/gettime.py
Normal file
@@ -0,0 +1,151 @@
|
||||
from bot import loaded_modules_dict
|
||||
from bot.constants import TELNET_TIMEOUT_NORMAL
|
||||
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 get_weekday_string(server_days_passed: int) -> str:
|
||||
days_of_the_week = [
|
||||
"Sunday",
|
||||
"Monday",
|
||||
"Tuesday",
|
||||
"Wednesday",
|
||||
"Thursday",
|
||||
"Friday",
|
||||
"Saturday"
|
||||
]
|
||||
|
||||
current_day_index = int(float(server_days_passed) % 7)
|
||||
if 0 <= current_day_index <= 6:
|
||||
return days_of_the_week[current_day_index]
|
||||
else:
|
||||
return ""
|
||||
|
||||
|
||||
def is_currently_bloodmoon(module: object, day: int, hour: int = -1) -> bool:
|
||||
active_dataset = module.dom.data.get("module_game_environment", {}).get("active_dataset", None)
|
||||
next_bloodmoon_date = int(
|
||||
module.dom.data
|
||||
.get("module_game_environment", {})
|
||||
.get(active_dataset, {})
|
||||
.get("gamestats", {})
|
||||
.get("BloodMoonDay", None)
|
||||
)
|
||||
|
||||
daylight_length = int(
|
||||
module.dom.data
|
||||
.get("module_game_environment", {})
|
||||
.get(active_dataset, {})
|
||||
.get("gamestats", {})
|
||||
.get("DayLightLength", None)
|
||||
)
|
||||
|
||||
night_length = (24 - daylight_length)
|
||||
morning_length = (night_length - 2)
|
||||
|
||||
if hour >= 0: # we want the exact bloodmoon
|
||||
if next_bloodmoon_date == day and 23 >= hour >= 22:
|
||||
return True
|
||||
if (next_bloodmoon_date + 1) == day and 0 <= hour <= morning_length:
|
||||
return True
|
||||
else: # we only want the day
|
||||
if next_bloodmoon_date == day:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def main_function(module, event_data, dispatchers_steamid=None):
|
||||
timeout = TELNET_TIMEOUT_NORMAL
|
||||
timeout_start = time()
|
||||
event_data[1]["action_identifier"] = action_name
|
||||
|
||||
if not module.telnet.add_telnet_command_to_queue("gettime"):
|
||||
module.callback_fail(callback_fail, module, event_data, dispatchers_steamid)
|
||||
return
|
||||
|
||||
poll_is_finished = False
|
||||
# Modern format: simple "Day 447, 00:44" response
|
||||
regex = r"Day\s(?P<day>\d{1,5}),\s(?P<hour>\d{1,2}):(?P<minute>\d{1,2})"
|
||||
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
|
||||
|
||||
module.callback_fail(callback_fail, module, event_data, dispatchers_steamid)
|
||||
|
||||
|
||||
def callback_success(module, event_data, dispatchers_steamid, match=None):
|
||||
active_dataset = (
|
||||
module.dom.data
|
||||
.get(module.get_module_identifier(), {})
|
||||
.get("active_dataset", None)
|
||||
)
|
||||
|
||||
# we can't save the gametime without knowing the game-name, as each game can have different stats.
|
||||
if active_dataset is None:
|
||||
module.callback_fail(callback_fail, module, event_data, dispatchers_steamid)
|
||||
|
||||
matched_day = int(match.group("day"))
|
||||
matched_hour = match.group("hour")
|
||||
matched_minute = match.group("minute")
|
||||
|
||||
is_bloodmoon = is_currently_bloodmoon(module, matched_day, int(matched_hour))
|
||||
is_bloodday = is_currently_bloodmoon(module, matched_day)
|
||||
|
||||
weekday_string = get_weekday_string(matched_day)
|
||||
|
||||
module.dom.data.upsert({
|
||||
module.get_module_identifier(): {
|
||||
active_dataset: {
|
||||
"last_recorded_gametime": {
|
||||
"day": matched_day,
|
||||
"hour": matched_hour,
|
||||
"minute": matched_minute,
|
||||
"weekday": weekday_string,
|
||||
"is_bloodmoon": is_bloodmoon,
|
||||
"is_bloodday": is_bloodday
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
# Update last_recorded_servertime for webserver status widget
|
||||
# Since modern 7D2D servers don't include timestamps in telnet output,
|
||||
# we use system time to track when data was last received
|
||||
from datetime import datetime
|
||||
module.dom.data.upsert({
|
||||
"module_telnet": {
|
||||
"last_recorded_servertime": datetime.now().strftime("%Y-%m-%dT%H:%M:%S")
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
def callback_fail(module, event_data, dispatchers_steamid):
|
||||
pass
|
||||
|
||||
|
||||
def skip_it(module, event_data, dispatchers_steamid=None):
|
||||
pass
|
||||
|
||||
|
||||
action_meta = {
|
||||
"description": "gets the current gettime readout",
|
||||
"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)
|
||||
102
bot/modules/game_environment/actions/manage_entities.py
Normal file
102
bot/modules/game_environment/actions/manage_entities.py
Normal file
@@ -0,0 +1,102 @@
|
||||
from bot import loaded_modules_dict
|
||||
from bot.constants import TELNET_TIMEOUT_EXTENDED
|
||||
from os import path, pardir
|
||||
from time import time, sleep
|
||||
import random
|
||||
import re
|
||||
|
||||
module_name = path.basename(path.normpath(path.join(path.abspath(__file__), pardir, pardir)))
|
||||
action_name = path.basename(path.abspath(__file__))[:-3]
|
||||
|
||||
|
||||
def kill_entity(module, event_data, dispatchers_steamid=None):
|
||||
timeout = TELNET_TIMEOUT_EXTENDED
|
||||
timeout_start = time()
|
||||
event_data[1]["action_identifier"] = action_name
|
||||
|
||||
entity_to_be_killed = event_data[1].get("entity_id", None)
|
||||
|
||||
command = "kill {}".format(entity_to_be_killed)
|
||||
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 - no datetime/stardate prefix
|
||||
regex = (
|
||||
r"Entity\s(?P<zombie_name>.*)\s" + str(entity_to_be_killed) + r"\skilled"
|
||||
)
|
||||
number_of_attempts = 0
|
||||
while not poll_is_finished and (time() < timeout_start + timeout):
|
||||
number_of_attempts += 1
|
||||
telnet_buffer_copy = (module.telnet.telnet_buffer + '.')[:-1]
|
||||
for match in re.finditer(regex, telnet_buffer_copy, re.DOTALL):
|
||||
return match
|
||||
|
||||
sleep(1)
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def main_function(module, event_data, dispatchers_steamid):
|
||||
action = event_data[1].get("action", None)
|
||||
dataset = event_data[1].get("dataset")
|
||||
entity_id = event_data[1].get("entity_id")
|
||||
entity_name = event_data[1].get("entity_name")
|
||||
|
||||
if action is not None:
|
||||
if action == "kill":
|
||||
match = kill_entity(module, event_data, dispatchers_steamid)
|
||||
if match is not False:
|
||||
if entity_name == "zombieScreamer":
|
||||
module.callback_success(callback_success, module, event_data, dispatchers_steamid, match)
|
||||
|
||||
module.callback_fail(callback_fail, module, event_data, dispatchers_steamid)
|
||||
|
||||
|
||||
def callback_success(module, event_data, dispatchers_steamid, match=None):
|
||||
action = event_data[1].get("action", None)
|
||||
entity_id = event_data[1].get("entity_id")
|
||||
entity_name = event_data[1].get("entity_name")
|
||||
|
||||
if all([
|
||||
action is not None
|
||||
]):
|
||||
if entity_name == "zombieScreamer":
|
||||
possible_maybes = [
|
||||
"hopefully",
|
||||
"probably dead, yes!",
|
||||
"i think",
|
||||
"i'm almost certain",
|
||||
"yeah. definitely!!"
|
||||
]
|
||||
event_data = ['say_to_all', {
|
||||
'message': '[CCFFCC]Screamer ([FFFFFF]{entity_id}[CCFFCC]) killed[-], [FFFFFF]{maybe}[-]...'.format(
|
||||
entity_id=entity_id,
|
||||
maybe=random.choice(possible_maybes)
|
||||
)
|
||||
}]
|
||||
module.trigger_action_hook(module, event_data=event_data)
|
||||
else:
|
||||
event_data = ['say_to_all', {
|
||||
'message': '[CCFFCC]entity ([FFFFFF]{entity_id}[CCFFCC]) killed[-]'.format(
|
||||
entity_id=entity_id
|
||||
)
|
||||
}]
|
||||
module.trigger_action_hook(module, event_data=event_data)
|
||||
|
||||
|
||||
def callback_fail(module, event_data, dispatchers_steamid):
|
||||
pass
|
||||
|
||||
|
||||
action_meta = {
|
||||
"description": "manages entity 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)
|
||||
59
bot/modules/game_environment/actions/say_to_all.py
Normal file
59
bot/modules/game_environment/actions/say_to_all.py
Normal file
@@ -0,0 +1,59 @@
|
||||
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
|
||||
|
||||
message = event_data[1].get("message", None)
|
||||
|
||||
command = "say \"{}\"".format(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)
|
||||
50
bot/modules/game_environment/actions/schedule_shutdown.py
Normal file
50
bot/modules/game_environment/actions/schedule_shutdown.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):
|
||||
shutdown_in_seconds = int(event_data[1]["shutdown_in_seconds"])
|
||||
active_dataset = module.dom.data.get("module_game_environment", {}).get("active_dataset", None)
|
||||
|
||||
module.dom.data.upsert({
|
||||
"module_game_environment": {
|
||||
active_dataset: {
|
||||
"cancel_shutdown": False,
|
||||
"shutdown_in_seconds": shutdown_in_seconds,
|
||||
"force_shutdown": False
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
event_data = ['say_to_all', {
|
||||
'message': (
|
||||
'a [FF6666]scheduled shutdown[-] is about to take place!'
|
||||
'shutdown in {seconds} seconds'.format(
|
||||
seconds=shutdown_in_seconds
|
||||
)
|
||||
)
|
||||
}]
|
||||
module.trigger_action_hook(module, event_data=event_data)
|
||||
|
||||
|
||||
def callback_success(module, event_data, dispatchers_steamid, match=None):
|
||||
pass
|
||||
|
||||
|
||||
def callback_fail(module, event_data, dispatchers_steamid):
|
||||
pass
|
||||
|
||||
|
||||
action_meta = {
|
||||
"description": "Sets the schedule for a shutdown",
|
||||
"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)
|
||||
70
bot/modules/game_environment/actions/shutdown.py
Normal file
70
bot/modules/game_environment/actions/shutdown.py
Normal file
@@ -0,0 +1,70 @@
|
||||
from bot import loaded_modules_dict
|
||||
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):
|
||||
timeout = 10
|
||||
|
||||
if not module.telnet.add_telnet_command_to_queue("shutdown"):
|
||||
module.callback_fail(callback_fail, module, event_data, dispatchers_steamid)
|
||||
return
|
||||
|
||||
poll_is_finished = False
|
||||
# Modern format - no datetime/stardate prefix, just look for "Disconnect"
|
||||
regex = r"Disconnect.*"
|
||||
|
||||
timeout_start = time()
|
||||
while not poll_is_finished and (time() < timeout_start + timeout):
|
||||
sleep(0.5)
|
||||
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
|
||||
|
||||
module.callback_fail(callback_fail, module, event_data, dispatchers_steamid)
|
||||
|
||||
|
||||
def callback_success(module, event_data, dispatchers_steamid, match=None):
|
||||
active_dataset = module.dom.data.get("module_game_environment", {}).get("active_dataset", None)
|
||||
module.dom.data.upsert({
|
||||
"module_game_environment": {
|
||||
active_dataset: {
|
||||
"cancel_shutdown": False,
|
||||
"shutdown_in_seconds": None,
|
||||
"force_shutdown": False
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
def callback_fail(module, event_data, dispatchers_steamid):
|
||||
active_dataset = module.dom.data.get("module_game_environment", {}).get("active_dataset", None)
|
||||
module.dom.data.upsert({
|
||||
"module_game_environment": {
|
||||
active_dataset: {
|
||||
"cancel_shutdown": False,
|
||||
"shutdown_in_seconds": None,
|
||||
"force_shutdown": False
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
action_meta = {
|
||||
"description": "Cleanly shuts down the server",
|
||||
"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)
|
||||
@@ -0,0 +1,46 @@
|
||||
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
|
||||
|
||||
if action == "show_options":
|
||||
current_view = "options"
|
||||
current_view_steamid = None
|
||||
elif action == "show_frontend":
|
||||
current_view = "frontend"
|
||||
current_view_steamid = None
|
||||
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 entity table stuff",
|
||||
"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,51 @@
|
||||
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
|
||||
next_bloodmoon_date = event_data[1].get("blood_moon_date", None)
|
||||
if next_bloodmoon_date is not None:
|
||||
module.callback_success(callback_success, module, event_data, dispatchers_steamid)
|
||||
|
||||
module.callback_fail(callback_fail, module, event_data, dispatchers_steamid)
|
||||
|
||||
|
||||
def callback_success(module, event_data, dispatchers_steamid, match=None):
|
||||
active_dataset = module.dom.data.get("module_game_environment", {}).get("active_dataset", None)
|
||||
next_bloodmoon_date = event_data[1].get("blood_moon_date", None)
|
||||
|
||||
module.dom.data.upsert({
|
||||
module.get_module_identifier(): {
|
||||
active_dataset: {
|
||||
"gamestats": {
|
||||
"BloodMoonDay": next_bloodmoon_date
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
def callback_fail(module, event_data, dispatchers_steamid):
|
||||
pass
|
||||
|
||||
|
||||
def skip_it(module, event_data, dispatchers_steamid=None):
|
||||
pass
|
||||
|
||||
|
||||
action_meta = {
|
||||
"description": "updates bloodmoon date",
|
||||
"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)
|
||||
Reference in New Issue
Block a user