reworked map notifications so a new map with its infos is forwarded through flask over nginx and that main loops to respond every 5 seconds

This commit is contained in:
jenz 2026-02-22 23:45:00 +01:00
parent a7bde0361a
commit fcf3490693
7 changed files with 86 additions and 46 deletions

View File

@ -0,0 +1,21 @@
server {
# SSL configuration
listen 443 ssl;
ssl_certificate /etc/nginx/ssl/unloze-cert.pem;
ssl_certificate_key /etc/nginx/ssl/unloze-key.pem;
access_log off; #finally stops spamming god bless
server_name mapnotification.unloze.com;
location / {
proxy_pass http://127.0.0.1:5086;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}

View File

@ -1,3 +1,8 @@
requests
mysql-connector-python
python-a2s
flask
flask_cors
waitress
werkzeug
python app.py

View File

@ -1,10 +1,19 @@
#!/home/nonroot/stoat_map_notifications/venv/bin/python3
from settings import get_connection_unloze_playtime, stoat_token, stoat_url_map_notifications, stoat_url_50_last_messages
from settings import get_connection_unloze_playtime, stoat_token, stoat_url_map_notifications, stoat_url_50_last_messages, ips
import requests
import re
import a2s
import traceback
import json
from flask import Flask
from flask import request
from flask_cors import CORS
from werkzeug.middleware.proxy_fix import ProxyFix
import threading
import time
app = Flask(__name__)
app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_proto=1)
CORS(app)
#runs every 3 minutes to inform about a new map
@ -128,7 +137,7 @@ def check_new_map_notification_status(fixed, last_msg_id):
show_map_notifications = []
#if first time we take the most recent message as starting point
if not last_msg_id:
url = stoat_url_50_last_messages.replace('/messages?limit=50&include_users=true&sort=Oldest&after=', '/messages?limit=50&include_users=true')
url = stoat_url_50_last_messages.replace('/messages?limit=5&include_users=true&sort=Oldest&after=', '/messages?limit=5&include_users=true')
response = requests.get(url, headers=headers)
else:
response = requests.get(stoat_url_50_last_messages + last_msg_id, headers=headers)
@ -176,11 +185,12 @@ def check_new_map_notification_status(fixed, last_msg_id):
return valid_map_notification_cmds_add, valid_map_notification_cmds_remove, invalid_map_notification_cmds, last_msg_id, show_map_notifications
def send_post_notify_message_to_stoat(list_of_people_to_notify, infomap):
def send_post_notify_message_to_stoat(list_of_people_to_notify, content, infomap):
list_of_people_to_notify = list_of_people_to_notify[0]
message = f"Map changed to: {infomap}\n\n"
message = f"{content}\n\n"
try:
list_of_people_to_notify = json.loads(list_of_people_to_notify)
message += "People to notify: "
except:
#in case it fails there should be nobody to notify
list_of_people_to_notify = []
@ -193,7 +203,7 @@ def send_post_notify_message_to_stoat(list_of_people_to_notify, infomap):
message += f"<@{people}> "
if not message.endswith("\n"):
message += "\n"
message += "Check <#01KGH9S0R3A1Y7BDVWWD8NMNGS> for information or https://unloze.com/pages/servers\n(updated every 5 minutes)"
message += f"commands: showlist, add {infomap}, remove {infomap}"
headers = {
"x-bot-token": f"{stoat_token}",
"Content-Type": "application/json"
@ -208,18 +218,10 @@ def update_last_msg_id(msg_id):
with open("last_msg_id.txt", 'w') as f:
f.write(msg_id)
def update_file_current_map(infomap):
with open("currentmap_file.txt", 'w') as f:
f.write(infomap)
def get_last_msg_id_read():
with open("last_msg_id.txt", 'r') as f:
return f.readline()
def get_last_current_map():
with open("currentmap_file.txt", 'r') as f:
return f.readline()
def notify_of_new_map(infomap):
with get_connection_unloze_playtime() as conn:
with conn.cursor() as cur:
@ -232,7 +234,25 @@ def notify_of_new_map(infomap):
res = cur.fetchone()
return res
def main():
#nginx used for reserve proxy
@app.route('/', methods = ['POST'])
def got_new_map_to_announce():
real_ip = request.headers.get('X-Real-IP', request.remote_addr)
#ipv4 and ipv6 checks
if real_ip != ips[0] and not real_ip.startswith(ips[1]):
return "invalid"
try:
content = request.get_json()["content"]
#print('content: ', content)
infomap = content.split("Map changed to: ")[1].split("\nPlayerCount:")[0]
list_of_people_to_notify = notify_of_new_map(infomap)
send_post_notify_message_to_stoat(list_of_people_to_notify, content, infomap)
except:
err = traceback.format_exc()
return ""
def main_loop():
#get all maps
r = requests.get("https://uk-fastdl.unloze.com/css_ze/maps/")
bz2_files = re.findall(r'([^\s]+\.bz2)', r.text)
@ -246,32 +266,26 @@ def main():
#insert maps if they are not already.
insert_maps(fixed)
#check last 50 messages for new map notification updates
last_msg_id = get_last_msg_id_read()
valid_map_notification_cmds_add, valid_map_notification_cmds_remove, invalid_map_notification_cmds, last_msg_id, show_map_notifications = check_new_map_notification_status(fixed, last_msg_id)
#check last 5 messages for new map notification updates
while True:
last_msg_id = get_last_msg_id_read()
valid_map_notification_cmds_add, valid_map_notification_cmds_remove, invalid_map_notification_cmds, last_msg_id, show_map_notifications = check_new_map_notification_status(fixed, last_msg_id)
if valid_map_notification_cmds_add:
stoat_send_valid_map_notifications("added", valid_map_notification_cmds_add)
if valid_map_notification_cmds_remove:
stoat_send_valid_map_notifications("removed", valid_map_notification_cmds_remove)
if invalid_map_notification_cmds:
stoat_send_invalid_map_notifications(invalid_map_notification_cmds)
if show_map_notifications:
stoat_send_map_notification_list(show_map_notifications)
if valid_map_notification_cmds_add:
stoat_send_valid_map_notifications("added", valid_map_notification_cmds_add)
if valid_map_notification_cmds_remove:
stoat_send_valid_map_notifications("removed", valid_map_notification_cmds_remove)
if invalid_map_notification_cmds:
stoat_send_invalid_map_notifications(invalid_map_notification_cmds)
if show_map_notifications:
stoat_send_map_notification_list(show_map_notifications)
update_last_msg_id(last_msg_id)
address = ("51.195.188.106", int("27015"))
info = a2s.info(address)
infomap = info.map_name
file_current_map = get_last_current_map()
print('file_current_map: ', file_current_map, ' infomap: ', infomap)
if infomap != file_current_map:
list_of_people_to_notify = notify_of_new_map(infomap)
send_post_notify_message_to_stoat(list_of_people_to_notify, infomap)
update_file_current_map(infomap)
update_last_msg_id(last_msg_id)
time.sleep(5)
if __name__ == '__main__':
main()
t = threading.Thread(target=main_loop, daemon=True)
t.start()
from waitress import serve
serve(app, host="127.0.0.1", port=5086, threads = 1)

View File

@ -1,7 +1,7 @@
import mysql.connector
stoat_token = ""
ips = ["", ""]
stoat_url_map_notifications = ""
stoat_url_50_last_messages = ""

View File

@ -1,5 +1,5 @@
[Unit]
Description=updates map notifications ever 5 minutes
Description=updates map notifications and receives map info through http requests
[Service]
Type=simple
@ -7,4 +7,4 @@ User=nonroot
Environment=PYTHONUNBUFFERED=1
Environment=PATH=/home/nonroot/stoat_map_notifications/venv/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games:/snap/bin
WorkingDirectory=/home/nonroot/stoat_map_notifications
ExecStart=/home/nonroot/stoat_map_notifications/main.py
ExecStart=/home/nonroot/stoat_map_notifications/app.py

View File

@ -1,8 +1,8 @@
[Unit]
Description=checks every 3 minutes on stoat about map notifcations
Description=restart map notification flask service once every day at midnight
[Timer]
OnCalendar=*:0/3
OnCalendar=*-*-1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 00:00:00
[Install]
WantedBy=multi-user.target