Files
gtav-src/tools_ng/script/gen9/server.py
T
2025-09-29 00:52:08 +02:00

143 lines
5.5 KiB
Python
Executable File

import rsgdnd.utils as utils
import rsgdnd.server as server
import threading
import importlib
import time
import json
import sys
import os
services = {}
service_defs = {}
services_mtime = 0
services_running = False
services_lock = threading.Lock()
def get_callback(self, in_path, response):
global services_lock
in_path = in_path.replace("\\", "/")
utils.log("==================")
utils.log(f"server: in coming path '{in_path}'")
utils.log("==================")
# pass through
handled = []
with services_lock:
for k, service in services.items():
callback = "get_callback"
callback = service[callback] if callback in service else None
if callback and callback(self, in_path, response):
handled.append(k)
if len(handled) > 1:
utils.log(f"server: {in_path} handled by multiple services, is that intended? "+",".join(handled))
return len(handled) != 0
def post_callback(self, in_path, data, response):
global services_lock
in_path = in_path.replace("\\", "/")
utils.log("==================")
utils.log(f"server: in coming path '{in_path}'")
utils.log("==================")
# pass through
handled = []
with services_lock:
for k, service in services.items():
callback = "post_callback"
callback = service[callback] if callback in service else None
if callback and callback(self, in_path, data, response):
handled.append(k)
if len(handled) > 1:
utils.log(f"server: {in_path} handled by multiple services, is that intended? "+",".join(handled))
return len(handled) != 0
def service_update():
global services
global service_defs
global services_mtime
global services_running
services_running = True
while services_running:
# check if service defs have updated
if services_mtime != os.stat("services.json").st_mtime:
services_mtime = os.stat("services.json").st_mtime
do_update = False
with open("services.json") as serv_json:
try:
service_defs = json.loads(serv_json.read())
do_update = True
except Exception as error:
utils.log("Failed trying to open parse services.json")
utils.log(error)
if do_update:
with services_lock:
# stop any services that shouldn't be running anymore
removals = []
for k, v in services.items():
try:
if k not in service_defs:
if "stop" in v and callable(v["stop"]):
utils.log(f"server: stopping '{k}'")
v["stop"]()
removals.append(k)
except Exception as error:
utils.log("Failed trying to stop services")
utils.log(error)
for k in removals:
utils.log(f"server: removing '{k}' from the service list")
del services[k]
# start services
for k, v in service_defs.items():
if k not in services:
try:
if k in sys.modules:
importlib.reload(sys.modules[k])
new_service = importlib.import_module(k)
services[k] = { "module": new_service }
for id in v:
if hasattr(new_service, v[id]):
services[k][id] = getattr(new_service, v[id])
else:
services[k][id] = None
if not any([id in services[k] for id in ["get_callback", "post_callback", "start", "stop"]]):
raise ValueError(k+" doesn't define any of the service interfaces.")
for func in [services[k][id] for id in ["get_callback", "post_callback", "start", "stop"] if id in services[k]]:
if not callable(func):
raise ValueError(k+" '"+func.__name__+"' is not callable")
utils.log(f"server: added '{k}' to the service list")
if "start" in services[k] and callable(services[k]["start"]):
utils.log(f"server: starting '{k}'")
services[k]["start"]()
except Exception as error:
utils.log("Failed trying to start services")
utils.log(error)
if k in services:
del services[k]
time.sleep(1)
@utils.trywrap()
def main():
global services_running
update = threading.Thread(target=service_update)
update.start()
server.run_whitelist(get_callback=get_callback, post_callback=post_callback)
services_running = False
update.join()
pass
if __name__ == "__main__":
main()