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/
Bot Yaptırılacak
1
●276
- 01-10-2025, 20:53:40
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.