Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Steamdeck / path fixes #7

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .github/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# .github/release.yml

changelog:
exclude:
labels:
- ignore-for-release
# authors:
# - octocat
categories:
- title: Changed temp directory
labels:
- release
49 changes: 45 additions & 4 deletions .github/workflows/dotnet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ on:

jobs:
build:

name: Build Solution
runs-on: ubuntu-latest

steps:
Expand All @@ -27,12 +27,53 @@ jobs:
- name: Run Publish Script
run: cd scripts && ./publish.sh
- name: Upload artifact
uses: actions/upload-artifact@v1.0.0
uses: actions/upload-artifact@v4
with:
name: DayZLauncher-UnixPatcher
path: "./unixpatcher.tar.xz"
- name: Upload artifact
uses: actions/upload-artifact@v1.0.0
uses: actions/upload-artifact@v4
with:
name: DayZLauncher-UnixPatcher-Musl
path: "./unixpatcher-musl.tar.xz"
path: "./unixpatcher-musl.tar.xz"
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: CHANGELOG
path: "./CHANGELOG.txt"

release:
name: Upload Release Assets
needs: build
runs-on: ubuntu-latest
steps:
- name: Download release
uses: actions/download-artifact@v4
with:
name: DayZLauncher-UnixPatcher
- name: Download release-musl
uses: actions/download-artifact@v4
with:
name: DayZLauncher-UnixPatcher-Musl
- name: Download Changelog
uses: actions/download-artifact@v4
with:
name: CHANGELOG
- name: Generate release tag
id: generate_release_tag
uses: alexvingg/[email protected]
with:
github_token: ${{ secrets.CUSTOM_GITHUB_TOKEN }}
tag_prefix: ''
- name: Release with Notes
uses: softprops/action-gh-release@v1
with:
files: |
unixpatcher.tar.xz
unixpatcher-musl.tar.xz
body_path: CHANGELOG.txt
tag_name: ${{ steps.generate_release_tag.outputs.release_tag }}
release_name: Release ${{ steps.generate_release_tag.outputs.release_tag }}
generate_release_notes: true
env:
GITHUB_TOKEN: ${{ secrets.CUSTOM_GITHUB_TOKEN }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore

# User-specific files
.DS_STORE
*.rsuser
*.suo
*.user
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Changes:
- New patch installation script
- Addition - New DayZ absolute path detection function on launch

Fixes:
- Fix for steamdeck - Renamed temp folder (Error rm ./!Linux file not found / can't touch file etc.)
- Fix for steamdeck / external libraries - Now works when game is installed on a different drive (Changed ToUnixPath function)
45 changes: 45 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,50 @@
# DayZLauncher-UnixPatcher

## Fork details
This is a fork of Valters-Tomsons [DayZLauncher-UnixPatcher](https://github.com/valters-tomsons/DayZLauncher-UnixPatcher).

This fork provides a few changes / fixes to the patcher.

##

### Changes
1. Added a patch.sh script to simplify installation (not completed, but usable).
2. Renamed the temp doriectory from `!Linux` to `linux-temp` as some systems wouldn't allow the shell to access the `!Linux` directory (File not found errors).
3. Added a function to locate the absolute path of the DayZ installation.
4. Changed the UnixJunctions function accept any drive letter and use absolute path, this accomodates for cases where the installation is on an external drive / SD card.

### Known issues
1. On some occasions, closing the launcher during a 'preventative sync' causes the launcher to delete the workshop mods and force Steam to redownload them.
2. Verifying the mod signatures sometimes fails. This is due to the Launcher using 'Hash algorithm name' whereas Mono (the wine .Net equivalent) expects a 'Hash algorithm OID' instead. I am not completely sure of the implicarions of this yet.
3. On very rare ocassions the launcher fails to load the patch and displays an error message on launch. Relaunching seems to solve this.
4. Although this does enable workshop functionality it doesn't fix the poor performance of the launcher. If like me you are running a stupid amount of mods it can be very slow to initialize. DO NOT interrupt it or things will get messed up!

### Installation
1. Make sure that you have deleted your compatdata directory and validated game files first!: \
``` (Example) rm -rf /$HOME/.steam/steam/steamapps/compatdata/221100 ``` \
``` (Manually verify game files in steam) ```
2. Download the latest release from here and unzip: \
``` wget https://github.com/djedu/DayZLauncher-UnixPatcher/releases/latest/download/unixpatcher.tar.xz```
``` tar -xvf ./unixpatcher.tar.xz```
3. Change the patch.sh file to be executable: \
``` chmod +x ./unixpatcher/patch.sh ```
4. Run the patch: \
``` ./unixpatcher/patch.sh ```

### Disclaimer
As with the original project, use this at your own risk! \
This patch may cause your mods to vanish and believe me I know the pain, running with over 1300 workshop mods...\
Other issues may happen to the stability of the launcher and game! \
It is not known for this patch to catch battleye's attention as it doesn't modify the game in any way but that could change without notice! \
Again, USE THIS AT YOUR OWN RISK!

### Issues
If you have any issues with any of the modifications I have made please get in touch, but for any other issues please check out the [original repository](https://github.com/valters-tomsons/DayZLauncher-UnixPatcher) first.

##

## Original README:

Provides unofficial fixes for the DayZ launcher when running in Linux/Proton.

Features:
Expand Down
42 changes: 42 additions & 0 deletions scripts/patch.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/bin/bash

# Known directories:
case1="$HOME/.steam/steam/steamapps/common/DayZ/"
case2="/run/media/mmcblk0p1/steamapps/common/DayZ"
case3="/run/media/mmcblk0p1/SteamLibrary/steamapps/common/DayZ"

echo "Make sure you have deleted your compatdata and verified the game files first!"
echo "See https://github.com/djedu/DayZLauncher-UnixPatcher for more information."
echo ""
echo "Starting patch in 5 seconds..."
sleep 5
echo ""

# Set executable:
chmod +x ./bin/DayZLauncher.UnixPatcher

# Patch launcher:
echo "Attempting to patch the DayZ Launcher..."
if [-d "$case1"]
then
echo "DayZ Launcher found at $case1/Launcher"
./DayZLauncher.UnixPatcher "$case1"
exit 0
else if [-d "$case2"]
then
echo "DayZ Launcher found at $case2/Launcher"
./DayZLauncher.UnixPatcher "$case2"
exit 0
else if [-d "$case3"]
then
echo "DayZ Launcher found at $case3/Launcher"
./DayZLauncher.UnixPatcher "$case3"
exit 0
else
echo "DayZ path not found!"
echo "Run the patch manually via a terminal from here by typing:"
echo "./bin/DayZLauncher.UnixPatcher '/Path/To/DayZ/'"
exit 0
fi
echo "Patch failed!"
exit 1
3 changes: 3 additions & 0 deletions scripts/publish.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ dotnet publish -c release -r linux-musl-x64 -o ./publish-musl
mkdir ./release && mkdir ./release/bin
mkdir ./release-musl && mkdir ./release-musl/bin

cp ./scripts/patch.sh ./release/patch.sh
cp ./scripts/patch.sh ./release-musl/patch.sh

mv ./publish/* ./release/bin/
mv ./publish-musl/* ./release-musl/bin/

Expand Down
129 changes: 123 additions & 6 deletions src/DayZLauncher.UnixPatcher.Utils/UnixJunctions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
using System.IO;
using System.Reflection;
using System.Threading;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Linq;


namespace DayZLauncher.UnixPatcher.Utils;

Expand All @@ -15,13 +19,126 @@ namespace DayZLauncher.UnixPatcher.Utils;
public static class UnixJunctions
{
private static bool IsRunningOnMono => Type.GetType("Mono.Runtime") != null;

private static string steamFolder;
private static string steamDrive;
private static string steamPath;
private static string appFolder;
private static string absolutePath;

static UnixJunctions()
{
if (IsRunningOnMono)
{
Console.WriteLine("UnixJunctions: running on Mono runtime!");
}
try
{
List<string> LibraryFolders()
{
string wineFolder = @"C:\Program Files (x86)\Steam\steamapps";
string wineFile = wineFolder + @"\libraryfolders.vdf";
Regex wineRegex = new Regex("[A-Z]:\\\\.[A-z+.]*");
Console.WriteLine("UnixJunctions.LibraryFolders: Searching for Linux Steam installation...");
using (StreamReader reader = new StreamReader(wineFile))
{
string line;
while ((line = reader.ReadLine()) != null)
{
Match match = wineRegex.Match(line);
if (match.Success)
{
steamPath = Regex.Unescape(match.Value).Replace(@"\\", @"\");
Console.WriteLine($"UnixJunctions.LibraryFolders: Found Linux Steam installation folder in: {steamPath}");
break;
}
else
{
Console.WriteLine($"UnixJunctions.LibraryFolders: Error finding Linux Steam installation! Patch may not work correctly!");
}
}
}

List<string> libraryFolders = new List<string>();
string libraryFile = steamPath + @"\steamapps\libraryfolders.vdf";
Regex libraryRegex = new Regex(@"path\x22\s*\x22([A-Za-z0-9+\x2F+\x2D+\x2E]*)\x22");
Console.WriteLine("UnixJunctions.LibraryFolders: Searching for library folders...");
using (StreamReader reader = new StreamReader(libraryFile))
{
string line;
while ((line = reader.ReadLine()) != null)
{
Match match = libraryRegex.Match(line);
if (match.Success)
{
string matchBuild = Regex.Unescape(match.Groups[1].Value) + @"/steamapps/common";
steamFolder = "Z:" + matchBuild.Replace(@"/", @"\");
libraryFolders.Add(steamFolder);
Console.WriteLine($"UnixJunctions.LibraryFolders: Found steam library folder at: {steamFolder}");
}
else
{
Console.WriteLine($"UnixJunctions.LibraryFolders: Error finding library folders! Patch may not work correctly!");
}
}
}
return libraryFolders;
}

string AppFolder()
{
var appFolders = LibraryFolders().Select(x => x);
Console.WriteLine("UnixJunctions.AppFolder: Searching the library for DayZ");
foreach (var folder in appFolders)
{
try
{
Console.Write($"UnixJunctions.AppFolder: Searching for DayZ in {folder}...");
var matches = Directory.GetDirectories(folder, "DayZ");
if (matches.Length >= 1)
{
appFolder = matches[0];
Console.WriteLine($"UnixJunctions.AppFolder: Found app folder: {appFolder}");
return appFolder;
}
else
{
Console.WriteLine($"UnixJunctions.AppFolder: No DayZ installation found in {folder}!");
}
}
catch (DirectoryNotFoundException)
{
Console.WriteLine($"UnixJunctions.AppFolder: No DayZ installation found! Patch may not work correctly!");
//continue;
}

}
return null; // Add a return statement to ensure a value is always returned
}
string dayZPath = AppFolder();
if (dayZPath != null)
{
steamDrive = Path.GetPathRoot(dayZPath).Replace("\\", "");
int start = steamDrive.Length;
int end = dayZPath.IndexOf("\\steamapps");
if (end > start)
{
absolutePath = dayZPath.Substring(start, end - start);
Console.WriteLine($"UnixJunctions.AppFolder: Found DayZ path in {absolutePath}");
}
else
{
Console.WriteLine("UnixJunctions.AppFolder: Invalid DayZ path! Patch may not work correctly!");
}
}
else
{
Console.WriteLine("UnixJunctions.AppFolder: DayZ installation not found! Patch may not work correctly!");
}
}
catch (Exception ex)
{
Console.WriteLine("UnixJunctions: Exception locating DayZ library: " + ex.Message);
}
}

public static void Create(string junctionPoint, string targetDir, bool overwrite)
Expand Down Expand Up @@ -102,7 +219,7 @@ private static string RunShellCommand(string command, string arguments)
Console.WriteLine("UnixJunctions.RunShellCommand: command= " + command + " ;arguments= " + arguments);

var gameLocation = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
var basePath = gameLocation + @"\!Linux";
var basePath = gameLocation + @"\linux-temp";
Directory.CreateDirectory(basePath);

string uniqueId = Guid.NewGuid().ToString("N");
Expand Down Expand Up @@ -140,7 +257,7 @@ private static string RunShellCommand(string command, string arguments)
Console.WriteLine($"UnixJunctions: Error executing script '{uniqueId}'. Exit code: {process.ExitCode}");
}
}

while (!File.Exists(tempOutputPath))
{
Console.WriteLine("UnixJunctions.RunShellCommand: waiting for output file " + uniqueId);
Expand All @@ -152,7 +269,7 @@ private static string RunShellCommand(string command, string arguments)
Console.WriteLine("UnixJunctions.RunShellCommand: waiting for unix write unlock " + uniqueId);
Thread.Sleep(50);
}

// Read the output file
string scriptOutput = File.ReadAllText(tempOutputPath);
Console.WriteLine($"UnixJunctions.RunShellCommand: {uniqueId} output= {scriptOutput}");
Expand All @@ -163,7 +280,7 @@ private static string RunShellCommand(string command, string arguments)

private static string ToUnixPath(string windowsPath)
{
var result = windowsPath.Replace("Z:", string.Empty).Replace("\\", "/");
var result = Regex.Replace(windowsPath, @"[A-Z]:", $"{absolutePath}").Replace("\\", "/");
Console.WriteLine($"UnixJunctions.ToUnixPath: windowsPath='{windowsPath}', result='{result}'");
return result;
}
Expand All @@ -174,4 +291,4 @@ private static string EscapeSingleQuotes(string path)
Console.WriteLine($"UnixJunctions.EscapeSingleQutoes: path='{path}', result='{result}'");
return result;
}
}
}