Skip to content

Instantly share code, notes, and snippets.

@imniko
Forked from axxag/borderlands3.js
Last active November 22, 2023 11:13
Show Gist options
  • Save imniko/dcbd9a55b132c65885e9c60f285ff0fe to your computer and use it in GitHub Desktop.
Save imniko/dcbd9a55b132c65885e9c60f285ff0fe to your computer and use it in GitHub Desktop.
Borderlands3-Epic-NucleusCoop. This is a forked version of the original to make the script compatible with latest Epic version.
Game.DirSymlinkExclusions = [
"OakGame\\Binaries\\Win64",
];
Game.FileSymlinkExclusions = [
"steam_api64.dll",
"steam_appid.txt",
"xinput1_3.dll"
];
Game.GameName = "Borderlands 3";
Game.HandlerInterval = 100;
Game.SymlinkExe = false;
Game.SymlinkGame = true;
Game.SymlinkFolders = true;
Game.ExecutableName = "Borderlands3.exe";
Game.SteamID = "397540";
Game.GUID = "Borderlands 3";
Game.MaxPlayers = 4;
Game.MaxPlayersOneMonitor = 4;
Game.BinariesFolder = "OakGame\\Binaries\\Win64";
Game.UseNucleusEnvironment = false;
Game.UseGoldberg = true;
//Game.CreateSteamAppIdByExe = true;
Game.LauncherTitle = "splashscreen";
Game.Hook.ForceFocus = true;
Game.Hook.ForceFocusWindowName = "Borderlands® 3";
Game.SetWindowHook = true;
Game.ResetWindows = true;
Game.RefreshWindowAfterStart = true;
Game.Hook.DInputEnabled = false;
Game.Hook.XInputEnabled = true;
Game.Hook.XInputReroute = false;
Game.Hook.CustomDllEnabled = false;
Game.XInputPlusDll = ["xinput1_3.dll"];
Game.UserProfileConfigPath = "Documents\\My Games\\Borderlands 3\\Saved\\Config\\WindowsNoEditor";
Game.UserProfileSavePath = "Documents\\My Games\\Borderlands 3\\Saved\\SaveGames";
Game.Description = "Only works with the Epic Games version. Right click on borderlands3_preflight.ps1 inside Nucleus handlers folder and click Run with Powershell before running this handler. Go to network options, network mode and select LAN in each instance. If you use keyboards and mice after all the instances open and finish setting up press the END key just once to lock the input for all the instances to have their own cursor and kb. Press the END key again to unlock the input when you finish playing. You can also use CTRL+Q to close Nucleus and all its instances when the input is unlocked. Limit the fps for better performance, you can also alt-tab to the Nucleus app window to even out fps, the game windows will still remain on top.";
Game.PauseBetweenContextAndLaunch = 7;
Game.PauseBetweenStarts = 40;
//USS deprecated options:
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.HookReRegisterRawInput = false;
Game.HookReRegisterRawInputMouse = false;
Game.HookReRegisterRawInputKeyboard = false;
Game.DrawFakeMouseCursor = false;
//ProtoInput:
Game.SupportsMultipleKeyboardsAndMice = true;
Game.ProtoInput.InjectStartup = false;
Game.ProtoInput.InjectRuntime_RemoteLoadMethod = false;
Game.ProtoInput.InjectRuntime_EasyHookMethod = true;
Game.ProtoInput.InjectRuntime_EasyHookStealthMethod = false;
Game.LockInputAtStart = false;
Game.LockInputSuspendsExplorer = true;
Game.ProtoInput.FreezeExternalInputWhenInputNotLocked = false;
Game.LockInputToggleKey = 0x23;
Game.ProtoInput.RenameHandlesHook = false;
Game.ProtoInput.RenameHandles = [];
Game.ProtoInput.RenameNamedPipes = [];
Game.ProtoInput.RegisterRawInputHook = true;
Game.ProtoInput.GetRawInputDataHook = false;
Game.ProtoInput.MessageFilterHook = true;
Game.ProtoInput.GetCursorPosHook = false;
Game.ProtoInput.SetCursorPosHook = false;
Game.ProtoInput.GetKeyStateHook = false;
Game.ProtoInput.GetAsyncKeyStateHook = false;
Game.ProtoInput.GetKeyboardStateHook = false;
Game.ProtoInput.CursorVisibilityHook = false;
Game.ProtoInput.ClipCursorHook = true;
Game.ProtoInput.FocusHooks = false;
Game.ProtoInput.DrawFakeCursor = false;
Game.ProtoInput.FindWindowHook = false;
Game.ProtoInput.RawInputFilter = false;
Game.ProtoInput.MouseMoveFilter = false;
Game.ProtoInput.MouseActivateFilter = false;
Game.ProtoInput.WindowActivateFilter = false;
Game.ProtoInput.WindowActvateAppFilter = false;
Game.ProtoInput.MouseWheelFilter = false;
Game.ProtoInput.MouseButtonFilter = false;
Game.ProtoInput.KeyboardButtonFilter = false;
Game.ProtoInput.SendMouseWheelMessages = true;
Game.ProtoInput.SendMouseButtonMessages = true;
Game.ProtoInput.SendMouseMovementMessages = true;
Game.ProtoInput.SendKeyboardButtonMessages = true;
Game.ProtoInput.XinputHook = false;
Game.ProtoInput.UseOpenXinput = false;
Game.ProtoInput.UseDinputRedirection = false;
Game.ProtoInput.DinputDeviceHook = false;
Game.ProtoInput.DinputHookAlsoHooksGetDeviceState = false;
Game.ProtoInput.EnableFocusMessageLoop = false;
//Game.ProtoInput.FocusLoopIntervalMilliseconds = 40000;
//Game.ProtoInput.FocusLoop_WM_ACTIVATE = true;
//Game.ProtoInput.FocusLoop_WM_ACTIVATEAPP = true;
//Game.ProtoInput.FocusLoop_WM_NCACTIVATE = true;
//Game.ProtoInput.FocusLoop_WM_SETFOCUS = true;
//Game.ProtoInput.FocusLoop_WM_MOUSEACTIVATE = true;
Game.ProtoInput.BlockedMessages = [ 0x0008 ]; // Blocks WM_KILLFOCUS
Game.Play = function () {
var EpicArgs = 'PREFLIGHT_SCRIPT_WILL_REPLACE';
var GameArgs = " -windowed -AlwaysFocus -nosplash" + Context.IsKeyboardPlayer ? " -NoController" : "";
var Args = GameArgs + EpicArgs;
Context.StartArguments = Args;
var savePath = Context.GetFolder(Nucleus.Folder.Documents) + "\\My Games\\Borderlands 3\\Saved\\Config\\WindowsNoEditor\\GameUserSettings.ini";
Context.ModifySaveFile(savePath, savePath, Nucleus.SaveType.INI, [
new Nucleus.IniSaveInfo("/Script/OakGame.OakGameUserSettings", "FullscreenMode", "2"),
new Nucleus.IniSaveInfo("/Script/OakGame.OakGameUserSettings", "ResolutionSizeX", Context.Width),
new Nucleus.IniSaveInfo("/Script/OakGame.OakGameUserSettings", "ResolutionSizeY", Context.Height)
]);
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.GetRawInputDataHookID);
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 messages
//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, true);
ProtoInput.StopFocusMessageLoop(player.ProtoInputInstanceHandle);
}
}
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);
ProtoInput.UninstallHook(player.ProtoInputInstanceHandle, ProtoInput.Values.GetRawInputDataHookID);
ProtoInput.InstallHook(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);
ProtoInput.StartFocusMessageLoop(player.ProtoInputInstanceHandle, 3000, true, true, false, false, false);
}
}
};
$NC_SCRIPT_PATH = ".\Borderlands3.js"
$NC_SCRIPT_REPLACE_STRING = "PREFLIGHT_SCRIPT_WILL_REPLACE"
$EPIC_LOG_PATH = "$env:USERPROFILE\AppData\Local\EpicGamesLauncher\Saved\Logs\EpicGamesLauncher.log"
try {
Write-Host Checking if NC Script file needs launch args
$containsString = Select-String -Path $NC_SCRIPT_PATH -Pattern $NC_SCRIPT_REPLACE_STRING
If ($null -eq $containsString) {
Write-Host "Launch args already added! Skipping..."
exit
}
}
catch {
Write-Error "Unable to open nucleus script file. Quitting..." -ErrorAction Stop
}
try {
Write-Host Checking if epic logs already contain launch args
$Launch_Info = Get-Content $env:USERPROFILE\AppData\Local\EpicGamesLauncher\Saved\Logs\EpicGamesLauncher.log | `
Where-Object { $_ -like '*FCommunityPortalLaunchAppTask: Launching app*Borderlands3.exe*' } | `
Select-Object -First 1
}
catch {
# Cant find args yet
}
if ($null -eq $Launch_Info) {
# Start an instance of Borderlands 3 using the Epic Launcher
try {
Write-Host Args not found yet. Starting Borderlands 3 using Epic Launcher
Start-Process -FilePath "com.epicgames.launcher://apps/Catnip?action=launch&silent=true"
}
catch {
Write-Error "Unable to launch Borderlands 3 using Epic Launcher. Quitting..." -ErrorAction Stop
}
# Get args needed to launch BL3 offline
try {
# Search through Epic Launcher logs to find the launch parameters for Borderlands 3.
Write-Host Finding offline launch arguments
while (($null -eq $Launch_Info ) -or ($null -eq $bl3_process)) {
Start-Sleep -s 1
$bl3_process = Get-Process -name Borderlands3 -ErrorAction SilentlyContinue
$Launch_Info = Get-Content $EPIC_LOG_PATH | `
Where-Object { $_ -like '*FCommunityPortalLaunchAppTask: Launching app*Borderlands3.exe*' } | `
Select-Object -First 1
}
Start-Sleep -s 15
Write-Host Killing Borderlands3
Stop-Process $bl3_process.Id
}
catch {
Write-Error "Unable to get offline args for Borderlands 3. Quitting..." -ErrorAction Stop
}
}
try {
Write-Host Parsing launch args
# Reformat it, split out the binary/args
$null, $bl3_bin = $Launch_Info -split "Launching app "
$bl3_bin = $bl3_bin -replace "'", ""
$bl3_bin, $bl3_arg = $bl3_bin -split "with commandline "
$bl3_bin = $bl3_bin -replace "Borderlands3.exe", "OakGame/Binaries/Win64/Borderlands3.exe"
# Sanity check- make sure binary exists
$null = Test-Path -Path $bl3_bin -ErrorAction stop
Write-Host Found Borderlands 3 args
Write-Host Writing launch args to script
(Get-Content -Path $NC_SCRIPT_PATH) -replace $NC_SCRIPT_REPLACE_STRING, $bl3_arg | Set-Content -Path $NC_SCRIPT_PATH
}
catch {
Write-Error "Unable to write launch args to NC script. Quitting..." -ErrorAction Stop
}
Write-Host All done!
@cholojuanito
Copy link

cholojuanito commented Jan 17, 2023

@Offworlder always hard to say with stuff like that. It sounds like there is a typo or you've modified the borderlands3.js file. Also you should be starting the game from the Nucleus launcher, not running the JS file separately.

Because without running it through the Nucleus launcher this script won't have access to the Game object which the first line references it through

1  Game.DirSymlinkExclusions = [ "OakGame\\Binaries\\Win64"];
    ...

@Querzion
Copy link

Screenshot_1
Since there's something wrong with something. I keep getting this error, when I try to start BL3. Only BL3. Question is now... Should I try to re-install the game a fourth time or start dissecting the messages and reinstall the drivers that seems to have gotten broken?

@SMURFING4GAMES
Copy link

when i drag it into handlers is the thing supposed to be there
Capture

@SMURFING4GAMES
Copy link

cuz its not and thats where i get lost

@imniko
Copy link
Author

imniko commented Nov 22, 2023

I dont have the game installed, sorry that I cant help you guys anymore.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment