156 lines
5 KiB
TypeScript
156 lines
5 KiB
TypeScript
/*
|
|
* Vencord, a Discord client mod
|
|
* Copyright (c) 2024 Vendicated and contributors
|
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
*/
|
|
|
|
import { DataStore } from "@api/index";
|
|
import { definePluginSettings } from "@api/Settings";
|
|
import { Devs } from "@utils/constants";
|
|
import { useForceUpdater } from "@utils/react";
|
|
import definePlugin, { OptionType } from "@utils/types";
|
|
import { React } from "@webpack/common";
|
|
|
|
import { ReplaceSettings, ReplaceTutorial } from "./ReplaceSettings";
|
|
import { parse } from "path";
|
|
|
|
const APP_IDS_KEY = "ReplaceActivityType_appids";
|
|
export type AppIdSetting = {
|
|
disableAssets: boolean;
|
|
disableTimestamps: boolean;
|
|
appId: string;
|
|
enabled: boolean;
|
|
newActivityType: ActivityType;
|
|
newName: string,
|
|
newDetails: string,
|
|
newState: string,
|
|
newLargeImageUrl: string,
|
|
newLargeImageText: string,
|
|
newSmallImageUrl: string,
|
|
newSmallImageText: string;
|
|
newStreamUrl: string;
|
|
};
|
|
|
|
export interface Activity {
|
|
state: string;
|
|
details: string;
|
|
timestamps?: {
|
|
start?: number;
|
|
end?: number;
|
|
};
|
|
url?: string;
|
|
assets: ActivityAssets;
|
|
buttons?: Array<string>;
|
|
name: string;
|
|
application_id: string;
|
|
metadata?: {
|
|
button_urls?: Array<string>;
|
|
};
|
|
type: number;
|
|
flags: number;
|
|
}
|
|
|
|
interface ActivityAssets {
|
|
large_image: string;
|
|
large_text: string;
|
|
small_image: string;
|
|
small_text: string;
|
|
}
|
|
|
|
export const enum ActivityType {
|
|
PLAYING = 0,
|
|
STREAMING = 1,
|
|
LISTENING = 2,
|
|
WATCHING = 3,
|
|
COMPETING = 5
|
|
}
|
|
|
|
export const makeEmptyAppId: () => AppIdSetting = () => ({
|
|
appId: "",
|
|
enabled: true,
|
|
newActivityType: ActivityType.PLAYING,
|
|
newName: "",
|
|
newDetails: "",
|
|
newState: "",
|
|
newLargeImageUrl: "",
|
|
newLargeImageText: "",
|
|
newSmallImageUrl: "",
|
|
newSmallImageText: "",
|
|
newStreamUrl: "",
|
|
disableTimestamps: false,
|
|
disableAssets: false
|
|
});
|
|
|
|
let appIds = [makeEmptyAppId()];
|
|
|
|
const settings = definePluginSettings({
|
|
replacedAppIds: {
|
|
type: OptionType.COMPONENT,
|
|
description: "",
|
|
component: () => {
|
|
const update = useForceUpdater();
|
|
return (
|
|
<>
|
|
<ReplaceSettings
|
|
appIds={appIds}
|
|
update={update}
|
|
save={async () => DataStore.set(APP_IDS_KEY, appIds)}
|
|
/>
|
|
</>
|
|
);
|
|
}
|
|
},
|
|
});
|
|
|
|
export default definePlugin({
|
|
name: "RPCEditor",
|
|
description: "Edit the type and content of any Rich Presence",
|
|
authors: [Devs.Nyako, Devs.nin0dev],
|
|
patches: [
|
|
{
|
|
find: '"LocalActivityStore"',
|
|
replacement: {
|
|
match: /\i\((\i)\)\{.{0,50}activity.{0,10}=\i;/,
|
|
replace: "$&$self.patchActivity($1.activity);",
|
|
}
|
|
}
|
|
],
|
|
settings,
|
|
settingsAboutComponent: () => <ReplaceTutorial />,
|
|
|
|
async start() {
|
|
appIds = await DataStore.get(APP_IDS_KEY) ?? [makeEmptyAppId()];
|
|
},
|
|
parseField(text: string, originalActivity: Activity): string {
|
|
if (text === "null") return "";
|
|
return text
|
|
.replaceAll(":name:", originalActivity.name)
|
|
.replaceAll(":details:", originalActivity.details)
|
|
.replaceAll(":state:", originalActivity.state)
|
|
.replaceAll(":large_image:", originalActivity.assets.large_image)
|
|
.replaceAll(":large_text:", originalActivity.assets.large_text)
|
|
.replaceAll(":small_image:", originalActivity.assets.small_image)
|
|
.replaceAll(":small_text:", originalActivity.assets.small_text);
|
|
},
|
|
patchActivity(activity: Activity) {
|
|
if (!activity) return;
|
|
appIds.forEach(app => {
|
|
if (app.enabled && app.appId === activity.application_id) {
|
|
const oldActivity = { ...activity };
|
|
activity.type = app.newActivityType;
|
|
if (app.newName) activity.name = this.parseField(app.newName, oldActivity);
|
|
if (app.newActivityType === ActivityType.STREAMING && app.newStreamUrl) activity.url = app.newStreamUrl;
|
|
if (app.newDetails) activity.details = this.parseField(app.newDetails, oldActivity);
|
|
if (app.newState) activity.state = this.parseField(app.newState, oldActivity);
|
|
if (app.newLargeImageText) activity.assets.large_text = this.parseField(app.newLargeImageText, oldActivity);
|
|
if (app.newLargeImageUrl) activity.assets.large_image = this.parseField(app.newLargeImageUrl, oldActivity);
|
|
if (app.newSmallImageText) activity.assets.small_text = this.parseField(app.newSmallImageText, oldActivity);
|
|
if (app.newSmallImageUrl) activity.assets.small_image = this.parseField(app.newSmallImageUrl, oldActivity);
|
|
// @ts-ignore here we are intentionally nulling assets
|
|
if (app.disableAssets) activity.assets = {};
|
|
if (app.disableTimestamps) activity.timestamps = {};
|
|
}
|
|
});
|
|
},
|
|
});
|