Skip to content

Commit 26c5562

Browse files
committed
feat: Support for Millennium > 2.35.0
1 parent d4201c1 commit 26c5562

5 files changed

Lines changed: 254 additions & 110 deletions

File tree

src/include/semver.h

Lines changed: 8 additions & 28 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/routes/installer.cc

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,9 @@
4444
#include <http.h>
4545
#include <task_scheduler.h>
4646
#include <unzip.h>
47+
#include <semver.h>
4748
#include <atomic>
49+
#include <format>
4850
#include <windows.h>
4951
#include <tlhelp32.h>
5052

@@ -189,6 +191,25 @@ TaskScheduler::TaskResult DownloadReleaseAssets(std::unique_ptr<double>& progres
189191
return { true, "success" };
190192
}
191193

194+
static bool UsesNewInstallLayout(const std::string& tagName)
195+
{
196+
std::string version = tagName;
197+
if (!version.empty() && version[0] == 'v') {
198+
version = version.substr(1);
199+
}
200+
try {
201+
return semver::cmp(version, "2.35.0") > 0;
202+
} catch (...) {
203+
return false;
204+
}
205+
}
206+
207+
static std::string GetLocalAppDataPath()
208+
{
209+
const char* localAppData = std::getenv("LOCALAPPDATA");
210+
return localAppData ? std::string(localAppData) : std::string();
211+
}
212+
192213
TaskScheduler::TaskResult InstallReleaseAssets(std::unique_ptr<double>& progress, const nlohmann::json& releaseInfo, const nlohmann::json& osReleaseInfo,
193214
const std::string& steamPath)
194215
{
@@ -198,7 +219,37 @@ TaskScheduler::TaskResult InstallReleaseAssets(std::unique_ptr<double>& progress
198219
const auto fileName = std::filesystem::temp_directory_path() / osReleaseInfo["name"].get<std::string>();
199220
double currentFileProgress = 0.0;
200221

201-
ExtractZippedArchive(fileName.string().c_str(), steamPath.c_str(), progress.get(), &currentFileProgress);
222+
std::string tagName = releaseInfo.contains("tag_name") ? releaseInfo["tag_name"].get<std::string>() : "";
223+
224+
if (UsesNewInstallLayout(tagName)) {
225+
std::string localAppData = GetLocalAppDataPath();
226+
if (localAppData.empty()) {
227+
return { false, "Failed to resolve %LOCALAPPDATA% path." };
228+
}
229+
230+
auto millenniumPath = std::filesystem::path(localAppData) / "Millennium";
231+
std::filesystem::create_directories(millenniumPath);
232+
233+
ExtractZippedArchive(fileName.string().c_str(), millenniumPath.string().c_str(), progress.get(), &currentFileProgress);
234+
235+
auto source = millenniumPath / "lib" / "millennium.bootstrap64.dll";
236+
auto dest = std::filesystem::path(steamPath) / "wsock32.dll";
237+
238+
if (!std::filesystem::exists(source)) {
239+
return { false, "millennium.bootstrap64.dll not found after extraction." };
240+
}
241+
242+
std::error_code ec;
243+
std::filesystem::remove(dest, ec);
244+
245+
std::filesystem::create_hard_link(source, dest, ec);
246+
if (ec) {
247+
return { false, std::format("Failed to create hardlink: {}", ec.message()) };
248+
}
249+
} else {
250+
ExtractZippedArchive(fileName.string().c_str(), steamPath.c_str(), progress.get(), &currentFileProgress);
251+
}
252+
202253
return { true, "success" };
203254
}
204255

src/routes/uninstall_select.cc

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -108,30 +108,56 @@ ComponentProps MakeComponentProps(std::vector<std::filesystem::path> pathList)
108108

109109
std::vector<std::pair<std::string, std::tuple<ComponentState, ComponentProps>>> uninstallComponents;
110110

111+
static std::filesystem::path GetMillenniumLocalPath()
112+
{
113+
const char* localAppData = std::getenv("LOCALAPPDATA");
114+
if (localAppData) {
115+
return std::filesystem::path(localAppData) / "Millennium";
116+
}
117+
return {};
118+
}
119+
111120
// clang-format off
112121
void InitializeUninstaller()
113122
{
114123
steamPath = GetSteamPath();
124+
auto millenniumLocalPath = GetMillenniumLocalPath();
115125

116126
isUninstalling = false;
117127
uninstallFinished = false;
118128

129+
bool isNewLayout = !millenniumLocalPath.empty() && std::filesystem::exists(millenniumLocalPath);
130+
131+
std::vector<std::filesystem::path> millenniumPaths;
132+
133+
if (isNewLayout) {
134+
// New install (>2.35.0): files in %LOCALAPPDATA%/Millennium + hardlink in Steam
135+
millenniumPaths = {
136+
millenniumLocalPath / "lib",
137+
millenniumLocalPath / "bin",
138+
steamPath / "wsock32.dll",
139+
};
140+
} else {
141+
// Legacy install (<=2.35.0): files in Steam directory
142+
millenniumPaths = {
143+
steamPath / "user32.dll",
144+
steamPath / "version.dll",
145+
steamPath / "wsock32.dll",
146+
steamPath / "ext" / "compat32" / "millennium_x86.dll",
147+
steamPath / "ext" / "compat32" / "python311.dll",
148+
steamPath / "ext" / "compat64" / "millennium_x64.dll",
149+
steamPath / "ext" / "compat64" / "python311.dll",
150+
steamPath / "millennium.hhx64.dll",
151+
steamPath / "millennium.dll",
152+
steamPath / "python311.dll",
153+
};
154+
}
155+
119156
uninstallComponents = {
120-
{ "Millennium", std::make_tuple(ComponentState({ false, true }), MakeComponentProps({
121-
steamPath / "user32.dll",
122-
steamPath / "version.dll",
123-
steamPath / "wsock32.dll",
124-
steamPath / "ext" / "compat32" / "millennium_x86.dll",
125-
steamPath / "ext" / "compat32" / "python311.dll",
126-
steamPath / "ext" / "compat64" / "millennium_x64.dll",
127-
steamPath / "ext" / "compat64" / "python311.dll",
128-
steamPath / "millennium.hhx64.dll",
129-
steamPath / "millennium.dll",
130-
steamPath / "python311.dll"
131-
})) },
132-
{ "Custom Steam Components", std::make_tuple(ComponentState({ false, true }), MakeComponentProps({
133-
steamPath / "ext" / "data" / "assets",
134-
steamPath / "ext" / "data" / "shims"
157+
{ "Millennium", std::make_tuple(ComponentState({ false, true }), MakeComponentProps(millenniumPaths)) },
158+
{ "Custom Steam Components", std::make_tuple(ComponentState({ false, true }), MakeComponentProps({
159+
steamPath / "ext" / "data" / "assets",
160+
steamPath / "ext" / "data" / "shims"
135161
})) },
136162
{ "Dependencies", std::make_tuple(ComponentState({ false, true }), MakeComponentProps({ steamPath / "ext" / "data" / "cache", steamPath / "ext" / "data" / "pyx64" })) },
137163
{ "Themes", std::make_tuple(ComponentState({ false, true }), MakeComponentProps({ steamPath / "steamui" / "skins" })) },

0 commit comments

Comments
 (0)