Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Wondering if your favorite Chrome extension works with Extendium? Check our offi
1. Ensure you have **Millennium** installed on your Steam client.
2. Download the **[latest release](https://github.com/BossSloth/Extendium/releases/latest)** from GitHub or install it from the **[Steambrew](https://steambrew.app/plugin?id=788ed8554492)** website.
3. (Manual only) Place the plugin files into your Millennium plugins directory (typically a `plugins` folder inside your Steam installation).
4. **Restart** your Steam client.
4. **Restart** your Steam client using your normal Millennium launch method (on macOS, typically `Steam Millennium.app`).
5. Open the Millennium plugin menu and **enable** the Extendium plugin.
6. Click **Save Changes** at the top of the menu and **restart Steam** one more time.

Expand Down Expand Up @@ -85,6 +85,7 @@ If everything goes fully wrong (e.g. an extension breaks the client and you can'
Don't worry, almost nothing is saved in these files, only extension settings and some browser state. If you want to be sure, back them up first.

- **Windows**: `%localappdata%\Steam\htmlcache\Default`
- **macOS**: `~/Library/Application Support/Steam/config/htmlcache/Default`
- **Linux**: `~/.steam/steam/config/htmlcache/Default`

After deleting these files, boot up Steam.
Expand Down Expand Up @@ -123,9 +124,14 @@ Follow the [Manual Extension Installation](#manual-extension-installation) steps

- **Windows (Millennium < 3.0)**: `<Steam folder>/plugins/extendium/fake-header-extension`
- **Windows (Millennium >= 3.0)**: `<Steam folder>/millennium/plugins/extendium/fake-header-extension`
- **macOS**: `~/Library/Application Support/Millennium/plugins/extendium/fake-header-extension`
- **Linux**: `~/.local/share/millennium/plugins/extendium/fake-header-extension`

After loading it, restart Steam to make sure Extendium picks it up.
After loading it, restart Steam using your normal Millennium launch method to make sure Extendium picks it up.

If you previously selected **Ignore and don't show again**, close Steam, delete
`install-state.json` from the `extendium` plugin directory listed above, and
relaunch Steam to let Extendium retry the helper installation.

## Known Limitations

Expand Down
36 changes: 32 additions & 4 deletions backend/install_extension/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,25 @@ function M.is_windows()
return jit.os == "Windows"
end

function M.is_macos()
return jit.os == "OSX"
end

function M.is_linux()
return jit.os == "Linux"
end

function M.get_platform_name()
if M.is_windows() then
return "Windows"
elseif M.is_macos() then
return "macOS"
elseif M.is_linux() then
return "Linux"
end
return "Unsupported (" .. tostring(jit.os) .. ")"
end

function M.get_plugin_dir()
local backend_path = utils.get_backend_path()
if not backend_path then
Expand All @@ -32,17 +51,23 @@ function M.get_steam_config_dir()
local steam_path = millennium.steam_path()
logger:info("[install] Steam path: " .. tostring(steam_path))

local is_win = M.is_windows()
logger:info("[install] Platform: " .. (is_win and "Windows" or "Linux"))
logger:info("[install] Platform: " .. M.get_platform_name())

if is_win then
if M.is_windows() then
-- Windows: %LOCALAPPDATA%\Steam\htmlcache\Default
local appdata = utils.getenv("LOCALAPPDATA")
if appdata then
return fs.join(appdata, "Steam", "htmlcache", "Default")
end
return nil
else
elseif M.is_macos() then
-- macOS: ~/Library/Application Support/Steam/config/htmlcache/Default
local home = utils.getenv("HOME")
if home then
return fs.join(home, "Library", "Application Support", "Steam", "config", "htmlcache", "Default")
end
return nil
elseif M.is_linux() then
-- Linux: ~/.local/share/Steam/config/htmlcache/Default
-- Or symlink: ~/.steam/steam/config/htmlcache/Default
local home = utils.getenv("HOME")
Expand All @@ -51,6 +76,9 @@ function M.get_steam_config_dir()
end
return nil
end

logger:error("[install] Unsupported platform: " .. tostring(jit.os))
return nil
end

-- Generic JSON file reader with logging
Expand Down
17 changes: 9 additions & 8 deletions backend/install_extension/hmac.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@ local json_helpers = require("install_extension.json_helpers")
local sha2 = require("install_extension.sha2")

---@class HmacContext
---@field sid string
---@field device_id string
---@field seed_hex string
---@field seed_bytes string
local HmacContext = {}
HmacContext.__index = HmacContext

---@param sid string
---@param device_id string
---@param seed_hex string
---@return HmacContext
function HmacContext.new(sid, seed_hex)
function HmacContext.new(device_id, seed_hex)
local self = setmetatable({}, HmacContext)
self.sid = sid or ""
self.device_id = device_id or ""
self.seed_hex = seed_hex or "" -- Empty for Steam CEF
self.seed_bytes = sha2.hex_to_bin(seed_hex or "")
return self
Expand All @@ -31,7 +31,7 @@ function HmacContext:compute_mac(json_path, value)
local json_value = json_helpers.encode_sorted(cleaned)
json_value = json_helpers.escape_for_hmac(json_value)

local message = self.sid .. json_path .. json_value
local message = self.device_id .. json_path .. json_value
logger:info("[install] Computing MAC for path: " .. json_path)
logger:info("[install] Message length: " .. #message)
logger:info("[install] JSON preview: " .. json_value:sub(1, 100) .. "...")
Expand All @@ -48,9 +48,10 @@ end
---@param macs table
---@return string|nil
function HmacContext:compute_super_mac(macs)
-- Use sorted JSON for consistent key ordering
local macs_json = json_helpers.encode_sorted(macs)
local message = self.sid .. macs_json
-- Chromium removes empty descendants before serializing tracked values.
local cleaned_macs = json_helpers.remove_empty_children(macs) or {}
local macs_json = json_helpers.encode_sorted(cleaned_macs)
local message = self.device_id .. macs_json

logger:info("[install] Computing super MAC...")
logger:info("[install] MACs JSON: " .. macs_json:sub(1, 100) .. "...")
Expand Down
Loading