change_name_badge.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. import os
  2. from dotenv import load_dotenv
  3. import discord
  4. from discord.ext import commands, tasks
  5. from discord.commands import Option
  6. from discord.commands import slash_command
  7. import configparser
  8. import time
  9. import mysql.connector
  10. import json
  11. ## Note: to use this script on a other server you need to change the SQL querys. It is deactivatable in the config.cfg file.
  12. class changedcname(commands.Cog):
  13. def __init__(self, bot: discord.Bot):
  14. self.bot = bot
  15. def _load_config(self):
  16. config = configparser.ConfigParser()
  17. configFilePath = r'config.cfg'
  18. config.read(configFilePath)
  19. return config
  20. @commands.Cog.listener()
  21. async def on_ready(self):
  22. self.change_name_badge.start()
  23. @tasks.loop(minutes=15)
  24. async def change_name_badge(self):
  25. config = self._load_config()
  26. enable_change_dc_name = config.getboolean("Role Management", "enable_change_dc_name", fallback=False)
  27. if not enable_change_dc_name:
  28. return
  29. # Load .env file for the gameserver database
  30. load_dotenv()
  31. dbhost = os.getenv("HOST2")
  32. dbname = os.getenv("NAME2")
  33. dbpsswd = os.getenv("PASSWORD2")
  34. dbdb = os.getenv("DATABASE2")
  35. guild_id = os.getenv("SERVER")
  36. if not all([dbhost, dbname, dbpsswd, dbdb, guild_id]):
  37. print("Fehler: Mindestens eine .env Variable fehlt!")
  38. return
  39. guild = self.bot.get_guild(int(guild_id))
  40. if not guild:
  41. print("Server (Guild) nicht gefunden.")
  42. return
  43. # Database initialization
  44. try:
  45. conn = mysql.connector.connect(
  46. host=dbhost, user=dbname, password=dbpsswd, database=dbdb,
  47. charset='utf8mb4', collation='utf8mb4_unicode_ci'
  48. )
  49. cursor = conn.cursor()
  50. except Exception as e:
  51. print(f"Datenbankverbindung fehlgeschlagen: {e}")
  52. return
  53. # 1. ALLES in EINER Abfrage holen (verhindert Listen-Verschiebungen)
  54. cursor.execute("""
  55. SELECT
  56. ny_groups_meta.internal_identifier,
  57. players.charinfo,
  58. users.discord
  59. FROM ny_groups_meta
  60. JOIN players ON ny_groups_meta.character_identifier = players.citizenid
  61. JOIN users ON players.userId = users.userId
  62. ORDER BY ny_groups_meta.internal_identifier
  63. """)
  64. rows = cursor.fetchall()
  65. cursor.close()
  66. conn.close()
  67. # 2. Daten filtern und Duplikate (Twinks) aussortieren
  68. valid_users = {}
  69. blacklisted_ids = set()
  70. for badge, char_data, discord_str in rows:
  71. if not discord_str:
  72. continue
  73. # Discord ID extrahieren
  74. discord_id_parts = discord_str.split(":")
  75. user_id = None
  76. for part in discord_id_parts:
  77. if part.isdigit():
  78. user_id = int(part)
  79. break
  80. if not user_id:
  81. continue
  82. # --- DEIN DUPLIKAT-SCHUTZ ---
  83. # Wenn der User schon geblacklistet ist, überspringen
  84. if user_id in blacklisted_ids:
  85. continue
  86. # Wenn wir den User zum ZWEITEN Mal sehen, ist es ein Duplikat
  87. if user_id in valid_users:
  88. del valid_users[user_id] # Von den gültigen löschen
  89. blacklisted_ids.add(user_id) # Auf die Blacklist setzen
  90. continue
  91. # Vornamen und Nachnamen aus JSON holen
  92. firstname, lastname = "", ""
  93. if char_data:
  94. try:
  95. char_dict = json.loads(char_data)
  96. firstname = char_dict.get("firstname", "")
  97. lastname = char_dict.get("lastname", "")
  98. except (json.JSONDecodeError, KeyError, TypeError):
  99. pass
  100. # Ziel-Nickname generieren und auf 32 Zeichen limitieren (Discord Limit)
  101. target_nick = f"[{badge}] {firstname} {lastname}".strip()
  102. if len(target_nick) > 32:
  103. target_nick = target_nick[:32]
  104. # User in die Liste der "sicheren" Einträge packen
  105. valid_users[user_id] = target_nick
  106. # 3. Namen auf dem Discord-Server aktualisieren
  107. print(f"Aktualisiere {len(valid_users)} User. Duplikate ignoriert: {len(blacklisted_ids)}")
  108. for user_id, target_nick in valid_users.items():
  109. member = guild.get_member(user_id)
  110. if member:
  111. # WICHTIG: Nur ändern, wenn der Name nicht schon exakt so ist! (Schützt vor Discord API Sperren)
  112. if member.display_name != target_nick:
  113. try:
  114. await member.edit(nick=target_nick)
  115. except discord.Forbidden:
  116. pass # Der Bot hat nicht die Rechte (User hat höhere Rolle als der Bot)
  117. except Exception as e:
  118. print(f"Fehler beim Ändern des Namens von User {user_id}: {e}")
  119. def setup(bot: discord.Bot):
  120. bot.add_cog(changedcname(bot))