Skip to content
Beta: this is a preview of the new SplitScreen.Me. Data may be reset before launch.

Metal Gear Solid V: The Phantom Pain · handler “Metal Gear Online 3”

Version 2

Release notes

First release 2

Released
Size
27.7 MB
Downloads
386
Check
Verified
SHA-256
eaed6c4edae54f926185c332367507e1f141bca4def9609c694514cb5be40cdc
Download v2 (.nc)All versions

Files 21

PathSize
Metal Gear Solid V/downgrade.xdelta27.4 MB
Metal Gear Solid V/Goldberg SteamEmu Saves/287700/local/MGO_GAME_DATA016 KB
Metal Gear Solid V/Goldberg SteamEmu Saves/287700/local/MGO_GAME_DATA116 KB
Metal Gear Solid V/Goldberg SteamEmu Saves/287700/local/PERSONAL_DATA03.0 KB
Metal Gear Solid V/Goldberg SteamEmu Saves/287700/local/PERSONAL_DATA13.0 KB
Metal Gear Solid V/Goldberg SteamEmu Saves/287700/local/TPP_CONFIG_DATA02.0 KB
Metal Gear Solid V/Goldberg SteamEmu Saves/287700/local/TPP_CONFIG_DATA12.0 KB
Metal Gear Solid V/Goldberg SteamEmu Saves/287700/local/TPP_GRAPHICS_CONFIG762 B
Metal Gear Solid V/Goldberg SteamEmu Saves/287700/remote/MGO_GAME_DATA16 KB
Metal Gear Solid V/Goldberg SteamEmu Saves/287700/remote/PERSONAL_DATA3.0 KB
Metal Gear Solid V/Goldberg SteamEmu Saves/287700/remote/TPP_CONFIG_DATA2.0 KB
Metal Gear Solid V/MGSV_TPP_WideScreen_Patch.cfg1.3 KB
Metal Gear Solid V/MGS_V_Patch.exe109 KB
Metal Gear Solid V/rez.ps15.0 KB
Metal Gear Solid V/WinCrop/WinCrop.deps.json413 B
Metal Gear Solid V/WinCrop/WinCrop.dll8.0 KB
Metal Gear Solid V/WinCrop/WinCrop.exe146 KB
Metal Gear Solid V/WinCrop/WinCrop.pdb12 KB
Metal Gear Solid V/WinCrop/WinCrop.runtimeconfig.json147 B
Metal Gear Solid V/xdelta.exe610 KB
handler.js30 KB

handler.js

Plain text
Hub.Handler.Version = 2; // Released at https://hub.splitscreen.me/ on Mon Mar 11 2024 21:01:07 GMT+0000 (Coordinated Universal Time).
Hub.Handler.Id = "D5QoyqGRxeBETvuRg";
Hub.Maintainer.Name = "happyexpress";
Hub.Maintainer.Id = "yasq5hW6LH5sjwQty";

Game.Description =
  "Requirements: \n" +
  "1. Docker Desktop for Windows https://www.docker.com/products/docker-desktop/ \n" +
  "2. .NET 6.0 Runtime https://dotnet.microsoft.com/en-us/download/dotnet/6.0 \n" +
  "3. MGO3 Server Emulator https://github.com/mxmstr/mgsv_emulator/releases/ \n" +
  " \n" +
  "Steps: \n" +
  "-Add your Nucleus Co-op app folder to your antivirus exclusions. \n" +
  "-Open Docker Desktop. \n" +
  "-Extract MGO3.Server.Emulator.zip and run RunServer.bat. \n" +
  "-Open Nucleus as Administrator. \n" +
  "-Start the handler and wait for each instance to boot and get resized. \n" +
  "-Inputs will lock automatically. Press the End key to unlock them when you want to end the session. \n" +
  "-Once ingame, Player 1 can press Start -> Create Match to create a lobby. \n" +
  "-Everyone else can press Start -> Select Match to join it.";

Game.FileSymlinkExclusions = ["mgsvmgo.exe"];
Game.KillMutex = ["MGO 3.0"];
Game.PartialMutexSearch = true;

Game.GameName = "Metal Gear Solid V - Metal Gear Online 3";
Game.HandlerInterval = 100;
Game.SupportsKeyboard = false;
Game.SymlinkExe = false;
Game.SymlinkGame = true;
// Game.KeepSymLinkOnExit = true;
Game.GUID = "MGSV";
Game.ExecutableName = "mgsvmgo.exe";
Game.MaxPlayers = 16;
Game.MaxPlayersOneMonitor = 8;
Game.Hook.DInputEnabled = false;
Game.UseDInputBlocker = false;
Game.Hook.DInputForceDisable = false;
Game.Hook.XInputEnabled = false;
Game.Hook.XInputReroute = false;
Game.Hook.CustomDllEnabled = false;
Game.XInputPlusDll = [];
// Game.ProcessChangesAtEnd = true;
Game.PauseBetweenStarts = 0;
Game.PauseBetweenContextAndLaunch = 0;
Game.PauseBetweenProcessGrab = 15;
//Game.PromptBetweenInstances = true;

Game.RequiresAdmin = true;
Game.UseNucleusEnvironment = true;
Game.UseGoldberg = true;
Game.SteamID = "287700";
Game.GoldbergNoLocalSave = true;
Game.UserProfileSavePathNoCopy = true;
Game.DocumentsConfigPathNoCopy = true;
Game.ThirdPartyLaunch = true;
Game.IgnoreThirdPartyPrompt = true;
//Game.ForceEnvironmentUse = true;

Game.DontResize = true;
Game.DontReposition = true;
Game.DontRemoveBorders = true;
Game.SetWindowHook = true;
// Game.NotTopMost = true;
// Game.HideDesktop = false;

Game.SupportsMultipleKeyboardsAndMice = true;

Game.HookSetCursorPos = false;
Game.HookGetCursorPos = false;
Game.HookGetKeyState = false;
Game.HookGetAsyncKeyState = false;
Game.HookGetKeyboardState = false;
Game.HookFilterRawInput = false;
Game.HookFilterMouseMessages = false;
Game.HookUseLegacyInput = false;
Game.HookDontUpdateLegacyInMouseMsg = false;
Game.HookMouseVisibility = false;
Game.SendNormalMouseInput = false;
Game.SendNormalKeyboardInput = false;
Game.SendScrollWheel = false;
Game.ForwardRawKeyboardInput = false;
Game.ForwardRawMouseInput = false;
Game.DrawFakeMouseCursor = false;

Game.LockInputAtStart = true;
Game.LockInputSuspendsExplorer = true;
Game.ProtoInput.FreezeExternalInputWhenInputNotLocked = true;
Game.LockInputToggleKey = 0x23;

Game.ProtoInput.InjectStartup = false;
Game.ProtoInput.InjectRuntime_RemoteLoadMethod = false;
Game.ProtoInput.InjectRuntime_EasyHookMethod = true;
Game.ProtoInput.InjectRuntime_EasyHookStealthMethod = false;
Game.ProtoInput.RegisterRawInputHook = true;
Game.ProtoInput.GetRawInputDataHook = true;
Game.ProtoInput.MessageFilterHook = true;
Game.ProtoInput.ClipCursorHook = true;
Game.ProtoInput.FocusHooks = true;
Game.ProtoInput.SendMouseWheelMessages = true;
Game.ProtoInput.SendMouseButtonMessages = true;
Game.ProtoInput.SendMouseMovementMessages = true;
Game.ProtoInput.SendKeyboardButtonMessages = true;
Game.ProtoInput.EnableFocusMessageLoop = false;
Game.ProtoInput.DrawFakeCursor = false;
Game.ProtoInput.BlockedMessages = [0x0008];
Game.ProtoInput.RenameHandlesHook = false;
Game.ProtoInput.RenameHandles = [];
Game.ProtoInput.RenameNamedPipes = [];
Game.ProtoInput.XinputHook = true;
Game.ProtoInput.UseOpenXinput = true;
Game.ProtoInput.UseDinputRedirection = false;
Game.ProtoInput.AutoHideTaskbar = true;

var ResAnswers = ["1080p", "900p", "720p", "576p", "1440p", "2160p"];
var ResValues = [
  [1920, 1080],
  [1600, 900],
  [1280, 720],
  [1024, 576],
  [2560, 1440],
  [3840, 2160]
];
Game.AddOption("Internal Resolution", "Don't use anything below 1080p when using the horizontal 2-player layout, as the cropping won't work correctly.", "InternalResolution", ResAnswers);

var GfxAnswers = ["None", "Low", "Medium", "High"];
Game.AddOption("Graphics Preset", "Set the graphics settings to a preset.", "GraphicsPreset", GfxAnswers);

// depth_of_field | effect | lighting | model_detail | motion_blur_amount | postprocess | shadow | ssao | texture | texture_filtering | volumetric_clouds
const GFXPresets = {
  High: ["Enable", "High", "High", "High", "Large", "High", "High", "High", "High", "High", "Off"],
  Medium: ["Enable", "Low", "Low", "Medium", "Large", "High", "Medium", "Off", "Medium", "Medium", "Off"],
  Low: ["Enable", "Low", "Low", "Low", "Medium", "Low", "Low", "Off", "Low", "Medium", "Off"]
};

var instanceFolder = "";

Game.Play = function() {
  instanceFolder = Context.GetFolder(Nucleus.Folder.InstancedGameFolder);
  var userRoot = Context.EnvironmentPlayer;
  var downgrade = true;
  var InternalResolution = ResValues[ResAnswers.indexOf(Context.Options["InternalResolution"])];

  var GFXPresetOption = Context.Options["GraphicsPreset"];
  var GFXPreset = GFXPresetOption == "None" ? null : GFXPresets[GFXPresetOption];

  const copiedFiles = ["downgrade.xdelta", "xdelta.exe", "MGS_V_Patch.exe", "MGSV_TPP_WideScreen_Patch.cfg"];

  for (let index = 0; index < copiedFiles.length; ++index) {
    const fileName = copiedFiles[index];
    var savePath = instanceFolder + "\\" + fileName;
    var savePkgOrigin = System.IO.Path.Combine(Game.Folder, fileName);
    System.IO.File.Copy(savePkgOrigin, savePath, true);
  }

  // Start the server
  // RunCMD("server", [
  // "cd " + Game.Folder
  // //,"@echo off																									"
  // ,"SETLOCAL EnableDelayedExpansion                                                                          	"
  // ,"                                                                                                         	"
  // ,"REM Check if the container \"mgo\" exists                                                                 "
  // ,"FOR /f \"tokens=*\" %%i IN ('docker ps -a -q --filter \"name=^mgo$\" 2^>nul') DO SET MGO_CONTAINER_ID=%%i "
  // ,"                                                                                                         	"
  // ,"REM If the container does not exist, load the image and create the container                             	"
  // ,"IF \"!MGO_CONTAINER_ID!\"==\"\" (                                                                         "
  // ,"	echo Container \"mgo\" does not exist. Loading image and creating container.                            "
  // ,"	docker load -i mgo.tar                                                                                 	"
  // ,"	docker run -m 512m -d -p 80:80 --name mgo mgo                                                          	"
  // ,") ELSE (                                                                                                 	"
  // ,"	echo Container \"mgo\" already exists. Skipping image load.                                             "
  // ,"	REM Optional: Start the container if it's not running                                                  	"
  // ,"	docker start mgo                                                                                   		"
  // ,")                                                                                                        	"
  // ,"                                                                                                         	"
  // ,"ENDLOCAL                                                                                                 	"
  // ,"PAUSE;"
  // ]);

  if (!System.IO.Directory.Exists(userRoot + "\\AppData\\Roaming\\Goldberg SteamEmu Saves\\287700\\local")) {
    // If this folder doesn't exist, we can assume first time setup needs to be done
    RunCMD("copysaves", ['xcopy /E /I /Y "' + Game.Folder + "\\Goldberg SteamEmu Saves" + '" "' + userRoot + "\\AppData\\Roaming\\Goldberg SteamEmu Saves" + '"']);
    Context.Wait(2000);
  }

  var path = userRoot + "\\AppData\\Roaming\\Goldberg SteamEmu Saves\\287700\\local\\TPP_GRAPHICS_CONFIG";
  var lines = (GFXPreset == null
    ? []
    : [
        '5|         "depth_of_field" : "' + GFXPreset[0] + '",',
        '6|         "effect" : "' + GFXPreset[1] + '",',
        '7|         "lighting" : "' + GFXPreset[2] + '",',
        '8|         "model_detail" : "' + GFXPreset[3] + '",',
        '9|         "motion_blur_amount" : "' + GFXPreset[4] + '",',
        '10|         "postprocess" : "' + GFXPreset[5] + '",',
        '11|         "shadow" : "' + GFXPreset[6] + '",',
        '12|         "ssao" : "' + GFXPreset[7] + '",',
        '13|         "texture" : "' + GFXPreset[8] + '",',
        '14|         "texture_filtering" : "' + GFXPreset[9] + '",',
        '15|         "volumetric_clouds" : "' + GFXPreset[10] + '"'
        //]);
      ]
  ).concat(['21|         "height" : ' + InternalResolution[1] + ",", '23|         "width" : ' + InternalResolution[0] + ",", '24|         "window_mode" : "FullScreenWindowed"']);
  Context.ReplaceLinesInTextFile(path, lines);

  // Downgrade the copied exe to the previous version
  var savePath = instanceFolder + "\\mgsvmgoOld.exe";
  var savePkgOrigin = Context.RootInstallFolder + "\\mgsvmgo.exe";
  System.IO.File.Copy(savePkgOrigin, savePath, true);

  RunCMD(
    "downgrade",
    downgrade
      ? [
          "(xdelta.exe -d -s mgsvmgoOld.exe downgrade.xdelta mgsvmgo.exe);",
          'IF %ERRORLEVEL% NEQ 0 (%SystemRoot%\\Sysnative\\msg.exe * "EXE downgrade failed! Are you sure you have the latest legit Steam version?"); '
          //,"PAUSE;"
        ]
      : ['ren "mgsvmgoOld.exe" "mgsvmgo.exe"']
  );
  Context.Wait(3000);

  var path = instanceFolder + "\\MGSV_TPP_WideScreen_Patch.cfg";
  var lines = ["4|horizontalRes=" + Context.Width, "5|verticalRes=" + Context.Height];
  Context.ReplaceLinesInTextFile(path, lines);

  var url = "http://127.0.0.1:80";
  var urlStartOffset = 0x1271a8;
  var urlEndOffset = 0x1271d7;

  // Apply widescreen patch, apply url patch, start game, wait and then crop window
  RunPowershell(
    "start",
    HexEditFunction.concat([
      "echo 'yes' | .\\MGS_V_Patch.exe",
      "ReplaceHexBlockInExe " + '-filePath "' + instanceFolder + '\\mgsvmgo.exe" ' + '-replacementHex "' + url + '" ' + '-startOffset "' + urlStartOffset + '" ' + '-endOffset "' + urlEndOffset + '" '
    ])
      .concat(SetupEnvironmentFunction)
      .concat([
        "SetupEnvironment -NucleusEnvironmentRoot " + Context.EnvironmentRoot + " -playerNickname " + Context.Nickname,
        '$process = Start-Process -FilePath "mgsvmgo.exe" -PassThru ' + '-ArgumentList " /AppData 99c85cdbf2c837d50d37c82af2c837d5c12d5e80fbc837d5f2c837d5f2c837d5f2 " ',
        "Start-Sleep -Seconds 10",
        '."' + Game.Folder + '\\WinCrop\\WinCrop.exe" $process.Id ' + Context.Width + " " + Context.Height + " " + Context.PosX + " " + Context.PosY
      ])
  );
};

Game.ProtoInput.OnInputLocked = function() {
  for (var i = 0; i < PlayerList.Count; i++) {
    var player = PlayerList[i];

    ProtoInput.InstallHook(player.ProtoInputInstanceHandle, ProtoInput.Values.GetCursorPosHookID);
    ProtoInput.InstallHook(player.ProtoInputInstanceHandle, ProtoInput.Values.SetCursorPosHookID);
    ProtoInput.InstallHook(player.ProtoInputInstanceHandle, ProtoInput.Values.GetKeyStateHookID);
    ProtoInput.InstallHook(player.ProtoInputInstanceHandle, ProtoInput.Values.GetAsyncKeyStateHookID);
    ProtoInput.InstallHook(player.ProtoInputInstanceHandle, ProtoInput.Values.GetKeyboardStateHookID);
    ProtoInput.InstallHook(player.ProtoInputInstanceHandle, ProtoInput.Values.CursorVisibilityStateHookID);

    ProtoInput.InstallHook(player.ProtoInputInstanceHandle, ProtoInput.Values.FocusHooksHookID);

    ProtoInput.EnableMessageFilter(player.ProtoInputInstanceHandle, ProtoInput.Values.RawInputFilterID);

    // Avoid the mouse move filter unless absolutely necessary as it can massively affect performance if the game gets primary input from mouse move moessages
    //ProtoInput.EnableMessageFilter(player.ProtoInputInstanceHandle, ProtoInput.Values.MouseMoveFilterID);

    ProtoInput.EnableMessageFilter(player.ProtoInputInstanceHandle, ProtoInput.Values.MouseActivateFilterID);
    ProtoInput.EnableMessageFilter(player.ProtoInputInstanceHandle, ProtoInput.Values.WindowActivateFilterID);
    ProtoInput.EnableMessageFilter(player.ProtoInputInstanceHandle, ProtoInput.Values.WindowActivateAppFilterID);
    ProtoInput.EnableMessageFilter(player.ProtoInputInstanceHandle, ProtoInput.Values.MouseWheelFilterID);
    ProtoInput.EnableMessageFilter(player.ProtoInputInstanceHandle, ProtoInput.Values.MouseButtonFilterID);
    ProtoInput.EnableMessageFilter(player.ProtoInputInstanceHandle, ProtoInput.Values.KeyboardButtonFilterID);

    ProtoInput.SetDrawFakeCursor(player.ProtoInputInstanceHandle, false);

    ProtoInput.StartFocusMessageLoop(player.ProtoInputInstanceHandle, 5, true, true, true, true, true);

    // Disable the bypass: let the input be processed by Proto Input
    ProtoInput.SetRawInputBypass(player.ProtoInputInstanceHandle, false);
  }
};

Game.ProtoInput.OnInputUnlocked = function() {
  for (var i = 0; i < PlayerList.Count; i++) {
    var player = PlayerList[i];

    ProtoInput.UninstallHook(player.ProtoInputInstanceHandle, ProtoInput.Values.GetCursorPosHookID);
    ProtoInput.UninstallHook(player.ProtoInputInstanceHandle, ProtoInput.Values.SetCursorPosHookID);
    ProtoInput.UninstallHook(player.ProtoInputInstanceHandle, ProtoInput.Values.GetKeyStateHookID);
    ProtoInput.UninstallHook(player.ProtoInputInstanceHandle, ProtoInput.Values.GetAsyncKeyStateHookID);
    ProtoInput.UninstallHook(player.ProtoInputInstanceHandle, ProtoInput.Values.GetKeyboardStateHookID);
    ProtoInput.UninstallHook(player.ProtoInputInstanceHandle, ProtoInput.Values.CursorVisibilityStateHookID);

    // Intentionally disable focus so all the instances don't respond to input at the same time
    ProtoInput.UninstallHook(player.ProtoInputInstanceHandle, ProtoInput.Values.FocusHooksHookID);

    ProtoInput.DisableMessageFilter(player.ProtoInputInstanceHandle, ProtoInput.Values.RawInputFilterID);
    ProtoInput.DisableMessageFilter(player.ProtoInputInstanceHandle, ProtoInput.Values.MouseMoveFilterID);
    ProtoInput.DisableMessageFilter(player.ProtoInputInstanceHandle, ProtoInput.Values.MouseActivateFilterID);
    ProtoInput.DisableMessageFilter(player.ProtoInputInstanceHandle, ProtoInput.Values.WindowActivateFilterID);
    ProtoInput.DisableMessageFilter(player.ProtoInputInstanceHandle, ProtoInput.Values.WindowActivateAppFilterID);
    ProtoInput.DisableMessageFilter(player.ProtoInputInstanceHandle, ProtoInput.Values.MouseWheelFilterID);
    ProtoInput.DisableMessageFilter(player.ProtoInputInstanceHandle, ProtoInput.Values.MouseButtonFilterID);
    ProtoInput.DisableMessageFilter(player.ProtoInputInstanceHandle, ProtoInput.Values.KeyboardButtonFilterID);

    ProtoInput.SetDrawFakeCursor(player.ProtoInputInstanceHandle, false);

    // Intentionally disable focus so all the instances don't respond to input at the same time
    ProtoInput.StopFocusMessageLoop(player.ProtoInputInstanceHandle);

    // Enable the bypass: allow any raw input to pass
    ProtoInput.SetRawInputBypass(player.ProtoInputInstanceHandle, true);
  }
};

function RunCMD(fileName, cmdScript) {
  var cmdFile = instanceFolder + "\\" + fileName + ".bat";
  Context.WriteTextFile(cmdFile, cmdScript);
  Context.RunAdditionalFiles(["all|" + cmdFile], false, 0, true, false);
}

function RunPowershell(fileName, psScript) {
  var psFile = instanceFolder + "\\" + fileName + ".ps1";
  Context.WriteTextFile(psFile, psScript);
  var cmdScript = [
    '%SystemRoot%\\sysnative\\WindowsPowerShell\\v1.0\\powershell.exe -ExecutionPolicy RemoteSigned -command ".\\' + fileName + '.ps1"'
    //,"PAUSE;"
  ];
  RunCMD(fileName, cmdScript);
}

const HexEditFunction = [
  " function ReplaceHexBlockInExe {																",
  "	param (																						",
  "		[string]$filePath,                                                                      ",
  "		[int]$startOffset,                                                                      ",
  "		[int]$endOffset,                                                                        ",
  "		[string]$replacementHex                                                                 ",
  "	)                                                                                           ",
  "                                                                                              ",
  "	if (-not (Test-Path -Path $filePath -PathType Leaf)) {                                      ",
  '		Write-Host "File not found: $filePath"                                                ',
  "		return                                                                                  ",
  "	}                                                                                           ",
  "                                                                                              ",
  "	$binaryData = [System.IO.File]::ReadAllBytes($filePath)                                     ",
  "                                                                                              ",
  "	if ($startOffset -lt 0 -or $startOffset -ge $binaryData.Length -or                          ",
  "		$endOffset -lt 0 -or $endOffset -ge $binaryData.Length -or                              ",
  "		$startOffset -gt $endOffset) {                                                          ",
  '		Write-Host "Invalid range specified."                                                 ',
  "		return                                                                                  ",
  "	}                                                                                           ",
  "                                                                                              ",
  "	$blockLength = $endOffset - $startOffset + 1                                                ",
  "	$zeroBytes = [byte[]]@(0) * $blockLength                                                    ",
  "	$replacementBytes = [System.Text.Encoding]::UTF8.GetBytes($replacementHex)					",
  "	[Array]::Copy($zeroBytes, 0, $binaryData, $startOffset, $blockLength)                       ",
  "	[Array]::Copy($replacementBytes, 0, $binaryData, $startOffset, $replacementBytes.Length)    ",
  "	[System.IO.File]::WriteAllBytes($filePath, $binaryData)                                     ",
  "                                                                                              ",
  '	Write-Host "Hex block replaced and updated in $filePath."									',
  " } 																							"
];

const SetupEnvironmentFunction = [
  " function SetupEnvironment {																			",
  "	param (																								",
  "		[string]$NucleusEnvironmentRoot,                                                                ",
  "		[string]$playerNickname                                                                 		",
  "	)                                                                                           		",
  'Write-Host "Setting up Nucleus environment"                                                         ',
  "                                                                                                      ",
  "$username = $env:USERNAME                                                                             ",
  "                                                                                                      ",
  "try {                                                                                                 ",
  "	$username = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name.Split('\\')[1]           ",
  "} catch {                                                                                             ",
  "	Write-Host \"ERROR - getting current user's username, defaulting to using environment's username\"  ",
  "}                                                                                                     ",
  "                                                                                                      ",
  "# Set environment variables                                                                           ",
  '$env:APPDATA = "$NucleusEnvironmentRoot\\$playerNickname\\AppData\\Roaming"            ',
  '$env:LOCALAPPDATA = "$NucleusEnvironmentRoot\\$playerNickname\\AppData\\Local"         ',
  '$env:USERPROFILE = "$NucleusEnvironmentRoot\\$playerNickname"                          ',
  '$env:HOMEPATH = "Users\\$username\\NucleusCoop\\$playerNickname"                                   ',
  "                                                                                                      ",
  "# Create directories                                                                                  ",
  "$directories = @(                                                                                     ",
  '	"$NucleusEnvironmentRoot",                                                           ',
  '	"$NucleusEnvironmentRoot\\$playerNickname",                                          ',
  '	"$NucleusEnvironmentRoot\\$playerNickname\\AppData\\Roaming",                        ',
  '	"$NucleusEnvironmentRoot\\$playerNickname\\AppData\\Local"                           ',
  ")                                                                                                     ",
  "                                                                                                      ",
  "foreach ($directory in $directories) {                                                                ",
  "	New-Item -ItemType Directory -Force -Path $directory                                                ",
  "}                                                                                                     ",
  "}                                                                                                     "
];

const ResizeWindowFunction = [
  "function ResizeWindow {                                                                                                                          ",
  "	param (                                                                                                                                        ",
  "		[Parameter(Mandatory=$true)]                                                                                                               ",
  "		[int]$ProcessId,                                                                                                                           ",
  "                                                                                                                                                 ",
  "		[Parameter(Mandatory=$true)]                                                                                                               ",
  "		[int]$Left,                                                                                                                                ",
  "                                                                                                                                                 ",
  "		[Parameter(Mandatory=$true)]                                                                                                               ",
  "		[int]$Top,                                                                                                                                 ",
  "                                                                                                                                                 ",
  "		[Parameter(Mandatory=$true)]                                                                                                               ",
  "		[int]$Width,                                                                                                                               ",
  "                                                                                                                                                 ",
  "		[Parameter(Mandatory=$true)]                                                                                                               ",
  "		[int]$Height                                                                                                                               ",
  "	)                                                                                                                                              ",
  "                                                                                                                                                 ",
  "	# Get the process by ID                                                                                                                        ",
  "	$process = Get-Process -Id $ProcessId -ErrorAction SilentlyContinue                                                                            ",
  "                                                                                                                                                 ",
  "	if ($process -ne $null) {                                                                                                                      ",
  "		# Get the window handle                                                                                                                    ",
  "		$hwnd = $process.MainWindowHandle                                                                                                          ",
  "                                                                                                                                                 ",
  "		# Move and resize the window                                                                                                               ",
  "		$result = [User32]::MoveWindow($hwnd, $Left, $Top, $Width, $Height, $true)                                                                 ",
  "                                                                                                                                                 ",
  "		if ($result -eq 0) {                                                                                                                       ",
  '			Write-Host "Window repositioned and resized successfully."                                                                           ',
  "		} else {                                                                                                                                   ",
  '			Write-Host "Failed to reposition and resize the window. Error code: $result"                                                         ',
  "		}                                                                                                                                          ",
  "	} else {                                                                                                                                       ",
  '		Write-Host "Process with ID $ProcessId not found."                                                                                       ',
  "	}                                                                                                                                              ",
  "}                                                                                                                                                ",
  "                                                                                                                                                 ",
  "# Define User32 class for MoveWindow function                                                                                                    ",
  'Add-Type @"                                                                                                                                     ',
  "	using System;                                                                                                                                  ",
  "	using System.Runtime.InteropServices;                                                                                                          ",
  "                                                                                                                                                 ",
  "	public class User32 {                                                                                                                          ",
  '		[DllImport("user32.dll", SetLastError = true)]                                                                                           ',
  "		public static extern int MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, [MarshalAs(UnmanagedType.Bool)] bool bRepaint);    ",
  "	}                                                                                                                                              ",
  '"@                                                                                                                                              '
];