diff --git a/Dockerfile b/Dockerfile index dcf5310..c9b49a6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,7 +12,7 @@ RUN apt-get update && apt-get install -y \ # Python python3 python3-dev python3-pip \ # Camoufox build system tools - git p7zip-full golang-go aria2 curl \ + git p7zip-full golang-go aria2 curl rsync \ # CA certificates ca-certificates \ && update-ca-certificates @@ -23,10 +23,10 @@ ENV PATH="/root/.cargo/bin:${PATH}" # Fetch Firefox & apply initial patches RUN make setup-minimal && \ make mozbootstrap && \ - mkdir /app/dist + mkdir -p /app/dist # Mount .mozbuild directory and dist folder VOLUME /root/.mozbuild VOLUME /app/dist -ENTRYPOINT ["python3", "./multibuild.py"] +ENTRYPOINT ["python3", "./multibuild.py"] \ No newline at end of file diff --git a/additions/camoucfg/MaskConfig.hpp b/additions/camoucfg/MaskConfig.hpp index 3e6370e..c254163 100644 --- a/additions/camoucfg/MaskConfig.hpp +++ b/additions/camoucfg/MaskConfig.hpp @@ -13,6 +13,7 @@ Written by daijro. #include "mozilla/glue/Debug.h" #include #include +#include #include #include #include @@ -27,185 +28,174 @@ namespace MaskConfig { // Function to get the value of an environment variable as a UTF-8 string. inline std::optional get_env_utf8(const std::string& name) { #ifdef _WIN32 - std::wstring wName(name.begin(), name.end()); - DWORD size = GetEnvironmentVariableW(wName.c_str(), nullptr, 0); - if (size == 0) return std::nullopt; // Environment variable not found + std::wstring wName(name.begin(), name.end()); + DWORD size = GetEnvironmentVariableW(wName.c_str(), nullptr, 0); + if (size == 0) return std::nullopt; // Environment variable not found - std::vector buffer(size); - GetEnvironmentVariableW(wName.c_str(), buffer.data(), size); - std::wstring wValue(buffer.data()); + std::vector buffer(size); + GetEnvironmentVariableW(wName.c_str(), buffer.data(), size); + std::wstring wValue(buffer.data()); - // Convert UTF-16 to UTF-8 - std::wstring_convert> converter; - return converter.to_bytes(wValue); + // Convert UTF-16 to UTF-8 + std::wstring_convert> converter; + return converter.to_bytes(wValue); #else - const char* value = std::getenv(name.c_str()); - if (!value) return std::nullopt; - return std::string(value); + const char* value = std::getenv(name.c_str()); + if (!value) return std::nullopt; + return std::string(value); #endif } -// Helper function to load and parse configuration from environment variables. -namespace { -nlohmann::json loadConfig() { +inline const nlohmann::json& GetJson() { + static std::once_flag initFlag; + static nlohmann::json jsonConfig; + + std::call_once(initFlag, []() { std::string jsonString; int index = 1; - // Read environment variables CAMOU_CONFIG_1, CAMOU_CONFIG_2, ... while (true) { - std::string envName = "CAMOU_CONFIG_" + std::to_string(index); - auto partialConfig = get_env_utf8(envName); - if (!partialConfig) - break; - jsonString += *partialConfig; - index++; + std::string envName = "CAMOU_CONFIG_" + std::to_string(index); + auto partialConfig = get_env_utf8(envName); + if (!partialConfig) break; + + jsonString += *partialConfig; + index++; } - // If the concatenated string is empty, try reading the original CAMOU_CONFIG variable. if (jsonString.empty()) { - auto originalConfig = get_env_utf8("CAMOU_CONFIG"); - if (originalConfig) - jsonString = *originalConfig; + // Check for the original CAMOU_CONFIG as fallback + auto originalConfig = get_env_utf8("CAMOU_CONFIG"); + if (originalConfig) jsonString = *originalConfig; } - // If no configuration is provided, return an empty JSON. if (jsonString.empty()) { - return nlohmann::json{}; + jsonConfig = nlohmann::json{}; + return; } - // Validate JSON correctness. + // Validate if (!nlohmann::json::accept(jsonString)) { - printf_stderr("ERROR: Invalid JSON passed to CAMOU_CONFIG!\n"); - return nlohmann::json{}; + printf_stderr("ERROR: Invalid JSON passed to CAMOU_CONFIG!\n"); + jsonConfig = nlohmann::json{}; + return; } - return nlohmann::json::parse(jsonString); -} -} // namespace + jsonConfig = nlohmann::json::parse(jsonString); + }); -// Global configuration cache, initialized only once. -static const nlohmann::json g_jsonConfig = loadConfig(); - -// Function returns a reference to the already parsed JSON. -inline const nlohmann::json& GetJson() { - return g_jsonConfig; + return jsonConfig; } inline bool HasKey(const std::string& key, const nlohmann::json& data) { - return data.contains(key); + return data.contains(key); } inline std::optional GetString(const std::string& key) { - const auto& data = GetJson(); - if (!HasKey(key, data)) return std::nullopt; - return data[key].get(); + const auto& data = GetJson(); + if (!HasKey(key, data)) return std::nullopt; + return data[key].get(); } inline std::vector GetStringList(const std::string& key) { - std::vector result; - const auto& data = GetJson(); - if (!HasKey(key, data)) return {}; - for (const auto& item : data[key]) { - result.push_back(item.get()); - } - return result; + std::vector result; + const auto& data = GetJson(); + if (!HasKey(key, data)) return {}; + for (const auto& item : data[key]) { + result.push_back(item.get()); + } + return result; } inline std::vector GetStringListLower(const std::string& key) { - std::vector result = GetStringList(key); - for (auto& str : result) { - std::transform(str.begin(), str.end(), str.begin(), - [](unsigned char c) { return std::tolower(c); }); - } - return result; + std::vector result = GetStringList(key); + for (auto& str : result) { + std::transform(str.begin(), str.end(), str.begin(), + [](unsigned char c) { return std::tolower(c); }); + } + return result; } template inline std::optional GetUintImpl(const std::string& key) { - const auto& data = GetJson(); - if (!HasKey(key, data)) return std::nullopt; - if (data[key].is_number_unsigned()) - return data[key].get(); - printf_stderr("ERROR: Value for key '%s' is not an unsigned integer\n", key.c_str()); - return std::nullopt; + const auto& data = GetJson(); + if (!HasKey(key, data)) return std::nullopt; + if (data[key].is_number_unsigned()) return data[key].get(); + printf_stderr("ERROR: Value for key '%s' is not an unsigned integer\n", + key.c_str()); + return std::nullopt; } inline std::optional GetUint64(const std::string& key) { - return GetUintImpl(key); + return GetUintImpl(key); } inline std::optional GetUint32(const std::string& key) { - return GetUintImpl(key); + return GetUintImpl(key); } inline std::optional GetInt32(const std::string& key) { - const auto& data = GetJson(); - if (!HasKey(key, data)) return std::nullopt; - if (data[key].is_number_integer()) - return data[key].get(); - printf_stderr("ERROR: Value for key '%s' is not an integer\n", key.c_str()); - return std::nullopt; + const auto& data = GetJson(); + if (!HasKey(key, data)) return std::nullopt; + if (data[key].is_number_integer()) return data[key].get(); + printf_stderr("ERROR: Value for key '%s' is not an integer\n", key.c_str()); + return std::nullopt; } inline std::optional GetDouble(const std::string& key) { - const auto& data = GetJson(); - if (!HasKey(key, data)) return std::nullopt; - if (data[key].is_number_float()) - return data[key].get(); - if (data[key].is_number_unsigned() || data[key].is_number_integer()) - return static_cast(data[key].get()); - printf_stderr("ERROR: Value for key '%s' is not a double\n", key.c_str()); - return std::nullopt; + const auto& data = GetJson(); + if (!HasKey(key, data)) return std::nullopt; + if (data[key].is_number_float()) return data[key].get(); + if (data[key].is_number_unsigned() || data[key].is_number_integer()) + return static_cast(data[key].get()); + printf_stderr("ERROR: Value for key '%s' is not a double\n", key.c_str()); + return std::nullopt; } inline std::optional GetBool(const std::string& key) { - const auto& data = GetJson(); - if (!HasKey(key, data)) return std::nullopt; - if (data[key].is_boolean()) return data[key].get(); - printf_stderr("ERROR: Value for key '%s' is not a boolean\n", key.c_str()); - return std::nullopt; + const auto& data = GetJson(); + if (!HasKey(key, data)) return std::nullopt; + if (data[key].is_boolean()) return data[key].get(); + printf_stderr("ERROR: Value for key '%s' is not a boolean\n", key.c_str()); + return std::nullopt; } inline bool CheckBool(const std::string& key) { - return GetBool(key).value_or(false); + return GetBool(key).value_or(false); } -inline std::optional> GetRect(const std::string& left, - const std::string& top, - const std::string& width, - const std::string& height) { - std::array, 4> values = { - GetUint32(left).value_or(0), - GetUint32(top).value_or(0), - GetUint32(width), - GetUint32(height) - }; +inline std::optional> GetRect( + const std::string& left, const std::string& top, const std::string& width, + const std::string& height) { + std::array, 4> values = { + GetUint32(left).value_or(0), GetUint32(top).value_or(0), GetUint32(width), + GetUint32(height)}; - if (!values[2].has_value() || !values[3].has_value()) { - if (values[2].has_value() ^ values[3].has_value()) - printf_stderr("Both %s and %s must be provided. Using default behavior.\n", - height.c_str(), width.c_str()); - return std::nullopt; - } - - std::array result; - std::transform(values.begin(), values.end(), result.begin(), - [](const auto& value) { return value.value(); }); - - return result; -} - -inline std::optional> GetInt32Rect(const std::string& left, - const std::string& top, - const std::string& width, - const std::string& height) { - if (auto optValue = GetRect(left, top, width, height)) { - std::array result; - std::transform(optValue->begin(), optValue->end(), result.begin(), - [](const auto& val) { return static_cast(val); }); - return result; - } + if (!values[2].has_value() || !values[3].has_value()) { + if (values[2].has_value() ^ values[3].has_value()) + printf_stderr( + "Both %s and %s must be provided. Using default behavior.\n", + height.c_str(), width.c_str()); return std::nullopt; + } + + std::array result; + std::transform(values.begin(), values.end(), result.begin(), + [](const auto& value) { return value.value(); }); + + return result; +} + +inline std::optional> GetInt32Rect( + const std::string& left, const std::string& top, const std::string& width, + const std::string& height) { + if (auto optValue = GetRect(left, top, width, height)) { + std::array result; + std::transform(optValue->begin(), optValue->end(), result.begin(), + [](const auto& val) { return static_cast(val); }); + return result; + } + return std::nullopt; } // Helpers for WebGL diff --git a/multibuild.py b/multibuild.py index 2fbdc83..e424fae 100644 --- a/multibuild.py +++ b/multibuild.py @@ -22,6 +22,7 @@ import os import sys from dataclasses import dataclass from typing import List +import shutil # Constants AVAILABLE_TARGETS = ["linux", "windows", "macos"] @@ -86,7 +87,7 @@ def run_build(target, arch): # Move assets to dist print('Assets:', ', '.join(builder.assets)) for asset in builder.assets: - os.rename(asset, f'dist/{asset}') + shutil.move(asset, f'dist/{asset}') def main():