using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using Sulakore.Communication; using Sulakore.Modules; using Tangine; namespace HabboHealBot { [Module("Auto Medic", "Automates the :offer heal process")] [Author("User")] public class HealBot : Extension { // Status-Variable, damit Prozesse nicht unterbrochen werden private bool _isBusy = false; // Speichert die Zuordnung von Index (Raum-ID) zu EntityID (Datenbank-ID) // Das wird benötigt, weil der Chat den Index sendet, der Klick aber oft die ID braucht. private Dictionary _userMap = new Dictionary(); public HealBot() { // Events registrieren Triggers.In(In.Chat, OnChat); // Wenn jemand spricht Triggers.In(In.Users, OnUsers); // Wenn User den Raum betreten Triggers.In(In.RoomReady, OnRoomReady); // Wenn wir den Raum betreten (Reset) } // 1. Liste zurücksetzen wenn wir den Raum wechseln private void OnRoomReady(DataInterceptedEventArgs e) { _userMap.Clear(); _isBusy = false; } // 2. User tracken (Index zu ID Zuordnung) private void OnUsers(DataInterceptedEventArgs e) { var parser = e.Packet; int count = parser.ReadInt(); for (int i = 0; i < count; i++) { int id = parser.ReadInt(); // Entity ID (Datenbank ID) string name = parser.ReadString(); string motto = parser.ReadString(); string look = parser.ReadString(); int index = parser.ReadInt(); // Room Index // Restliche Daten überspringen (Koordinaten etc.) // Hinweis: Die Struktur kann je nach Server leicht variieren, // aber ID und Index kommen meist zuerst. if (!_userMap.ContainsKey(index)) { _userMap.Add(index, id); } } } // 3. Auf "heal" im Chat reagieren private void OnChat(DataInterceptedEventArgs e) { // Wenn wir gerade schon jemanden heilen -> Ignorieren if (_isBusy) return; int index = e.Packet.ReadInt(); string message = e.Packet.ReadString(); // Prüfen ob "heal" (groß/kleinschreibung egal) vorkommt if (message.ToLower().Contains("heal")) { // Prüfen, ob wir die ID zu diesem User haben if (_userMap.ContainsKey(index)) { int targetId = _userMap[index]; // Prozess starten (Async damit der Main-Thread nicht blockiert) Task.Run(() => PerformHealRoutine(targetId)); } } } private async Task PerformHealRoutine(int targetUserId) { _isBusy = true; // Blockieren Console.WriteLine($"[Bot] Healing User ID: {targetUserId}..."); try { // Schritt 1: :offer senden await SendPacketAsync(Out.Shout, ":offer", 0); await Task.Delay(600); // Warten bis Menü da ist (Evtl. anpassen je nach Lag) // Schritt 2: 1 senden (Heal auswählen) await SendPacketAsync(Out.Shout, "1", 0); await Task.Delay(600); // Warten auf "Click the user" Prompt // Schritt 3: User anklicken // Auf den meisten Servern ist "Anklicken" das Paket "GetSelectedBadges" // oder einfach das Abfragen der User-Info. // Paket-Struktur: {Header} {Int: UserID} await SendPacketAsync(Out.GetSelectedBadges, targetUserId); // Falls "GetSelectedBadges" auf deinem Server nicht als Klick zählt, // probiere stattdessen Out.RoomUserAction oder Out.LookTo Console.WriteLine("[Bot] Heal sequence finished."); } catch (Exception ex) { Console.WriteLine("[Bot] Error: " + ex.Message); } finally { // Prozess freigeben await Task.Delay(500); // Kurzer Cooldown _isBusy = false; } } // Helfer für asynchrones Senden private async Task SendPacketAsync(ushort header, params object[] values) { await SendToServerAsync(header, values); } } }