From 4d5b55a7f15930a13c791fbe3c270e755e1ef1d8 Mon Sep 17 00:00:00 2001 From: mons Date: Thu, 13 Aug 2026 18:17:43 -0400 Subject: [PATCH] added features. --- .env.example | 2 + .gitignore | 5 +++ README.md | 2 +- main.py | 121 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 .env.example create mode 100644 .gitignore create mode 100644 main.py diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..ab0bf8f --- /dev/null +++ b/.env.example @@ -0,0 +1,2 @@ +url = https://discord.com/api/webhooks/... +hostname = your.domain.tld:port \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1426094 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +*.json +.env +.vscode/ +!.vscode/extensions.json +*.code-workspace diff --git a/README.md b/README.md index e939b68..eceeda2 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ # mss-webhooksu -Discord webhook that pings you. \ No newline at end of file +Discord webhook that pings you when someone joins or leaves a minecraft server. \ No newline at end of file diff --git a/main.py b/main.py new file mode 100644 index 0000000..86c70aa --- /dev/null +++ b/main.py @@ -0,0 +1,121 @@ +import json +import requests +from dotenv import dotenv_values + +config = dotenv_values(".env") + +WEBHOOK_URL = config["url"] +HOSTNAME = config["hostname"] + +STATUS_FILE = "previous_status.json" # could get it from the .env, but it's not secret information so :shrug: + +with open(STATUS_FILE, "r") as file: + previous_status = json.load(file) + +try: + response = requests.get( + f"https://api.mcsrvstat.us/3/{HOSTNAME}", + timeout=10 + ) + response.raise_for_status() + server_status = response.json() +except requests.RequestException as e: + print(f"Failed to get server status: {e}") + exit(1) + +previous_players_data = previous_status.get("players", {}) +current_players_data = server_status.get("players", {}) + +previous_online = previous_players_data.get("online", 0) +current_online = current_players_data.get("online", 0) + +previous_max = previous_players_data.get("max", 0) +current_max = current_players_data.get("max", 0) + +previous_player_list = { + player["name"] + for player in previous_players_data.get("list", []) +} + +current_player_list = { + player["name"] + for player in current_players_data.get("list", []) +} + +if ( + previous_online == current_online + and previous_player_list == current_player_list +): + print("nothing changed.") + exit() + + +if current_online > previous_online: + pc_diff_sign = "+" +elif current_online < previous_online: + pc_diff_sign = "-" +else: + pc_diff_sign = " " + + +if previous_online != current_online: + pc_diff_previously = f"(previously {previous_online})" +else: + pc_diff_previously = "" + + +playercount_diff_formatted = ( + f"{pc_diff_sign} {current_online}/{current_max} " + f"{pc_diff_previously}" +) + + +joined_players = current_player_list - previous_player_list +left_players = previous_player_list - current_player_list + +player_diff = [] + +for player in sorted(current_player_list): + if player in joined_players: + player_diff.append(f"+ {player}") + else: + player_diff.append(f" {player}") + +for player in sorted(left_players): + player_diff.append(f"- {player}") + +player_diff_formatted = "\n".join(player_diff) or " no one is here." + + +payload = { + "content": f"""--- +# status changed on {HOSTNAME} + +```diff +{playercount_diff_formatted} +``` + +```diff +{player_diff_formatted} +``` +""" +} + + +try: + response = requests.post( + WEBHOOK_URL, + json=payload, + timeout=10 + ) + response.raise_for_status() +except requests.RequestException as e: + print(f"failed to send webhook: {e}") + exit(1) + + +print("success") + + +with open(STATUS_FILE, "w") as file: + json.dump(server_status, file, indent=2) \ No newline at end of file