mirror of
https://github.com/EDCD/EDMarketConnector.git
synced 2025-04-13 15:57:14 +03:00
[1805] Pull In Code from 1808
This commit is contained in:
parent
85f5c3283d
commit
81a3b4fd5f
75
monitor.py
75
monitor.py
@ -15,7 +15,7 @@ import sys
|
||||
import threading
|
||||
from calendar import timegm
|
||||
from collections import defaultdict
|
||||
from os import SEEK_END, SEEK_SET, listdir
|
||||
from os import SEEK_END, SEEK_SET, listdir, environ
|
||||
from os.path import basename, expanduser, getctime, isdir, join
|
||||
from time import gmtime, localtime, mktime, sleep, strftime, strptime, time
|
||||
from typing import TYPE_CHECKING, Any, BinaryIO, MutableMapping
|
||||
@ -35,18 +35,16 @@ MAX_NAVROUTE_DISCREPANCY = 5 # Timestamp difference in seconds
|
||||
MAX_FCMATERIALS_DISCREPANCY = 5 # Timestamp difference in seconds
|
||||
|
||||
if sys.platform == 'win32':
|
||||
import ctypes
|
||||
from ctypes.wintypes import BOOL, HWND, LPARAM
|
||||
import win32process
|
||||
import win32con
|
||||
import win32security
|
||||
import win32gui
|
||||
import win32api
|
||||
|
||||
import pywintypes
|
||||
from watchdog.events import FileSystemEventHandler, FileSystemEvent
|
||||
from watchdog.observers import Observer
|
||||
from watchdog.observers.api import BaseObserver
|
||||
|
||||
EnumWindowsProc = ctypes.WINFUNCTYPE(BOOL, HWND, LPARAM)
|
||||
GetProcessHandleFromHwnd = ctypes.windll.oleacc.GetProcessHandleFromHwnd
|
||||
|
||||
else:
|
||||
# Linux's inotify doesn't work over CIFS or NFS, so poll
|
||||
FileSystemEventHandler = object # dummy
|
||||
@ -113,6 +111,13 @@ class EDLogs(FileSystemEventHandler):
|
||||
# be >= for Live, and < for Legacy.
|
||||
self.live_galaxy_base_version = semantic_version.Version('4.0.0')
|
||||
|
||||
if sys.platform == 'win32':
|
||||
# Get the SID of the user we're running as for later use in
|
||||
# `game_running()`
|
||||
self.user_sid, self.user_domain, self.user_type = win32security.LookupAccountName(
|
||||
None, environ['USERNAME']
|
||||
)
|
||||
|
||||
self.__init_state()
|
||||
|
||||
def __init_state(self) -> None:
|
||||
@ -2123,23 +2128,57 @@ class EDLogs(FileSystemEventHandler):
|
||||
if sys.platform == 'win32':
|
||||
def WindowTitle(h): # noqa: N802
|
||||
if h:
|
||||
length = win32gui.GetWindowTextLength(h) + 1
|
||||
buf = ctypes.create_unicode_buffer(length)
|
||||
if win32gui.GetWindowText(h):
|
||||
return buf.value
|
||||
return win32gui.GetWindowText(h)
|
||||
return None
|
||||
|
||||
def callback(hWnd, lParam): # noqa: N803
|
||||
name = WindowTitle(hWnd)
|
||||
def callback(hwnd, hwnds): # noqa: N803
|
||||
name = WindowTitle(hwnd)
|
||||
if name and name.startswith('Elite - Dangerous'):
|
||||
handle = GetProcessHandleFromHwnd(hWnd)
|
||||
if handle: # If GetProcessHandleFromHwnd succeeds then the app is already running as this user
|
||||
win32api.CloseHandle(handle)
|
||||
return False # stop enumeration
|
||||
# We've found a window that *looks* like an ED game process, but now we need to check
|
||||
# if it's owned by the current user.
|
||||
|
||||
# Get the process_id of the window we found
|
||||
# <https://mhammond.github.io/pywin32/win32process__GetWindowThreadProcessId_meth.html>
|
||||
thread_id, process_id = win32process.GetWindowThreadProcessId(hwnd)
|
||||
|
||||
# Use that to get a process handle
|
||||
# <https://mhammond.github.io/pywin32/win32api__OpenProcess_meth.html>
|
||||
# The first arg can't simply be `0`, and `win32con.PROCESS_TERMINATE` works
|
||||
handle = win32api.OpenProcess(win32con.PROCESS_QUERY_INFORMATION, False, process_id)
|
||||
if handle:
|
||||
# We got the handle OK, now we need a token for it
|
||||
process_token = win32security.OpenProcessToken(handle, win32security.TOKEN_QUERY)
|
||||
# So we can use that to get information about the User
|
||||
token_information, i = win32security.GetTokenInformation(
|
||||
process_token, win32security.TokenUser
|
||||
)
|
||||
# And lastly check if token_information, which should be a PySID object, matches
|
||||
# that of the current user we looked up in `__init__()`.
|
||||
if token_information == self.user_sid:
|
||||
# This can be used to convert the token to username, domain name, and account type
|
||||
# user, domain, name_use = win32security.LookupAccountSid(None, token_information)
|
||||
hwnds.append(hwnd)
|
||||
return False # Indicate window found, so stop iterating
|
||||
|
||||
return True
|
||||
|
||||
return not win32gui.EnumWindows(EnumWindowsProc(callback), 0)
|
||||
# Ref: <http://timgolden.me.uk/python/win32_how_do_i/find-the-window-for-my-subprocess.html>
|
||||
ed_windows: list[int] = []
|
||||
try:
|
||||
win32gui.EnumWindows(callback, ed_windows)
|
||||
|
||||
except pywintypes.error as e:
|
||||
# Ref: <https://lists.archive.carbon60.com/python/python/135503>
|
||||
# Because False is returned in the callback to indicate "found the window, stop
|
||||
# processing", this causes EnumWindows() to return `0`, which is generically
|
||||
# treated as an error, so exception is raised.
|
||||
# So, check the exception's .winerror, and ignore if `0`.
|
||||
if e.winerror != 0:
|
||||
logger.exception("EnumWindows exception:")
|
||||
|
||||
bacon = bool(ed_windows)
|
||||
print(bacon)
|
||||
return bacon
|
||||
|
||||
return False
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user