~nickwinston123/armagetronad/arma_chatbot_config

« back to all changes in this revision

Viewing changes to launcher/launcher.py

  • Committer: hackermans
  • Date: 2025-05-28 18:34:25 UTC
  • Revision ID: nickwinston123@gmail.com-20250528183425-z5cssgt5eeqyqox3

consolidated arma chatbot config programs

- arma_terminal: live console viewer with input passthrough
- game_manager: manages bans, IP rotation, and keeping the game open
- game_updater: syncs updated game files from shared folder
- ollama_chat: ai chatbot 

- launcher: launches all not already opened programs with positioning and window checks

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python3
 
2
import subprocess
 
3
import time
 
4
import win32gui
 
5
import win32con
 
6
import sys
 
7
import os
 
8
import logging
 
9
import configparser
 
10
import re
 
11
import ctypes
 
12
from ctypes import wintypes
 
13
 
 
14
config = configparser.ConfigParser()
 
15
ini_path = os.path.join(os.path.dirname(__file__), 'launcher_real.ini')
 
16
try:
 
17
    config.read(ini_path)
 
18
except Exception as e:
 
19
    logging.error(f"Error reading configuration: {e}")
 
20
    sys.exit(1)
 
21
 
 
22
CONFIG_DIR = config.get('Paths', 'config_dir')
 
23
LOG_FILE   = config.get('Paths', 'log_file')
 
24
 
 
25
raw_excl = config.get('Settings', 'exclude_keywords').strip()
 
26
if raw_excl.startswith('[') and raw_excl.endswith(']'):
 
27
    raw_excl = raw_excl[1:-1]
 
28
EXCLUDE_KEYWORDS = [kw.strip().lower() for kw in raw_excl.split(',') if kw.strip()]
 
29
 
 
30
PYTHON = sys.executable
 
31
 
 
32
def get_work_area():
 
33
    SPI_GETWORKAREA = 0x0030
 
34
    rect = wintypes.RECT()
 
35
    ctypes.windll.user32.SystemParametersInfoW(SPI_GETWORKAREA, 0, ctypes.byref(rect), 0)
 
36
    return rect.right - rect.left, rect.bottom - rect.top
 
37
 
 
38
screen_w, screen_h = get_work_area()
 
39
half_w, half_h = screen_w // 2, screen_h // 2
 
40
 
 
41
WINDOWS = [
 
42
    # top-left
 
43
    (["arma_terminal"],
 
44
     f'cmd.exe /C start "" cmd /K "title arma_terminal && python \"{os.path.join(CONFIG_DIR, "arma_terminal", "arma_terminal.py")}\""',
 
45
     (0, 0),
 
46
     False),
 
47
 
 
48
    # top-right
 
49
    (["game_manager"],
 
50
     f'cmd.exe /C start "" cmd /K "title game_manager && python \"{os.path.join(CONFIG_DIR, "game_manager", "game_manager.py")}\""',
 
51
     (half_w, 0),
 
52
     False),
 
53
 
 
54
    # bottom-left
 
55
    (["ollama_chat"],
 
56
     f'cmd.exe /C start "" cmd /K "title ollama_chat && python \"{os.path.join(CONFIG_DIR, "ollama_chat", "ollama_chat.py")}\""',
 
57
     (0, half_h),
 
58
     False),
 
59
]
 
60
 
 
61
# bottom-right
 
62
UPDATER = (
 
63
    ["game_updater"],
 
64
    f'cmd.exe /C start "" cmd /K "title game_updater && '
 
65
    f'cd /d \"{os.path.join(CONFIG_DIR, "game_updater")}\" && '
 
66
    f'python game_updater.py"',
 
67
    (half_w, half_h),
 
68
    False
 
69
)
 
70
 
 
71
def enum_windows():
 
72
    wins = []
 
73
    def cb(hwnd, _):
 
74
        if win32gui.IsWindowVisible(hwnd):
 
75
            title = win32gui.GetWindowText(hwnd)
 
76
            if title:
 
77
                wins.append((hwnd, title))
 
78
        return True
 
79
    win32gui.EnumWindows(cb, None)
 
80
    return wins
 
81
 
 
82
def normalize(s: str) -> str:
 
83
    return re.sub(r'\s+', ' ', s.strip().lower())
 
84
 
 
85
def find_window(alias_list):
 
86
    norm_aliases = [normalize(a) for a in alias_list]
 
87
    for hwnd, title in enum_windows():
 
88
        n = normalize(title)
 
89
        if any(excl in n for excl in EXCLUDE_KEYWORDS):
 
90
            continue
 
91
        if any(alias in n for alias in norm_aliases):
 
92
            print(f"[DEBUG] Matched: {title!r} ← for {alias_list}")
 
93
            return hwnd
 
94
 
 
95
    if alias_list == ["game_manager"]:
 
96
        for hwnd, title in enum_windows():
 
97
            n = normalize(title)
 
98
            if n.startswith("[c:\\users\\itsne\\desktop\\arma_chatbot_config\\vpn\\ovpn") and "openvpn" in n:
 
99
                print(f"[DEBUG] Matched OpenVPN: {title!r}")
 
100
                return hwnd
 
101
 
 
102
    print(f"[DEBUG] No match for: {alias_list}")
 
103
    print("[DEBUG] Open windows:")
 
104
    for _, t in enum_windows():
 
105
        print(" -", t)
 
106
    return None
 
107
 
 
108
def launch_and_position(aliases, cmd, pos, minimize):
 
109
    x, y = pos or (0, 0)
 
110
    hwnd = find_window(aliases)
 
111
    if hwnd:
 
112
        print(f"[REPOSITION] {aliases[0]}; moving to {x},{y}")
 
113
        win32gui.MoveWindow(hwnd, x, y, half_w, half_h, True)
 
114
        if minimize:
 
115
            win32gui.ShowWindow(hwnd, win32con.SW_MINIMIZE)
 
116
        return
 
117
 
 
118
    print(f"[LAUNCH] {aliases[0]} …")
 
119
    subprocess.Popen(cmd, shell=True)
 
120
 
 
121
    for _ in range(50):
 
122
        time.sleep(0.1)
 
123
        hwnd = find_window(aliases)
 
124
        if hwnd:
 
125
            break
 
126
 
 
127
    if not hwnd:
 
128
        print(f"[WARN] couldn’t find window “{aliases[0]}” after launch.")
 
129
        return
 
130
 
 
131
    print(f"[POSITION] {aliases[0]}; moving to {x},{y}")
 
132
    win32gui.MoveWindow(hwnd, x, y, half_w, half_h, True)
 
133
    if minimize:
 
134
        win32gui.ShowWindow(hwnd, win32con.SW_MINIMIZE)
 
135
 
 
136
def main():
 
137
    for aliases, cmd, pos, mini in WINDOWS:
 
138
        launch_and_position(aliases, cmd, pos, mini)
 
139
 
 
140
    aliases, cmd, pos, mini = UPDATER
 
141
    launch_and_position(aliases, cmd, pos, mini)
 
142
 
 
143
if __name__ == "__main__":
 
144
    main()