Skip to content

Commit e42273d

Browse files
committed
feat: Add Quick CSS tab to Millennium Settings
1 parent e3fb0ac commit e42273d

File tree

21 files changed

+825
-234
lines changed

21 files changed

+825
-234
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@
1111
**/.DS_Store
1212

1313
node_modules/
14-
.vscode/
14+
.vscode/
15+
src\include\millennium\virtfs.h

CMakeLists.txt

Lines changed: 30 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -248,30 +248,6 @@ endif()
248248
# =====================================
249249
# Build Frontend Assets
250250
# =====================================
251-
252-
file(GLOB_RECURSE SDK_SOURCE_FILES
253-
"${CMAKE_CURRENT_SOURCE_DIR}/sdk/**/*"
254-
"${CMAKE_CURRENT_SOURCE_DIR}/sdk/*"
255-
)
256-
# Remove node_modules from SDK source files
257-
list(FILTER SDK_SOURCE_FILES EXCLUDE REGEX ".*/node_modules/.*")
258-
259-
file(GLOB_RECURSE FRONTEND_SOURCE_FILES
260-
"${CMAKE_CURRENT_SOURCE_DIR}/src/frontend/**/*"
261-
"${CMAKE_CURRENT_SOURCE_DIR}/src/frontend/*"
262-
)
263-
# Remove node_modules from frontend source files
264-
list(FILTER FRONTEND_SOURCE_FILES EXCLUDE REGEX ".*/node_modules/.*")
265-
266-
# Add all source files as configure dependencies
267-
foreach(file ${SDK_SOURCE_FILES})
268-
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${file}")
269-
endforeach()
270-
271-
foreach(file ${FRONTEND_SOURCE_FILES})
272-
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${file}")
273-
endforeach()
274-
275251
# Find pnpm executable
276252
find_program(PNPM_EXECUTABLE pnpm)
277253
if(NOT PNPM_EXECUTABLE)
@@ -301,6 +277,9 @@ endif()
301277
# =========================
302278
# Build SDK
303279
# =========================
280+
281+
if (CMAKE_BUILD_TYPE STREQUAL "Release")
282+
304283
message(STATUS "[Millennium] Building SDK with ${PNPM_COMMAND}...")
305284
execute_process(
306285
COMMAND ${PNPM_COMMAND} install
@@ -365,6 +344,7 @@ if(NOT FRONTEND_BUILD_RESULT EQUAL 0)
365344
endif()
366345

367346
message(STATUS "[Millennium] Frontend build completed successfully")
347+
endif()
368348

369349
# =====================================
370350
# Platform-Specific Compiler Flags
@@ -627,9 +607,7 @@ endif()
627607
function(filename_to_identifier filename output_var)
628608
get_filename_component(name_without_ext "${filename}" NAME_WE)
629609
string(TOUPPER "${name_without_ext}" upper_name)
630-
631610
string(REGEX REPLACE "[-.]" "_" clean_name "${upper_name}")
632-
633611
if(filename MATCHES "\\.map$")
634612
set(${output_var} "MILLENNIUM_${clean_name}_MAP_" PARENT_SCOPE)
635613
else()
@@ -638,15 +616,17 @@ function(filename_to_identifier filename output_var)
638616
endfunction()
639617

640618
file(GLOB CHUNK_FILES "${CMAKE_SOURCE_DIR}/sdk/typescript-packages/loader/build/chunks/*")
641-
642619
set(HEADER_CONTENT "/**\n * Auto-generated by Millennium during CMake configuration - do not edit manually :)\n */\n")
643-
set(HEADER_CONTENT "${HEADER_CONTENT}#define INCBIN_PREFIX\n")
644-
set(HEADER_CONTENT "${HEADER_CONTENT}#include \"incbin.h\"\n")
645-
set(HEADER_CONTENT "${HEADER_CONTENT}/** Millennium frontend library -- responsible for displaying Millennium UI, and loading themes */\n")
646-
set(HEADER_CONTENT "${HEADER_CONTENT}INCTXT(MILLENNIUM_FRONTEND_BIN_, \"../../../build/frontend.bin\");\n\n")
647-
set(HEADER_CONTENT "${HEADER_CONTENT}/** Millennium API library */\n")
648-
set(HEADER_CONTENT "${HEADER_CONTENT}INCTXT(MILLENNIUM_API_BIN_, \"../../../sdk/typescript-packages/loader/build/millennium.js\");\n")
649-
set(HEADER_CONTENT "${HEADER_CONTENT}/** Millennium API chunk files */\n")
620+
621+
if(CMAKE_BUILD_TYPE STREQUAL "Release")
622+
set(HEADER_CONTENT "${HEADER_CONTENT}#define INCBIN_PREFIX\n")
623+
set(HEADER_CONTENT "${HEADER_CONTENT}#include \"incbin.h\"\n")
624+
set(HEADER_CONTENT "${HEADER_CONTENT}/** Millennium frontend library -- responsible for displaying Millennium UI, and loading themes */\n")
625+
set(HEADER_CONTENT "${HEADER_CONTENT}INCTXT(MILLENNIUM_FRONTEND_BIN_, \"../../../build/frontend.bin\");\n\n")
626+
set(HEADER_CONTENT "${HEADER_CONTENT}/** Millennium API library */\n")
627+
set(HEADER_CONTENT "${HEADER_CONTENT}INCTXT(MILLENNIUM_API_BIN_, \"../../../sdk/typescript-packages/loader/build/millennium.js\");\n")
628+
set(HEADER_CONTENT "${HEADER_CONTENT}/** Millennium API chunk files */\n")
629+
endif()
650630

651631
set(MAP_ENTRIES "")
652632
foreach(chunk_file ${CHUNK_FILES})
@@ -657,16 +637,26 @@ foreach(chunk_file ${CHUNK_FILES})
657637
file(RELATIVE_PATH rel_path "${CMAKE_SOURCE_DIR}" "${chunk_file}")
658638
filename_to_identifier("${filename}" var_name)
659639

660-
set(HEADER_CONTENT "${HEADER_CONTENT}INCTXT(${var_name}, \"../../../${rel_path}\");\n")
661-
set(MAP_ENTRIES "${MAP_ENTRIES}\t{ fmt::format(\"https://millennium.ftp/{}/chunks/${filename}\", GetScrambledApiPathToken()), ${var_name}Data },\n")
640+
if(CMAKE_BUILD_TYPE STREQUAL "Release")
641+
set(HEADER_CONTENT "${HEADER_CONTENT}INCTXT(${var_name}, \"../../../${rel_path}\");\n")
642+
set(MAP_ENTRIES "${MAP_ENTRIES}\t{ fmt::format(\"https://millennium.ftp/{}/chunks/${filename}\", GetScrambledApiPathToken()), []() { return ${var_name}Data; } },\n")
643+
else()
644+
set(MAP_ENTRIES "${MAP_ENTRIES}\t{ fmt::format(\"https://millennium.ftp/{}/chunks/${filename}\", GetScrambledApiPathToken()), []() { return SystemIO::ReadFileSync(MILLENNIUM_ROOT \"/${rel_path}\"); } },\n")
645+
endif()
662646
endforeach()
663647

664648
set(HEADER_CONTENT "${HEADER_CONTENT}\n// clang-format off\n")
665-
set(HEADER_CONTENT "${HEADER_CONTENT}std::unordered_map<std::string, const char*> INTERNAL_FTP_CALL_DATA = {\n")
666-
set(HEADER_CONTENT "${HEADER_CONTENT}\t{ fmt::format(\"https://millennium.ftp/{}/millennium-frontend.js\", GetScrambledApiPathToken()), MILLENNIUM_FRONTEND_BIN_Data },\n")
667-
set(HEADER_CONTENT "${HEADER_CONTENT}\t{ fmt::format(\"https://millennium.ftp/{}/millennium.js\", GetScrambledApiPathToken()), MILLENNIUM_API_BIN_Data },\n")
668-
set(HEADER_CONTENT "${HEADER_CONTENT}${MAP_ENTRIES}")
649+
set(HEADER_CONTENT "${HEADER_CONTENT}std::unordered_map<std::string, std::function<const std::string()>> INTERNAL_FTP_CALL_DATA = {\n")
650+
651+
if(CMAKE_BUILD_TYPE STREQUAL "Release")
652+
set(HEADER_CONTENT "${HEADER_CONTENT}\t{ fmt::format(\"https://millennium.ftp/{}/millennium-frontend.js\", GetScrambledApiPathToken()), []() { return MILLENNIUM_FRONTEND_BIN_Data; } },\n")
653+
set(HEADER_CONTENT "${HEADER_CONTENT}\t{ fmt::format(\"https://millennium.ftp/{}/millennium.js\", GetScrambledApiPathToken()), []() { return MILLENNIUM_API_BIN_Data; } },\n")
654+
else()
655+
set(HEADER_CONTENT "${HEADER_CONTENT}\t{ fmt::format(\"https://millennium.ftp/{}/millennium-frontend.js\", GetScrambledApiPathToken()), []() { return SystemIO::ReadFileSync(MILLENNIUM_ROOT \"/build/frontend.bin\"); } },\n")
656+
set(HEADER_CONTENT "${HEADER_CONTENT}\t{ fmt::format(\"https://millennium.ftp/{}/millennium.js\", GetScrambledApiPathToken()), []() { return SystemIO::ReadFileSync(MILLENNIUM_ROOT \"/sdk/typescript-packages/loader/build/millennium.js\"); } },\n")
657+
endif()
669658

659+
set(HEADER_CONTENT "${HEADER_CONTENT}${MAP_ENTRIES}")
670660
string(REGEX REPLACE ",\n$" "\n" HEADER_CONTENT "${HEADER_CONTENT}")
671661
set(HEADER_CONTENT "${HEADER_CONTENT}};\n")
672662
set(HEADER_CONTENT "${HEADER_CONTENT}// clang-format on\n")

src/backend/entry_point.cc

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,17 @@ int GetOperatingSystemType()
5757
#endif
5858
}
5959

60+
std::string Millennium_GetQuickCss()
61+
{
62+
const std::string quickCssPath = fmt::format("{}/quickcss.css", GetEnv("MILLENNIUM__CONFIG_PATH"));
63+
64+
if (!std::filesystem::exists(quickCssPath)) {
65+
SystemIO::WriteFileSync(quickCssPath, "/* Quick CSS file created by Millennium */\n");
66+
}
67+
68+
return SystemIO::ReadFileSync(quickCssPath);
69+
}
70+
6071
/**
6172
* Enable/disable plugins
6273
*/
@@ -96,10 +107,15 @@ MILLENNIUM_IPC_DECL(Core_GetStartConfig)
96107
{ "buildDate", GetBuildTimestamp() },
97108
{ "millenniumUpdates", nlohmann::json::object() },
98109
{ "platformType", GetOperatingSystemType() },
99-
{ "millenniumLinuxUpdateScript", GetEnv("MILLENNIUM_UPDATE_SCRIPT_PROMPT") }
110+
{ "millenniumLinuxUpdateScript", GetEnv("MILLENNIUM_UPDATE_SCRIPT_PROMPT") },
111+
{ "quickCss", Millennium_GetQuickCss() }
100112
};
101113
}
102114

115+
/** Quick CSS utilities */
116+
IPC_RET(Core_LoadQuickCss, Millennium_GetQuickCss());
117+
IPC_NIL(Core_SaveQuickCss, SystemIO::WriteFileSync(fmt::format("{}/quickcss.css", GetEnv("MILLENNIUM__CONFIG_PATH")), ARGS["css"].get<std::string>()));
118+
103119
/** General utilities */
104120
IPC_RET(Core_GetSteamPath, SystemIO::GetSteamPath())
105121
IPC_RET(Core_FindAllThemes, Millennium::Themes::FindAllThemes())

src/core/http_hook.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ void HttpHookManager::RetrieveRequestFromDisk(const nlohmann::basic_json<>& mess
320320
auto it = INTERNAL_FTP_CALL_DATA.find(strRequestFile);
321321
if (it != INTERNAL_FTP_CALL_DATA.end()) {
322322
fileType = eFileType::js;
323-
fileContent = Base64Encode(it->second);
323+
fileContent = Base64Encode(it->second());
324324

325325
}
326326
/** Handle normal disk request */

src/core/millennium_updater.cc

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,17 @@ void MillenniumUpdater::DeleteOldMillenniumVersion()
227227
#endif
228228
}
229229

230+
void RateLimitedLogger(const std::string& message, const double& progress)
231+
{
232+
static auto last_call = std::chrono::steady_clock::now() - std::chrono::seconds(2);
233+
auto now = std::chrono::steady_clock::now();
234+
235+
if (std::chrono::duration_cast<std::chrono::seconds>(now - last_call).count() > 1) {
236+
IpcForwardInstallLog({ message, progress, false });
237+
last_call = now;
238+
}
239+
}
240+
230241
void MillenniumUpdater::Co_BeginUpdate(const std::string& downloadUrl, const size_t downloadSize)
231242
{
232243
try {
@@ -238,25 +249,13 @@ void MillenniumUpdater::Co_BeginUpdate(const std::string& downloadUrl, const siz
238249
Http::DownloadWithProgress({ downloadUrl, downloadSize }, tempFilePath, [](size_t downloaded, size_t total)
239250
{
240251
const double progress = (static_cast<double>(downloaded) / total) * 50.0;
241-
static auto last_call = std::chrono::steady_clock::now() - std::chrono::seconds(2);
242-
auto now = std::chrono::steady_clock::now();
243-
244-
if (std::chrono::duration_cast<std::chrono::seconds>(now - last_call).count() > 1) {
245-
IpcForwardInstallLog({ "Downloading update assets...", progress, false });
246-
last_call = now;
247-
}
252+
RateLimitedLogger("Downloading update assets...", progress);
248253
});
249254

250255
Util::ExtractZipArchive(tempFilePath.string(), SystemIO::GetInstallPath().generic_string(), [](int current, int total, const char* file)
251256
{
252257
const double progress = 50.0 + (static_cast<double>(current) / total) * 50.0;
253-
static auto last_call = std::chrono::steady_clock::now() - std::chrono::seconds(2);
254-
auto now = std::chrono::steady_clock::now();
255-
256-
if (std::chrono::duration_cast<std::chrono::seconds>(now - last_call).count() > 1) {
257-
IpcForwardInstallLog({ fmt::format("Processing update file {}/{}", current, total), progress, false });
258-
last_call = now;
259-
}
258+
RateLimitedLogger(fmt::format("Processing update file {}/{}", current, total), progress);
260259
});
261260

262261
/** Remove the temporary file after installation */

src/frontend/components/Icons.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,11 @@ const MillenniumIcons = {
5555
</g>
5656
</svg>
5757
),
58+
RabbitRunning: () => (
59+
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
60+
<path d="M 409.77777777777777 63.111111111111114 L 408 61.333333333333336 L 409.77777777777777 63.111111111111114 L 408 61.333333333333336 Q 400.8888888888889 55.111111111111114 392 57.77777777777778 Q 383.1111111111111 59.55555555555556 380.44444444444446 69.33333333333333 L 379.55555555555554 71.11111111111111 L 379.55555555555554 71.11111111111111 Q 375.1111111111111 87.11111111111111 374.22222222222223 103.11111111111111 Q 407.1111111111111 131.55555555555554 422.22222222222223 173.33333333333334 Q 410.6666666666667 170.66666666666666 400 170.66666666666666 Q 399.1111111111111 170.66666666666666 398.22222222222223 170.66666666666666 Q 385.77777777777777 141.33333333333334 361.77777777777777 120 Q 337.77777777777777 99.55555555555556 305.77777777777777 91.55555555555556 L 303.1111111111111 90.66666666666667 L 303.1111111111111 90.66666666666667 Q 294.22222222222223 88 286.22222222222223 92.44444444444444 Q 271.1111111111111 103.11111111111111 276.44444444444446 120 Q 297.77777777777777 174.22222222222223 348.44444444444446 200 Q 344 208.88888888888889 342.22222222222223 219.55555555555554 L 248.88888888888889 166.22222222222223 L 248.88888888888889 166.22222222222223 Q 206.22222222222223 142.22222222222223 158.22222222222223 142.22222222222223 Q 112.88888888888889 144 88 181.33333333333334 Q 73.77777777777777 164.44444444444446 49.77777777777778 163.55555555555554 Q 28.444444444444443 164.44444444444446 14.222222222222221 177.77777777777777 Q 0.8888888888888888 192 0 213.33333333333334 Q 0.8888888888888888 234.66666666666666 14.222222222222221 248.88888888888889 Q 28.444444444444443 262.22222222222223 49.77777777777778 263.1111111111111 Q 64.88888888888889 263.1111111111111 77.33333333333333 255.11111111111111 Q 83.55555555555556 278.22222222222223 102.22222222222223 296 L 228.44444444444446 411.55555555555554 L 228.44444444444446 411.55555555555554 Q 245.33333333333334 426.6666666666667 266.6666666666667 426.6666666666667 L 369.77777777777777 426.6666666666667 L 369.77777777777777 426.6666666666667 Q 382.22222222222223 426.6666666666667 390.22222222222223 418.6666666666667 Q 398.22222222222223 410.6666666666667 398.22222222222223 398.22222222222223 Q 398.22222222222223 385.77777777777777 390.22222222222223 377.77777777777777 Q 382.22222222222223 369.77777777777777 369.77777777777777 369.77777777777777 L 312.8888888888889 369.77777777777777 L 284.44444444444446 369.77777777777777 L 284.44444444444446 331.55555555555554 L 284.44444444444446 331.55555555555554 Q 284.44444444444446 302.22222222222223 267.55555555555554 280 Q 250.66666666666666 257.77777777777777 222.22222222222223 248.88888888888889 L 195.55555555555554 240.88888888888889 L 195.55555555555554 240.88888888888889 Q 183.11111111111111 236.44444444444446 185.77777777777777 224 Q 190.22222222222223 211.55555555555554 202.66666666666666 214.22222222222223 L 230.22222222222223 221.33333333333334 L 230.22222222222223 221.33333333333334 Q 267.55555555555554 232.88888888888889 289.77777777777777 262.22222222222223 Q 312 292.44444444444446 312.8888888888889 331.55555555555554 L 312.8888888888889 344.8888888888889 L 312.8888888888889 344.8888888888889 L 362.6666666666667 316.44444444444446 L 362.6666666666667 316.44444444444446 L 368 312.8888888888889 L 368 312.8888888888889 L 458.6666666666667 312.8888888888889 L 458.6666666666667 312.8888888888889 Q 480.8888888888889 312 496 296.8888888888889 Q 511.1111111111111 281.77777777777777 512 259.55555555555554 Q 511.1111111111111 233.77777777777777 492.44444444444446 217.77777777777777 L 461.3333333333333 192.88888888888889 L 461.3333333333333 192.88888888888889 Q 455.1111111111111 187.55555555555554 448.8888888888889 184 Q 454.22222222222223 150.22222222222223 443.55555555555554 119.11111111111111 Q 433.77777777777777 88 409.77777777777777 63.111111111111114 L 409.77777777777777 63.111111111111114 Z M 126.22222222222223 402.6666666666667 Q 116.44444444444444 409.77777777777777 114.66666666666667 421.3333333333333 L 114.66666666666667 421.3333333333333 L 114.66666666666667 421.3333333333333 Q 112 432 118.22222222222223 442.6666666666667 Q 125.33333333333333 452.44444444444446 136.88888888888889 454.22222222222223 Q 147.55555555555554 456.8888888888889 158.22222222222223 450.6666666666667 L 199.11111111111111 423.1111111111111 L 199.11111111111111 423.1111111111111 L 155.55555555555554 383.1111111111111 L 155.55555555555554 383.1111111111111 L 126.22222222222223 402.6666666666667 L 126.22222222222223 402.6666666666667 Z M 426.6666666666667 241.77777777777777 Q 427.55555555555554 228.44444444444446 440.8888888888889 227.55555555555554 Q 454.22222222222223 228.44444444444446 455.1111111111111 241.77777777777777 Q 454.22222222222223 255.11111111111111 440.8888888888889 256 Q 427.55555555555554 255.11111111111111 426.6666666666667 241.77777777777777 L 426.6666666666667 241.77777777777777 Z" />
61+
</svg>
62+
),
5863
};
5964

6065
export { MillenniumIcons };

src/frontend/components/SteamComponents.tsx

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,58 @@ export const SettingsDialogSubHeader: React.FC<SettingsDialogSubHeaderProps> = (
5454
export const Separator: React.FC = () => <div className={fieldClasses.StandaloneFieldSeparator} />;
5555

5656
export const DesktopTooltip = findModuleDetailsByExport(
57-
(m) => m.toString().includes(`divProps`) && m.toString().includes(`tooltipProps`) && m.toString().includes(`toolTipContent`) && m.toString().includes(`tool-tip-source`),
58-
)[1];
57+
(m) =>
58+
m?.toString()?.includes(`divProps`) &&
59+
m?.toString()?.includes(`tooltipProps`) &&
60+
m?.toString()?.includes(`toolTipContent`) &&
61+
m?.toString()?.includes(`tool-tip-source`),
62+
)?.[1];
63+
64+
export const createWindowContext = findModuleDetailsByExport(
65+
(m) =>
66+
m?.toString()?.includes('current?.params.bNoInitialShow') &&
67+
m?.toString()?.includes('current?.params.bNoFocusOnShow') &&
68+
m?.toString()?.includes('current.m_callbacks'),
69+
)?.[1];
70+
71+
export const ModalManagerInstance = findModuleDetailsByExport((m) => {
72+
return m?.hasOwnProperty('m_mapModalManager');
73+
})?.[1];
74+
75+
export const windowHandler = findModuleDetailsByExport(
76+
(m) => m?.toString()?.includes('SetCurrentLoggedInAccountID') && m?.toString()?.includes('bIgnoreSavedDimensions') && m?.toString()?.includes('updateParamsBeforeShow'),
77+
)?.[1];
78+
79+
export const RenderWindowTitle = findModuleDetailsByExport((m) => m?.toString()?.includes('title-bar-actions window-controls'))?.[1];
80+
81+
export const g_ModalManager = findModuleDetailsByExport((m) => {
82+
return m?.toString()?.includes('useContext') && m?.toString()?.includes('ModalManager') && m?.length === 0;
83+
})?.[1];
84+
85+
export const OwnerWindowRef = findModuleDetailsByExport(
86+
(m) =>
87+
m?.toString()?.includes('ownerWindow') &&
88+
m?.toString()?.includes('children') &&
89+
m?.toString()?.includes('useMemo') &&
90+
m?.toString()?.includes('Provider') &&
91+
!m?.toString()?.includes('refFocusNavContext'),
92+
)?.[1];
93+
94+
export const popupModalManager: any = Object.values(findModuleDetailsByExport((m) => m?.toString()?.includes('GetContextMenuManagerFromWindow'))?.[0] || {})?.find(
95+
(obj) => obj && obj?.hasOwnProperty('m_mapManagers'),
96+
);
97+
98+
export const contextMenuManager = findModuleDetailsByExport(
99+
(m) =>
100+
m?.toString()?.includes('CreateContextMenuInstance') &&
101+
m?.prototype?.hasOwnProperty('GetVisibleMenus') &&
102+
m?.prototype?.hasOwnProperty('GetAllMenus') &&
103+
m?.prototype?.hasOwnProperty('ShowMenu'),
104+
)?.[1];
105+
106+
export const PopupModalHandler: any = Object.values(
107+
findModuleDetailsByExport((m) => m?.toString()?.includes('this.context.callbacks?.onDisabledItemSelected'))?.[0] || {},
108+
)?.find((m) => m?.toString()?.includes('useId'));
59109

60110
interface GenericConfirmDialogProps {
61111
children: ReactNode;

0 commit comments

Comments
 (0)