Skip to content

Commit

Permalink
bring back the old roblox version directory (#3908)
Browse files Browse the repository at this point in the history
  • Loading branch information
bluepilledgreat authored Dec 6, 2024
1 parent f4cb8b4 commit 78882ec
Show file tree
Hide file tree
Showing 12 changed files with 106 additions and 102 deletions.
10 changes: 5 additions & 5 deletions Bloxstrap/AppData/CommonAppData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,13 @@ public abstract class CommonAppData
};

public virtual string ExecutableName { get; } = null!;

public virtual string Directory { get; } = null!;

public string LockFilePath => Path.Combine(Directory, "Bloxstrap.lock");
public string Directory => Path.Combine(Paths.Versions, State.VersionGuid);

public string ExecutablePath => Path.Combine(Directory, ExecutableName);


public virtual AppState State { get; } = null!;

public virtual IReadOnlyDictionary<string, string> PackageDirectoryMap { get; set; }


Expand Down
4 changes: 0 additions & 4 deletions Bloxstrap/AppData/IAppData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@ internal interface IAppData

string Directory { get; }

string OldDirectory { get; }

string LockFilePath { get; }

string ExecutablePath { get; }

AppState State { get; }
Expand Down
6 changes: 1 addition & 5 deletions Bloxstrap/AppData/RobloxPlayerData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,7 @@ public class RobloxPlayerData : CommonAppData, IAppData

public override string ExecutableName => "RobloxPlayerBeta.exe";

public override string Directory => Path.Combine(Paths.Roblox, "Player");

public string OldDirectory => Path.Combine(Paths.Roblox, "Player.old");

public AppState State => App.State.Prop.Player;
public override AppState State => App.State.Prop.Player;

public override IReadOnlyDictionary<string, string> PackageDirectoryMap { get; set; } = new Dictionary<string, string>()
{
Expand Down
6 changes: 1 addition & 5 deletions Bloxstrap/AppData/RobloxStudioData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,7 @@ public class RobloxStudioData : CommonAppData, IAppData

public override string ExecutableName => "RobloxStudioBeta.exe";

public override string Directory => Path.Combine(Paths.Roblox, "Studio");

public string OldDirectory => Path.Combine(Paths.Roblox, "Studio.old");

public AppState State => App.State.Prop.Studio;
public override AppState State => App.State.Prop.Studio;

public override IReadOnlyDictionary<string, string> PackageDirectoryMap { get; set; } = new Dictionary<string, string>()
{
Expand Down
4 changes: 2 additions & 2 deletions Bloxstrap/Bloxstrap.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
<UseWPF>true</UseWPF>
<UseWindowsForms>True</UseWindowsForms>
<ApplicationIcon>Bloxstrap.ico</ApplicationIcon>
<Version>2.8.1</Version>
<FileVersion>2.8.1</FileVersion>
<Version>2.8.2</Version>
<FileVersion>2.8.2</FileVersion>
<ApplicationManifest>app.manifest</ApplicationManifest>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
Expand Down
123 changes: 60 additions & 63 deletions Bloxstrap/Bootstrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public class Bootstrapper

private string _launchCommandLine = App.LaunchSettings.RobloxLaunchArgs;
private string _latestVersionGuid = null!;
private string _latestVersionDirectory = null!;
private PackageManifest _versionPackageManifest = null!;

private bool _isInstalling = false;
Expand All @@ -58,7 +59,7 @@ public class Bootstrapper
private double _taskbarProgressMaximum;
private long _totalDownloadedBytes = 0;

private bool _mustUpgrade => String.IsNullOrEmpty(AppData.State.VersionGuid) || File.Exists(AppData.LockFilePath) || !File.Exists(AppData.ExecutablePath);
private bool _mustUpgrade => String.IsNullOrEmpty(AppData.State.VersionGuid) || !File.Exists(AppData.ExecutablePath);
private bool _noConnection = false;

private AsyncMutex? _mutex;
Expand Down Expand Up @@ -313,6 +314,7 @@ private async Task GetLatestVersionInfo()
key.SetValueSafe("www.roblox.com", Deployment.IsDefaultChannel ? "" : Deployment.Channel);

_latestVersionGuid = clientVersion.VersionGuid;
_latestVersionDirectory = Path.Combine(Paths.Versions, _latestVersionGuid);

string pkgManifestUrl = Deployment.GetLocation($"/{_latestVersionGuid}-rbxPkgManifest.txt");
var pkgManifestData = await App.HttpClient.GetStringAsync(pkgManifestUrl);
Expand Down Expand Up @@ -513,18 +515,13 @@ public void Cancel()
try
{
// clean up install
if (Directory.Exists(AppData.Directory))
Directory.Delete(AppData.Directory, true);
if (Directory.Exists(_latestVersionDirectory))
Directory.Delete(_latestVersionDirectory, true);
}
catch (Exception ex)
{
App.Logger.WriteLine(LOG_IDENT, "Could not fully clean up installation!");
App.Logger.WriteException(LOG_IDENT, ex);

// assurance to make sure the next launch does a fresh install
// we probably shouldn't be using the lockfile to do this, but meh
var lockFile = new FileInfo(AppData.LockFilePath);
lockFile.Create().Dispose();
}
}
else if (_appPid != 0)
Expand Down Expand Up @@ -649,69 +646,67 @@ private async Task<bool> CheckForUpdates()

return false;
}
#endregion
#endregion

#region Roblox Install
private async Task UpgradeRoblox()
private void CleanupVersionsFolder()
{
const string LOG_IDENT = "Bootstrapper::UpgradeRoblox";

if (String.IsNullOrEmpty(AppData.State.VersionGuid))
SetStatus(Strings.Bootstrapper_Status_Installing);
else
SetStatus(Strings.Bootstrapper_Status_Upgrading);

Directory.CreateDirectory(Paths.Base);
Directory.CreateDirectory(Paths.Downloads);
Directory.CreateDirectory(Paths.Roblox);
const string LOG_IDENT = "Bootstrapper::CleanupVersionsFolder";

if (Directory.Exists(AppData.Directory))
foreach (string dir in Directory.GetDirectories(Paths.Versions))
{
if (Directory.Exists(AppData.OldDirectory))
Directory.Delete(AppData.OldDirectory, true);
string dirName = Path.GetFileName(dir);

try
{
// test to see if any files are in use
// if you have a better way to check for this, please let me know!
Directory.Move(AppData.Directory, AppData.OldDirectory);
}
catch (Exception ex)
if (dirName != App.State.Prop.Player.VersionGuid && dirName != App.State.Prop.Studio.VersionGuid)
{
App.Logger.WriteLine(LOG_IDENT, "Could not clear old files, aborting update.");
App.Logger.WriteException(LOG_IDENT, ex);

// 0x80070020 is the HRESULT that indicates that a process is still running
// (either RobloxPlayerBeta or RobloxCrashHandler), so we'll silently ignore it
if ((uint)ex.HResult != 0x80070020)
try
{
Directory.Delete(dir, true);
}
catch (IOException ex)
{
// ensure no files are marked as read-only for good measure
foreach (var file in Directory.GetFiles(AppData.Directory, "*", SearchOption.AllDirectories))
Filesystem.AssertReadOnly(file);
App.Logger.WriteLine(LOG_IDENT, $"Failed to delete {dir}");
App.Logger.WriteException(LOG_IDENT, ex);
}
}
}
}

Frontend.ShowMessageBox(
Strings.Bootstrapper_FilesInUse,
_mustUpgrade ? MessageBoxImage.Error : MessageBoxImage.Warning
);
private void MigrateCompatibilityFlags()
{
const string LOG_IDENT = "Bootstrapper::MigrateCompatibilityFlags";

if (_mustUpgrade)
App.Terminate(ErrorCode.ERROR_CANCELLED);
}
string oldClientLocation = Path.Combine(Paths.Versions, AppData.State.VersionGuid, AppData.ExecutableName);
string newClientLocation = Path.Combine(_latestVersionDirectory, AppData.ExecutableName);

return;
}
// move old compatibility flags for the old location
using RegistryKey appFlagsKey = Registry.CurrentUser.CreateSubKey($"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers");
string? appFlags = appFlagsKey.GetValue(oldClientLocation) as string;

Directory.Delete(AppData.OldDirectory, true);
if (appFlags is not null)
{
App.Logger.WriteLine(LOG_IDENT, $"Migrating app compatibility flags from {oldClientLocation} to {newClientLocation}...");
appFlagsKey.SetValueSafe(newClientLocation, appFlags);
appFlagsKey.DeleteValueSafe(oldClientLocation);
}
}

_isInstalling = true;
private async Task UpgradeRoblox()
{
const string LOG_IDENT = "Bootstrapper::UpgradeRoblox";

Directory.CreateDirectory(AppData.Directory);
if (String.IsNullOrEmpty(AppData.State.VersionGuid))
SetStatus(Strings.Bootstrapper_Status_Installing);
else
SetStatus(Strings.Bootstrapper_Status_Upgrading);

Directory.CreateDirectory(Paths.Base);
Directory.CreateDirectory(Paths.Downloads);
Directory.CreateDirectory(Paths.Versions);

_isInstalling = true;

// installer lock, it should only be present while roblox is in the process of upgrading
// if it's present while we're launching, then it's an unfinished install and must be reinstalled
var lockFile = new FileInfo(AppData.LockFilePath);
lockFile.Create().Dispose();
Directory.CreateDirectory(_latestVersionDirectory);

var cachedPackageHashes = Directory.GetFiles(Paths.Downloads).Select(x => Path.GetFileName(x));

Expand Down Expand Up @@ -779,7 +774,7 @@ private async Task UpgradeRoblox()
await Task.WhenAll(extractionTasks);

App.Logger.WriteLine(LOG_IDENT, "Writing AppSettings.xml...");
await File.WriteAllTextAsync(Path.Combine(AppData.Directory, "AppSettings.xml"), AppSettings);
await File.WriteAllTextAsync(Path.Combine(_latestVersionDirectory, "AppSettings.xml"), AppSettings);

if (_cancelTokenSource.IsCancellationRequested)
return;
Expand Down Expand Up @@ -814,7 +809,7 @@ private async Task UpgradeRoblox()
return;
}

string baseDirectory = Path.Combine(AppData.Directory, AppData.PackageDirectoryMap[package.Name]);
string baseDirectory = Path.Combine(_latestVersionDirectory, AppData.PackageDirectoryMap[package.Name]);

ExtractPackage(package);

Expand All @@ -838,13 +833,17 @@ private async Task UpgradeRoblox()

// finishing and cleanup

MigrateCompatibilityFlags();

AppData.State.VersionGuid = _latestVersionGuid;

AppData.State.PackageHashes.Clear();

foreach (var package in _versionPackageManifest)
AppData.State.PackageHashes.Add(package.Name, package.Signature);

CleanupVersionsFolder();

var allPackageHashes = new List<string>();

allPackageHashes.AddRange(App.State.Prop.Player.PackageHashes.Values);
Expand Down Expand Up @@ -885,8 +884,6 @@ private async Task UpgradeRoblox()

App.State.Save();

lockFile.Delete();

_isInstalling = false;
}

Expand Down Expand Up @@ -919,7 +916,7 @@ private async Task ApplyModifications()

const string path = "rbxasset://fonts/CustomFont.ttf";

foreach (string jsonFilePath in Directory.GetFiles(Path.Combine(AppData.Directory, "content\\fonts\\families")))
foreach (string jsonFilePath in Directory.GetFiles(Path.Combine(_latestVersionDirectory, "content\\fonts\\families")))
{
string jsonFilename = Path.GetFileName(jsonFilePath);
string modFilepath = Path.Combine(modFontFamiliesFolder, jsonFilename);
Expand Down Expand Up @@ -980,7 +977,7 @@ private async Task ApplyModifications()
modFolderFiles.Add(relativeFile);

string fileModFolder = Path.Combine(Paths.Modifications, relativeFile);
string fileVersionFolder = Path.Combine(AppData.Directory, relativeFile);
string fileVersionFolder = Path.Combine(_latestVersionDirectory, relativeFile);

if (File.Exists(fileVersionFolder) && MD5Hash.FromFile(fileModFolder) == MD5Hash.FromFile(fileVersionFolder))
{
Expand Down Expand Up @@ -1016,7 +1013,7 @@ private async Task ApplyModifications()
{
App.Logger.WriteLine(LOG_IDENT, $"{fileLocation} was removed as a mod but does not belong to a package");

string versionFileLocation = Path.Combine(AppData.Directory, fileLocation);
string versionFileLocation = Path.Combine(_latestVersionDirectory, fileLocation);

if (File.Exists(versionFileLocation))
File.Delete(versionFileLocation);
Expand Down Expand Up @@ -1204,7 +1201,7 @@ private void ExtractPackage(Package package, List<string>? files = null)
return;
}

string packageFolder = Path.Combine(AppData.Directory, packageDir);
string packageFolder = Path.Combine(_latestVersionDirectory, packageDir);
string? fileFilter = null;

// for sharpziplib, each file in the filter needs to be a regex
Expand Down
14 changes: 14 additions & 0 deletions Bloxstrap/Extensions/RegistryKeyEx.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,19 @@ public static void SetValueSafe(this RegistryKey registryKey, string? name, obje
App.Terminate(ErrorCode.ERROR_INSTALL_FAILURE);
}
}

public static void DeleteValueSafe(this RegistryKey registryKey, string name)
{
try
{
App.Logger.WriteLine("RegistryKeyEx::DeleteValueSafe", $"Deleting {registryKey}\\{name}");
registryKey.DeleteValue(name);
}
catch (UnauthorizedAccessException)
{
Frontend.ShowMessageBox(Strings.Dialog_RegistryWriteError, System.Windows.MessageBoxImage.Error);
App.Terminate(ErrorCode.ERROR_INSTALL_FAILURE);
}
}
}
}
22 changes: 12 additions & 10 deletions Bloxstrap/Installer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -287,8 +287,8 @@ public static void DoUninstall(bool keepData)

() => File.Delete(StartMenuShortcut),

() => Directory.Delete(Paths.Versions, true),
() => Directory.Delete(Paths.Downloads, true),
() => Directory.Delete(Paths.Roblox, true),

() => File.Delete(App.State.FileLocation)
};
Expand Down Expand Up @@ -547,15 +547,6 @@ public static void HandleUpgrade()

App.FastFlags.SetValue("FFlagDisableNewIGMinDUA", null);
App.FastFlags.SetValue("FFlagFixGraphicsQuality", null);

try
{
Directory.Delete(Path.Combine(Paths.Base, "Versions"), true);
}
catch (Exception ex)
{
App.Logger.WriteException(LOG_IDENT, ex);
}
}

if (Utilities.CompareVersions(existingVer, "2.8.1") == VersionComparison.LessThan)
Expand All @@ -572,6 +563,17 @@ public static void HandleUpgrade()
App.FastFlags.SetValue("FFlagEnableInGameMenuChromeABTest4", null);
}

if (Utilities.CompareVersions(existingVer, "2.8.2") == VersionComparison.LessThan)
{
try
{
Directory.Delete(Path.Combine(Paths.Base, "Roblox"), true);
}
catch (Exception ex)
{
App.Logger.WriteException(LOG_IDENT, ex);
}
}

App.Settings.Save();
App.FastFlags.Save();
Expand Down
3 changes: 2 additions & 1 deletion Bloxstrap/Models/Entities/ActivityData.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Web;
using System.Windows;
using System.Windows.Input;
using Bloxstrap.AppData;
using Bloxstrap.Models.APIs;
using CommunityToolkit.Mvvm.Input;

Expand Down Expand Up @@ -149,7 +150,7 @@ public string GetInviteDeeplink(bool launchData = true)

private void RejoinServer()
{
string playerPath = Path.Combine(Paths.Roblox, "Player", "RobloxPlayerBeta.exe");
string playerPath = new RobloxPlayerData().ExecutablePath;

Process.Start(playerPath, GetInviteDeeplink(false));
}
Expand Down
Loading

0 comments on commit 78882ec

Please sign in to comment.