Начинающий
- Статус
- Оффлайн
- Регистрация
- 2 Фев 2020
- Сообщения
- 240
- Реакции
- 18
Всем привет. Выкладываю в открытый доступ небольшую утилиту для Инвокера, которую нашёл в одном из закрытых каналов (спиздил с компа). Продавалась по подписке, но смысла прятать такие приятные вещи не вижу.
Что это?
Исполняемый файл (.exe), написанный на Python. Он не вшивается в клиент игры, а просто эмулирует нажатия клавиш поверх окна Dota 2. Помогает быстрее выкастовать сферы и собрать спеллы одной комбинацией.
Как работает:
При запуске не видно в диспетчере задач. Назначаете горячие клавиши (например, Alt+1, Alt+2) и получаете готовые скиллы без задержек.
Важно:
Что это?
Исполняемый файл (.exe), написанный на Python. Он не вшивается в клиент игры, а просто эмулирует нажатия клавиш поверх окна Dota 2. Помогает быстрее выкастовать сферы и собрать спеллы одной комбинацией.
Как работает:
При запуске не видно в диспетчере задач. Назначаете горячие клавиши (например, Alt+1, Alt+2) и получаете готовые скиллы без задержек.
Важно:
- В комплекте идёт исходный код. Сможете подогнать под себя.
- Это макрос, а не чит. Однако технически это нарушение правил Valve, и за его использование аккаунт могут заблокировать (обычно дают предупреждение или бан в матчмейкинге при жалобах). Пользуйтесь на свой страх и риск, на основном акке я бы не советовал запускать.
- Файл без какой-либо защиты.
Пожалуйста, авторизуйтесь для просмотра ссылки.
source code:
import customtkinter as ctk
from customtkinter import *
import tkinter as tk
from tkinter import ttk
import keyboard
import time
import random
import json
import threading
import os
from dataclasses import dataclass
from typing import Dict, List
import queue
import atexit
ctk.set_appearance_mode("dark")
ctk.set_default_color_theme("blue")
@dataclass
class Macro:
name: str
hotkey: str
keys: List[str]
min_delay: int
max_delay: int
include_r: bool = False
enabled: bool = True
class ModernInvokerMacroGUI:
def __init__(self):
self.root = ctk.CTk()
self.root.title("Invoker Master")
self.root.geometry("800x700")
self.center_window()
self.root.overrideredirect(True)
self.macros: Dict[str, Macro] = {}
self.macro_enabled = True
self.current_hotkey = None
self.config_file = "invoker_macros.json"
self.listening_for_hotkey = False
self.command_queue = queue.Queue()
self.is_running = True
self.worker_thread = None
self.start_worker()
self.create_custom_title_bar()
self.load_macros()
self.create_gui()
self.start_hotkey_listener()
atexit.register(self.cleanup)
def start_worker(self):
def worker():
while self.is_running:
try:
macro = self.command_queue.get(timeout=0.1)
if macro and self.macro_enabled and macro.enabled:
self.cast_spell(macro)
except queue.Empty:
continue
except Exception as e:
print(f"Worker error: {e}")
self.worker_thread = threading.Thread(target=worker, daemon=True)
self.worker_thread.start()
def cleanup(self):
self.is_running = False
try:
keyboard.unhook_all()
except:
pass
def center_window(self):
self.root.update_idletasks()
width = 800
height = 700
x = (self.root.winfo_screenwidth() // 2) - (width // 2)
y = (self.root.winfo_screenheight() // 2) - (height // 2)
self.root.geometry(f'{width}x{height}+{x}+{y}')
def create_custom_title_bar(self):
self.title_bar = ctk.CTkFrame(self.root, height=40, corner_radius=0)
self.title_bar.pack(fill="x", padx=0, pady=0)
self.title_bar.pack_propagate(False)
title_frame = ctk.CTkFrame(self.title_bar, fg_color="transparent")
title_frame.pack(side="left", padx=10)
title_label = ctk.CTkLabel(
title_frame,
text="⚡ INVOKER MASTER ⚡",
font=ctk.CTkFont(size=16, weight="bold")
)
title_label.pack(side="left")
buttons_frame = ctk.CTkFrame(self.title_bar, fg_color="transparent")
buttons_frame.pack(side="right", padx=10)
self.minimize_btn = ctk.CTkButton(
buttons_frame,
text="—",
width=30,
height=30,
corner_radius=5,
fg_color="transparent",
hover_color=("#2b2b2b", "#2b2b2b"),
command=self.minimize_window
)
self.minimize_btn.pack(side="left", padx=2)
self.close_btn = ctk.CTkButton(
buttons_frame,
text="✕",
width=30,
height=30,
corner_radius=5,
fg_color="transparent",
hover_color="#C42B1C",
command=self.on_closing
)
self.close_btn.pack(side="left", padx=2)
self.title_bar.bind("<Button-1>", self.start_move)
self.title_bar.bind("<B1-Motion>", self.on_move)
title_label.bind("<Button-1>", self.start_move)
title_label.bind("<B1-Motion>", self.on_move)
def start_move(self, event):
self.x = event.x
self.y = event.y
def on_move(self, event):
deltax = event.x - self.x
deltay = event.y - self.y
x = self.root.winfo_x() + deltax
y = self.root.winfo_y() + deltay
self.root.geometry(f"+{x}+{y}")
def minimize_window(self):
self.root.iconify()
def create_gui(self):
main_container = ctk.CTkFrame(self.root, fg_color="transparent")
main_container.pack(fill="both", expand=True, padx=15, pady=15)
top_frame = ctk.CTkFrame(main_container, fg_color="transparent")
top_frame.pack(fill="x", pady=(0, 15))
self.toggle_btn = ctk.CTkButton(
top_frame,
text="🟢 MACROS ACTIVE",
command=self.toggle_macros,
width=180,
height=40,
font=ctk.CTkFont(size=14, weight="bold"),
fg_color="#2ecc71",
hover_color="#27ae60"
)
self.toggle_btn.pack(side="left", padx=5)
info_frame = ctk.CTkFrame(top_frame, fg_color=("gray75", "gray25"))
info_frame.pack(side="left", padx=10, fill="x", expand=True)
info_label = ctk.CTkLabel(
info_frame,
text="F6 - Toggle Macros | F7 - Hide/Show",
font=ctk.CTkFont(size=12)
)
info_label.pack(padx=10, pady=8)
content_frame = ctk.CTkFrame(main_container)
content_frame.pack(fill="both", expand=True)
list_frame = ctk.CTkFrame(content_frame)
list_frame.pack(side="left", fill="both", expand=True, padx=(0, 7))
list_label = ctk.CTkLabel(
list_frame,
text="📋 ACTIVE MACROS",
font=ctk.CTkFont(size=16, weight="bold")
)
list_label.pack(pady=(10, 5))
tree_frame = ctk.CTkFrame(list_frame)
tree_frame.pack(fill="both", expand=True, padx=10, pady=5)
style = ttk.Style()
style.theme_use('clam')
style.configure(
"Custom.Treeview",
background="#2b2b2b",
foreground="white",
fieldbackground="#2b2b2b",
borderwidth=0,
rowheight=25
)
style.configure(
"Custom.Treeview.Heading",
background="#1f538d",
foreground="white",
borderwidth=0,
font=('Arial', 10, 'bold')
)
style.map('Custom.Treeview',
background=[('selected', '#1f538d')],
foreground=[('selected', 'white')])
columns = ('Hotkey', 'Name', 'Keys', 'Delay', 'R', 'Status')
self.tree = ttk.Treeview(
tree_frame,
columns=columns,
show='headings',
height=10,
style="Custom.Treeview"
)
column_widths = [70, 120, 100, 80, 40, 60]
column_headers = ['Hotkey', 'Name', 'Keys', 'Delay(ms)', 'R', 'Status']
for col, width, header in zip(columns, column_widths, column_headers):
self.tree.heading(col, text=header)
self.tree.column(col, width=width, anchor='center')
scrollbar = ttk.Scrollbar(
tree_frame,
orient="vertical",
command=self.tree.yview
)
self.tree.configure(yscrollcommand=scrollbar.set)
self.tree.pack(side="left", fill="both", expand=True)
scrollbar.pack(side="right", fill="y")
btn_frame = ctk.CTkFrame(list_frame, fg_color="transparent")
btn_frame.pack(fill="x", padx=10, pady=10)
self.delete_btn = ctk.CTkButton(
btn_frame,
text="🗑️ Delete",
command=self.delete_macro,
width=90,
fg_color="#e74c3c",
hover_color="#c0392b"
)
self.delete_btn.pack(side="left", padx=2)
self.toggle_macro_btn = ctk.CTkButton(
btn_frame,
text="🔄 Toggle",
command=self.toggle_selected_macro,
width=90,
fg_color="#f39c12",
hover_color="#e67e22"
)
self.toggle_macro_btn.pack(side="left", padx=2)
self.test_btn = ctk.CTkButton(
btn_frame,
text="▶️ Test",
command=self.test_selected_macro,
width=90,
fg_color="#3498db",
hover_color="#2980b9"
)
self.test_btn.pack(side="left", padx=2)
create_frame = ctk.CTkFrame(content_frame)
create_frame.pack(side="right", fill="both", expand=True, padx=(7, 0))
create_label = ctk.CTkLabel(
create_frame,
text="✨ CREATE NEW MACRO",
font=ctk.CTkFont(size=16, weight="bold")
)
create_label.pack(pady=(10, 15))
input_frame = ctk.CTkFrame(create_frame, fg_color="transparent")
input_frame.pack(fill="x", padx=20)
ctk.CTkLabel(input_frame, text="Macro Name:", font=ctk.CTkFont(size=12)).pack(anchor="w", pady=(0, 2))
self.name_entry = ctk.CTkEntry(input_frame, height=35, placeholder_text="e.g., Sun Strike")
self.name_entry.pack(fill="x", pady=(0, 10))
ctk.CTkLabel(input_frame, text="Hotkey:", font=ctk.CTkFont(size=12)).pack(anchor="w", pady=(0, 2))
hotkey_frame = ctk.CTkFrame(input_frame, fg_color="transparent")
hotkey_frame.pack(fill="x", pady=(0, 10))
self.hotkey_entry = ctk.CTkEntry(hotkey_frame, height=35, placeholder_text="Click Set")
self.hotkey_entry.pack(side="left", fill="x", expand=True, padx=(0, 5))
self.set_hotkey_btn = ctk.CTkButton(
hotkey_frame,
text="Set",
command=self.start_hotkey_capture,
width=60,
height=35
)
self.set_hotkey_btn.pack(side="right")
ctk.CTkLabel(input_frame, text="Keys (comma separated):", font=ctk.CTkFont(size=12)).pack(anchor="w", pady=(0, 2))
self.keys_entry = ctk.CTkEntry(input_frame, height=35, placeholder_text="q,w,e")
self.keys_entry.pack(fill="x", pady=(0, 5))
ctk.CTkLabel(
input_frame,
text="Example: q,w,e (R will be added automatically if selected)",
font=ctk.CTkFont(size=10),
text_color="gray"
).pack(anchor="w", pady=(0, 10))
delay_frame = ctk.CTkFrame(input_frame, fg_color="transparent")
delay_frame.pack(fill="x", pady=(0, 10))
min_frame = ctk.CTkFrame(delay_frame, fg_color="transparent")
min_frame.pack(side="left", fill="x", expand=True, padx=(0, 5))
ctk.CTkLabel(min_frame, text="Min (ms):", font=ctk.CTkFont(size=12)).pack(anchor="w")
self.min_delay = ctk.CTkEntry(min_frame, height=35)
self.min_delay.insert(0, "50")
self.min_delay.pack(fill="x")
max_frame = ctk.CTkFrame(delay_frame, fg_color="transparent")
max_frame.pack(side="right", fill="x", expand=True, padx=(5, 0))
ctk.CTkLabel(max_frame, text="Max (ms):", font=ctk.CTkFont(size=12)).pack(anchor="w")
self.max_delay = ctk.CTkEntry(max_frame, height=35)
self.max_delay.insert(0, "150")
self.max_delay.pack(fill="x")
self.include_r_var = ctk.BooleanVar(value=False)
self.r_checkbox = ctk.CTkCheckBox(
input_frame,
text="➕ Add R at the end (Invoke)",
variable=self.include_r_var,
font=ctk.CTkFont(size=12)
)
self.r_checkbox.pack(anchor="w", pady=(0, 15))
self.create_btn = ctk.CTkButton(
create_frame,
text="✨ CREATE MACRO ✨",
command=self.create_macro,
height=45,
font=ctk.CTkFont(size=14, weight="bold"),
fg_color="#2ecc71",
hover_color="#27ae60"
)
self.create_btn.pack(padx=20, pady=10, fill="x")
self.status_bar = ctk.CTkFrame(self.root, height=30, fg_color=("gray80", "gray20"))
self.status_bar.pack(fill="x", side="bottom")
self.status_bar.pack_propagate(False)
self.status_label = ctk.CTkLabel(
self.status_bar,
text="✅ Ready",
font=ctk.CTkFont(size=11)
)
self.status_label.pack(side="left", padx=10)
self.macro_count_label = ctk.CTkLabel(
self.status_bar,
text=f"📊 Macros: {len(self.macros)}",
font=ctk.CTkFont(size=11)
)
self.macro_count_label.pack(side="right", padx=10)
self.refresh_macro_list()
try:
keyboard.add_hotkey('f6', self.toggle_macros)
keyboard.add_hotkey('f7', self.toggle_gui)
except:
pass
def start_hotkey_capture(self):
if self.listening_for_hotkey:
return
self.listening_for_hotkey = True
self.hotkey_entry.configure(state="normal")
self.hotkey_entry.delete(0, "end")
self.hotkey_entry.insert(0, "Press any key...")
self.hotkey_entry.configure(state="disabled")
self.set_hotkey_btn.configure(text="🎯 Listening...", state="disabled")
def on_key(event):
if not self.listening_for_hotkey:
return
if event.name in ['f6', 'f7', 'ctrl', 'alt', 'shift']:
return
self.current_hotkey = event.name
self.hotkey_entry.configure(state="normal")
self.hotkey_entry.delete(0, "end")
self.hotkey_entry.insert(0, event.name)
self.hotkey_entry.configure(state="disabled")
self.set_hotkey_btn.configure(text="Set", state="normal")
self.listening_for_hotkey = False
try:
keyboard.unhook(on_key)
except:
pass
self.update_status(f"Hotkey set: {event.name}")
keyboard.hook(on_key)
def create_macro(self):
name = self.name_entry.get().strip()
hotkey = self.current_hotkey
keys_str = self.keys_entry.get().strip()
if not hotkey:
self.show_error("Please set a hotkey")
return
if not name:
self.show_error("Please enter a name")
return
if not keys_str:
self.show_error("Please enter keys")
return
if hotkey in self.macros:
if not self.ask_yes_no("Overwrite", f"Hotkey '{hotkey}' is already used. Overwrite?"):
return
try:
min_delay = int(self.min_delay.get())
max_delay = int(self.max_delay.get())
if min_delay > max_delay:
min_delay, max_delay = max_delay, min_delay
if min_delay < 10:
min_delay = 10
except ValueError:
self.show_error("Invalid delay values")
return
keys = [k.strip().lower() for k in keys_str.split(',')]
macro = Macro(
name=name,
hotkey=hotkey,
keys=keys,
min_delay=min_delay,
max_delay=max_delay,
include_r=self.include_r_var.get()
)
self.macros[hotkey] = macro
self.save_macros()
self.refresh_macro_list()
self.clear_inputs()
self.add_macro_hotkey(macro)
self.update_status(f"✅ Macro '{name}' created successfully!")
self.macro_count_label.configure(text=f"📊 Macros: {len(self.macros)}")
def add_macro_hotkey(self, macro: Macro):
def callback():
if self.macro_enabled and macro.enabled:
self.command_queue.put(macro)
try:
keyboard.remove_hotkey(macro.hotkey)
except:
pass
try:
keyboard.add_hotkey(macro.hotkey, callback)
except:
pass
def cast_spell(self, macro: Macro):
try:
time.sleep(0.01)
for i, key in enumerate(macro.keys):
keyboard.press(key)
time.sleep(random.uniform(0.03, 0.05))
keyboard.release(key)
if i < len(macro.keys) - 1:
delay = random.randint(macro.min_delay, macro.max_delay) / 1000
time.sleep(delay)
if macro.include_r:
time.sleep(random.uniform(0.075, 0.1))
keyboard.press('r')
time.sleep(random.uniform(0.03, 0.05))
keyboard.release('r')
self.root.after(0, lambda: self.update_status(f"✅ Executed: {macro.name}"))
except Exception as e:
self.root.after(0, lambda: self.update_status(f"❌ Error: {str(e)}"))
def test_selected_macro(self):
selection = self.tree.selection()
if not selection:
self.show_info("Select a macro to test")
return
item = self.tree.item(selection[0])
hotkey = item['values'][0]
if hotkey in self.macros:
macro = self.macros[hotkey]
self.command_queue.put(macro)
self.update_status(f"🧪 Testing: {macro.name}")
def toggle_macros(self):
self.macro_enabled = not self.macro_enabled
if self.macro_enabled:
self.toggle_btn.configure(text="🟢 MACROS ACTIVE", fg_color="#2ecc71", hover_color="#27ae60")
self.update_status("✅ Macros activated")
else:
self.toggle_btn.configure(text="🔴 MACROS INACTIVE", fg_color="#e74c3c", hover_color="#c0392b")
self.update_status("⏸️ Macros deactivated")
def toggle_selected_macro(self):
selection = self.tree.selection()
if selection:
item = self.tree.item(selection[0])
hotkey = item['values'][0]
if hotkey in self.macros:
self.macros[hotkey].enabled = not self.macros[hotkey].enabled
self.refresh_macro_list()
self.save_macros()
status = "enabled" if self.macros[hotkey].enabled else "disabled"
self.update_status(f"Macro '{self.macros[hotkey].name}' {status}")
def delete_macro(self):
selection = self.tree.selection()
if selection:
item = self.tree.item(selection[0])
hotkey = item['values'][0]
if hotkey in self.macros:
macro_name = self.macros[hotkey].name
try:
keyboard.remove_hotkey(hotkey)
except:
pass
del self.macros[hotkey]
self.refresh_macro_list()
self.save_macros()
self.update_status(f"🗑️ Deleted: {macro_name}")
self.macro_count_label.configure(text=f"📊 Macros: {len(self.macros)}")
def refresh_macro_list(self):
for item in self.tree.get_children():
self.tree.delete(item)
for macro in self.macros.values():
status = "✅" if macro.enabled else "❌"
keys_str = ','.join(macro.keys)
delay_str = f"{macro.min_delay}-{macro.max_delay}"
include_r = "✓" if macro.include_r else "✗"
self.tree.insert('', 'end', values=(
macro.hotkey, macro.name, keys_str, delay_str, include_r, status
))
def clear_inputs(self):
self.name_entry.delete(0, "end")
self.hotkey_entry.configure(state="normal")
self.hotkey_entry.delete(0, "end")
self.hotkey_entry.configure(state="normal")
self.hotkey_entry.configure(placeholder_text="Click Set")
self.keys_entry.delete(0, "end")
self.min_delay.delete(0, "end")
self.min_delay.insert(0, "50")
self.max_delay.delete(0, "end")
self.max_delay.insert(0, "150")
self.include_r_var.set(False)
self.current_hotkey = None
self.set_hotkey_btn.configure(text="Set", state="normal")
def save_macros(self):
data = {}
for hotkey, macro in self.macros.items():
data[hotkey] = {
'name': macro.name,
'keys': macro.keys,
'min_delay': macro.min_delay,
'max_delay': macro.max_delay,
'include_r': macro.include_r,
'enabled': macro.enabled
}
try:
with open(self.config_file, 'w', encoding='utf-8') as f:
json.dump(data, f, indent=2, ensure_ascii=False)
except Exception as e:
self.update_status(f"❌ Save error: {str(e)}")
def load_macros(self):
if os.path.exists(self.config_file):
try:
with open(self.config_file, 'r', encoding='utf-8') as f:
data = json.load(f)
for hotkey, macro_data in data.items():
macro = Macro(
name=macro_data['name'],
hotkey=hotkey,
keys=macro_data['keys'],
min_delay=macro_data.get('min_delay', 50),
max_delay=macro_data.get('max_delay', 150),
include_r=macro_data.get('include_r', False),
enabled=macro_data.get('enabled', True)
)
self.macros[hotkey] = macro
except Exception as e:
print(f"Error loading macros: {e}")
def start_hotkey_listener(self):
for macro in self.macros.values():
self.add_macro_hotkey(macro)
def toggle_gui(self):
if self.root.state() == 'normal':
self.root.withdraw()
self.update_status("👻 Hidden (F7 to show)")
else:
self.root.deiconify()
self.update_status("👀 Visible")
def update_status(self, message):
self.status_label.configure(text=f"💫 {message}")
def show_error(self, message):
self.update_status(f"❌ {message}")
def show_info(self, message):
self.update_status(f"ℹ️ {message}")
def ask_yes_no(self, title, message):
dialog = ctk.CTkInputDialog(text=message, title=title)
return dialog.get_input() is not None
def run(self):
self.root.protocol("WM_DELETE_WINDOW", self.on_closing)
self.root.mainloop()
def on_closing(self):
self.is_running = False
if self.worker_thread:
self.worker_thread.join(timeout=0.5)
self.save_macros()
self.cleanup()
self.root.destroy()
if __name__ == "__main__":
required_packages = ['keyboard', 'customtkinter', 'pillow']
for package in required_packages:
try:
__import__(package)
except ImportError:
print(f"Installing {package}...")
os.system(f"pip install {package}")
app = ModernInvokerMacroGUI()
app.run()
Последнее редактирование: