Skip to content

Commit

Permalink
Abstract differences in handling player and studio
Browse files Browse the repository at this point in the history
  • Loading branch information
pizzaboxer committed Aug 19, 2024
1 parent 765cccf commit d15e910
Show file tree
Hide file tree
Showing 6 changed files with 174 additions and 114 deletions.
63 changes: 63 additions & 0 deletions Bloxstrap/AppData/CommonAppData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Bloxstrap.AppData
{
public abstract class CommonAppData
{
// in case a new package is added, you can find the corresponding directory
// by opening the stock bootstrapper in a hex editor
private IReadOnlyDictionary<string, string> _commonMap { get; } = new Dictionary<string, string>()
{
{ "Libraries.zip", @"" },
{ "shaders.zip", @"shaders\" },
{ "ssl.zip", @"ssl\" },

// the runtime installer is only extracted if it needs installing
{ "WebView2.zip", @"" },
{ "WebView2RuntimeInstaller.zip", @"WebView2RuntimeInstaller\" },

{ "content-avatar.zip", @"content\avatar\" },
{ "content-configs.zip", @"content\configs\" },
{ "content-fonts.zip", @"content\fonts\" },
{ "content-sky.zip", @"content\sky\" },
{ "content-sounds.zip", @"content\sounds\" },
{ "content-textures2.zip", @"content\textures\" },
{ "content-models.zip", @"content\models\" },

{ "content-textures3.zip", @"PlatformContent\pc\textures\" },
{ "content-terrain.zip", @"PlatformContent\pc\terrain\" },
{ "content-platform-fonts.zip", @"PlatformContent\pc\fonts\" },

{ "extracontent-luapackages.zip", @"ExtraContent\LuaPackages\" },
{ "extracontent-translations.zip", @"ExtraContent\translations\" },
{ "extracontent-models.zip", @"ExtraContent\models\" },
{ "extracontent-textures.zip", @"ExtraContent\textures\" },
{ "extracontent-places.zip", @"ExtraContent\places\" },
};

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

public CommonAppData()
{
if (PackageDirectoryMap is null)
{
PackageDirectoryMap = _commonMap;
return;
}

var merged = new Dictionary<string, string>();

foreach (var entry in _commonMap)
merged[entry.Key] = entry.Value;

foreach (var entry in PackageDirectoryMap)
merged[entry.Key] = entry.Value;

PackageDirectoryMap = merged;
}
}
}
23 changes: 23 additions & 0 deletions Bloxstrap/AppData/IAppData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Bloxstrap.AppData
{
internal interface IAppData
{
string ProductName { get; }

string BinaryType { get; }

string RegistryName { get; }

string ExecutableName { get; }

string StartEvent { get; }

IReadOnlyDictionary<string, string> PackageDirectoryMap { get; set; }
}
}
26 changes: 26 additions & 0 deletions Bloxstrap/AppData/RobloxPlayerData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Bloxstrap.AppData
{
public class RobloxPlayerData : CommonAppData, IAppData
{
public string ProductName { get; } = "Roblox";

public string BinaryType { get; } = "WindowsPlayer";

public string RegistryName { get; } = "RobloxPlayer";

public string ExecutableName { get; } = "RobloxPlayerBeta.exe";

public string StartEvent { get; } = "www.roblox.com/robloxStartedEvent";

public override IReadOnlyDictionary<string, string> PackageDirectoryMap { get; set; } = new Dictionary<string, string>()
{
{ "RobloxApp.zip", @"" }
};
}
}
42 changes: 42 additions & 0 deletions Bloxstrap/AppData/RobloxStudioData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Bloxstrap.AppData
{
public class RobloxStudioData : CommonAppData, IAppData
{
public string ProductName { get; } = "Roblox Studio";

public string BinaryType { get; } = "WindowsStudio64";

public string RegistryName { get; } = "RobloxStudio";

public string ExecutableName { get; } = "RobloxStudioBeta.exe";

public string StartEvent { get; } = "www.roblox.com/robloxStudioStartedEvent";

public override IReadOnlyDictionary<string, string> PackageDirectoryMap { get; set; } = new Dictionary<string, string>()
{
{ "RobloxStudio.zip", @"" },
{ "redist.zip", @"" },
{ "LibrariesQt5.zip", @"" },

{ "content-studio_svg_textures.zip", @"content\studio_svg_textures\"},
{ "content-qt_translations.zip", @"content\qt_translations\" },
{ "content-api-docs.zip", @"content\api_docs\" },

{ "extracontent-scripts.zip", @"ExtraContent\scripts\" },

{ "BuiltInPlugins.zip", @"BuiltInPlugins\" },
{ "BuiltInStandalonePlugins.zip", @"BuiltInStandalonePlugins\" },

{ "ApplicationConfig.zip", @"ApplicationConfig\" },
{ "Plugins.zip", @"Plugins\" },
{ "Qml.zip", @"Qml\" },
{ "StudioFonts.zip", @"StudioFonts\" }
};
}
}
46 changes: 20 additions & 26 deletions Bloxstrap/Bootstrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

using Bloxstrap.Integrations;
using Bloxstrap.Resources;
using Bloxstrap.AppData;

namespace Bloxstrap
{
Expand All @@ -24,8 +25,9 @@ public class Bootstrapper

private bool FreshInstall => String.IsNullOrEmpty(_versionGuid);

private string _playerFileName => _launchMode == LaunchMode.Player ? "RobloxPlayerBeta.exe" : "RobloxStudioBeta.exe";
private string _playerLocation => Path.Combine(_versionFolder, _playerFileName);
private IAppData AppData;

private string _playerLocation => Path.Combine(_versionFolder, AppData.ExecutableName);

private string _launchCommandLine = App.LaunchSettings.RobloxLaunchArgs;
private LaunchMode _launchMode = App.LaunchSettings.RobloxLaunchMode;
Expand Down Expand Up @@ -73,8 +75,6 @@ private int _distributionSize
private int _packagesExtracted = 0;
private bool _cancelFired = false;

private IReadOnlyDictionary<string, string> _packageDirectories;

public IBootstrapperDialog? Dialog = null;

public bool IsStudioLaunch => _launchMode != LaunchMode.Player;
Expand All @@ -85,19 +85,17 @@ public Bootstrapper(bool installWebView2)
{
_installWebView2 = installWebView2;

_packageDirectories = _launchMode == LaunchMode.Player ? PackageMap.Player : PackageMap.Studio;
if (_launchMode == LaunchMode.Player)
AppData = new RobloxPlayerData();
else
AppData = new RobloxStudioData();
}

private void SetStatus(string message)
{
App.Logger.WriteLine("Bootstrapper::SetStatus", message);

string productName = "Roblox";

if (_launchMode != LaunchMode.Player)
productName = "Roblox Studio";

message = message.Replace("{product}", productName);
message = message.Replace("{product}", AppData.ProductName);

if (Dialog is not null)
Dialog.Message = message;
Expand Down Expand Up @@ -229,9 +227,7 @@ private async Task CheckLatestVersion()

string channel = "production";

string keyPath = _launchMode == LaunchMode.Player ? "RobloxPlayer" : "RobloxStudio";

using var key = Registry.CurrentUser.CreateSubKey($"SOFTWARE\\ROBLOX Corporation\\Environments\\{keyPath}\\Channel");
using var key = Registry.CurrentUser.CreateSubKey($"SOFTWARE\\ROBLOX Corporation\\Environments\\{AppData.RegistryName}\\Channel");

var match = Regex.Match(App.LaunchSettings.RobloxLaunchArgs, "channel:([a-zA-Z0-9-_]+)", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);

Expand All @@ -246,11 +242,9 @@ private async Task CheckLatestVersion()

ClientVersion clientVersion;

string binaryType = _launchMode == LaunchMode.Player ? "WindowsPlayer" : "WindowsStudio64";

try
{
clientVersion = await RobloxDeployment.GetInfo(channel, binaryType);
clientVersion = await RobloxDeployment.GetInfo(channel, AppData.BinaryType);
}
catch (HttpResponseException ex)
{
Expand All @@ -263,15 +257,15 @@ and not HttpStatusCode.Forbidden
App.Logger.WriteLine(LOG_IDENT, $"Changing channel from {channel} to {RobloxDeployment.DefaultChannel} because HTTP {(int)ex.ResponseMessage.StatusCode}");

channel = RobloxDeployment.DefaultChannel;
clientVersion = await RobloxDeployment.GetInfo(channel, binaryType);
clientVersion = await RobloxDeployment.GetInfo(channel, AppData.BinaryType);
}

if (clientVersion.IsBehindDefaultChannel)
{
App.Logger.WriteLine(LOG_IDENT, $"Changing channel from {channel} to {RobloxDeployment.DefaultChannel} because channel is behind production");

channel = RobloxDeployment.DefaultChannel;
clientVersion = await RobloxDeployment.GetInfo(channel, binaryType);
clientVersion = await RobloxDeployment.GetInfo(channel, AppData.BinaryType);
}

key.SetValue("www.roblox.com", channel);
Expand Down Expand Up @@ -325,13 +319,13 @@ private async Task StartRoblox()

App.Logger.WriteLine(LOG_IDENT, $"Started Roblox (PID {gameClientPid})");

string eventName = _launchMode == LaunchMode.Player ? "www.roblox.com/robloxStartedEvent" : "www.roblox.com/robloxQTStudioStartedEvent";
using (SystemEvent startEvent = new(eventName))
using (var startEvent = new SystemEvent(AppData.StartEvent))
{
bool startEventFired = await startEvent.WaitForEvent();

startEvent.Close();

// TODO: this cannot silently exit like this
if (!startEventFired)
return;
}
Expand Down Expand Up @@ -695,7 +689,7 @@ private async Task InstallLatestVersion()
// move old compatibility flags for the old location
using (RegistryKey appFlagsKey = Registry.CurrentUser.CreateSubKey($"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers"))
{
string oldGameClientLocation = Path.Combine(oldVersionFolder, _playerFileName);
string oldGameClientLocation = Path.Combine(oldVersionFolder, AppData.ExecutableName);
string? appFlags = (string?)appFlagsKey.GetValue(oldGameClientLocation);

if (appFlags is not null)
Expand Down Expand Up @@ -812,7 +806,7 @@ private async Task ApplyModifications()
{
const string LOG_IDENT = "Bootstrapper::ApplyModifications";

if (Process.GetProcessesByName(_playerFileName[..^4]).Any())
if (Process.GetProcessesByName(AppData.ExecutableName[..^4]).Any())
{
App.Logger.WriteLine(LOG_IDENT, "Roblox is running, aborting mod check");
return;
Expand Down Expand Up @@ -958,7 +952,7 @@ private async Task ApplyModifications()
if (modFolderFiles.Contains(fileLocation))
continue;

var package = _packageDirectories.SingleOrDefault(x => x.Value != "" && fileLocation.StartsWith(x.Value));
var package = AppData.PackageDirectoryMap.SingleOrDefault(x => x.Value != "" && fileLocation.StartsWith(x.Value));

// package doesn't exist, likely mistakenly placed file
if (String.IsNullOrEmpty(package.Key))
Expand Down Expand Up @@ -1128,7 +1122,7 @@ private Task ExtractPackage(Package package)
return Task.CompletedTask;

string packageLocation = Path.Combine(Paths.Downloads, package.Signature);
string packageFolder = Path.Combine(_versionFolder, _packageDirectories[package.Name]);
string packageFolder = Path.Combine(_versionFolder, AppData.PackageDirectoryMap[package.Name]);

App.Logger.WriteLine(LOG_IDENT, $"Extracting {package.Name}...");

Expand Down Expand Up @@ -1158,7 +1152,7 @@ private async Task ExtractFileFromPackage(string packageName, string fileName)
if (entry is null)
return;

string extractionPath = Path.Combine(_versionFolder, _packageDirectories[package.Name], entry.FullName);
string extractionPath = Path.Combine(_versionFolder, AppData.PackageDirectoryMap[package.Name], entry.FullName);
entry.ExtractToFile(extractionPath, true);
}
#endregion
Expand Down
Loading

0 comments on commit d15e910

Please sign in to comment.