Skip to content

Commit

Permalink
Create Crosshair.py
Browse files Browse the repository at this point in the history
  • Loading branch information
Teemsploit authored Aug 3, 2024
1 parent e9558ed commit 8e67677
Showing 1 changed file with 224 additions and 0 deletions.
224 changes: 224 additions & 0 deletions Crosshair.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
import ctypes
import json
import os
import psutil
import sys
import threading
import time
import logging

CROSSHAIR_COLOR = 0xFF0000 # rgb(255,0,0)
CROSSHAIR_SIZE = 8
VISIBLE = True
COLOR_CYCLE_KEYS = [0x2D, 0x2E] # VK_INSERT, VK_DELETE
CONSOLE_KEY = 0x23 # VK_END
HOME_KEY = 0x24 # VK_HOME
CLOSE_KEY = 0x27 # VK_RIGHT
SW_SHOW = 5
SW_HIDE = 0
CONFIG_FILE_PATH = os.path.join(os.getenv('APPDATA'), 'crosshair_config.json')
LOG_FILE_PATH = os.path.join(os.getenv('APPDATA'), 'crosshair.log')
user32 = ctypes.windll.user32
kernel32 = ctypes.windll.kernel32

logging.basicConfig(filename=LOG_FILE_PATH, level=logging.DEBUG,
format='%(asctime)s - %(levelname)s - %(message)s')

class CrosshairApp:
def __init__(self):
self.crosshair_color = CROSSHAIR_COLOR
self.visible = VISIBLE
self.screen_width, self.screen_height = self.get_screen_dimensions()
self.center_x, self.center_y = self.screen_width // 2, self.screen_height // 2

def log_and_show_error(self, message):
logging.error(message)
print(message)
user32.MessageBoxW(0, message, "Error", 1)

def is_admin(self):
try:
return ctypes.windll.shell32.IsUserAnAdmin()
except Exception as e:
self.log_and_show_error(f"Error checking admin status: {e}")
return False

def request_admin(self):
script = os.path.abspath(sys.argv[0])
try:
ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, f'"{script}"', None, 1)
except Exception as e:
self.log_and_show_error(f"Error requesting admin privileges: {e}")
sys.exit()

def show_elevation_message(self):
message = (
"This application needs administrator privileges for the following reasons:\n\n"
"1. **Screen Drawing**: The application uses GDI (Graphics Device Interface) functions to draw directly on the screen.\n"
" Administrator privileges ensure that the crosshair remains visible and unaffected by other applications that might\n"
" override the drawing context.\n\n"
"2. **Real-Time Priority**: The application sets its process priority to real-time to ensure the crosshair rendering is\n"
" smooth and responsive. This helps in reducing latency and improving the user experience.\n\n"
"3. **Configuration Management**: The application reads and writes its configuration settings to the APPDATA directory.\n"
" Administrator privileges help in managing file permissions and ensuring the settings are saved correctly.\n\n"
"4. **Input Handling**: The application monitors global key events to provide functionalities like color cycling and\n"
" visibility toggling. Administrator privileges allow the application to capture these events reliably.\n\n"
"Click 'Yes' to grant administrator privileges. If you choose 'No', the application may experience errors."
)
result = ctypes.windll.user32.MessageBoxW(0, message, "Administrator Access Request", 4)
if result == 6: # IDYES
self.request_admin()
sys.exit()

def set_real_time_priority(self):
try:
p = psutil.Process(os.getpid())
p.nice(psutil.REALTIME_PRIORITY_CLASS)
print("Process priority set to real-time.")
except Exception as e:
self.log_and_show_error(f"Error setting real-time priority: {e}")

def load_config(self):
if os.path.exists(CONFIG_FILE_PATH):
try:
with open(CONFIG_FILE_PATH, 'r') as f:
config = json.load(f)
self.crosshair_color = config.get('color', self.crosshair_color)
self.visible = config.get('visible', self.visible)
print(f"Loaded config: Color={self.crosshair_color:#06X}, Visible={self.visible}")
except Exception as e:
self.log_and_show_error(f"Error loading config: {e}")

def save_config(self):
try:
config = {
'color': self.crosshair_color,
'visible': self.visible,
}
with open(CONFIG_FILE_PATH, 'w') as f:
json.dump(config, f, indent=4)
print(f"Saved config: Color={self.crosshair_color:#06X}, Visible={self.visible}")
except Exception as e:
self.log_and_show_error(f"Error saving config: {e}")

def draw_crosshair(self, hdc, x, y, color):
colorref = (color & 0xFF) | ((color & 0xFF00) << 8) | ((color & 0xFF0000) >> 8)
for i in range(-CROSSHAIR_SIZE, CROSSHAIR_SIZE + 1):
ctypes.windll.gdi32.SetPixel(hdc, x + i, y, colorref)
ctypes.windll.gdi32.SetPixel(hdc, x, y + i, colorref)

def get_screen_dimensions(self):
width = user32.GetSystemMetrics(0) # SM_CXSCREEN
height = user32.GetSystemMetrics(1) # SM_CYSCREEN
return width, height

def draw_crosshair_windows(self):
hdc = user32.GetDC(0)
self.draw_crosshair(hdc, self.center_x, self.center_y, self.crosshair_color)
user32.ReleaseDC(0, hdc)

def toggle_visibility(self):
self.visible = not self.visible
self.save_config()

def cycle_color(self):
if self.crosshair_color == 0xFF0000: # Red
self.crosshair_color = 0x00FF00 # Green
elif self.crosshair_color == 0x00FF00: # Green
self.crosshair_color = 0x0000FF # Blue
elif self.crosshair_color == 0x0000FF: # Blue
self.crosshair_color = 0xFF0000 # Red
self.save_config()

def show_keybindings_message(self):
keybindings_message = (
"Key Bindings:\n"
"Insert: Cycle through Red, Green, Blue\n"
"Delete: Toggle Crosshair Visibility\n"
"End: Open/Close Console\n"
"Home: Reopen Key Bindings\n"
"Right Arrow: Close Crosshair"
)
user32.MessageBoxW(0, keybindings_message, "Key Bindings", 1)

def show_console(self):
kernel32.AllocConsole()
console_handle = kernel32.GetConsoleWindow()
user32.ShowWindow(console_handle, SW_SHOW)
self.save_config()
print("Console shown.")

def hide_console(self):
console_handle = kernel32.GetConsoleWindow()
user32.ShowWindow(console_handle, SW_HIDE)
self.save_config()
print("Console hidden.")

def close_crosshair(self):
self.visible = False
self.save_config()
print("Crosshair closed.")

def check_toggle_key(self):
while True:
try:
if user32.GetAsyncKeyState(COLOR_CYCLE_KEYS[1]) & 0x8000: # VK_DELETE
self.toggle_visibility()
time.sleep(0.3)

if user32.GetAsyncKeyState(CONSOLE_KEY) & 0x8000: # VK_END
if kernel32.GetConsoleWindow():
self.hide_console()
else:
self.show_console()
time.sleep(0.3)

if user32.GetAsyncKeyState(HOME_KEY) & 0x8000: # VK_HOME
self.show_keybindings_message()
time.sleep(0.3)

if user32.GetAsyncKeyState(CLOSE_KEY) & 0x8000: # VK_RIGHT
self.close_crosshair()
time.sleep(0.3)
except Exception as e:
self.log_and_show_error(f"Error in check_toggle_key thread: {e}")

def color_cycle_key(self):
while True:
try:
if user32.GetAsyncKeyState(COLOR_CYCLE_KEYS[0]) & 0x8000: # VK_INSERT
self.cycle_color()
time.sleep(0.3)
except Exception as e:
self.log_and_show_error(f"Error in color_cycle_key thread: {e}")

def run(self):
if not self.is_admin():
self.show_elevation_message()

self.set_real_time_priority()
self.load_config()
self.show_keybindings_message()

toggle_thread = threading.Thread(target=self.check_toggle_key, daemon=True)
toggle_thread.start()

color_cycle_thread = threading.Thread(target=self.color_cycle_key, daemon=True)
color_cycle_thread.start()

try:
while True:
if self.visible:
try:
self.draw_crosshair_windows()
except Exception as e:
self.log_and_show_error(f"Error in main loop: {e}")
time.sleep(0.005)
except KeyboardInterrupt:
self.save_config()
print("Script terminated.")
sys.exit()

if __name__ == "__main__":
app = CrosshairApp()
app.run()

0 comments on commit 8e67677

Please sign in to comment.