Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add regex support for webkit patching #147

Merged
merged 8 commits into from
Oct 26, 2024
Merged
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
54 changes: 0 additions & 54 deletions .github/workflows/artifact.yml
Original file line number Diff line number Diff line change
Expand Up @@ -276,57 +276,3 @@ jobs:
include-hidden-files: true
name: millennium-linux
path: /home/runner/env/

release:
needs: [build-windows, build-linux]
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: true

- name: Download Windows Artifact
uses: actions/download-artifact@v4
with:
name: millennium-windows
path: ./artifacts/windows

- name: Download Linux Artifact
uses: actions/download-artifact@v4
with:
name: millennium-linux
path: ./artifacts/linux

- name: Get Version
id: read_version
run: bash scripts/ci/posix/version.sh
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Proccess Artifacts
run: |
mkdir -p ./artifacts/release

cd ./artifacts/windows
zip -r ../release/millennium-v${{ steps.read_version.outputs.version }}-windows-x86_64.zip .
cd - # return to the original directory

cd ./artifacts/linux
tar -czvf ../release/millennium-v${{ steps.read_version.outputs.version }}-linux-x86_64.tar.gz .
cd - # return to the original directory

- name: Upload Windows Artifact
uses: actions/upload-artifact@v4
with:
include-hidden-files: true
name: millennium-windows
path: ./artifacts/release/millennium-v${{ steps.read_version.outputs.version }}-windows-x86_64.zip

- name: Upload Linux Artifact
uses: actions/upload-artifact@v4
with:
include-hidden-files: true
name: millennium-linux
path: ./artifacts/release/millennium-v${{ steps.read_version.outputs.version }}-linux-x86_64.tar.gz

9 changes: 9 additions & 0 deletions assets/core/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,15 @@
from updater.version_control import Updater
updater = Updater()


def inject_webkit_shim(shim_script: str):
# write the contents to a file
with open(os.path.join(Millennium.steam_path(), "steamui", "shim.js"), "w") as f:
f.write(shim_script)
f.close()

add_browser_js(os.path.join(Millennium.steam_path(), "shim.js"))

def get_load_config():
millennium = configparser.ConfigParser()
config_path = os.path.join(Millennium.get_install_path(), "ext", "millennium.ini")
Expand Down
4 changes: 2 additions & 2 deletions assets/pipx/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))

import pipx.config as config
import config as config
import time
import importlib.metadata
import dev_tools, pip_setup, package_manager
Expand Down Expand Up @@ -31,4 +31,4 @@ def main():
elapsed_time_ms = (time.perf_counter() - start_time) * 1000
logger.log(f"Finished in {elapsed_time_ms:.2f} ms")

main()
main()
106 changes: 106 additions & 0 deletions assets/src/Webkit.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import { Millennium } from "millennium-lib";
import { ConditionalControlFlowType, Theme, ThemeItem } from "./types";
import { constructThemePath } from "./patcher/Dispatch";

interface WebkitItem {
matchString: string,
targetPath: string,
fileType: ConditionalControlFlowType
}

const ParseMatchAndTarget = (theme: Theme): WebkitItem[] => {

let webkitItems: WebkitItem[] = []

// Add condition keys into the webkitItems array
for (const item in theme?.Conditions) {
const condition = theme.Conditions[item]

for (const value in condition?.values) {
const controlFlow = condition.values[value]


for (const control in controlFlow?.TargetCss?.affects) {
const matchString = controlFlow.TargetCss.affects[control]
const targetPath = controlFlow.TargetCss.src

webkitItems.push({ matchString, targetPath, fileType: ConditionalControlFlowType.TargetCss })
}

for (const control in controlFlow?.TargetJs?.affects) {
const matchString = controlFlow.TargetJs.affects[control]
const targetPath = controlFlow.TargetJs.src

webkitItems.push({ matchString, targetPath, fileType: ConditionalControlFlowType.TargetJs })
}
}
}

// Add patch keys into the webkitItems array
for (const item in theme?.Patches) {
const patch = theme.Patches[item]

if (patch.TargetCss) {
if (Array.isArray(patch.TargetCss)) {
for (const target in patch.TargetCss) {
webkitItems.push({ matchString: patch.MatchRegexString, targetPath: patch.TargetCss[target], fileType: ConditionalControlFlowType.TargetCss })
}
}
else {
webkitItems.push({ matchString: patch.MatchRegexString, targetPath: patch.TargetCss, fileType: ConditionalControlFlowType.TargetCss })
}
}

if (patch.TargetJs) {
if (Array.isArray(patch.TargetJs)) {
for (const target in patch.TargetJs) {
webkitItems.push({ matchString: patch.MatchRegexString, targetPath: patch.TargetJs[target], fileType: ConditionalControlFlowType.TargetJs })
}
}
else {
webkitItems.push({ matchString: patch.MatchRegexString, targetPath: patch.TargetJs, fileType: ConditionalControlFlowType.TargetJs })
}
}
}

// Filter out duplicates
webkitItems = webkitItems.filter((item, index, self) =>
index === self.findIndex((t) => (
t.matchString === item.matchString && t.targetPath === item.targetPath
))
)

return webkitItems
}

const CreateWebkitScript = (themeData: ThemeItem) => {
console.log(themeData)

let script = ``;
const webkitItems: WebkitItem[] = ParseMatchAndTarget(themeData?.data)

for (const item in webkitItems) {
const webkitItem = webkitItems[item]

const cssPath = constructThemePath(themeData?.native, webkitItem.targetPath)
const jsPath = ["https://s.ytimg.com/millennium-virtual", "skins", themeData?.native, webkitItem.targetPath].join('/')

script += `
if (RegExp("${webkitItem.matchString}").test(window.location.href)) {
console.log("Matched: ${webkitItem.matchString}, injecting ${webkitItem.fileType === ConditionalControlFlowType.TargetCss ? cssPath : jsPath}");
${
webkitItem.fileType === ConditionalControlFlowType.TargetCss
? `document.head.appendChild(Object.assign(document.createElement('link'), { rel: 'stylesheet', href: '${cssPath}' }))`
: `document.head.appendChild(Object.assign(document.createElement('script'), { src: '${jsPath}' }))`
}
}\n
`
}

console.log(script)
Millennium.callServerMethod("inject_webkit_shim", { shim_script:
`(() => { ${script} })()`
})
}

export { CreateWebkitScript }
3 changes: 3 additions & 0 deletions assets/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { PatchNotification } from "./ui/Notifications";
import { Settings, SettingsStore } from "./Settings";
import { DispatchGlobalColors } from "./patcher/v1/GlobalColors";
import { WatchDog } from "./Events";
import { CreateWebkitScript } from "./Webkit";

/**
* @note crashes steam on silent boot startup
Expand Down Expand Up @@ -78,6 +79,8 @@ const InitializePatcher = (startTime: number, result: SettingsProps) => {

Logger.Log(`Received props in [${(performance.now() - startTime).toFixed(3)}ms]`, result)

CreateWebkitScript(result.active_theme);

const theme: ThemeItem = result.active_theme
const systemColors: SystemAccentColor = result.accent_color

Expand Down
4 changes: 3 additions & 1 deletion cli/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ if (WINDRES)

add_custom_target(resource-cli DEPENDS ${CMAKE_BINARY_DIR}/version-cli.o)
add_dependencies(CLI resource-cli)

target_link_libraries(CLI PRIVATE ${CMAKE_BINARY_DIR}/version-cli.o)
endif()

install(TARGETS CLI DESTINATION /usr/local/bin)
Expand All @@ -62,5 +64,5 @@ if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
# set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} Wl,--gc-sections -s")
endif()

target_link_libraries(CLI PRIVATE CLI11::CLI11 CURL::libcurl ${CMAKE_BINARY_DIR}/version-cli.o)
target_link_libraries(CLI PRIVATE CLI11::CLI11 CURL::libcurl)
set_target_properties(CLI PROPERTIES OUTPUT_NAME "millennium")
5 changes: 5 additions & 0 deletions src/TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,8 @@
- hot reload plugin backends
- hot reload pipx bootstrapper
- figure out how to properly shutdown a python backend


- Better webkit patching
- Custom accent color separate from windows
- Auto update themes
12 changes: 12 additions & 0 deletions src/sys/plugin-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,18 @@
"frontend": {
"type": "string",
"markdownDescription": "The relative path to the frontend directory. If not provided, the default folder is `frontend`."
},
"thumbnail": {
"type": "string",
"markdownDescription": "An absolute path to an image resource, usually hosted on Imgur or GitHub's raw CDN. The image should be 16:9 and a minimum size of 512x288 pixels."
},
"splash_image": {
"type": "string",
"markdownDescription": "An absolute path to an image resource, usually hosted on Imgur or GitHub's raw CDN. This image is displayed as a backdrop when viewing your plugin page online. The image should be 16:9 and a minimum size of 1920x1080 pixels."
},
"version": {
"type": "string",
"markdownDescription": "The version of your plugin."
}
},
"required": [
Expand Down