Rebranding and stuff

This commit is contained in:
amsyarasyiq 2024-02-08 14:52:05 +08:00
parent 69264afbb2
commit f3537648d5
10 changed files with 104 additions and 52 deletions

View file

@ -1,6 +1,7 @@
BSD 3-Clause License
Copyright (c) 2023, Team Vendetta
Copyright (c) 2024, pylixonly
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

View file

@ -1,8 +1,12 @@
# Vendetta
> [!NOTE]
> This fork is still progressing, own loader coming soon?
> TODO: better name
# Pyondetta (Vendetta's fork)
A mod for Discord's mobile apps.
## Installing
Vendetta's codebase is platform-agnostic, but you need a platform-specific loader.
Pyondetta's codebase is platform-agnostic, but you need a platform-specific loader.
### Android
* Root - [VendettaXposed](https://github.com/vendetta-mod/VendettaXposed/releases/latest)
@ -17,13 +21,13 @@ Vendetta's codebase is platform-agnostic, but you need a platform-specific loade
- These IPAs do *not* work with AltStore! You should use [Sideloadly](https://sideloadly.io).
## Contributing
1. Install a Vendetta loader with loader config support (any mentioned in the [Installing](#installing) section).
1. Install a Pyondetta loader with loader config support (any mentioned in the [Installing](#installing) section).
2. Go to Settings > General and enable Developer Settings.
3. Clone the repo:
```
git clone https://github.com/vendetta-mod/Vendetta
git clone https://github.com/pyoncord/pyondetta
```
4. Install dependencies:
@ -32,7 +36,7 @@ Vendetta's codebase is platform-agnostic, but you need a platform-specific loade
```
<sup>`npm` or `yarn` should also work.</sup>
5. Build Vendetta's code:
5. Build Pyondetta's code:
```
pnpm build
```
@ -42,6 +46,6 @@ Vendetta's codebase is platform-agnostic, but you need a platform-specific loade
7. Go to Settings > Developer enabled earlier). Enable `Load from custom url` and input the IP address and port of the server (e.g. e.g. `http://192.168.1.236:4040`) in the new input box labelled `VENDETTA URL`.
8. Restart Discord. Upon reload, you should notice that your device will download Vendetta's bundled code from your server, rather than GitHub.
8. Restart Discord. Upon reload, you should notice that your device will download Pyondetta's bundled code from your server, rather than GitHub.
9. Make your changes, rebuild, reload, go wild!

108
build.mjs
View file

@ -1,34 +1,48 @@
import { build } from "esbuild";
import alias from "esbuild-plugin-alias";
// eslint-disable-next-line simple-import-sort/imports
import swc from "@swc/core";
import { promisify } from "util";
import { exec as _exec } from "child_process";
import fs from "fs/promises";
import path from "path";
import { execSync } from "child_process";
import esbuild from "esbuild";
import { readFile } from "fs/promises";
import { createServer } from "http";
import { argv } from "process";
const exec = promisify(_exec);
const hasArg = condition => argv.some(i => condition.test(i));
const isDev = hasArg(/-d|--dev/);
const isFlag = (s, l) => argv.slice(2).some(c => c === `-${s}` || c === `--${l}`);
const tsconfig = JSON.parse(await fs.readFile("./tsconfig.json"));
const aliases = Object.fromEntries(Object.entries(tsconfig.compilerOptions.paths).map(([alias, [target]]) => [alias, path.resolve(target)]));
const commit = (await exec("git rev-parse HEAD")).stdout.trim().substring(0, 7) || "custom";
const isRelease = isFlag("r", "release");
const shouldServe = isFlag("s", "serve");
const shouldWatch = isFlag("w", "watch");
// TODO: This does not change unless you re-execute the script
const timeHash = Number(new Date).toString(36);
const commitHash = execSync("git rev-parse --short HEAD").toString().trim();
try {
await build({
entryPoints: ["./src/entry.ts"],
outfile: "./dist/vendetta.js",
minify: !isDev,
const ctx = await esbuild.context({
entryPoints: ["src/entry.js"],
bundle: true,
minify: isRelease,
format: "iife",
target: "esnext",
outfile: "dist/pyoncord.js",
keepNames: true,
define: {
__vendettaIsDev: `${!isRelease}`,
__vendettaVersion: `"${isRelease ? commitHash : timeHash}"`,
},
footer: {
js: "//# sourceURL=pyondetta"
},
loader: { ".png": "dataurl" },
legalComments: "none",
alias: {
"@*": "src*",
"@types": "src/def.d.ts"
},
plugins: [
{
name: "swc",
setup: (build) => {
build.onLoad({ filter: /\.[jt]sx?/ }, async (args) => {
// This actually works for dependencies as well!!
setup(build) {
build.onLoad({ filter: /\.[jt]sx?/ }, async args => {
const result = await swc.transformFile(args.path, {
jsc: {
externalHelpers: true,
@ -38,26 +52,56 @@ try {
include: [
"transform-classes",
"transform-arrow-functions",
],
]
},
});
return { contents: result.code };
});
},
}
},
alias(aliases),
],
define: {
__vendettaIsDev: `${isDev}`,
__vendettaVersion: `"${isDev ? commit : "local build"}"`,
},
footer: {
js: "//# sourceURL=Vendetta",
},
legalComments: "none",
{
name: "buildLog",
setup: async build => {
build.onStart(() => console.log(`Building with commit hash "${commitHash}", isRelease="${isRelease}", timeHash="${timeHash}"`));
build.onEnd(result => console.log(`Built with ${result.errors?.length} errors!`));
}
}
]
});
console.log("Build successful!", `isDev=${isDev}`);
if (shouldWatch) {
await ctx.watch();
console.log("Watching...");
}
if (shouldServe) {
await ctx.rebuild();
const server = createServer(async (req, res) => {
try {
if (req.url === "/vendetta.js" || req.url === "/pyoncord.js" || req.url === "/pyondetta.js") {
await ctx.rebuild();
res.writeHead(200);
res.end(await readFile("./dist/pyoncord.js"), "utf-8");
} else {
res.writeHead(404);
res.end();
}
} catch (error) {
res.writeHead(500);
res.end();
}
}).listen(4040);
// @ts-ignore
console.log(`Serving on port ${server.address()?.port}, CTRL+C to stop`);
}
if (!shouldServe && !shouldWatch) {
ctx.rebuild();
ctx.dispose();
}
} catch (e) {
console.error("Build failed...", e);
process.exit(1);

View file

@ -1,9 +1,12 @@
{
"name": "vendetta",
"name": "pyondetta",
"version": "1.0.0",
"description": "A mod for Discord's mobile apps.",
"scripts": {
"build": "node build.mjs"
"dev": "node build.mjs",
"build": "node build.mjs --release",
"serve": "node build.mjs --serve",
"watch": "node build.mjs --watch"
},
"keywords": [
"discord",
@ -11,7 +14,7 @@
"ios",
"react native"
],
"author": "Beef",
"author": "pylixonly, Team Vendetta",
"license": "BSD-3-Clause",
"devDependencies": {
"@react-native-clipboard/clipboard": "1.10.0",

View file

@ -1,7 +1,7 @@
import { ClientInfoManager } from "@lib/native";
// This logs in the native logging implementation, e.g. logcat
console.log("Hello from Vendetta!");
console.log("Hello from Pyon-ified Vendetta!");
// Make 'freeze' and 'seal' do nothing
Object.freeze = Object;

View file

@ -15,7 +15,7 @@ export default function SettingsSection() {
return (
<ErrorBoundary>
<FormSection key="Vendetta" title={`Vendetta${settings.safeMode?.enabled ? " (Safe Mode)" : ""}`}>
<FormSection key="Vendetta" title={`Pyondetta${settings.safeMode?.enabled ? " (Safe Mode)" : ""}`}>
{screens.map((s, i) => (
<>
<FormRow

View file

@ -119,8 +119,8 @@ export const getYouData = () => {
return {
getLayout: () => ({
title: "Vendetta",
label: "Vendetta",
title: "Pyondetta",
label: "Pyondetta",
// We can't use our keyMap function here since `settings` is an array not an object
settings: getRenderableScreens(true).map(s => s.key)
}),

View file

@ -61,7 +61,7 @@ export default function Developer() {
<TableRowGroup title="Loader config">
<TableSwitchRow
label="Load from custom url"
subLabel={"Load Vendetta from a custom endpoint."}
subLabel={"Load Pyondetta from a custom endpoint."}
icon={<TableRow.Icon source={getAssetIDByName("copy")} />}
value={loaderConfig.customLoadUrl.enabled}
onValueChange={(v: boolean) => {
@ -73,7 +73,7 @@ export default function Developer() {
size="md"
onChange={(v: string) => loaderConfig.customLoadUrl.url = v}
placeholder="http://localhost:4040/vendetta.js"
label="Vendetta URL"
label="Pyondetta URL"
/>} />}
{window.__vendetta_loader.features.devtools && <TableSwitchRow
label="Load React DevTools"
@ -111,7 +111,7 @@ export default function Developer() {
options: [
// @ts-expect-error
// Of course, to trigger an error, we need to do something incorrectly. The below will do!
{ label: "Vendetta", onPress: () => navigation.push("VendettaCustomPage", { render: () => <undefined /> }) },
{ label: "Pyondetta", onPress: () => navigation.push("VendettaCustomPage", { render: () => <undefined /> }) },
{ label: "Discord", isDestructive: true, onPress: () => navigation.push("VendettaCustomPage", { noErrorBoundary: true }) },
],
})}

View file

@ -24,7 +24,7 @@ export default function General() {
const versions = [
{
label: "Vendetta",
label: "Pyondetta",
version: debugInfo.vendetta.version,
icon: "ic_progress_wrench_24px",
},

View file

@ -44,7 +44,7 @@ function oldYouPatch(patches: Function[]) {
ancestorRendererData: data.rendererConfigs[s.key],
setting: s.key,
title: data.titleConfig[s.key],
breadcrumbs: ["Vendetta"],
breadcrumbs: ["Pyondetta"],
icon: data.rendererConfigs[s.key].icon,
})),
// .filter can be removed when dropping support for 189.3 and below (unless Discord changes things again)
@ -78,7 +78,7 @@ function newYouPatch(patches: Function[]) {
patches.push(before("type", settingsListComponents.SearchableSettingsList, ([{ sections }]) => manipulateSections(sections, data.getLayout())));
patches.push(after("getSettingListSearchResultItems", gettersModule, (_, ret) => {
ret.forEach((s: any) => screens.some(b => b.key === s.setting) && (s.breadcrumbs = ["Vendetta"]))
ret.forEach((s: any) => screens.some(b => b.key === s.setting) && (s.breadcrumbs = ["Pyondetta"]))
}));
const oldRendererConfig = settingConstantsModule.SETTING_RENDERER_CONFIG;
@ -94,7 +94,7 @@ function newYouPatch(patches: Function[]) {
const isLabel = (i: any, name: string) => i?.label === name || i?.title === name;
function manipulateSections(sections: any[], layout: any) {
if (!Array.isArray(sections) || sections.find((i: any) => isLabel(i, "Vendetta"))) return;
if (!Array.isArray(sections) || sections.find((i: any) => isLabel(i, "Pyondetta"))) return;
// Add our settings
const accountSettingsIndex = sections.findIndex((i: any) => isLabel(i, i18n.Messages.ACCOUNT_SETTINGS));