Temporary Fix for commands
This commit is contained in:
parent
5084adb3a8
commit
5d1ac74115
8 changed files with 236 additions and 120 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -1,6 +1,4 @@
|
||||||
.idea
|
.idea
|
||||||
node_modules/
|
|
||||||
dist/
|
|
||||||
pnpm-lock.yaml
|
pnpm-lock.yaml
|
||||||
yarn.lock
|
yarn.lock
|
||||||
package-lock.json
|
package-lock.json
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { storage } from "@vendetta/plugin";
|
import { storage } from "@vendetta/plugin";
|
||||||
import { sendMessage } from "../utils/messages";
|
import { sendMessage, validateChannelForCommand } from "../utils/messages";
|
||||||
import { catFact, dogFact, uselessFact } from "../utils/api";
|
import { catFact, dogFact, uselessFact } from "../utils/api";
|
||||||
|
|
||||||
// Helper function to format fact response
|
// Helper function to format fact response
|
||||||
|
|
@ -20,8 +20,17 @@ export const catFactCommand = {
|
||||||
inputType: 1,
|
inputType: 1,
|
||||||
type: 1,
|
type: 1,
|
||||||
execute: async (args: any, ctx: any) => {
|
execute: async (args: any, ctx: any) => {
|
||||||
const fact = await catFact();
|
const channelValidation = validateChannelForCommand(ctx);
|
||||||
return sendMessage(ctx.channel.id, formatFactResponse(fact), ctx.message?.id, storage);
|
if (channelValidation) return channelValidation;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const fact = await catFact();
|
||||||
|
return sendMessage(ctx.channel.id, formatFactResponse(fact), ctx.message?.id, storage);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[CatFact] Error:', error);
|
||||||
|
// Silent fail - no error message in chat
|
||||||
|
return { type: 4 };
|
||||||
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -34,8 +43,17 @@ export const dogFactCommand = {
|
||||||
inputType: 1,
|
inputType: 1,
|
||||||
type: 1,
|
type: 1,
|
||||||
execute: async (args: any, ctx: any) => {
|
execute: async (args: any, ctx: any) => {
|
||||||
const fact = await dogFact();
|
const channelValidation = validateChannelForCommand(ctx);
|
||||||
return sendMessage(ctx.channel.id, formatFactResponse(fact), ctx.message?.id, storage);
|
if (channelValidation) return channelValidation;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const fact = await dogFact();
|
||||||
|
return sendMessage(ctx.channel.id, formatFactResponse(fact), ctx.message?.id, storage);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[DogFact] Error:', error);
|
||||||
|
// Silent fail - no error message in chat
|
||||||
|
return { type: 4 };
|
||||||
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -48,7 +66,16 @@ export const uselessFactCommand = {
|
||||||
inputType: 1,
|
inputType: 1,
|
||||||
type: 1,
|
type: 1,
|
||||||
execute: async (args: any, ctx: any) => {
|
execute: async (args: any, ctx: any) => {
|
||||||
const fact = await uselessFact();
|
const channelValidation = validateChannelForCommand(ctx);
|
||||||
return sendMessage(ctx.channel.id, formatFactResponse(fact), ctx.message?.id, storage);
|
if (channelValidation) return channelValidation;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const fact = await uselessFact();
|
||||||
|
return sendMessage(ctx.channel.id, formatFactResponse(fact), ctx.message?.id, storage);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[UselessFact] Error:', error);
|
||||||
|
// Silent fail - no error message in chat
|
||||||
|
return { type: 4 };
|
||||||
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,16 @@
|
||||||
import { findByProps } from "@vendetta/metro";
|
import { findByProps } from "@vendetta/metro";
|
||||||
import { url } from "@vendetta/metro/common";
|
import { url } from "@vendetta/metro/common";
|
||||||
|
import { validateChannelForCommand } from "../utils/messages";
|
||||||
|
|
||||||
const APIUtils = findByProps("getAPIBaseURL", "get");
|
const APIUtils = findByProps("getAPIBaseURL", "get");
|
||||||
const MessageActions = findByProps("sendMessage");
|
const MessageActions = findByProps("sendMessage");
|
||||||
const messageUtil = findByProps("sendBotMessage", "sendMessage", "receiveMessage");
|
const messageUtil = findByProps("sendBotMessage", "sendMessage", "receiveMessage");
|
||||||
|
|
||||||
|
// Generate consistent nonce
|
||||||
|
const generateNonce = () => {
|
||||||
|
return (BigInt(Date.now()) * BigInt(4194304) + BigInt(Math.floor(Math.random() * 4194304))).toString();
|
||||||
|
};
|
||||||
|
|
||||||
// Helper functions for fetching messages
|
// Helper functions for fetching messages
|
||||||
const getFirstGuildMessage = async (
|
const getFirstGuildMessage = async (
|
||||||
guildId: string,
|
guildId: string,
|
||||||
|
|
@ -65,6 +71,20 @@ export const firstMessageCommand = {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
execute: async (args: any, ctx: any) => {
|
execute: async (args: any, ctx: any) => {
|
||||||
|
// Special handling for threads/forum channels
|
||||||
|
if (ctx.channel.type >= 10 && ctx.channel.type <= 15) {
|
||||||
|
return {
|
||||||
|
type: 4,
|
||||||
|
data: {
|
||||||
|
content: "FirstMessage command doesn't work in thread or forum channels.",
|
||||||
|
flags: 64
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const channelValidation = validateChannelForCommand(ctx);
|
||||||
|
if (channelValidation) return channelValidation;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const options = new Map(args.map((option: any) => [option.name, option]));
|
const options = new Map(args.map((option: any) => [option.name, option]));
|
||||||
const user = options.get("user")?.value;
|
const user = options.get("user")?.value;
|
||||||
|
|
@ -96,7 +116,7 @@ export const firstMessageCommand = {
|
||||||
}
|
}
|
||||||
} else if (channel) {
|
} else if (channel) {
|
||||||
if (isDM) {
|
if (isDM) {
|
||||||
messageUtil.sendBotMessage(channelId, "This combination cannot be used in DMs!");
|
// Silent fail for invalid combination
|
||||||
return { type: 4 };
|
return { type: 4 };
|
||||||
}
|
}
|
||||||
message = await getFirstGuildMessage(guildId, null, channel);
|
message = await getFirstGuildMessage(guildId, null, channel);
|
||||||
|
|
@ -104,7 +124,7 @@ export const firstMessageCommand = {
|
||||||
} else {
|
} else {
|
||||||
// both user and channel specified
|
// both user and channel specified
|
||||||
if (isDM) {
|
if (isDM) {
|
||||||
messageUtil.sendBotMessage(channelId, "This combination cannot be used in DMs!");
|
// Silent fail for invalid combination
|
||||||
return { type: 4 };
|
return { type: 4 };
|
||||||
}
|
}
|
||||||
message = await getFirstGuildMessage(guildId, user, channel);
|
message = await getFirstGuildMessage(guildId, user, channel);
|
||||||
|
|
@ -112,12 +132,12 @@ export const firstMessageCommand = {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (send) {
|
if (send) {
|
||||||
const fixNonce = Date.now().toString();
|
const nonce = generateNonce();
|
||||||
MessageActions.sendMessage(
|
MessageActions.sendMessage(
|
||||||
ctx.channel.id,
|
ctx.channel.id,
|
||||||
{ content: result },
|
{ content: result },
|
||||||
void 0,
|
void 0,
|
||||||
{ nonce: fixNonce }
|
{ nonce }
|
||||||
);
|
);
|
||||||
return { type: 4 };
|
return { type: 4 };
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -126,7 +146,7 @@ export const firstMessageCommand = {
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("[FirstMessage] Error:", error);
|
console.error("[FirstMessage] Error:", error);
|
||||||
messageUtil.sendBotMessage(ctx.channel.id, "Failed to fetch the first message. Please try again.");
|
// Silent fail - no error message in chat
|
||||||
return { type: 4 };
|
return { type: 4 };
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { findByProps } from "@vendetta/metro";
|
import { findByProps } from "@vendetta/metro";
|
||||||
import { alerts } from "@vendetta/ui";
|
import { alerts } from "@vendetta/ui";
|
||||||
|
import { validateChannelForCommand } from "../utils/messages";
|
||||||
|
|
||||||
const MessageActions = findByProps("sendMessage");
|
const MessageActions = findByProps("sendMessage");
|
||||||
const messageUtil = findByProps(
|
const messageUtil = findByProps(
|
||||||
|
|
@ -27,6 +28,7 @@ const fetchImage = async (isNSFW: boolean): Promise<string | null> => {
|
||||||
if (!Array.isArray(data) || data.length === 0) {
|
if (!Array.isArray(data) || data.length === 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return data[0].file_url;
|
return data[0].file_url;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("[KonoChan Randomizer] Error fetching image:", error);
|
console.error("[KonoChan Randomizer] Error fetching image:", error);
|
||||||
|
|
@ -45,6 +47,11 @@ const showNSFWWarning = () => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Generate consistent nonce
|
||||||
|
const generateNonce = () => {
|
||||||
|
return (BigInt(Date.now()) * BigInt(4194304) + BigInt(Math.floor(Math.random() * 4194304))).toString();
|
||||||
|
};
|
||||||
|
|
||||||
// Common options for both commands
|
// Common options for both commands
|
||||||
const nsfwOption = {
|
const nsfwOption = {
|
||||||
name: "nsfw",
|
name: "nsfw",
|
||||||
|
|
@ -62,30 +69,36 @@ export const konoSelfCommand = {
|
||||||
displayDescription: "Fetch a random image from KonoChan for yourself.",
|
displayDescription: "Fetch a random image from KonoChan for yourself.",
|
||||||
options: [nsfwOption],
|
options: [nsfwOption],
|
||||||
execute: async (args: any, ctx: any) => {
|
execute: async (args: any, ctx: any) => {
|
||||||
const options = new Map(args.map((option: any) => [option.name, option]));
|
const channelValidation = validateChannelForCommand(ctx);
|
||||||
const isNSFW = options.get("nsfw")?.value || false;
|
if (channelValidation) return channelValidation;
|
||||||
|
|
||||||
// Check if channel is NSFW for NSFW content
|
try {
|
||||||
if (isNSFW && !ctx.channel.nsfw) {
|
const options = new Map(args.map((option: any) => [option.name, option]));
|
||||||
showNSFWWarning();
|
const isNSFW = options.get("nsfw")?.value || false;
|
||||||
return { type: 4 };
|
|
||||||
}
|
|
||||||
|
|
||||||
const imageUrl = await fetchImage(isNSFW);
|
// Check if channel is NSFW for NSFW content
|
||||||
|
if (isNSFW && !ctx.channel.nsfw) {
|
||||||
|
showNSFWWarning();
|
||||||
|
return { type: 4 };
|
||||||
|
}
|
||||||
|
|
||||||
|
const imageUrl = await fetchImage(isNSFW);
|
||||||
|
|
||||||
|
if (!imageUrl) {
|
||||||
|
// Silent fail - no error message
|
||||||
|
return { type: 4 };
|
||||||
|
}
|
||||||
|
|
||||||
if (!imageUrl) {
|
|
||||||
messageUtil.sendBotMessage(
|
messageUtil.sendBotMessage(
|
||||||
ctx.channel.id,
|
ctx.channel.id,
|
||||||
"No image found. Try again later.",
|
`Here's your random image: ${imageUrl}`,
|
||||||
);
|
);
|
||||||
return { type: 4 };
|
return { type: 4 };
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[KonoSelf] Error:', error);
|
||||||
|
// Silent fail - no error message in chat
|
||||||
|
return { type: 4 };
|
||||||
}
|
}
|
||||||
|
|
||||||
messageUtil.sendBotMessage(
|
|
||||||
ctx.channel.id,
|
|
||||||
`Here's your random image: ${imageUrl}`,
|
|
||||||
);
|
|
||||||
return { type: 4 };
|
|
||||||
},
|
},
|
||||||
applicationId: "-1",
|
applicationId: "-1",
|
||||||
inputType: 1,
|
inputType: 1,
|
||||||
|
|
@ -100,33 +113,36 @@ export const konoSendCommand = {
|
||||||
"Fetch a random image from KonoChan and send it to the channel.",
|
"Fetch a random image from KonoChan and send it to the channel.",
|
||||||
options: [nsfwOption],
|
options: [nsfwOption],
|
||||||
execute: async (args: any, ctx: any) => {
|
execute: async (args: any, ctx: any) => {
|
||||||
const options = new Map(args.map((option: any) => [option.name, option]));
|
const channelValidation = validateChannelForCommand(ctx);
|
||||||
const isNSFW = options.get("nsfw")?.value || false;
|
if (channelValidation) return channelValidation;
|
||||||
|
|
||||||
// Check if channel is NSFW for NSFW content
|
try {
|
||||||
if (isNSFW && !ctx.channel.nsfw) {
|
const options = new Map(args.map((option: any) => [option.name, option]));
|
||||||
showNSFWWarning();
|
const isNSFW = options.get("nsfw")?.value || false;
|
||||||
|
|
||||||
|
// Check if channel is NSFW for NSFW content
|
||||||
|
if (isNSFW && !ctx.channel.nsfw) {
|
||||||
|
showNSFWWarning();
|
||||||
|
return { type: 4 };
|
||||||
|
}
|
||||||
|
|
||||||
|
const imageUrl = await fetchImage(isNSFW);
|
||||||
|
|
||||||
|
if (!imageUrl) {
|
||||||
|
// Silent fail - no error message
|
||||||
|
return { type: 4 };
|
||||||
|
}
|
||||||
|
|
||||||
|
const nonce = generateNonce();
|
||||||
|
MessageActions.sendMessage(ctx.channel.id, { content: imageUrl }, void 0, {
|
||||||
|
nonce,
|
||||||
|
});
|
||||||
|
return { type: 4 };
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[KonoSend] Error:', error);
|
||||||
|
// Silent fail - no error message in chat
|
||||||
return { type: 4 };
|
return { type: 4 };
|
||||||
}
|
}
|
||||||
|
|
||||||
const imageUrl = await fetchImage(isNSFW);
|
|
||||||
|
|
||||||
if (!imageUrl) {
|
|
||||||
const fixNonce = Date.now().toString();
|
|
||||||
MessageActions.sendMessage(
|
|
||||||
ctx.channel.id,
|
|
||||||
{ content: "No image found. Try again later." },
|
|
||||||
void 0,
|
|
||||||
{ nonce: fixNonce },
|
|
||||||
);
|
|
||||||
return { type: 4 };
|
|
||||||
}
|
|
||||||
|
|
||||||
const fixNonce = Date.now().toString();
|
|
||||||
MessageActions.sendMessage(ctx.channel.id, { content: imageUrl }, void 0, {
|
|
||||||
nonce: fixNonce,
|
|
||||||
});
|
|
||||||
return { type: 4 };
|
|
||||||
},
|
},
|
||||||
applicationId: "-1",
|
applicationId: "-1",
|
||||||
inputType: 1,
|
inputType: 1,
|
||||||
|
|
|
||||||
|
|
@ -1,63 +1,56 @@
|
||||||
import { findByProps } from "@vendetta/metro";
|
import { plugins, themes } from "@vendetta";
|
||||||
import { themes } from "@vendetta/themes";
|
|
||||||
import { plugins } from "@vendetta/plugins";
|
|
||||||
import { storage } from "@vendetta/plugin";
|
import { storage } from "@vendetta/plugin";
|
||||||
import { alerts } from "@vendetta/ui";
|
import { alerts } from "@vendetta/ui";
|
||||||
import { sendMessage } from "../utils/messages";
|
import { sendMessage, validateChannelForCommand } from "../utils/messages";
|
||||||
import { openURL } from "@vendetta/metro/common";
|
|
||||||
|
|
||||||
const SPLIT_LARGE_MESSAGES_PLUGIN =
|
const SPLIT_LARGE_MESSAGES_PLUGIN = "github.com/fres621/vendetta-plugins";
|
||||||
"https://vd-plugins.github.io/proxy/actuallythesun.github.io/vendetta-plugins/SplitLargeMessages/";
|
|
||||||
|
|
||||||
const STATUS = {
|
const STATUS = {
|
||||||
ENABLED: "🟢",
|
ENABLED: "✅",
|
||||||
DISABLED: "🔴",
|
DISABLED: "❌",
|
||||||
SELECTED: "🔶",
|
SELECTED: "✅",
|
||||||
NOT_SELECTED: "🔷",
|
NOT_SELECTED: "❌",
|
||||||
} as const;
|
};
|
||||||
|
|
||||||
// Helper Functions
|
// Helper functions
|
||||||
const addonAuthors = (authors: Array<{ name: string }>) =>
|
const addonAuthors = (authors: any[]) => {
|
||||||
authors.map((author) => author.name).join(", ");
|
if (!authors || authors.length === 0) return "Unknown";
|
||||||
|
return authors.map((author) => author.name).join(", ");
|
||||||
|
};
|
||||||
|
|
||||||
const formatList = (list: string[]) => list.join("\n").trimEnd();
|
const formatList = (list: string[]) => list.join("\n");
|
||||||
|
|
||||||
const getListLength = (list: string[]) => formatList(list).length;
|
const getListLength = (list: string[]) => formatList(list).length;
|
||||||
|
|
||||||
const isSLMPluginInstalled = () =>
|
const isSLMPluginInstalled = () => {
|
||||||
Object.keys(plugins).includes(SPLIT_LARGE_MESSAGES_PLUGIN);
|
return Object.values(plugins).some((plugin) => plugin.id === SPLIT_LARGE_MESSAGES_PLUGIN);
|
||||||
|
};
|
||||||
|
|
||||||
const isSLMPluginEnabled = () =>
|
const isSLMPluginEnabled = () => {
|
||||||
Object.values(plugins).find((p) => p.id === SPLIT_LARGE_MESSAGES_PLUGIN)
|
const slmPlugin = Object.values(plugins).find((p) => p.id === SPLIT_LARGE_MESSAGES_PLUGIN);
|
||||||
?.enabled ?? false;
|
return slmPlugin?.enabled ?? false;
|
||||||
|
};
|
||||||
|
|
||||||
const showSplitPluginDialog = () => {
|
const showSplitPluginDialog = () => {
|
||||||
return alerts.showConfirmationAlert({
|
return alerts.showConfirmationAlert({
|
||||||
title: "Large Message Warning",
|
title: "Install Split Large Messages Plugin",
|
||||||
content:
|
content: "This list is over 2000 characters. Install the Split Large Messages plugin to send it.",
|
||||||
"This list is too long to send! Would you like to install the Split Large Messages plugin?",
|
confirmText: "Install",
|
||||||
confirmText: "Install Plugin",
|
|
||||||
cancelText: "Cancel",
|
cancelText: "Cancel",
|
||||||
confirmColor: "brand",
|
|
||||||
onConfirm: () => {
|
onConfirm: () => {
|
||||||
openURL(SPLIT_LARGE_MESSAGES_PLUGIN);
|
// Implementation to install plugin would go here
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const showEnablePluginDialog = () => {
|
const showEnablePluginDialog = () => {
|
||||||
return alerts.showConfirmationAlert({
|
return alerts.showConfirmationAlert({
|
||||||
title: "Plugin Disabled",
|
title: "Enable Split Large Messages Plugin",
|
||||||
content:
|
content: "This list is over 2000 characters. Enable the Split Large Messages plugin to send it.",
|
||||||
"The Split Large Messages plugin is installed but disabled. Would you like to enable it now?",
|
confirmText: "Enable",
|
||||||
confirmText: "Enable Plugin",
|
|
||||||
cancelText: "Cancel",
|
cancelText: "Cancel",
|
||||||
confirmColor: "brand",
|
|
||||||
onConfirm: () => {
|
onConfirm: () => {
|
||||||
// Enable the plugin
|
const slmPlugin = Object.values(plugins).find((p) => p.id === SPLIT_LARGE_MESSAGES_PLUGIN);
|
||||||
const slmPlugin = Object.values(plugins).find(
|
|
||||||
(p) => p.id === SPLIT_LARGE_MESSAGES_PLUGIN,
|
|
||||||
);
|
|
||||||
if (slmPlugin) {
|
if (slmPlugin) {
|
||||||
slmPlugin.enabled = true;
|
slmPlugin.enabled = true;
|
||||||
}
|
}
|
||||||
|
|
@ -67,8 +60,7 @@ const showEnablePluginDialog = () => {
|
||||||
|
|
||||||
// Command handlers
|
// Command handlers
|
||||||
async function handlePluginList(detailed: boolean, ctx: any) {
|
async function handlePluginList(detailed: boolean, ctx: any) {
|
||||||
const alwaysDetailed =
|
const alwaysDetailed = storage.listSettings?.pluginListAlwaysDetailed ?? false;
|
||||||
storage.listSettings?.pluginListAlwaysDetailed ?? false;
|
|
||||||
const pluginList = [
|
const pluginList = [
|
||||||
`**My Plugin List | ${Object.keys(plugins).length} Plugins**`,
|
`**My Plugin List | ${Object.keys(plugins).length} Plugins**`,
|
||||||
"",
|
"",
|
||||||
|
|
@ -182,9 +174,17 @@ export const pluginListCommand = {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
execute: async (args: any, ctx: any) => {
|
execute: async (args: any, ctx: any) => {
|
||||||
const detailed =
|
const channelValidation = validateChannelForCommand(ctx);
|
||||||
args.find((arg: any) => arg.name === "detailed")?.value ?? false;
|
if (channelValidation) return channelValidation;
|
||||||
return handlePluginList(detailed, ctx);
|
|
||||||
|
try {
|
||||||
|
const detailed = args.find((arg: any) => arg.name === "detailed")?.value ?? false;
|
||||||
|
return handlePluginList(detailed, ctx);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[PluginList] Error:', error);
|
||||||
|
// Silent fail - no error message in chat
|
||||||
|
return { type: 4 };
|
||||||
|
}
|
||||||
},
|
},
|
||||||
applicationId: "-1",
|
applicationId: "-1",
|
||||||
inputType: 1,
|
inputType: 1,
|
||||||
|
|
@ -207,9 +207,17 @@ export const themeListCommand = {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
execute: async (args: any, ctx: any) => {
|
execute: async (args: any, ctx: any) => {
|
||||||
const detailed =
|
const channelValidation = validateChannelForCommand(ctx);
|
||||||
args.find((arg: any) => arg.name === "detailed")?.value ?? false;
|
if (channelValidation) return channelValidation;
|
||||||
return handleThemeList(detailed, ctx);
|
|
||||||
|
try {
|
||||||
|
const detailed = args.find((arg: any) => arg.name === "detailed")?.value ?? false;
|
||||||
|
return handleThemeList(detailed, ctx);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[ThemeList] Error:', error);
|
||||||
|
// Silent fail - no error message in chat
|
||||||
|
return { type: 4 };
|
||||||
|
}
|
||||||
},
|
},
|
||||||
applicationId: "-1",
|
applicationId: "-1",
|
||||||
inputType: 1,
|
inputType: 1,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { findByStoreName } from "@vendetta/metro";
|
import { findByStoreName } from "@vendetta/metro";
|
||||||
import { sendMessage } from "../utils/messages";
|
import { sendMessage, validateChannelForCommand } from "../utils/messages";
|
||||||
import { getPetPetData } from "../utils/api";
|
import { getPetPetData } from "../utils/api";
|
||||||
|
|
||||||
const UserStore = findByStoreName("UserStore");
|
const UserStore = findByStoreName("UserStore");
|
||||||
|
|
@ -20,10 +20,19 @@ export const petPetCommand = {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
execute: async (args: any, ctx: any) => {
|
execute: async (args: any, ctx: any) => {
|
||||||
const user = await UserStore.getUser(args[0].value);
|
const channelValidation = validateChannelForCommand(ctx);
|
||||||
const image = user.getAvatarURL(512);
|
if (channelValidation) return channelValidation;
|
||||||
const data = await getPetPetData(image);
|
|
||||||
return sendMessage(ctx.channel.id, data.url, ctx.message?.id);
|
try {
|
||||||
|
const user = await UserStore.getUser(args[0].value);
|
||||||
|
const image = user.getAvatarURL(512);
|
||||||
|
const data = await getPetPetData(image);
|
||||||
|
return sendMessage(ctx.channel.id, data.url, ctx.message?.id);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[PetPet] Error:', error);
|
||||||
|
// Silent fail - no error message in chat
|
||||||
|
return { type: 4 };
|
||||||
|
}
|
||||||
},
|
},
|
||||||
applicationId: "-1",
|
applicationId: "-1",
|
||||||
inputType: 1,
|
inputType: 1,
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import { findByProps } from "@vendetta/metro";
|
||||||
import { getDebugInfo } from "@vendetta/debug";
|
import { getDebugInfo } from "@vendetta/debug";
|
||||||
import { ReactNative } from "@vendetta/metro/common";
|
import { ReactNative } from "@vendetta/metro/common";
|
||||||
import { storage } from "@vendetta/plugin";
|
import { storage } from "@vendetta/plugin";
|
||||||
|
import { validateChannelForCommand } from "../utils/messages";
|
||||||
|
|
||||||
const MessageActions = findByProps("sendMessage");
|
const MessageActions = findByProps("sendMessage");
|
||||||
const messageUtil = findByProps("sendBotMessage", "sendMessage", "receiveMessage");
|
const messageUtil = findByProps("sendBotMessage", "sendMessage", "receiveMessage");
|
||||||
|
|
@ -145,8 +146,16 @@ for (const cat of categories) {
|
||||||
if (storage[cat] === undefined) storage[cat] = true;
|
if (storage[cat] === undefined) storage[cat] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Command execution function
|
// Generate consistent nonce
|
||||||
function sysinfoCommand(args: any[], ctx: any) {
|
const generateNonce = () => {
|
||||||
|
return (BigInt(Date.now()) * BigInt(4194304) + BigInt(Math.floor(Math.random() * 4194304))).toString();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Command execution function (renamed to avoid conflict)
|
||||||
|
function executeSysinfoCommand(args: any[], ctx: any) {
|
||||||
|
const channelValidation = validateChannelForCommand(ctx);
|
||||||
|
if (channelValidation) return channelValidation;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let output = ["__System Information__\n"];
|
let output = ["__System Information__\n"];
|
||||||
const data = generateSystemInfo();
|
const data = generateSystemInfo();
|
||||||
|
|
@ -171,18 +180,18 @@ function sysinfoCommand(args: any[], ctx: any) {
|
||||||
messageUtil.sendBotMessage(ctx.channel.id, output.join("\n"));
|
messageUtil.sendBotMessage(ctx.channel.id, output.join("\n"));
|
||||||
return { type: 4 };
|
return { type: 4 };
|
||||||
} else {
|
} else {
|
||||||
const fixNonce = Date.now().toString();
|
const nonce = generateNonce();
|
||||||
MessageActions.sendMessage(
|
MessageActions.sendMessage(
|
||||||
ctx.channel.id,
|
ctx.channel.id,
|
||||||
{ content: output.join("\n") },
|
{ content: output.join("\n") },
|
||||||
void 0,
|
void 0,
|
||||||
{ nonce: fixNonce }
|
{ nonce }
|
||||||
);
|
);
|
||||||
return { type: 4 };
|
return { type: 4 };
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("[Sysinfo] Error:", e);
|
console.error("[Sysinfo] Error:", e);
|
||||||
messageUtil.sendBotMessage(ctx.channel.id, "Failed to generate system information. Please try again.");
|
// Silent fail - no chat message
|
||||||
return { type: 4 };
|
return { type: 4 };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -210,7 +219,7 @@ export const sysinfoCommand = {
|
||||||
required: false,
|
required: false,
|
||||||
})),
|
})),
|
||||||
],
|
],
|
||||||
execute: sysinfoCommand,
|
execute: executeSysinfoCommand,
|
||||||
applicationId: "-1",
|
applicationId: "-1",
|
||||||
inputType: 1,
|
inputType: 1,
|
||||||
type: 1,
|
type: 1,
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,14 @@ import { findByProps } from "@vendetta/metro";
|
||||||
|
|
||||||
const MessageActions = findByProps("sendMessage");
|
const MessageActions = findByProps("sendMessage");
|
||||||
|
|
||||||
|
// Channel type validation
|
||||||
|
const isValidChannel = (channelType: number) => {
|
||||||
|
// Allow: Text (0), DM (1), Voice (2), Group DM (3), News (5)
|
||||||
|
// Block: Threads (10,11,12), Forum (15), Stage (13), Category (4)
|
||||||
|
const unsupportedTypes = [4, 10, 11, 12, 13, 15];
|
||||||
|
return !unsupportedTypes.includes(channelType);
|
||||||
|
};
|
||||||
|
|
||||||
export const sendMessage = (
|
export const sendMessage = (
|
||||||
channelId: string,
|
channelId: string,
|
||||||
content: string,
|
content: string,
|
||||||
|
|
@ -23,17 +31,38 @@ export const sendMessage = (
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// For normal messages, send through MessageActions
|
try {
|
||||||
const message = {
|
// For normal messages, send through MessageActions
|
||||||
content,
|
const message = {
|
||||||
...(replyToId && storage?.factSettings?.sendAsReply
|
content,
|
||||||
? { messageReference: { messageId: replyToId } }
|
...(replyToId && storage?.factSettings?.sendAsReply
|
||||||
: {}),
|
? { messageReference: { messageId: replyToId } }
|
||||||
};
|
: {}),
|
||||||
|
};
|
||||||
|
|
||||||
MessageActions.sendMessage(channelId, message, void 0, {
|
// Use consistent, collision-resistant nonce generation
|
||||||
nonce: (Date.now() * 4194304).toString(),
|
const nonce = (BigInt(Date.now()) * BigInt(4194304) + BigInt(Math.floor(Math.random() * 4194304))).toString();
|
||||||
});
|
|
||||||
|
|
||||||
return { type: 4 }; // Acknowledge the command
|
MessageActions.sendMessage(channelId, message, void 0, { nonce });
|
||||||
|
|
||||||
|
return { type: 4 }; // Acknowledge the command
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[Commands] Message send failed:', error);
|
||||||
|
// Silent fail - no error message in chat
|
||||||
|
return { type: 4 };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Helper function to validate channel types in commands
|
||||||
|
export const validateChannelForCommand = (ctx: any) => {
|
||||||
|
if (!isValidChannel(ctx.channel.type)) {
|
||||||
|
return {
|
||||||
|
type: 4,
|
||||||
|
data: {
|
||||||
|
content: "This command cannot be used in threads, forum channels, or voice channels.",
|
||||||
|
flags: 64 // Ephemeral
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return null;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue