• 01-10-2025, 20:36:38
    #1
    Merhaba,

    Çok bot yazdım ancak bunu denedim başarılı olamadım. Metin2'de bir pvp server var bunun için bot yazdırmak istiyorum.
    1600x900 pencere modunda metin taşlarını ekrandan tarayıp sırayla saldıracak. 5-10 saniye aralıkla z tuşuna basarak düşen itemleri toplayacak. Inject olabilir ancak server güvenlik önlemleri çok yüksek. Server: https://ebedi.misali2.com/
  • 01-10-2025, 20:53:40
    #2
    import pyautogui
    import cv2
    import numpy as np
    import time
    import random
    import threading
    from PIL import ImageGrab
    import keyboard
    import win32gui
    import win32con
    import win32api
    import json
    import os
    from datetime import datetime
    
    class Metin2Bot:
        def __init__(self, config_file="bot_config.json"):
            self.running = False
            self.paused = False
            self.config = self.load_config(config_file)
            
            # Pencere ayarları
            self.window_title = "Metin2"
            self.window_handle = None
            self.window_region = None
            
            # Zaman sayaçları
            self.last_pickup_time = time.time()
            self.last_hp_check = time.time()
            self.last_skill_time = time.time()
            self.pickup_interval = random.uniform(5, 10)
            
            # Bot durumu
            self.current_target = None
            self.attack_mode = False
            self.stats = {
                "metin_destroyed": 0,
                "items_picked": 0,
                "start_time": None,
                "total_clicks": 0
            }
            
            # Görüntü şablonları
            self.templates = {}
            self.load_templates()
            
        def load_config(self, config_file):
            """Konfigürasyon dosyasını yükle"""
            default_config = {
                "window_width": 1600,
                "window_height": 900,
                "metin_colors": {
                    "lower": [80, 80, 80],
                    "upper": [220, 220, 220]
                },
                "hp_bar_position": [100, 50],
                "hp_threshold": 30,
                "pickup_key": "z",
                "hp_potion_key": "1",
                "mp_potion_key": "2",
                "skills": {
                    "skill_1": {"key": "q", "cooldown": 5},
                    "skill_2": {"key": "w", "cooldown": 10},
                    "skill_3": {"key": "e", "cooldown": 15}
                },
                "attack_delay": [0.5, 1.0],
                "scan_interval": 0.3,
                "debug_mode": False
            }
            
            if os.path.exists(config_file):
                with open(config_file, 'r', encoding='utf-8') as f:
                    loaded_config = json.load(f)
                    default_config.update(loaded_config)
            else:
                with open(config_file, 'w', encoding='utf-8') as f:
                    json.dump(default_config, f, indent=4)
            
            return default_config
        
        def load_templates(self):
            """Görüntü şablonlarını yükle"""
            template_files = {
                "metin": "templates/metin.png",
                "hp_bar": "templates/hp_bar.png",
                "item": "templates/item.png",
                "mob": "templates/mob.png"
            }
            
            for name, path in template_files.items():
                if os.path.exists(path):
                    self.templates[name] = cv2.imread(path, cv2.IMREAD_GRAYSCALE)
                else:
                    print(f"Uyarı: {path} bulunamadı")
        
        def find_game_window(self):
            """Oyun penceresini bul ve konumunu al"""
            def enum_windows_callback(hwnd, windows):
                if win32gui.IsWindowVisible(hwnd):
                    window_text = win32gui.GetWindowText(hwnd)
                    if self.window_title in window_text:
                        windows.append(hwnd)
                return True
            
            windows = []
            win32gui.EnumWindows(enum_windows_callback, windows)
            
            if windows:
                self.window_handle = windows[0]
                rect = win32gui.GetWindowRect(self.window_handle)
                self.window_region = (rect[0], rect[1], rect[2], rect[3])
                print(f"Oyun penceresi bulundu: {self.window_region}")
                return True
            return False
        
        def bring_window_to_front(self):
            """Oyun penceresini öne getir"""
            if self.window_handle:
                win32gui.SetForegroundWindow(self.window_handle)
                time.sleep(0.1)
        
        def capture_screen(self):
            """Oyun ekranını yakala"""
            if self.window_region:
                screenshot = ImageGrab.grab(bbox=self.window_region)
                return cv2.cvtColor(np.array(screenshot), cv2.COLOR_RGB2BGR)
            return None
        
        def find_metin_stones(self, screenshot):
            """Metin taşlarını tespit et"""
            # Renk tabanlı tespit
            lower = np.array(self.config["metin_colors"]["lower"])
            upper = np.array(self.config["metin_colors"]["upper"])
            
            mask = cv2.inRange(screenshot, lower, upper)
            
            # Morfolojik işlemler ile gürültüyü azalt
            kernel = np.ones((5, 5), np.uint8)
            mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)
            mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
            
            # Konturları bul
            contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
            
            metin_positions = []
            for contour in contours:
                area = cv2.contourArea(contour)
                if 1000 < area < 50000:  # Alan filtresi
                    # Dikdörtgen kontrolü
                    x, y, w, h = cv2.boundingRect(contour)
                    aspect_ratio = float(w) / h
                    if 0.5 < aspect_ratio < 2.0:  # Metin taşları genelde kareye yakın
                        cx = x + w // 2
                        cy = y + h // 2
                        metin_positions.append({
                            "position": (cx + self.window_region[0], cy + self.window_region[1]),
                            "size": area,
                            "bounds": (x, y, w, h)
                        })
            
            # Template matching ile doğrula (eğer template varsa)
            if "metin" in self.templates and self.templates["metin"] is not None:
                metin_positions = self.verify_with_template(screenshot, metin_positions)
            
            # Mesafeye göre sırala (yakından uzağa)
            center_x = self.config["window_width"] // 2
            center_y = self.config["window_height"] // 2
            metin_positions.sort(key=lambda m: 
                ((m["position"][0] - center_x - self.window_region[0])**2 + 
                 (m["position"][1] - center_y - self.window_region[1])**2)**0.5
            )
            
            return metin_positions
        
        def verify_with_template(self, screenshot, positions):
            """Template matching ile pozisyonları doğrula"""
            gray = cv2.cvtColor(screenshot, cv2.COLOR_BGR2GRAY)
            template = self.templates["metin"]
            
            verified = []
            for metin in positions:
                x, y, w, h = metin["bounds"]
                roi = gray[max(0, y-20):min(gray.shape[0], y+h+20), 
                          max(0, x-20):min(gray.shape[1], x+w+20)]
                
                if roi.size > 0:
                    result = cv2.matchTemplate(roi, template, cv2.TM_CCOEFF_NORMED)
                    if result.max() > 0.6:
                        verified.append(metin)
            
            return verified if verified else positions
        
        def check_hp(self, screenshot):
            """HP kontrolü yap"""
            # Basit renk tabanlı HP kontrolü
            hp_region = screenshot[
                self.config["hp_bar_position"][1]:self.config["hp_bar_position"][1]+20,
                self.config["hp_bar_position"][0]:self.config["hp_bar_position"][0]+200
            ]
            
            # Kırmızı pikselleri say
            red_pixels = cv2.inRange(hp_region, np.array([0, 0, 150]), np.array([50, 50, 255]))
            hp_percentage = (cv2.countNonZero(red_pixels) / red_pixels.size) * 100
            
            return hp_percentage
        
        def use_potion(self, potion_type="hp"):
            """Pot kullan"""
            key = self.config["hp_potion_key"] if potion_type == "hp" else self.config["mp_potion_key"]
            pyautogui.press(key)
            print(f"{potion_type.upper()} potu kullanıldı")
        
        def attack_target(self, target):
            """Hedefe saldır"""
            x, y = target["position"]
            
            # Hedefi tıkla
            pyautogui.click(x, y, button='left')
            self.stats["total_clicks"] += 1
            
            # Rastgele gecikme
            delay = random.uniform(*self.config["attack_delay"])
            time.sleep(delay)
            
            # Skill kullan
            self.use_skills()
        
        def use_skills(self):
            """Becerileri kullan"""
            current_time = time.time()
            
            for skill_name, skill_info in self.config["skills"].items():
                if current_time - self.last_skill_time > skill_info["cooldown"]:
                    pyautogui.press(skill_info["key"])
                    self.last_skill_time = current_time
                    if self.config["debug_mode"]:
                        print(f"{skill_name} kullanıldı")
                    break
        
        def pickup_items(self):
            """Yerdeki itemleri topla"""
            pyautogui.press(self.config["pickup_key"])
            self.stats["items_picked"] += 1
            if self.config["debug_mode"]:
                print("Item toplandı")
        
        def find_items_on_ground(self, screenshot):
            """Yerdeki itemleri tespit et"""
            # Parlak itemler için renk tespiti
            hsv = cv2.cvtColor(screenshot, cv2.COLOR_BGR2HSV)
            
            # Parlak renk aralığı
            lower_bright = np.array([0, 0, 200])
            upper_bright = np.array([255, 30, 255])
            
            mask = cv2.inRange(hsv, lower_bright, upper_bright)
            contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
            
            items = []
            for contour in contours:
                area = cv2.contourArea(contour)
                if 50 < area < 1000:  # Küçük parlak alanlar
                    M = cv2.moments(contour)
                    if M["m00"] != 0:
                        cx = int(M["m10"] / M["m00"])
                        cy = int(M["m01"] / M["m00"])
                        items.append((cx, cy))
            
            return items
        
        def is_target_alive(self, target_pos):
            """Hedefin hala var olup olmadığını kontrol et"""
            screenshot = self.capture_screen()
            if screenshot is None:
                return False
            
            # Hedef bölgesini kontrol et
            x, y = target_pos["position"]
            x -= self.window_region[0]
            y -= self.window_region[1]
            
            roi_size = 50
            roi = screenshot[
                max(0, y-roi_size):min(screenshot.shape[0], y+roi_size),
                max(0, x-roi_size):min(screenshot.shape[1], x+roi_size)
            ]
            
            # Hedefin rengini kontrol et
            lower = np.array(self.config["metin_colors"]["lower"])
            upper = np.array(self.config["metin_colors"]["upper"])
            mask = cv2.inRange(roi, lower, upper)
            
            return cv2.countNonZero(mask) > 100
        
        def main_loop(self):
            """Ana bot döngüsü"""
            print("Bot başlatıldı.")
            print("Komutlar:")
            print("  P - Duraklat/Devam et")
            print("  Q - Çıkış")
            print("  S - İstatistikleri göster")
            
            self.stats["start_time"] = datetime.now()
            
            while self.running:
                try:
                    if self.paused:
                        time.sleep(0.1)
                        continue
                    
                    # Ekran görüntüsü al
                    screenshot = self.capture_screen()
                    if screenshot is None:
                        print("Oyun penceresi bulunamadı, tekrar arıyor...")
                        if self.find_game_window():
                            self.bring_window_to_front()
                        time.sleep(1)
                        continue
                    
                    # HP kontrolü
                    current_time = time.time()
                    if current_time - self.last_hp_check > 1:
                        hp = self.check_hp(screenshot)
                        if hp < self.config["hp_threshold"]:
                            self.use_potion("hp")
                        self.last_hp_check = current_time
                    
                    # Mevcut hedef kontrolü
                    if self.current_target and self.attack_mode:
                        if self.is_target_alive(self.current_target):
                            self.attack_target(self.current_target)
                            continue
                        else:
                            print("Metin taşı yok edildi!")
                            self.stats["metin_destroyed"] += 1
                            self.current_target = None
                            self.attack_mode = False
                            
                            # Item toplama zamanı
                            for _ in range(3):
                                self.pickup_items()
                                time.sleep(0.5)
                    
                    # Yeni metin taşı ara
                    metin_stones = self.find_metin_stones(screenshot)
                    
                    if metin_stones:
                        self.current_target = metin_stones[0]
                        self.attack_mode = True
                        print(f"Yeni hedef: {self.current_target['position']}")
                    else:
                        # Item toplama kontrolü
                        if current_time - self.last_pickup_time >= self.pickup_interval:
                            items = self.find_items_on_ground(screenshot)
                            if items or random.random() < 0.3:  # %30 şans ile de topla
                                self.pickup_items()
                                self.last_pickup_time = current_time
                                self.pickup_interval = random.uniform(5, 10)
                    
                    # Debug modu
                    if self.config["debug_mode"]:
                        self.draw_debug_info(screenshot, metin_stones)
                    
                    # Döngü gecikmesi
                    time.sleep(self.config["scan_interval"])
                    
                except Exception as e:
                    print(f"Hata: {e}")
                    import traceback
                    traceback.print_exc()
                    time.sleep(1)
        
        def draw_debug_info(self, screenshot, metin_stones):
            """Debug bilgilerini göster"""
            debug_img = screenshot.copy()
            
            # Metin taşlarını işaretle
            for metin in metin_stones:
                x, y, w, h = metin["bounds"]
                cv2.rectangle(debug_img, (x, y), (x+w, y+h), (0, 255, 0), 2)
                cv2.putText(debug_img, f"Size: {metin['size']}", 
                           (x, y-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1)
            
            # Debug penceresini göster
            cv2.imshow("Bot Debug", debug_img)
            cv2.waitKey(1)
        
        def show_stats(self):
            """İstatistikleri göster"""
            if self.stats["start_time"]:
                runtime = datetime.now() - self.stats["start_time"]
                print("\n=== Bot İstatistikleri ===")
                print(f"Çalışma Süresi: {runtime}")
                print(f"Yok Edilen Metin: {self.stats['metin_destroyed']}")
                print(f"Toplanan Item: {self.stats['items_picked']}")
                print(f"Toplam Tıklama: {self.stats['total_clicks']}")
                print(f"Metin/Saat: {self.stats['metin_destroyed'] / (runtime.seconds / 3600):.2f}")
                print("========================\n")
        
        def save_stats(self):
            """İstatistikleri dosyaya kaydet"""
            stats_file = f"bot_stats_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json"
            with open(stats_file, 'w', encoding='utf-8') as f:
                stats_copy = self.stats.copy()
                stats_copy["start_time"] = str(stats_copy["start_time"])
                stats_copy["end_time"] = str(datetime.now())
                json.dump(stats_copy, f, indent=4)
            print(f"İstatistikler kaydedildi: {stats_file}")
        
        def keyboard_handler(self):
            """Klavye komutlarını dinle"""
            while self.running:
                if keyboard.is_pressed('q'):
                    self.stop()
                    break
                elif keyboard.is_pressed('p'):
                    self.paused = not self.paused
                    status = "duraklatıldı" if self.paused else "devam ediyor"
                    print(f"Bot {status}")
                    time.sleep(0.5)
                elif keyboard.is_pressed('s'):
                    self.show_stats()
                    time.sleep(0.5)
                time.sleep(0.1)
        
        def start(self):
            """Botu başlat"""
            print("Oyun penceresi aranıyor...")
            if not self.find_game_window():
                print(f"'{self.window_title}' penceresi bulunamadı!")
                return
            
            self.bring_window_to_front()
            self.running = True
            
            # Thread'leri başlat
            bot_thread = threading.Thread(target=self.main_loop)
            keyboard_thread = threading.Thread(target=self.keyboard_handler)
            
            bot_thread.start()
            keyboard_thread.start()
            
            bot_thread.join()
            keyboard_thread.join()
        
        def stop(self):
            """Botu durdur"""
            self.running = False
            self.show_stats()
            self.save_stats()
            cv2.destroyAllWindows()
            print("Bot durduruldu.")
    
    # Gelişmiş özellikler için ek sınıf
    class Metin2BotAdvanced(Metin2Bot):
        def __init__(self, config_file="bot_config.json"):
            super().__init__(config_file)
            
            # Ek özellikler
            self.mob_detection = True
            self.auto_buff = True
            self.path_memory = []
            self.danger_zones = []
            
        def detect_mobs(self, screenshot):
            """Yakındaki mobları tespit et"""
            # Mob tespiti için HSV renk aralığı
            hsv = cv2.cvtColor(screenshot, cv2.COLOR_BGR2HSV)
            
            # Kırmızı isim rengi (düşman moblar)
            lower_red = np.array([0, 100, 100])
            upper_red = np.array([10, 255, 255])
            mask1 = cv2.inRange(hsv, lower_red, upper_red)
            
            lower_red2 = np.array([170, 100, 100])
            upper_red2 = np.array([180, 255, 255])
            mask2 = cv2.inRange(hsv, lower_red2, upper_red2)
            
            mask = cv2.bitwise_or(mask1, mask2)
            
            # Mob pozisyonlarını bul
            contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
            
            mobs = []
            for contour in contours:
                area = cv2.contourArea(contour)
                if 50 < area < 500:  # İsim etiketi boyutu
                    x, y, w, h = cv2.boundingRect(contour)
                    mobs.append({
                        "position": (x + w//2, y + h//2),
                        "danger_level": self.calculate_danger(x, y)
                    })
            
            return mobs
        
        def calculate_danger(self, x, y):
            """Tehlike seviyesini hesapla"""
            center_x = self.config["window_width"] // 2
            center_y = self.config["window_height"] // 2
            distance = ((x - center_x)**2 + (y - center_y)**2)**0.5
            
            if distance < 100:
                return "high"
            elif distance < 200:
                return "medium"
            else:
                return "low"
        
        def auto_buff_check(self):
            """Otomatik buff kontrolü"""
            buff_schedule = {
                "aura": {"key": "g", "interval": 300},  # 5 dakika
                "berserk": {"key": "h", "interval": 120}  # 2 dakika
            }
            
            current_time = time.time()
            for buff_name, buff_info in buff_schedule.items():
                last_used = getattr(self, f"last_{buff_name}_time", 0)
                if current_time - last_used > buff_info["interval"]:
                    pyautogui.press(buff_info["key"])
                    setattr(self, f"last_{buff_name}_time", current_time)
                    print(f"{buff_name} buff'ı yenilendi")
    
    # Ana program
    if __name__ == "__main__":
        print("Metin2 Bot v2.0")
        print("1. Normal Bot")
        print("2. Gelişmiş Bot")
        
        choice = input("Seçiminiz (1/2): ")
        
        if choice == "2":
            bot = Metin2BotAdvanced()
        else:
            bot = Metin2Bot()
        
        print("\nBot 3 saniye içinde başlayacak...")
        print("Oyunun 1600x900 pencere modunda açık olduğundan emin olun!")
        time.sleep(3)
        
        bot.start()
    şu kodu dene bakalım gereken ksıımları kendine göre düzenle.