Add Mass Effect Legendary Edition plugin

All the weird stuff here is done to get around the Origin DRM. The
only way I've found to make MO2 and Origin play nicely together is
to run Origin through MO2. Therefore, the plugin makes sure Origin
is dead when running an executable.

Then because Origin is still alive and hooked by MO2 (probably bad),
it tries to kill Origin after the game is closed. However, the
onFinishedRun callback is only called when all hooked processes are
closed so a a thread is used to monitor the processes.

Psutil is included from PyPi for accessing process data.
This commit is contained in:
Chris Bessent
2021-10-01 18:13:26 -07:00
committed by LostDragonist
parent ed23f47535
commit 10e59f0841
3 changed files with 86 additions and 0 deletions
+81
View File
@@ -0,0 +1,81 @@
from ..basic_game import BasicGame
import mobase
import sys
import psutil
import threading
import time
class MassEffectLegendaryGame(BasicGame):
Name = "Mass Effect Legendary Edition Support Plugin"
Author = "LostDragonist"
Version = "1.0.0"
GameName = "Mass Effect: Legendary Edition"
GameShortName = "masseffectlegendaryedition"
GameBinary = "Game/Launcher/MassEffectLauncher.exe"
GameLauncher = "MassEffectLauncher.exe"
GameDataPath = "%GAME_PATH%"
GameDocumentsDirectory = (
"%USERPROFILE%/Documents/BioWare/Mass Effect Legendary Edition/Save"
)
GameSaveExtension = "pcsav"
GameSteamId = 1328670
def init(self, organizer: mobase.IOrganizer) -> bool:
if not super().init(organizer):
return False
if not self._organizer.onAboutToRun(lambda appName: self._spawnOriginWatcher()):
print("Failed to register onAboutToRun callback!", file=sys.stderr)
return False
if not self._organizer.onFinishedRun(
lambda appName, result: self._stopOriginWatcher()
):
print("Failed to register onFinishedRun callback!", file=sys.stderr)
return False
return True
def _spawnOriginWatcher(self) -> bool:
_killOrigin()
self.worker = threading.Thread(target=_workerFunc)
self.worker.start()
return True
def _stopOriginWatcher(self) -> None:
self.worker.join(10.0)
def _killOrigin():
# Kill Origin if it's alive
for proc in psutil.process_iter():
if proc.name().lower() == "origin.exe":
proc.kill()
def _workerFunc():
gameAliveCount = 300 # Large number to allow Origin and the game to launch
keepGoing = True
while keepGoing:
gameAlive = False
# See if the game is alive
for proc in psutil.process_iter():
if proc.name().lower() in [
"masseffectlauncher.exe",
"masseffect1.exe",
"masseffect2.exe",
"masseffect3.exe",
]:
gameAlive = True
break
if gameAlive:
# Game is alive, sleep and keep monitoring
time.sleep(1)
gameAliveCount = 10
else:
gameAliveCount -= 1
if gameAliveCount <= 0:
_killOrigin()
# Exit the thread
keepGoing = False
+1
View File
@@ -1 +1,2 @@
psutil==5.8.0
vdf==3.4
+4
View File
@@ -16,6 +16,9 @@ sections=FUTURE,STDLIB,THIRDPARTY,MOBASE,FIRSTPARTY,LOCALFOLDER
warn_return_any = True
warn_unused_configs = True
[mypy-psutil.*]
ignore_missing_imports = True
[mypy-vdf.*]
ignore_missing_imports = True
@@ -28,6 +31,7 @@ skip_install = true
deps =
PyQt5-stubs
mobase-stubs
psutil==5.8.0
vdf==3.4
black
flake8