Skip to content
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
2 changes: 1 addition & 1 deletion MelonLoader.Installer/GameLaunchers/EgsLauncher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public override void AddGames()
if (name == null)
continue;

GameManager.TryAddGame(dir, name, this, null, out _);
GameManager.TryAddGame(dir, null, name, this, null, out _);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion MelonLoader.Installer/GameLaunchers/GogLauncher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public override void AddGames()
if (name == null)
continue;

GameManager.TryAddGame(path, name, this, null, out _);
GameManager.TryAddGame(path, null, name, this, null, out _);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion MelonLoader.Installer/GameLaunchers/SteamLauncher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public override void AddGames()
continue;

var iconPath = Path.Combine(steamPath, "appcache", "librarycache", id + "_icon.jpg");
GameManager.TryAddGame(appDir, name, this, iconPath, out _);
GameManager.TryAddGame(appDir, id, name, this, iconPath, out _);
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions MelonLoader.Installer/GameManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ private static void LoadSavedGames()
{
foreach (var gamePath in Config.LoadGameList())
{
TryAddGame(gamePath, null, null, null, out _);
TryAddGame(gamePath, null, null, null, null, out _);
}

// In case it was manually edited or if any games were removed
Expand Down Expand Up @@ -86,7 +86,7 @@ public static void RemoveGame(GameModel game)
Games.Remove(game);
}

public static GameModel? TryAddGame(string path, string? customName, GameLauncher? launcher, string? iconPath, [NotNullWhen(false)] out string? errorMessage)
public static GameModel? TryAddGame(string path, string? id, string? customName, GameLauncher? launcher, string? iconPath, [NotNullWhen(false)] out string? errorMessage)
{
if (File.Exists(path))
{
Expand Down Expand Up @@ -169,7 +169,7 @@ public static void RemoveGame(GameModel game)

var isProtected = Directory.Exists(Path.Combine(path, "EasyAntiCheat"));

var result = new GameModel(exe, customName ?? Path.GetFileNameWithoutExtension(exe), !is64, linux, launcher, icon, mlVersion, isProtected);
var result = new GameModel(exe, id, customName ?? Path.GetFileNameWithoutExtension(exe), !is64, linux, launcher, icon, mlVersion, isProtected);
errorMessage = null;

AddGameSorted(result);
Expand Down
16 changes: 15 additions & 1 deletion MelonLoader.Installer/MLManager.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Semver;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Text.Json.Nodes;

Expand Down Expand Up @@ -49,9 +50,22 @@ public static async Task<bool> Init()
return true;

inited = await RefreshVersions();

return inited;
}

public static void OpenSteamGameProperties(string? appId)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This class is meant for MelonLoader-related operations only. Move this to the SteamLauncher class

{
if(appId == null){
return;
}

Process.Start(new ProcessStartInfo(){
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please abide by the default coding conventions; fix the nest format

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a try-catch block in case it fails to open for whatever reason

FileName = $"steam://gameproperties/{appId}",
UseShellExecute = true
});
}

private static Task<bool> RefreshVersions()
{
Versions.Clear();
Expand Down Expand Up @@ -332,7 +346,7 @@ public static void SetLocalZip(string zipPath, InstallProgressEventHandler? onPr
onFinished?.Invoke(null);
}

public static async Task InstallAsync(string gameDir, bool removeUserFiles, MLVersion version, bool linux, bool x86, InstallProgressEventHandler? onProgress, InstallFinishedEventHandler? onFinished)
public static async Task InstallAsync(string gameDir, string? id, bool removeUserFiles, MLVersion version, bool linux, bool x86, InstallProgressEventHandler? onProgress, InstallFinishedEventHandler? onFinished)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please rename the id parameter and specify what it's for (ex. gameId)

{
var downloadUrl = linux ? (!x86 ? version.DownloadUrlLinux : null) : (x86 ? version.DownloadUrlWinX86 : version.DownloadUrlWin);
if (downloadUrl == null)
Expand Down
3 changes: 2 additions & 1 deletion MelonLoader.Installer/ViewModels/GameModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@

namespace MelonLoader.Installer.ViewModels;

public class GameModel(string path, string name, bool is32Bit, bool isLinux, GameLauncher? launcher, Bitmap? icon, SemVersion? mlVersion, bool isProtected) : ViewModelBase
public class GameModel(string path, string? id, string name, bool is32Bit, bool isLinux, GameLauncher? launcher, Bitmap? icon, SemVersion? mlVersion, bool isProtected) : ViewModelBase
{
public string Path => path;
public string? Id => id;
public string Name => name;
public bool Is32Bit => is32Bit;
public bool IsLinux => isLinux;
Expand Down
33 changes: 19 additions & 14 deletions MelonLoader.Installer/Views/DetailsView.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -58,26 +58,31 @@
VerticalAlignment="Center" Opacity="0.7" FontSize="14" />
</Grid>
</Grid>

<TextBlock Name="ShowLinuxInstructions" IsEnabled="{Binding !Installing}" Grid.Row="14" Tapped="ShowLinuxInstructionsHandler" HorizontalAlignment="Center" Foreground="Gray" TextDecorations="Underline" FontSize="13" Cursor="Hand" IsVisible="False">
How do I start MelonLoader?
</TextBlock>
</Grid>
<Grid Grid.Row="1" Margin="30" RowDefinitions="auto, *" IsVisible="{Binding LinuxInstructions}">
<TextBlock Grid.Row="0" FontSize="25" Margin="0 0 0 20">Linux Launch Instructions</TextBlock>
<StackPanel Orientation="Vertical" IsVisible="{Binding !Game.IsLinux}" Grid.Row="1">
<TextBlock TextWrapping="Wrap">In order to start MelonLoader under Wine, you'll need to export the following variable:</TextBlock>
<TextBox Margin="0 4 0 10" BorderBrush="Transparent" IsReadOnly="True">WINEDLLOVERRIDES="version=n,b"</TextBox>
<TextBlock TextWrapping="Wrap">On Steam, you can set the launch options to:</TextBlock>
<TextBox Margin="0 4 0 10" BorderBrush="Transparent" IsReadOnly="True">WINEDLLOVERRIDES="version=n,b" %command%"</TextBox>
</StackPanel>
<StackPanel Orientation="Vertical" IsVisible="{Binding Game.IsLinux}" Grid.Row="1">
<TextBlock TextWrapping="Wrap">In order to start MelonLoader, you'll need to export the following variables:</TextBlock>
<TextBox Name="LdLibPathVar" Margin="0 4 0 0" BorderBrush="Transparent" IsReadOnly="True"/>
<TextBox Name="LdPreloadVar" Margin="0 4 0 10" BorderBrush="Transparent" IsReadOnly="True">LD_PRELOAD="libversion.so"</TextBox>
<TextBlock TextWrapping="Wrap">On Steam, you can set the launch options to:</TextBlock>
<TextBox Name="SteamLaunchOptions" Margin="0 4 0 10" BorderBrush="Transparent" IsReadOnly="True"/>
</StackPanel>
<StackPanel Orientation="Vertical" IsVisible="{Binding !Game.IsLinux}" Grid.Row="1">
<TextBlock TextWrapping="Wrap">In order to start MelonLoader under Wine, you'll need to export the following variable:</TextBlock>
<TextBox Margin="0 4 0 10" BorderBrush="Transparent" IsReadOnly="True">WINEDLLOVERRIDES="version=n,b"</TextBox>
<TextBlock TextWrapping="Wrap">On Steam, you can set the launch options to:</TextBlock>
<TextBox Margin="0 4 0 10" BorderBrush="Transparent" IsReadOnly="True">WINEDLLOVERRIDES="version=n,b" %command%</TextBox>
</StackPanel>
<StackPanel Orientation="Vertical" IsVisible="{Binding Game.IsLinux}" Grid.Row="1">
<TextBlock TextWrapping="Wrap">In order to start MelonLoader, you'll need to export the following variables:</TextBlock>
<TextBox Name="LdLibPathVar" Margin="0 4 0 0" BorderBrush="Transparent" IsReadOnly="True"/>
<TextBox Name="LdPreloadVar" Margin="0 4 0 10" BorderBrush="Transparent" IsReadOnly="True">LD_PRELOAD="libversion.so"</TextBox>
<TextBlock TextWrapping="Wrap">On Steam, you can set the launch options to:</TextBlock>
<TextBox Name="SteamLaunchOptions" Margin="0 4 0 10" BorderBrush="Transparent" IsReadOnly="True"/>
</StackPanel>
<Button Grid.Row="2" Click="GamePropsHandler" Name="GamePropsButton"
HorizontalAlignment="Stretch" Background="#383" Height="40"
HorizontalContentAlignment="Center" VerticalContentAlignment="Center"
FontSize="18">Open Steam Game Properties
</Button>
</Grid>
</Grid>
</UserControl>
36 changes: 29 additions & 7 deletions MelonLoader.Installer/Views/DetailsView.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,16 @@ protected override async void OnDataContextChanged(EventArgs e)

if (Model == null)
return;
#if LINUX

#if LINUX
if (Model.Game.IsLinux)
{
LdLibPathVar.Text = $"LD_LIBRARY_PATH=\"{Model.Game.Dir}:$LD_LIBRARY_PATH\"";
SteamLaunchOptions.Text = $"{LdLibPathVar.Text} {LdPreloadVar.Text} %command%";
}

ShowLinuxInstructions.IsVisible = Model.Game.MLInstalled;
#endif
#endif

Model.Game.PropertyChanged += PropertyChangedHandler;

Expand Down Expand Up @@ -138,12 +138,27 @@ private void InstallHandler(object sender, RoutedEventArgs args)
Model.Installing = true;
ShowLinuxInstructions.IsVisible = false;

_ = MLManager.InstallAsync(Path.GetDirectoryName(Model.Game.Path)!, Model.Game.MLInstalled && !KeepFilesCheck.IsChecked!.Value,
_ = MLManager.InstallAsync(Path.GetDirectoryName(Model.Game.Path)!, Model.Game.Id, Model.Game.MLInstalled && !KeepFilesCheck.IsChecked!.Value,
(MLVersion)VersionCombobox.SelectedItem!, Model.Game.IsLinux, Model.Game.Is32Bit,
(progress, newStatus) => Dispatcher.UIThread.Post(() => OnInstallProgress(progress, newStatus)),
(errorMessage) => Dispatcher.UIThread.Post(() => OnOperationFinished(errorMessage)));
}

private void GamePropsHandler(object sender, RoutedEventArgs args)
Copy link
Collaborator

@slxdy slxdy Dec 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keep in mind that the installer supports multiple launchers. Make sure you only show this on Steam games or add support for other launchers

{
if (Model == null || !Model.Game.ValidateGame())
{
MainWindow.Instance.ShowMainView();
return;
}

if(Model.Game.Id != null)
{
MLManager.OpenSteamGameProperties(Model.Game.Id);
}

}

private void OnInstallProgress(double progress, string? newStatus)
{
if (newStatus != null)
Expand All @@ -163,9 +178,9 @@ private void OnOperationFinished(string? errorMessage, bool addedLocalBuild = fa
Model.Game.ValidateGame();
Model.Installing = false;

#if LINUX
ShowLinuxInstructions.IsVisible = Model.Game.MLInstalled;
#endif
#if LINUX
ShowLinuxInstructions.IsVisible = Model.Game.MLInstalled;
#endif

if (errorMessage != null)
{
Expand All @@ -192,6 +207,13 @@ private void OnOperationFinished(string? errorMessage, bool addedLocalBuild = fa
};
}

#if LINUX
if(isInstall && Model.Game.MLInstalled){
Model.LinuxInstructions = true;
}

#endif

DialogBox.ShowNotice("SUCCESS!", $"Successfully {operationType}{((!Model.Game.MLInstalled || isInstall) ? string.Empty : " to")}\nMelonLoader v{(Model.Game.MLInstalled ? Model.Game.MLVersion : currentMLVersion)}");
}

Expand Down
2 changes: 1 addition & 1 deletion MelonLoader.Installer/Views/MainView.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public async void AddGameManuallyHandler(object sender, RoutedEventArgs args)
return;

var path = files[0].Path.LocalPath;
GameManager.TryAddGame(path, null, null, null, out var error);
GameManager.TryAddGame(path, null, null, null, null, out var error);
if (error != null)
{
DialogBox.ShowError(error);
Expand Down