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

Left 4 Dead 2 · handler “Left 4 Dead 2”

Version 5

Release notes

auto set native splitscreen direction.

Released
Size
302 KB
Downloads
4,109
Check
Verified
SHA-256
11054f4ab2e3e2d6a68d3388a3cd8a6cfbe099699eb71098b500e4a97eb44978
Download v5 (.nc)All versions

Files 2

PathSize
handler.js10 KB
Left4Dead2/571568537.vpk3.9 MB

handler.js

Plain text
Hub.Handler.Version = 5; // Released at https://hub.splitscreen.me/ on Fri Feb 12 2021 22:53:25 GMT+0000 (UTC).
Hub.Handler.Id = "wFsXDjoAkHpL4XZm8";
Hub.Maintainer.Name = "Talos91";
Hub.Maintainer.Id = "eeL7HAz8zJovChWw4";

var answers1 = ["No", "Yes"];
Game.AddOption("Will you use the game's native splitscreen?", "If yes only launch two instances, you need 3 or 4 gamepads.", "Native", answers1);

Game.KillMutex = ["hl2_singleton_mutex"];
Game.DirSymlinkExclusions = ["left4dead2", "left4dead2\\cfg", "left4dead2\\addons", "bin"];
Game.FileSymlinkCopyInstead = ["360controller.cfg"];
Game.FileSymlinkExclusions = ["autoexec.cfg", "video.txt", "config.cfg", "steam_api.dll", "steam_appid.txt", "steam_interfaces.txt", "xinput1_3.dll", "dinput8.dll", "571568537.vpk", "pak01_000.vpk"];
Game.HandlerInterval = 100;
Game.SymlinkExe = false;
Game.SymlinkGame = true;
Game.SymlinkFolders = true;
Game.SupportsKeyboard = true;
Game.ExecutableName = "left4dead2.exe";
Game.SteamID = "550";
Game.GUID = "Left 4 Dead 2";
Game.GameName = "Left 4 Dead 2";
Game.UseNucleusEnvironment = true;
Game.NeedsSteamEmulation = false;
Game.UseGoldberg = true;
Game.GoldbergNoLocalSave = true;
Game.LauncherTitle = "";
Game.WorkingFolder = "bin";
Game.StartArguments = "-steam -window -AlwaysFocus -nointro -novid";
Game.MaxPlayersOneMonitor = 8;
Game.MaxPlayers = 8;
Game.Hook.ForceFocus = false;
Game.Hook.ForceFocusWindowName = "Left 4 Dead 2";
Game.DPIHandling = Nucleus.DPIHandling.InvScaled;
Game.HookFocus = true;
Game.Hook.DInputEnabled = false;
Game.Hook.DInputForceDisable = true;
Game.UseDInputBlocker = true;
Game.Hook.XInputEnabled = true;
Game.Hook.XInputReroute = false;
Game.XInputPlusDll = ["xinput1_3.dll"];
Game.Hook.CustomDllEnabled = false;
Game.UserProfileSavePath = "AppData\\Roaming\\Goldberg SteamEmu Saves\\550\\remote";
Game.UserProfileSavePathNoCopy = true;
Game.PauseBetweenStarts = 25;

Game.Play = function() {
  var saveSrc = System.IO.Path.Combine(Context.RootInstallFolder, "left4dead2\\cfg\\video.txt");
  var savePath = System.IO.Path.Combine(Context.RootFolder, "left4dead2\\cfg\\video.txt");
  Context.ModifySaveFile(saveSrc, savePath, Nucleus.SaveType.CFG, [
    new Nucleus.CfgSaveInfo("config", "setting.fullscreen", "0"),
    new Nucleus.CfgSaveInfo("config", "setting.defaultres", Math.max(640, Context.Width)),
    new Nucleus.CfgSaveInfo("config", "setting.defaultresheight", Math.max(360, Context.Height)),
    new Nucleus.CfgSaveInfo("config", "setting.nowindowborder", "0"),
    new Nucleus.CfgSaveInfo("VideoConfig", "setting.fullscreen", "0"),
    new Nucleus.CfgSaveInfo("VideoConfig", "setting.defaultres", Math.max(640, Context.Width)),
    new Nucleus.CfgSaveInfo("VideoConfig", "setting.defaultresheight", Math.max(360, Context.Height)),
    new Nucleus.CfgSaveInfo("VideoConfig ", "setting.nowindowborder", "0")
  ]);

  //copy config.cfg
  System.IO.File.Copy(System.IO.Path.Combine(Context.RootInstallFolder, "left4dead2\\cfg\\config.cfg"), System.IO.Path.Combine(Context.RootFolder, "left4dead2\\cfg\\config.cfg"), true);

  var autoExec = Context.GetFolder(Nucleus.Folder.InstancedGameFolder) + "\\left4dead2\\cfg\\autoexec.cfg";
  var lines = [
    "engine_no_focus_sleep 0" // unlimited FPS on all screens
  ];

  if (Player.IsKeyboardPlayer) {
    lines.push("joystick 0");
    lines.push("exec undo360controller.cfg");
  } else {
    lines.push("exec 360controller.cfg");
  }

  Context.WriteTextFile(autoExec, lines);

  var native = Context.Options["Native"];

  if (native == "Yes") {
    Game.PromptAfterFirstInstance = true;

    var savePath = (Context.SavePath = Context.GetFolder(Nucleus.Folder.InstancedGameFolder) + "\\left4dead2\\addons\\571568537.vpk");
    var savePkgOrigin = System.IO.Path.Combine(Game.Folder, "571568537.vpk");
    System.IO.File.Copy(savePkgOrigin, savePath, true);

    var txtPath = Context.GetFolder(Nucleus.Folder.InstancedGameFolder) + "\\left4dead2\\cfg\\360controller.cfg";
    var dict = ["60|cmd2 +jlook "];

    Context.ReplaceLinesInTextFile(txtPath, dict);

    if (Player.Owner.IsDualHorizontal()) {
      //patch native splitscreen aspect ratio
      Context.PatchFile(
        System.IO.Path.Combine(Context.RootInstallFolder, "left4dead2\\pak01_000.vpk"),
        System.IO.Path.Combine(Context.RootFolder, "left4dead2\\pak01_000.vpk"),
        [0x09, 0x22, 0x38, 0x20, 0x62, 0x79, 0x20, 0x39],
        [0x09, 0x22, 0x39, 0x20, 0x62, 0x79, 0x20, 0x35]
      );

      if (Context.PlayerID == 0) {
        var autoExec = Context.GetFolder(Nucleus.Folder.InstancedGameFolder) + "\\left4dead2\\cfg\\autoexec.cfg";
        var lines = ["sv_lan 1", "sv_allow_lobby_connect_only 0", "engine_no_focus_sleep 0", "name2 " + Context.Nickname + "-B", "ss_splitmode 0"];
        Context.WriteTextFile(autoExec, lines);

        var savePath = Context.GetFolder(Nucleus.Folder.InstancedGameFolder) + "\\XinputPlus.ini";
        Context.ModifySaveFile(savePath, savePath, Nucleus.SaveType.INI, [
          new Nucleus.IniSaveInfo("ControllerNumber", "Controller1", "1"),
          new Nucleus.IniSaveInfo("ControllerNumber", "Controller2", "2"),
          new Nucleus.IniSaveInfo("ControllerNumber", "Controller3", "0"),
          new Nucleus.IniSaveInfo("ControllerNumber", "Controller4", "0")
        ]);
      }
      if (Context.PlayerID == 1) {
        Context.StartArguments = "-steam -window -AlwaysFocus -nointro -novid -console";

        var autoExec = Context.GetFolder(Nucleus.Folder.InstancedGameFolder) + "\\left4dead2\\cfg\\autoexec.cfg";
        var lines = [
          "sv_lan 1",
          "sv_allow_lobby_connect_only 0",
          "engine_no_focus_sleep 0",
          "name2 " + Context.Nickname + "-B",
          "ss_splitmode 0",
          "connect_splitscreen localhost " + Context.LocalIP + ":27015 2"
        ];
        Context.WriteTextFile(autoExec, lines);

        var savePath = Context.GetFolder(Nucleus.Folder.InstancedGameFolder) + "\\XinputPlus.ini";
        Context.ModifySaveFile(savePath, savePath, Nucleus.SaveType.INI, [
          new Nucleus.IniSaveInfo("ControllerNumber", "Controller1", "3"),
          new Nucleus.IniSaveInfo("ControllerNumber", "Controller2", "4"),
          new Nucleus.IniSaveInfo("ControllerNumber", "Controller3", "0"),
          new Nucleus.IniSaveInfo("ControllerNumber", "Controller4", "0")
        ]);
      }
    }

    if (Player.Owner.IsDualVertical()) {
      Context.PatchFile(
        System.IO.Path.Combine(Context.RootInstallFolder, "left4dead2\\pak01_000.vpk"),
        System.IO.Path.Combine(Context.RootFolder, "left4dead2\\pak01_000.vpk"),
        [0x09, 0x22, 0x38, 0x20, 0x62, 0x79, 0x20, 0x33],
        [0x09, 0x22, 0x37, 0x20, 0x62, 0x79, 0x20, 0x34]
      );

      if (Context.PlayerID == 0) {
        var autoExec = Context.GetFolder(Nucleus.Folder.InstancedGameFolder) + "\\left4dead2\\cfg\\autoexec.cfg";
        var lines = ["sv_lan 1", "sv_allow_lobby_connect_only 0", "engine_no_focus_sleep 0", "name2 " + Context.Nickname + "-B", "ss_splitmode 1"];
        Context.WriteTextFile(autoExec, lines);

        var savePath = Context.GetFolder(Nucleus.Folder.InstancedGameFolder) + "\\XinputPlus.ini";
        Context.ModifySaveFile(savePath, savePath, Nucleus.SaveType.INI, [
          new Nucleus.IniSaveInfo("ControllerNumber", "Controller1", "1"),
          new Nucleus.IniSaveInfo("ControllerNumber", "Controller2", "3"),
          new Nucleus.IniSaveInfo("ControllerNumber", "Controller3", "0"),
          new Nucleus.IniSaveInfo("ControllerNumber", "Controller4", "0")
        ]);
      }
      if (Context.PlayerID == 1) {
        Context.StartArguments = "-steam -window -AlwaysFocus -nointro -novid -console";

        var autoExec = Context.GetFolder(Nucleus.Folder.InstancedGameFolder) + "\\left4dead2\\cfg\\autoexec.cfg";
        var lines = [
          "sv_lan 1",
          "sv_allow_lobby_connect_only 0",
          "engine_no_focus_sleep 0",
          "name2 " + Context.Nickname + "-B",
          "ss_splitmode 1",
          "hud_reloadscheme",
          "connect_splitscreen localhost " + Context.LocalIP + ":27015 2"
        ];
        Context.WriteTextFile(autoExec, lines);

        var savePath = Context.GetFolder(Nucleus.Folder.InstancedGameFolder) + "\\XinputPlus.ini";
        Context.ModifySaveFile(savePath, savePath, Nucleus.SaveType.INI, [
          new Nucleus.IniSaveInfo("ControllerNumber", "Controller1", "2"),
          new Nucleus.IniSaveInfo("ControllerNumber", "Controller2", "4"),
          new Nucleus.IniSaveInfo("ControllerNumber", "Controller3", "0"),
          new Nucleus.IniSaveInfo("ControllerNumber", "Controller4", "0")
        ]);
      }
    }
  }
  if (native == "No") {
    System.IO.File.Copy(System.IO.Path.Combine(Context.RootInstallFolder, "left4dead2\\pak01_000.vpk"), System.IO.Path.Combine(Context.RootFolder, "left4dead2\\pak01_000.vpk"), true);

    if (Player.IsKeyboardPlayer) {
      var savePath = Context.GetFolder(Nucleus.Folder.InstancedGameFolder) + "\\XinputPlus.ini";
      Context.ModifySaveFile(savePath, savePath, Nucleus.SaveType.INI, [
        new Nucleus.IniSaveInfo("ControllerNumber", "Controller1", "0"),
        new Nucleus.IniSaveInfo("ControllerNumber", "Controller2", "0"),
        new Nucleus.IniSaveInfo("ControllerNumber", "Controller3", "0"),
        new Nucleus.IniSaveInfo("ControllerNumber", "Controller4", "0")
      ]);
    } else {
      var savePath = Context.GetFolder(Nucleus.Folder.InstancedGameFolder) + "\\XInputPlus.ini";
      Context.ModifySaveFile(savePath, savePath, Nucleus.SaveType.INI, [
        new Nucleus.IniSaveInfo("ControllerNumber", "Controller1", Context.PlayerID + 1),
        new Nucleus.IniSaveInfo("ControllerNumber", "Controller2", Context.PlayerID + 1),
        new Nucleus.IniSaveInfo("ControllerNumber", "Controller3", Context.PlayerID + 1),
        new Nucleus.IniSaveInfo("ControllerNumber", "Controller4", Context.PlayerID + 1)
      ]);
    }

    if (Context.NumControllers < 5) {
      Game.Hook.XInputReroute = false;
    } else {
      Game.Hook.UseAlpha8CustomDll = true;
      Game.Hook.CustomDllEnabled = true;
    }
  }
};