From 87a567ad6a44324e52a25c516e68e62921fdfb07 Mon Sep 17 00:00:00 2001 From: amsyarasyiq <82711525+amsyarasyiq@users.noreply.github.com> Date: Fri, 15 Mar 2024 08:10:25 +0800 Subject: [PATCH] Pyoncord changes --- .github/workflows/build.yml | 8 +- .gitmodules | 3 - Makefile | 12 +- Package.swift | 12 +- VendettaTweak.plist => PyoncordTweak.plist | 0 README.md | 26 ++-- Resources/identity.js | 1 - Resources/payload-base.js | 5 + .../LoaderConfig.x.swift | 22 +-- .../Themes.x.swift | 26 ++-- Sources/PyoncordTweak/Tweak.x.swift | 142 ++++++++++++++++++ Sources/PyoncordTweak/Utils.x.swift | 16 ++ .../Tweak.m | 0 .../include/RCTCxxBridge.h | 0 .../include/Tweak.h | 0 .../include/module.modulemap | 2 +- Sources/VendettaTweak/Tweak.x.swift | 123 --------------- Sources/VendettaTweak/Utils.x.swift | 6 - VendettaXposed | 1 - control | 6 +- 20 files changed, 217 insertions(+), 194 deletions(-) delete mode 100644 .gitmodules rename VendettaTweak.plist => PyoncordTweak.plist (100%) delete mode 100644 Resources/identity.js create mode 100644 Resources/payload-base.js rename Sources/{VendettaTweak => PyoncordTweak}/LoaderConfig.x.swift (55%) rename Sources/{VendettaTweak => PyoncordTweak}/Themes.x.swift (83%) create mode 100644 Sources/PyoncordTweak/Tweak.x.swift create mode 100644 Sources/PyoncordTweak/Utils.x.swift rename Sources/{VendettaTweakC => PyoncordTweakC}/Tweak.m (100%) rename Sources/{VendettaTweakC => PyoncordTweakC}/include/RCTCxxBridge.h (100%) rename Sources/{VendettaTweakC => PyoncordTweakC}/include/Tweak.h (100%) rename Sources/{VendettaTweakC => PyoncordTweakC}/include/module.modulemap (57%) delete mode 100644 Sources/VendettaTweak/Tweak.x.swift delete mode 100644 Sources/VendettaTweak/Utils.x.swift delete mode 160000 VendettaXposed diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fa0debb..f0ebb6d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,6 +1,8 @@ name: Build -on: [push] +on: + push: + workflow_dispatch: jobs: build: @@ -30,7 +32,7 @@ jobs: with: orion: "true" - - name: Build package + - name: Build rootful package run: | rm -f packages/* make package FINALPACKAGE=1 @@ -38,7 +40,7 @@ jobs: - name: Upload package uses: actions/upload-artifact@v3 with: - name: "Package built by ${{ matrix.os }}" + name: "Rootful package built by ${{ matrix.os }}" path: ${{ github.workspace }}/packages/*-arm.deb - name: Build rootless package diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 47c279d..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "VendettaXposed"] - path = VendettaXposed - url = https://github.com/vendetta-mod/VendettaXposed diff --git a/Makefile b/Makefile index e4eee0a..e5f4971 100644 --- a/Makefile +++ b/Makefile @@ -7,13 +7,13 @@ endif include $(THEOS)/makefiles/common.mk -TWEAK_NAME = VendettaTweak +TWEAK_NAME = PyoncordTweak -VendettaTweak_FILES = $(shell find Sources/VendettaTweak -name '*.swift') $(shell find Sources/VendettaTweakC -name '*.m' -o -name '*.c' -o -name '*.mm' -o -name '*.cpp') -VendettaTweak_SWIFTFLAGS = -ISources/VendettaTweakC/include -VendettaTweak_CFLAGS = -fobjc-arc -ISources/VendettaTweakC/include +PyoncordTweak_FILES = $(shell find Sources/PyoncordTweak -name '*.swift') $(shell find Sources/PyoncordTweakC -name '*.m' -o -name '*.c' -o -name '*.mm' -o -name '*.cpp') +PyoncordTweak_SWIFTFLAGS = -ISources/PyoncordTweakC/include +PyoncordTweak_CFLAGS = -fobjc-arc -ISources/PyoncordTweakC/include -VendettaTweak_BUNDLE_NAME = VendettaPatches -VendettaTweak_BUNDLE_RESOURCE_DIRS = VendettaXposed/App/src/main/assets/js Resources +PyoncordTweak_BUNDLE_NAME = PyoncordPatches +PyoncordTweak_BUNDLE_RESOURCE_DIRS = Resources include $(THEOS_MAKE_PATH)/tweak.mk diff --git a/Package.swift b/Package.swift index a9608cc..a76267f 100644 --- a/Package.swift +++ b/Package.swift @@ -65,23 +65,23 @@ let swiftFlags: [String] = libFlags + [ ] let package = Package( - name: "VendettaTweak", + name: "PyoncordTweak", platforms: [.iOS(deploymentTarget)], products: [ .library( - name: "VendettaTweak", - targets: ["VendettaTweak"] + name: "PyoncordTweak", + targets: ["PyoncordTweak"] ), ], targets: [ .target( - name: "VendettaTweakC", + name: "PyoncordTweakC", cSettings: [.unsafeFlags(cFlags)], cxxSettings: [.unsafeFlags(cxxFlags)] ), .target( - name: "VendettaTweak", - dependencies: ["VendettaTweakC"], + name: "PyoncordTweak", + dependencies: ["PyoncordTweakC"], swiftSettings: [.unsafeFlags(swiftFlags)] ), ] diff --git a/VendettaTweak.plist b/PyoncordTweak.plist similarity index 100% rename from VendettaTweak.plist rename to PyoncordTweak.plist diff --git a/README.md b/README.md index 9344612..a713864 100644 --- a/README.md +++ b/README.md @@ -1,29 +1,29 @@ -> [!IMPORTANT] -> As of 06/02/24, Vendetta and related projects have been discontinued. +> [!NOTE] +> This tweak was desperately forked from VendettaTweak. I may not have the expertise to maintain or expand this tweak beyond its current state -# VendettaTweak +# PyoncordTweak -A rootful/rootless tweak to inject Vendetta into Discord. +A rootful/rootless tweak to inject [Bunny](https://github.com/pyoncord/Bunny) into Discord. Forked [VendettaTweak](https://github.com/vendetta-mod/VendettaTweak), modified to match with [PyoncordXposed](https://github.com/pyoncord/PyoncordXposed) behavior. There are still slight differences between these two, and this tweak may be missing some loader features. ## Installation ### Jailbroken (Rootful/Rootless) 1. Install Orion runtime via your preferred package manager, by adding `https://repo.chariz.com/` to your sources, then finding `Orion Runtime`. -1. Install Vendetta by downloading the appropriate `.deb` file (or by building your own, see [Building VendettaTweak locally](#building-vendettatweak-locally)). Use the file ending in `arm.deb` for rootful jailbreaks, and the file ending in `arm64.deb` for rootless jailbreaks. +1. Install Bunny by downloading the appropriate `.deb` file (or by building your own, see [Building PyoncordTweak locally](#building-pyoncordtweak-locally)). Use the file ending in `arm.deb` for rootful jailbreaks, and the file ending in `arm64.deb` for rootless jailbreaks. ### Non-Jailbroken 1. Download Orion from [here](https://github.com/theos/orion/releases). You will need the `deb` file ending in `arm.deb` NOT `arm64.deb`. -1. Download the rootful Vendetta `.deb` file (file ending in `arm.deb`) or build your own by following the [Building VendettaTweak locally](#building-vendettatweak-locally) steps. +1. Download the rootful PyoncordTweak `.deb` file (file ending in `arm.deb`) or build your own by following the [Building PyoncordTweak locally](#building-pyoncordtweak-locally) steps. 1. Clone [azule](https://github.com/Al4ise/Azule/tree/main) into a folder and `cd` into it. 1. Extract or obtain a decrypted Discord IPA. To extract the IPA from a jailbroken iDevice, we recommend [bagbak](https://github.com/ChiChou/bagbak). -1. Run `./azule -i -o -f `. Make sure to provide the full paths to the files (you cannot use relative paths unfortunately). Example: `./azule -i /Users/vendetta/IPA/Discord.ipa -o /Users/vendetta/IPA/VendettaDiscord -f /Users/vendetta/IPA/dev.theos.orion14_1.0.1_iphoneos-arm.deb /Users/vendetta/IPA/dev.beefers.vendetta_0.0.2_iphoneos-arm.deb` +1. Run `./azule -i -o -f `. Make sure to provide the full paths to the files (you cannot use relative paths unfortunately). Example: `./azule -i ~/Users/vendetta/IPA/Discord.ipa -o ~/Users/vendetta/IPA/outputs -f ~/Users/vendetta/IPA/dev.theos.orion14_1.0.1_iphoneos-arm.deb ~/Users/vendetta/IPA/com.pyoncord.bunny_0.0.1_iphoneos-arm.deb` 1. Install the generated IPA using your preferred sideloading method (at the time of writing this, only Sideloadly works). -## Building VendettaTweak locally +## Building PyoncordTweak locally -> **Note** +> [!NOTE] > These steps assume you use MacOS. 1. Install Xcode from the App Store. If you've previously installed the `Command Line Utilities` package, you will need to run `sudo xcode-select -switch /Applications/Xcode.app/Contents/Developer` to make sure you're using the Xcode tools instead. @@ -32,7 +32,7 @@ A rootful/rootless tweak to inject Vendetta into Discord. 2. Install the required dependencies. You can do this by running `brew install make ldid` in your terminal. If you do not have brew installed, follow the instructions [here](https://brew.sh/). -3. Setup your path accordingly. We recommend you run the following before running the next commands, as well as any time you want to build VendettaTweak. +3. Setup your path accordingly. We recommend you run the following before running the next commands, as well as any time you want to build PyoncordTweak. ```bash export PATH="$(brew --prefix make)/libexec/gnubin:$PATH" @@ -48,9 +48,9 @@ bash -c "$(curl -fsSL https://raw.githubusercontent.com/theos/theos/master/bin/i If you've already installed theos, you can run `$THEOS/bin/update-theos` to make sure it's up to date. -5. Clone this repository with `git clone git@github.com:vendetta-mod/VendettaTweak.git --recurse-submodules` and `cd` into it. Replace the URL with your fork if you've forked this repository. +5. Clone this repository with `git clone git@github.com:pyoncord/PyoncordTweak.git` and `cd` into it. Replace the URL with your fork if you've forked this repository. -6. To build VendettaTweak, you can run `rm -rf packages && make clean && make package FINALPACKAGE=1 && make package FINALPACKAGE=1 THEOS_PACKAGE_SCHEME=rootless`. The first command will remove any previous packages, the second will clean the project, the third will build the rootful package (which is denoted by the `arm.deb` ending), and the fourth will build the rootless package (which is denoted by the `arm64.deb` ending). +6. To build PyoncordTweak, you can run `rm -rf packages && make clean && make package FINALPACKAGE=1 && make package FINALPACKAGE=1 THEOS_PACKAGE_SCHEME=rootless`. The first command will remove any previous packages, the second will clean the project, the third will build the rootful package (which is denoted by the `arm.deb` ending), and the fourth will build the rootless package (which is denoted by the `arm64.deb` ending). The first time you run this, it might take a bit longer, but subsequent builds should be much faster. @@ -58,6 +58,6 @@ The resulting `.deb` files will be in the `packages` folder. As a reminder, `*ar ## Contributing -If you want to contribute, you will basically need to follow the steps for [Building VendettaTweak locally](#building-vendettatweak-locally), as well as run `make spm` for the Swift LSP to work. +If you want to contribute, you will basically need to follow the steps for [Building PyoncordTweak locally](#building-pyoncordtweak-locally), as well as run `make spm` for the Swift LSP to work. diff --git a/Resources/identity.js b/Resources/identity.js deleted file mode 100644 index 2e13347..0000000 --- a/Resources/identity.js +++ /dev/null @@ -1 +0,0 @@ -globalThis.__vendetta_loader={name:"VendettaTweak",features:{loaderConfig:true,devtools:{prop:"__vendetta_rdc",version:"4.27.1"},themes:{prop:"__vendetta_theme"}}}; \ No newline at end of file diff --git a/Resources/payload-base.js b/Resources/payload-base.js new file mode 100644 index 0000000..b8eb31f --- /dev/null +++ b/Resources/payload-base.js @@ -0,0 +1,5 @@ +globalThis.__PYON_LOADER__ = { + loaderName: "PyoncordTweak", + hasThemeSupport: true, + storedTheme: null +} diff --git a/Sources/VendettaTweak/LoaderConfig.x.swift b/Sources/PyoncordTweak/LoaderConfig.x.swift similarity index 55% rename from Sources/VendettaTweak/LoaderConfig.x.swift rename to Sources/PyoncordTweak/LoaderConfig.x.swift index 734cec8..f450a76 100644 --- a/Sources/VendettaTweak/LoaderConfig.x.swift +++ b/Sources/PyoncordTweak/LoaderConfig.x.swift @@ -13,21 +13,22 @@ struct CustomLoadUrl: Codable { struct LoaderConfig: Codable { let customLoadUrl: CustomLoadUrl let loadReactDevTools: Bool + var loadPyoncord: Bool? = nil } let defaultLoaderConfig = LoaderConfig( customLoadUrl: CustomLoadUrl( enabled: false, - url: URL(string: "http://localhost:4040/vendetta.js")! + url: URL(string: "http://localhost:4040/bunny.js")! ), loadReactDevTools: false ) -let documentDirectory = getDocumentDirectory() -let loaderConfigUrl = documentDirectory.appendingPathComponent("vendetta_loader.json") +let pyoncordDirectory = getPyoncordDirectory() +let loaderConfigUrl = pyoncordDirectory.appendingPathComponent("loader.json") func getLoaderConfig() -> LoaderConfig { - os_log("Getting loader config", log: vendettaLog, type: .debug) + os_log("Getting loader config", log: pyoncordLog, type: .debug) let fileManager = FileManager.default do { @@ -35,24 +36,15 @@ func getLoaderConfig() -> LoaderConfig { let data = try Data(contentsOf: loaderConfigUrl) let loaderConfig = try JSONDecoder().decode(LoaderConfig.self, from: data) - os_log("Got loader config", log: vendettaLog, type: .debug) + os_log("Got loader config", log: pyoncordLog, type: .debug) return loaderConfig } else { throw LoaderConfigError.doesNotExist } } catch { - os_log("Couldn't get loader config", log: vendettaLog, type: .error) - createLoaderConfig() + os_log("Couldn't get loader config", log: pyoncordLog, type: .error) return defaultLoaderConfig } } - -func createLoaderConfig() { - do { - let encodedConfig = try JSONEncoder().encode(defaultLoaderConfig) - try encodedConfig.write(to: loaderConfigUrl) - os_log("Created loader config", log: vendettaLog, type: .debug) - } catch {} -} diff --git a/Sources/VendettaTweak/Themes.x.swift b/Sources/PyoncordTweak/Themes.x.swift similarity index 83% rename from Sources/VendettaTweak/Themes.x.swift rename to Sources/PyoncordTweak/Themes.x.swift index 2bbbe4e..fe8d377 100644 --- a/Sources/VendettaTweak/Themes.x.swift +++ b/Sources/PyoncordTweak/Themes.x.swift @@ -1,6 +1,6 @@ import Orion import UIKit -import VendettaTweakC +import PyoncordTweakC import os struct Author: Codable { @@ -56,7 +56,7 @@ func hexToUIColor(_ hex: String) -> UIColor? { } func swizzleDCDThemeColor(_ semanticColors: [String: [String]]) { - os_log("Swizzling DCDThemeColor", log: vendettaLog, type: .info) + os_log("Swizzling DCDThemeColor", log: pyoncordLog, type: .info) let DCDTheme: AnyClass = NSClassFromString("DCDTheme")! let dcdThemeTarget: AnyClass = object_getClass(DCDTheme)! @@ -68,25 +68,25 @@ func swizzleDCDThemeColor(_ semanticColors: [String: [String]]) { let themeIndex: ThemeIndexType = unsafeBitCast(themeIndexImpl, to: ThemeIndexType.self) let DCDThemeColor: AnyClass = NSClassFromString("DCDThemeColor")! - os_log("Found instance of DCDThemeColor", log: vendettaLog, type: .debug) + os_log("Found instance of DCDThemeColor", log: pyoncordLog, type: .debug) let target: AnyClass = object_getClass(DCDThemeColor)! - os_log("Found DCDThemeColor", log: vendettaLog, type: .debug) + os_log("Found DCDThemeColor", log: pyoncordLog, type: .debug) var methodCount: UInt32 = 0 let methods = class_copyMethodList(target, &methodCount)! - os_log("DCDThemeColor has %{public}d methods", log: vendettaLog, type: .debug, methodCount) + os_log("DCDThemeColor has %{public}d methods", log: pyoncordLog, type: .debug, methodCount) for i in 0.. UIColor @@ -115,28 +115,28 @@ func swizzleDCDThemeColor(_ semanticColors: [String: [String]]) { } func swizzleUIColor(_ rawColors: [String: String]) { - os_log("Swizzling UIColor", log: vendettaLog, type: .info) + os_log("Swizzling UIColor", log: pyoncordLog, type: .info) let UIColor: AnyClass = NSClassFromString("UIColor")! - os_log("Found instance of UIColor", log: vendettaLog, type: .debug) + os_log("Found instance of UIColor", log: pyoncordLog, type: .debug) let target: AnyClass = object_getClass(UIColor)! - os_log("Found UIColor", log: vendettaLog, type: .debug) + os_log("Found UIColor", log: pyoncordLog, type: .debug) var methodCount: UInt32 = 0 let methods = class_copyMethodList(target, &methodCount)! - os_log("UIColor has %{public}d methods", log: vendettaLog, type: .debug, methodCount) + os_log("UIColor has %{public}d methods", log: pyoncordLog, type: .debug, methodCount) for i in 0.. UIColor = { (self: AnyObject) -> UIColor in return hexToUIColor(rawColor)! diff --git a/Sources/PyoncordTweak/Tweak.x.swift b/Sources/PyoncordTweak/Tweak.x.swift new file mode 100644 index 0000000..7c536d0 --- /dev/null +++ b/Sources/PyoncordTweak/Tweak.x.swift @@ -0,0 +1,142 @@ +import Orion +import PyoncordTweakC +import os + +let pyoncordLog = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "pyoncord") +let source = URL(string: "bunny")! + +let install_prefix = String(cString: get_install_prefix()) +let isJailbroken = FileManager.default.fileExists(atPath: "\(install_prefix)/Library/Application Support/PyoncordTweak/PyoncordPatches.bundle") + +let pyoncordPatchesBundlePath = isJailbroken ? "\(install_prefix)/Library/Application Support/PyoncordTweak/PyoncordPatches.bundle" : "\(Bundle.main.bundleURL.path)/PyoncordPatches.bundle" + +class FileManagerLoadHook: ClassHook { + func containerURLForSecurityApplicationGroupIdentifier(_ groupIdentifier: NSString?) -> URL? { + os_log("containerURLForSecurityApplicationGroupIdentifier called! %{public}@ groupIdentifier", log: pyoncordLog, type: .debug, groupIdentifier ?? "nil") + + if (isJailbroken) { + return orig.containerURLForSecurityApplicationGroupIdentifier(groupIdentifier) + } + + let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask) + let lastPath = paths.last! + return lastPath.appendingPathComponent("AppGroup") + } +} + +class LoadHook: ClassHook { + func executeApplicationScript(_ script: Data, url: URL, async: Bool) { + os_log("executeApplicationScript called!", log: pyoncordLog, type: .debug) + + let loaderConfig = getLoaderConfig() + + let pyoncordPatchesBundle = Bundle(path: pyoncordPatchesBundlePath)! + + if let patchPath = pyoncordPatchesBundle.url(forResource: "payload-base", withExtension: "js") { + let patchData = try! Data(contentsOf: patchPath) + os_log("Executing payload base", log: pyoncordLog, type: .debug) + orig.executeApplicationScript(patchData, url: source, async: true) + } + + let pyoncordDirectory = getPyoncordDirectory() + + var bundle = try? Data(contentsOf: pyoncordDirectory.appendingPathComponent("bunny.js")) + + let group = DispatchGroup() + + group.enter() + var bundleUrl: URL + if loaderConfig.customLoadUrl.enabled { + os_log( + "Custom load URL enabled, with URL %{public}@ ", log: pyoncordLog, type: .info, + loaderConfig.customLoadUrl.url.absoluteString) + bundleUrl = loaderConfig.customLoadUrl.url + } else { + if loaderConfig.loadPyoncord == true { + bundleUrl = URL( + string: "https://raw.githubusercontent.com/pyoncord/pyoncord/builds/pyoncord.js")! + } else { + bundleUrl = URL( + string: "https://raw.githubusercontent.com/pyoncord/detta-builds/main/bunny.js")! + } + } + + os_log("Fetching JS bundle", log: pyoncordLog, type: .info) + var bundleRequest = URLRequest( + url: bundleUrl, cachePolicy: .reloadIgnoringLocalAndRemoteCacheData, timeoutInterval: 3.0) + + if let bundleEtag = try? String( + contentsOf: pyoncordDirectory.appendingPathComponent("etag.txt")), bundle != nil + { + bundleRequest.addValue(bundleEtag, forHTTPHeaderField: "If-None-Match") + } + + let fetchTask = URLSession.shared.dataTask(with: bundleRequest) { data, response, error in + if let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 { + os_log("Successfully fetched JS Bundle", log: pyoncordLog, type: .debug) + bundle = data + try? bundle?.write(to: pyoncordDirectory.appendingPathComponent("bunny.js")) + + let etag = httpResponse.allHeaderFields["Etag"] as? String + try? etag?.write( + to: pyoncordDirectory.appendingPathComponent("etag.txt"), atomically: true, + encoding: .utf8) + } + + group.leave() + } + + fetchTask.resume() + group.wait() + + if let themeString = try? String( + contentsOf: pyoncordDirectory.appendingPathComponent("current-theme.json")) + { + orig.executeApplicationScript( + "globalThis.__PYON_LOADER__.storedTheme=\(themeString)".data(using: .utf8)!, url: source, async: async) + } + + let preloadsDirectory = pyoncordDirectory.appendingPathComponent("preloads") + + if FileManager.default.fileExists(atPath: preloadsDirectory.path) { + do { + let contents = try FileManager.default.contentsOfDirectory( + at: preloadsDirectory, includingPropertiesForKeys: nil, options: []) + + for fileURL in contents { + if fileURL.pathExtension == "js" { + os_log( + "Executing preload JS file %{public}@ ", log: pyoncordLog, type: .info, fileURL.absoluteString) + + if let data = try? Data(contentsOf: fileURL) { + orig.executeApplicationScript(data, url: source, async: async) + } + } + } + } catch { + os_log("Error reading contents of preloads directory", log: pyoncordLog, type: .error) + } + } + + if bundle != nil { + os_log("Executing JS bundle", log: pyoncordLog, type: .info) + orig.executeApplicationScript(bundle!, url: source, async: async) + } else { + os_log("Unable to fetch JS bundle", log: pyoncordLog, type: .error) + } + + os_log("Executing original script", log: pyoncordLog, type: .info) + orig.executeApplicationScript(script, url: url, async: async) + } +} + +struct PyoncordTweak: Tweak { + func tweakDidActivate() { + if let themeData = try? Data( + contentsOf: pyoncordDirectory.appendingPathComponent("current-theme.json")) { + let theme = try? JSONDecoder().decode(Theme.self, from: themeData) + if let semanticColors = theme?.data.semanticColors { swizzleDCDThemeColor(semanticColors) } + if let rawColors = theme?.data.rawColors { swizzleUIColor(rawColors) } + } + } +} diff --git a/Sources/PyoncordTweak/Utils.x.swift b/Sources/PyoncordTweak/Utils.x.swift new file mode 100644 index 0000000..48a0702 --- /dev/null +++ b/Sources/PyoncordTweak/Utils.x.swift @@ -0,0 +1,16 @@ +import Foundation + +func getPyoncordDirectory() -> URL { + let documentDirectoryURL = try! FileManager.default.url( + for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false) + + let pyoncordFolderURL = documentDirectoryURL.appendingPathComponent("pyoncord") + + // Create the "pyoncord" folder if it doesn't exist + if !FileManager.default.fileExists(atPath: pyoncordFolderURL.path) { + try! FileManager.default.createDirectory( + at: pyoncordFolderURL, withIntermediateDirectories: true, attributes: nil) + } + + return pyoncordFolderURL +} diff --git a/Sources/VendettaTweakC/Tweak.m b/Sources/PyoncordTweakC/Tweak.m similarity index 100% rename from Sources/VendettaTweakC/Tweak.m rename to Sources/PyoncordTweakC/Tweak.m diff --git a/Sources/VendettaTweakC/include/RCTCxxBridge.h b/Sources/PyoncordTweakC/include/RCTCxxBridge.h similarity index 100% rename from Sources/VendettaTweakC/include/RCTCxxBridge.h rename to Sources/PyoncordTweakC/include/RCTCxxBridge.h diff --git a/Sources/VendettaTweakC/include/Tweak.h b/Sources/PyoncordTweakC/include/Tweak.h similarity index 100% rename from Sources/VendettaTweakC/include/Tweak.h rename to Sources/PyoncordTweakC/include/Tweak.h diff --git a/Sources/VendettaTweakC/include/module.modulemap b/Sources/PyoncordTweakC/include/module.modulemap similarity index 57% rename from Sources/VendettaTweakC/include/module.modulemap rename to Sources/PyoncordTweakC/include/module.modulemap index 4302bab..d6117b6 100644 --- a/Sources/VendettaTweakC/include/module.modulemap +++ b/Sources/PyoncordTweakC/include/module.modulemap @@ -1,4 +1,4 @@ -module VendettaTweakC { +module PyoncordTweakC { umbrella "." export * } diff --git a/Sources/VendettaTweak/Tweak.x.swift b/Sources/VendettaTweak/Tweak.x.swift deleted file mode 100644 index 725e6c4..0000000 --- a/Sources/VendettaTweak/Tweak.x.swift +++ /dev/null @@ -1,123 +0,0 @@ -import Orion -import VendettaTweakC -import os - -let vendettaLog = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "vendetta") -let source = URL(string: "vendetta")! - -let install_prefix = String(cString: get_install_prefix()) -let isJailbroken = FileManager.default.fileExists(atPath: "\(install_prefix)/Library/Application Support/VendettaTweak/VendettaPatches.bundle") - -let vendettaPatchesBundlePath = isJailbroken ? "\(install_prefix)/Library/Application Support/VendettaTweak/VendettaPatches.bundle" : "\(Bundle.main.bundleURL.path)/VendettaPatches.bundle" - -class FileManagerLoadHook: ClassHook { - func containerURLForSecurityApplicationGroupIdentifier(_ groupIdentifier: NSString?) -> URL? { - os_log("containerURLForSecurityApplicationGroupIdentifier called! %{public}@ groupIdentifier", log: vendettaLog, type: .debug, groupIdentifier ?? "nil") - - if (isJailbroken) { - return orig.containerURLForSecurityApplicationGroupIdentifier(groupIdentifier) - } - - let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask) - let lastPath = paths.last! - return lastPath.appendingPathComponent("AppGroup") - } -} - -class LoadHook: ClassHook { - func executeApplicationScript(_ script: Data, url: URL, async: Bool) { - os_log("executeApplicationScript called!", log: vendettaLog, type: .debug) - - let loaderConfig = getLoaderConfig() - - let vendettaPatchesBundle = Bundle(path: vendettaPatchesBundlePath)! - var patches = ["modules", "identity"] - if loaderConfig.loadReactDevTools { - os_log("DevTools patch enabled", log: vendettaLog, type: .info) - patches.append("devtools") - } - - os_log("Executing patches", log: vendettaLog, type: .info) - for patch in patches { - if let patchPath = vendettaPatchesBundle.url(forResource: patch, withExtension: "js") { - let patchData = try! Data(contentsOf: patchPath) - os_log("Executing %{public}@ patch", log: vendettaLog, type: .debug, patch) - orig.executeApplicationScript(patchData, url: source, async: true) - } - } - - let documentDirectory = getDocumentDirectory() - - var vendetta = try? Data(contentsOf: documentDirectory.appendingPathComponent("vendetta.js")) - - let group = DispatchGroup() - - group.enter() - var vendettaUrl: URL - if loaderConfig.customLoadUrl.enabled { - os_log( - "Custom load URL enabled, with URL %{public}@ ", log: vendettaLog, type: .info, - loaderConfig.customLoadUrl.url.absoluteString) - vendettaUrl = loaderConfig.customLoadUrl.url - } else { - vendettaUrl = URL( - string: "https://raw.githubusercontent.com/vendetta-mod/builds/master/vendetta.js")! - } - - os_log("Fetching vendetta.js", log: vendettaLog, type: .info) - var vendettaRequest = URLRequest( - url: vendettaUrl, cachePolicy: .reloadIgnoringLocalAndRemoteCacheData, timeoutInterval: 3.0) - - if let vendettaEtag = try? String( - contentsOf: documentDirectory.appendingPathComponent("vendetta_etag.txt")), vendetta != nil - { - vendettaRequest.addValue(vendettaEtag, forHTTPHeaderField: "If-None-Match") - } - - let vendettaTask = URLSession.shared.dataTask(with: vendettaRequest) { data, response, error in - if let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 { - os_log("Successfully fetched vendetta.js", log: vendettaLog, type: .debug) - vendetta = data - try? vendetta?.write(to: documentDirectory.appendingPathComponent("vendetta.js")) - - let etag = httpResponse.allHeaderFields["Etag"] as? String - try? etag?.write( - to: documentDirectory.appendingPathComponent("vendetta_etag.txt"), atomically: true, - encoding: .utf8) - } - - group.leave() - } - - vendettaTask.resume() - group.wait() - - os_log("Executing original script", log: vendettaLog, type: .info) - orig.executeApplicationScript(script, url: url, async: async) - - if let themeString = try? String( - contentsOf: documentDirectory.appendingPathComponent("vendetta_theme.json")) - { - orig.executeApplicationScript( - "globalThis.__vendetta_theme=\(themeString)".data(using: .utf8)!, url: source, async: async) - } - - if vendetta != nil { - os_log("Executing vendetta.js", log: vendettaLog, type: .info) - orig.executeApplicationScript(vendetta!, url: source, async: async) - } else { - os_log("Unable to fetch vendetta.js", log: vendettaLog, type: .error) - } - } -} - -struct VendettaTweak: Tweak { - func tweakDidActivate() { - if let themeData = try? Data( - contentsOf: documentDirectory.appendingPathComponent("vendetta_theme.json")) { - let theme = try? JSONDecoder().decode(Theme.self, from: themeData) - if let semanticColors = theme?.data.semanticColors { swizzleDCDThemeColor(semanticColors) } - if let rawColors = theme?.data.rawColors { swizzleUIColor(rawColors) } - } - } -} diff --git a/Sources/VendettaTweak/Utils.x.swift b/Sources/VendettaTweak/Utils.x.swift deleted file mode 100644 index b8c8e23..0000000 --- a/Sources/VendettaTweak/Utils.x.swift +++ /dev/null @@ -1,6 +0,0 @@ -import Foundation - -func getDocumentDirectory() -> URL { - return try! FileManager.default.url( - for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false) -} diff --git a/VendettaXposed b/VendettaXposed deleted file mode 160000 index 0df9aae..0000000 --- a/VendettaXposed +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 0df9aaeb7bcf6eda8f405b1c959a4618c539fca3 diff --git a/control b/control index 2ba1f85..71003db 100644 --- a/control +++ b/control @@ -1,6 +1,6 @@ -Package: dev.beefers.vendetta -Name: Vendetta -Version: 0.0.2 +Package: com.pyoncord.bunny +Name: bunny +Version: 0.0.1 Architecture: iphoneos-arm Description: A mod for Discord's mobile apps. Maintainer: FieryFlames