diff --git a/src/plugins/cursorBuddy/index.tsx b/src/plugins/cursorBuddy/index.tsx
new file mode 100644
index 000000000..4269475e3
--- /dev/null
+++ b/src/plugins/cursorBuddy/index.tsx
@@ -0,0 +1,139 @@
+/*
+ * Vencord, a modification for Discord's desktop app
+ * Copyright (c) 2022 Vendicated and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+*/
+
+import { definePluginSettings, migratePluginSettings } from "@api/Settings";
+import { Devs, EquicordDevs } from "@utils/constants";
+import definePlugin, { OptionType } from "@utils/types";
+
+const ONEKO_IMAGE = "https://raw.githubusercontent.com/adryd325/oneko.js/c4ee66353b11a44e4a5b7e914a81f8d33111555e/oneko.gif";
+const ONEKO_SCRIPT = "https://raw.githubusercontent.com/adryd325/oneko.js/c4ee66353b11a44e4a5b7e914a81f8d33111555e/oneko.js";
+const FATASS_HORSE = "https://raw.githubusercontent.com/nexpid/fatass-horse/351f158bfd8fafd44d9c17faad61f2a80bcd33e3/horse.js";
+
+const settings = definePluginSettings({
+ buddy: {
+ description: "Pick a cursor buddy",
+ type: OptionType.SELECT,
+ options: [
+ {
+ label: "Oneko",
+ value: "oneko",
+ default: true
+ },
+ {
+ label: "Fatass Horse",
+ value: "fathorse"
+ }
+ ],
+ onChange: load,
+ },
+ speed: {
+ description: "Speed of Da Cat :3",
+ type: OptionType.NUMBER,
+ default: 10,
+ isValid: (value: number) => value >= 0 || "Speed must be bigger than 0",
+ onChange: load,
+ },
+ fps: {
+ description: "Framerate of the fatass horse",
+ type: OptionType.NUMBER,
+ default: 24,
+ isValid: (value: number) => value > 0 || "Framerate must be bigger than 0",
+ onChange: load
+ },
+ size: {
+ description: "Size of the fatass horse",
+ type: OptionType.NUMBER,
+ default: 120,
+ isValid: (value: number) => value > 0 || "Size must be bigger than 0",
+ onChange: load
+ },
+ fade: {
+ description: "If the horse should fade when the cursor is near",
+ type: OptionType.BOOLEAN,
+ default: true,
+ onChange: load
+ },
+ freeroam: {
+ description: "If the horse should roam freely when idle",
+ type: OptionType.BOOLEAN,
+ default: true,
+ onChange: load
+ },
+ shake: {
+ description: "If the horse should shake the window when it's walking",
+ type: OptionType.BOOLEAN,
+ default: false,
+ onChange: load
+ },
+}, {
+ fps: {
+ disabled() { return this.store.buddy !== "fathorse"; },
+ },
+ size: {
+ disabled() { return this.store.buddy !== "fathorse"; },
+ },
+ fade: {
+ disabled() { return this.store.buddy !== "fathorse"; },
+ },
+ freeroam: {
+ disabled() { return this.store.buddy !== "fathorse"; },
+ },
+ shake: {
+ disabled() { return this.store.buddy !== "fathorse"; },
+ }
+});
+
+function unload() {
+ if (settings.store.buddy === "oneko") document.getElementById("oneko")?.remove();
+ if (settings.store.buddy === "fathorse") document.getElementById("fathorse")?.remove();
+}
+
+function load() {
+ switch (settings.store.buddy) {
+ case "oneko": {
+ fetch(ONEKO_SCRIPT)
+ .then(x => x.text())
+ .then(s => s.replace("const nekoSpeed = 10;", `const nekoSpeed = ${settings.store.speed};`))
+ .then(s => s.replace("./oneko.gif", ONEKO_IMAGE)
+ .replace("(isReducedMotion)", "(false)"))
+ .then(eval);
+ break;
+ }
+ case "fathorse": {
+ fetch(FATASS_HORSE).then(x => x.text()).then(s => (0, eval)(s)({
+ speed: settings.store.speed,
+ fps: settings.store.fps,
+ size: settings.store.size,
+ fade: settings.store.fade,
+ freeroam: settings.store.freeroam,
+ shake: settings.store.shake
+ }));
+ }
+ }
+}
+
+migratePluginSettings("CursorBuddy", "Oneko", "oneko");
+export default definePlugin({
+ name: "CursorBuddy",
+ description: "only a slightly annoying plugin",
+ authors: [Devs.Ven, Devs.adryd, EquicordDevs.nexpid],
+ settings,
+
+ start: load,
+ stop: unload,
+});
diff --git a/src/plugins/oneko/index.ts b/src/plugins/oneko/index.ts
deleted file mode 100644
index 590ae5d0f..000000000
--- a/src/plugins/oneko/index.ts
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Vencord, a modification for Discord's desktop app
- * Copyright (c) 2022 Vendicated and contributors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
-*/
-
-import { isPluginEnabled } from "@api/PluginManager";
-import { definePluginSettings, migratePluginSettings } from "@api/Settings";
-import { Devs } from "@utils/constants";
-import definePlugin, { OptionType } from "@utils/types";
-
-const settings = definePluginSettings({
- speed: {
- description: "Speed of Da Cat :3",
- type: OptionType.NUMBER,
- default: 10,
- isValid: (value: number) => {
- if (value && value < 0) return "The number must be bigger than 0";
- return true;
- },
- onChange: () => {
- // note: cant call the start() function from here. so i just copy pasted it (This was pointed out in the last commit i made. So this is to just clear stuff up for any future devs that work on this :D )
- if (isPluginEnabled("Oneko")) {
- document.getElementById("oneko")?.remove();
- fetch("https://raw.githubusercontent.com/adryd325/oneko.js/c4ee66353b11a44e4a5b7e914a81f8d33111555e/oneko.js")
- .then(x => x.text())
- .then(s => s.replace("const nekoSpeed = 10;", `const nekoSpeed = ${settings.store.speed};`))
- .then(s => s.replace("./oneko.gif", "https://raw.githubusercontent.com/adryd325/oneko.js/c4ee66353b11a44e4a5b7e914a81f8d33111555e/oneko.gif")
- .replace("(isReducedMotion)", "(false)"))
- .then(eval);
- }
- return;
- }
- }
-});
-
-migratePluginSettings("Oneko", "oneko");
-export default definePlugin({
- name: "Oneko",
- description: "cat follow mouse (real)",
- // Listing adryd here because this literally just evals her script
- authors: [Devs.Ven, Devs.adryd],
- settings,
-
- start() {
- fetch("https://raw.githubusercontent.com/adryd325/oneko.js/c4ee66353b11a44e4a5b7e914a81f8d33111555e/oneko.js")
- .then(x => x.text())
- .then(s => s.replace("const nekoSpeed = 10;", `const nekoSpeed = ${settings.store.speed};`))
- .then(s => s.replace("./oneko.gif", "https://raw.githubusercontent.com/adryd325/oneko.js/c4ee66353b11a44e4a5b7e914a81f8d33111555e/oneko.gif")
- .replace("(isReducedMotion)", "(false)"))
- .then(eval);
- },
-
- stop() {
- document.getElementById("oneko")?.remove();
- }
-});