versionmanager + some more

This commit is contained in:
murdle 2025-05-01 14:24:44 -07:00
commit e220c2e20d
9 changed files with 294 additions and 0 deletions

134
.gitignore vendored Normal file
View File

@ -0,0 +1,134 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
.idea/
# Build results
[Dd]ebug/
[Rr]elease/
x64/
[Bb]in/
[Oo]bj/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.log
*.svclog
*.scc
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# Click-Once directory
publish/
# Publish Web Output
*.Publish.xml
*.pubxml
*.azurePubxml
# NuGet Packages Directory
## TODO: If you have NuGet Package Restore enabled, uncomment the next line
packages/
## TODO: If the tool you use requires repositories.config, also uncomment the next line
!packages/repositories.config
# Windows Azure Build Output
csx/
*.build.csdef
# Windows Store app package directory
AppPackages/
# Others
sql/
*.Cache
ClientBin/
[Ss]tyle[Cc]op.*
![Ss]tyle[Cc]op.targets
~$*
*~
*.dbmdl
*.[Pp]ublish.xml
*.publishsettings
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
App_Data/*.mdf
App_Data/*.ldf
# =========================
# Windows detritus
# =========================
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Mac desktop service store files
.DS_Store
_NCrunch*

6
README.md Normal file
View File

@ -0,0 +1,6 @@
# Roblox Legacy Patcher
## What is this?
This is a C# application which automatically downloads the latest version of Roblox Studio and makes it work on Windows 8.1 and below. It can run natively on Windows 8 and 8.1 with a patch, but a wrapper is also used if you're on Windows 7 due to missing DX apis.
## Notice
Currently, the application only allows you to run Roblox Studio. Because of Roblox's anticheat (aka Hyperion), we have not been able to get the client to work as of right now.

16
RobloxLegacy.sln Normal file
View File

@ -0,0 +1,16 @@

Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RobloxLegacy", "RobloxLegacy\RobloxLegacy.csproj", "{B3AE869E-4EC7-424E-AF85-AAC61974D3A2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B3AE869E-4EC7-424E-AF85-AAC61974D3A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B3AE869E-4EC7-424E-AF85-AAC61974D3A2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B3AE869E-4EC7-424E-AF85-AAC61974D3A2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B3AE869E-4EC7-424E-AF85-AAC61974D3A2}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,7 @@
namespace RobloxLegacy.AppData;
public interface IAppData
{
string Name { get; }
Dictionary<string, string> PackageFiles { get; }
}

View File

@ -0,0 +1,47 @@
namespace RobloxLegacy.AppData;
public class StudioData : IAppData
{
public string Name => "WindowsStudio64";
public Dictionary<string, string> PackageFiles { get; } = new()
{
["RobloxStudio.zip"] = "",
["RibbonConfig.zip"] = "RibbonConfig/",
["redist.zip"] = "",
["Libraries.zip"] = "",
["LibrariesQt5.zip"] = "",
["WebView2.zip"] = "",
["WebView2RuntimeInstaller.zip"] = "",
["shaders.zip"] = "shaders/",
["ssl.zip"] = "ssl/",
["Qml.zip"] = "Qml/",
["Plugins.zip"] = "Plugins/",
["StudioFonts.zip"] = "StudioFonts/",
["BuiltInPlugins.zip"] = "BuiltInPlugins/",
["ApplicationConfig.zip"] = "ApplicationConfig/",
["BuiltInStandalonePlugins.zip"] = "BuiltInStandalonePlugins/",
["content-qt_translations.zip"] = "content/qt_translations/",
["content-sky.zip"] = "content/sky/",
["content-fonts.zip"] = "content/fonts/",
["content-avatar.zip"] = "content/avatar/",
["content-models.zip"] = "content/models/",
["content-sounds.zip"] = "content/sounds/",
["content-configs.zip"] = "content/configs/",
["content-api-docs.zip"] = "content/api_docs/",
["content-textures2.zip"] = "content/textures/",
["content-studio_svg_textures.zip"] = "content/studio_svg_textures/",
["content-platform-fonts.zip"] = "PlatformContent/pc/fonts/",
["content-platform-dictionaries.zip"] = "PlatformContent/pc/shared_compression_dictionaries/",
["content-terrain.zip"] = "PlatformContent/pc/terrain/",
["content-textures3.zip"] = "PlatformContent/pc/textures/",
["extracontent-translations.zip"] = "ExtraContent/translations/",
["extracontent-luapackages.zip"] = "ExtraContent/LuaPackages/",
["extracontent-textures.zip"] = "ExtraContent/textures/",
["extracontent-scripts.zip"] = "ExtraContent/scripts/",
["extracontent-models.zip"] = "ExtraContent/models/"
};
}

3
RobloxLegacy/Program.cs Normal file
View File

@ -0,0 +1,3 @@
// See https://aka.ms/new-console-template for more information
Console.WriteLine("hi");

View File

@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="6.0.0" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,9 @@
namespace RobloxLegacy.Utilities;
public static class Logger
{
public static void Log(string msg)
{
Console.Write($"[+] {msg}");
}
}

View File

@ -0,0 +1,58 @@
using System.Text.Json.Serialization;
using System.IO.Compression;
using RobloxLegacy.AppData;
using RobloxLegacy.Utilities;
namespace RobloxLegacy;
public abstract class VersionData
{
[JsonPropertyName("version")]
public required string Version { get; set; }
[JsonPropertyName("clientVersionUpload")]
public required string UploadHash { get; set; }
}
public class VersionManager(IAppData appData)
{
private static readonly HttpClient Client = new();
private const string CdnUrl = "https://setup.rbxcdn.com";
private static string GetVersionPath(string version)
{
var localAppDataPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
return Path.Combine(localAppDataPath, "Roblox", "Versions", version);
}
private async Task<VersionData?> GetLatestVersion()
{
var url = $"https://clientsettings.roblox.com/v2/client-version/{appData.Name}/channel/LIVE";
var response = await Client.GetAsync(url);
if(!response.IsSuccessStatusCode) // just to be safe
return null;
var version = await response.Content.ReadAsAsync<VersionData>();
return version;
}
private static void ExtractBundle(string version, string folder, Stream file)
{
var extractPath = Path.Combine(GetVersionPath(version), folder);
ZipFile.ExtractToDirectory(file, extractPath);
}
public async Task InstallPackage()
{
var version = await GetLatestVersion();
if(version == null)
throw new Exception("No version data found");
Logger.Log($"Installing {appData.Name} version {version.Version}");
foreach (var file in appData.PackageFiles)
{
var fileName = $"{version.UploadHash}-{file.Key}";
var fileStream = await Client.GetStreamAsync($"{CdnUrl}/{fileName}");
ExtractBundle(version.UploadHash, file.Value, fileStream);
}
}
}