bump to 1.1.0
This commit is contained in:
parent
e05df4ac83
commit
1bb01b83aa
4 changed files with 358 additions and 5 deletions
|
|
@ -18,6 +18,8 @@ import {
|
|||
} from "./src/commands/spotify";
|
||||
import { garyCommand } from "./src/commands/gary";
|
||||
import { lovefemboysCommand } from "./src/commands/lovefemboys";
|
||||
import { ipCommand } from "./src/commands/ip";
|
||||
import { nekoslifeCommand } from "./src/commands/nekoslife";
|
||||
import settings from "./settings";
|
||||
|
||||
// Initialize storage with default values
|
||||
|
|
@ -58,7 +60,9 @@ if (!storage.enabledCommands) {
|
|||
spotifyArtists: true,
|
||||
spotifyCover: true,
|
||||
gary: true,
|
||||
ip: true, // IP command - enabled by default
|
||||
lovefemboys: false, // Hidden command - disabled by default
|
||||
nekoslife: false, // Hidden command - disabled by default
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -67,6 +71,7 @@ if (!storage.hiddenSettings) {
|
|||
storage.hiddenSettings = {
|
||||
enabled: false,
|
||||
visible: false,
|
||||
konochanBypassNsfw: false, // NSFW bypass option
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -87,7 +92,9 @@ const commandMap = {
|
|||
spotifyArtists: spotifyArtistsCommand,
|
||||
spotifyCover: spotifyCoverCommand,
|
||||
gary: garyCommand,
|
||||
ip: ipCommand, // Add IP command
|
||||
lovefemboys: lovefemboysCommand, // Add hidden command to map
|
||||
nekoslife: nekoslifeCommand, // Add NekosLife command
|
||||
};
|
||||
|
||||
// Store registered commands for cleanup
|
||||
|
|
|
|||
|
|
@ -42,7 +42,9 @@ storage.enabledCommands ??= {
|
|||
spotifyArtists: true,
|
||||
spotifyCover: true,
|
||||
gary: true,
|
||||
ip: true, // IP command - enabled by default
|
||||
lovefemboys: false, // Hidden command - disabled by default
|
||||
nekoslife: false, // Hidden command - disabled by default
|
||||
};
|
||||
|
||||
storage.pendingRestart ??= false;
|
||||
|
|
@ -207,7 +209,7 @@ function Header({ onHiddenUnlock }: { onHiddenUnlock?: () => void }) {
|
|||
);
|
||||
}
|
||||
|
||||
// Hidden Commands Settings Page with NSFW bypass option
|
||||
// Hidden Commands Settings Page with NSFW bypass option and NekosLife
|
||||
function HiddenSettingsPage() {
|
||||
useProxy(storage);
|
||||
const [, forceUpdate] = React.useReducer((x) => x + 1, 0);
|
||||
|
|
@ -257,6 +259,17 @@ function HiddenSettingsPage() {
|
|||
forceUpdate();
|
||||
}}
|
||||
/>
|
||||
<FormSwitchRow
|
||||
label="/nekoslife"
|
||||
subLabel="Get images/gifs from nekos.life (NSFW content available)"
|
||||
leading={<FormRow.Icon source={getAssetIDByName("ImageIcon")} />}
|
||||
value={storage.enabledCommands.nekoslife}
|
||||
onValueChange={(v) => {
|
||||
storage.enabledCommands.nekoslife = v;
|
||||
storage.pendingRestart = true;
|
||||
forceUpdate();
|
||||
}}
|
||||
/>
|
||||
</BetterTableRowGroup>
|
||||
|
||||
<BetterTableRowGroup title="NSFW Bypass Options" icon={getAssetIDByName("WarningIcon")}>
|
||||
|
|
@ -310,8 +323,9 @@ function HiddenSettingsPage() {
|
|||
onConfirm: () => {
|
||||
storage.hiddenSettings.enabled = false;
|
||||
storage.hiddenSettings.visible = false;
|
||||
storage.hiddenSettings.konochanBypassNsfw = false; // Reset bypass option
|
||||
storage.hiddenSettings.konochanBypassNsfw = false;
|
||||
storage.enabledCommands.lovefemboys = false;
|
||||
storage.enabledCommands.nekoslife = false; // Reset nekoslife too
|
||||
storage.pendingRestart = true;
|
||||
showToast("Hidden settings reset", getAssetIDByName("CheckmarkIcon"));
|
||||
},
|
||||
|
|
@ -692,7 +706,7 @@ function SpotifySettingsPage() {
|
|||
);
|
||||
}
|
||||
|
||||
// Other Settings Page
|
||||
// Other Settings Page - Updated with IP command
|
||||
function OtherSettingsPage() {
|
||||
useProxy(storage);
|
||||
const [, forceUpdate] = React.useReducer((x) => x + 1, 0);
|
||||
|
|
@ -727,6 +741,20 @@ function OtherSettingsPage() {
|
|||
}}
|
||||
/>
|
||||
</BetterTableRowGroup>
|
||||
|
||||
<BetterTableRowGroup title="Network Commands" icon={getAssetIDByName("GlobeEarthIcon")}>
|
||||
<FormSwitchRow
|
||||
label="/ip"
|
||||
subLabel="IP address and domain lookup"
|
||||
leading={<FormRow.Icon source={getAssetIDByName("GlobeEarthIcon")} />}
|
||||
value={storage.enabledCommands.ip}
|
||||
onValueChange={(v) => {
|
||||
storage.enabledCommands.ip = v;
|
||||
storage.pendingRestart = true;
|
||||
forceUpdate();
|
||||
}}
|
||||
/>
|
||||
</BetterTableRowGroup>
|
||||
</RN.View>
|
||||
</ScrollView>
|
||||
);
|
||||
|
|
@ -845,6 +873,12 @@ function CreditsPage() {
|
|||
avatar: "https://github.com/Zach11111.png",
|
||||
github: "https://github.com/Zach11111"
|
||||
},
|
||||
{
|
||||
command: "IP & NekosLife Commands",
|
||||
author: "scruzism",
|
||||
avatar: "https://github.com/scruzism.png",
|
||||
github: "https://github.com/scruzism"
|
||||
},
|
||||
];
|
||||
|
||||
const handleProfilePress = (githubUrl: string) => {
|
||||
|
|
@ -883,7 +917,7 @@ function CreditsPage() {
|
|||
<BetterTableRowGroup title="About" icon={getAssetIDByName("InfoIcon")} padding={true}>
|
||||
<RN.Text style={styles.versionText}>
|
||||
Commands Plugin Collection{'\n'}
|
||||
Version 1.0.2
|
||||
Version 1.1.0
|
||||
</RN.Text>
|
||||
</BetterTableRowGroup>
|
||||
</RN.View>
|
||||
|
|
@ -972,7 +1006,7 @@ export default function Settings() {
|
|||
/>
|
||||
<FormRow
|
||||
label="Other Commands"
|
||||
subLabel="System info and miscellaneous"
|
||||
subLabel="System info, network tools, and miscellaneous"
|
||||
leading={<FormRow.Icon source={getAssetIDByName("MoreHorizontalIcon")} />}
|
||||
trailing={<FormRow.Arrow />}
|
||||
onPress={() => navigation.push("VendettaCustomPage", {
|
||||
|
|
|
|||
156
plugins/Commands/src/commands/ip.ts
Normal file
156
plugins/Commands/src/commands/ip.ts
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
import { findByProps } from "@vendetta/metro";
|
||||
import { showToast } from "@vendetta/ui/toasts";
|
||||
import { getAssetIDByName } from "@vendetta/ui/assets";
|
||||
|
||||
const MessageActions = findByProps("sendMessage");
|
||||
const messageUtil = findByProps("sendBotMessage", "sendMessage", "receiveMessage");
|
||||
|
||||
interface IpWhoisResponse {
|
||||
success: boolean;
|
||||
ip: string;
|
||||
type: string;
|
||||
as: string;
|
||||
org: string;
|
||||
isp: string;
|
||||
continent: string;
|
||||
country: string;
|
||||
country_capital: string;
|
||||
city: string;
|
||||
region: string;
|
||||
country_phone: string;
|
||||
latitude: number;
|
||||
longitude: number;
|
||||
timezone: string;
|
||||
currency: string;
|
||||
completed_requests: number;
|
||||
}
|
||||
|
||||
export const ipCommand = {
|
||||
name: "ip",
|
||||
displayName: "ip",
|
||||
description: "IP address and domain lookup",
|
||||
displayDescription: "IP address and domain lookup",
|
||||
options: [
|
||||
{
|
||||
name: "query",
|
||||
displayName: "query",
|
||||
description: "Enter IPv4/IPv6 address or domain name",
|
||||
displayDescription: "Enter IPv4/IPv6 address or domain name",
|
||||
type: 3, // String
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: "send",
|
||||
displayName: "send",
|
||||
description: "Send to chat",
|
||||
displayDescription: "Send to chat",
|
||||
type: 5, // Boolean
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
name: "ephemeral",
|
||||
displayName: "ephemeral",
|
||||
description: "Send as ephemeral message (only you can see)",
|
||||
displayDescription: "Send as ephemeral message (only you can see)",
|
||||
type: 5, // Boolean
|
||||
required: false,
|
||||
}
|
||||
],
|
||||
execute: async (args: any, ctx: any) => {
|
||||
try {
|
||||
const query = args.find((arg: any) => arg.name === "query")?.value;
|
||||
const shouldSend = args.find((arg: any) => arg.name === "send")?.value || false;
|
||||
const isEphemeral = args.find((arg: any) => arg.name === "ephemeral")?.value || false;
|
||||
|
||||
if (!query) {
|
||||
const errorMsg = "❌ Query parameter is required!";
|
||||
if (isEphemeral) {
|
||||
return {
|
||||
type: 4,
|
||||
data: {
|
||||
content: errorMsg,
|
||||
flags: 64,
|
||||
},
|
||||
};
|
||||
}
|
||||
showToast(errorMsg, getAssetIDByName("CircleXIcon"));
|
||||
return { type: 4 };
|
||||
}
|
||||
|
||||
// Show loading toast
|
||||
if (!isEphemeral && !shouldSend) {
|
||||
showToast(`Looking up IP information for ${query}...`, getAssetIDByName("DownloadIcon"));
|
||||
}
|
||||
|
||||
// Build API URL with all requested fields
|
||||
const url = `http://ipwhois.app/json/${encodeURIComponent(query)}?objects=` +
|
||||
`success,ip,type,as,org,isp,continent,country,country_capital,city,region,` +
|
||||
`country_phone,latitude,longitude,timezone,currency,completed_requests`;
|
||||
|
||||
const response = await fetch(url);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
||||
}
|
||||
|
||||
const data: IpWhoisResponse = await response.json();
|
||||
|
||||
if (!data.success) {
|
||||
const errorMsg = `❌ Failed to lookup IP information for: ${query}`;
|
||||
if (isEphemeral) {
|
||||
return {
|
||||
type: 4,
|
||||
data: {
|
||||
content: errorMsg,
|
||||
flags: 64,
|
||||
},
|
||||
};
|
||||
}
|
||||
showToast(errorMsg, getAssetIDByName("CircleXIcon"));
|
||||
return { type: 4 };
|
||||
}
|
||||
|
||||
// Format the response as code block
|
||||
const formattedData = JSON.stringify(data, null, 4);
|
||||
const content = `\`\`\`json\n${formattedData}\n\`\`\``;
|
||||
|
||||
if (isEphemeral) {
|
||||
return {
|
||||
type: 4,
|
||||
data: {
|
||||
content,
|
||||
flags: 64,
|
||||
},
|
||||
};
|
||||
} else if (shouldSend) {
|
||||
const fixNonce = Date.now().toString();
|
||||
MessageActions.sendMessage(ctx.channel.id, { content }, void 0, { nonce: fixNonce });
|
||||
return { type: 4 };
|
||||
} else {
|
||||
// Send as bot message (ephemeral-like)
|
||||
messageUtil.sendBotMessage(ctx.channel.id, content);
|
||||
return { type: 4 };
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[IP] Command error:', error);
|
||||
const errorMessage = `❌ An error occurred while looking up IP information: ${error.message || 'Unknown error'}`;
|
||||
|
||||
const isEphemeral = args?.find?.((arg: any) => arg.name === "ephemeral")?.value ?? false;
|
||||
|
||||
if (isEphemeral) {
|
||||
return {
|
||||
type: 4,
|
||||
data: {
|
||||
content: errorMessage,
|
||||
flags: 64,
|
||||
},
|
||||
};
|
||||
}
|
||||
showToast(errorMessage, getAssetIDByName("CircleXIcon"));
|
||||
return { type: 4 };
|
||||
}
|
||||
},
|
||||
applicationId: "-1",
|
||||
inputType: 1,
|
||||
type: 1,
|
||||
};
|
||||
156
plugins/Commands/src/commands/nekoslife.ts
Normal file
156
plugins/Commands/src/commands/nekoslife.ts
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
import { findByProps } from "@vendetta/metro";
|
||||
import { showToast } from "@vendetta/ui/toasts";
|
||||
import { getAssetIDByName } from "@vendetta/ui/assets";
|
||||
|
||||
const MessageActions = findByProps("sendMessage");
|
||||
const messageUtil = findByProps("sendBotMessage", "sendMessage", "receiveMessage");
|
||||
|
||||
interface IpWhoisResponse {
|
||||
success: boolean;
|
||||
ip: string;
|
||||
type: string;
|
||||
as: string;
|
||||
org: string;
|
||||
isp: string;
|
||||
continent: string;
|
||||
country: string;
|
||||
country_capital: string;
|
||||
city: string;
|
||||
region: string;
|
||||
country_phone: string;
|
||||
latitude: number;
|
||||
longitude: number;
|
||||
timezone: string;
|
||||
currency: string;
|
||||
completed_requests: number;
|
||||
}
|
||||
|
||||
export const ipCommand = {
|
||||
name: "ip",
|
||||
displayName: "ip",
|
||||
description: "IP address and domain lookup",
|
||||
displayDescription: "IP address and domain lookup",
|
||||
options: [
|
||||
{
|
||||
name: "query",
|
||||
displayName: "query",
|
||||
description: "Enter IPv4/IPv6 address or domain name",
|
||||
displayDescription: "Enter IPv4/IPv6 address or domain name",
|
||||
type: 3, // String
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: "send",
|
||||
displayName: "send",
|
||||
description: "Send to chat",
|
||||
displayDescription: "Send to chat",
|
||||
type: 5, // Boolean
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
name: "ephemeral",
|
||||
displayName: "ephemeral",
|
||||
description: "Send as ephemeral message (only you can see)",
|
||||
displayDescription: "Send as ephemeral message (only you can see)",
|
||||
type: 5, // Boolean
|
||||
required: false,
|
||||
}
|
||||
],
|
||||
execute: async (args: any, ctx: any) => {
|
||||
try {
|
||||
const query = args.find((arg: any) => arg.name === "query")?.value;
|
||||
const shouldSend = args.find((arg: any) => arg.name === "send")?.value || false;
|
||||
const isEphemeral = args.find((arg: any) => arg.name === "ephemeral")?.value || false;
|
||||
|
||||
if (!query) {
|
||||
const errorMsg = "❌ Query parameter is required!";
|
||||
if (isEphemeral) {
|
||||
return {
|
||||
type: 4,
|
||||
data: {
|
||||
content: errorMsg,
|
||||
flags: 64,
|
||||
},
|
||||
};
|
||||
}
|
||||
showToast(errorMsg, getAssetIDByName("CircleXIcon"));
|
||||
return { type: 4 };
|
||||
}
|
||||
|
||||
// Show loading toast
|
||||
if (!isEphemeral && !shouldSend) {
|
||||
showToast(`Looking up IP information for ${query}...`, getAssetIDByName("DownloadIcon"));
|
||||
}
|
||||
|
||||
// Build API URL with all requested fields
|
||||
const url = `http://ipwhois.app/json/${encodeURIComponent(query)}?objects=` +
|
||||
`success,ip,type,as,org,isp,continent,country,country_capital,city,region,` +
|
||||
`country_phone,latitude,longitude,timezone,currency,completed_requests`;
|
||||
|
||||
const response = await fetch(url);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
||||
}
|
||||
|
||||
const data: IpWhoisResponse = await response.json();
|
||||
|
||||
if (!data.success) {
|
||||
const errorMsg = `❌ Failed to lookup IP information for: ${query}`;
|
||||
if (isEphemeral) {
|
||||
return {
|
||||
type: 4,
|
||||
data: {
|
||||
content: errorMsg,
|
||||
flags: 64,
|
||||
},
|
||||
};
|
||||
}
|
||||
showToast(errorMsg, getAssetIDByName("CircleXIcon"));
|
||||
return { type: 4 };
|
||||
}
|
||||
|
||||
// Format the response as code block
|
||||
const formattedData = JSON.stringify(data, null, 4);
|
||||
const content = `\`\`\`json\n${formattedData}\n\`\`\``;
|
||||
|
||||
if (isEphemeral) {
|
||||
return {
|
||||
type: 4,
|
||||
data: {
|
||||
content,
|
||||
flags: 64,
|
||||
},
|
||||
};
|
||||
} else if (shouldSend) {
|
||||
const fixNonce = Date.now().toString();
|
||||
MessageActions.sendMessage(ctx.channel.id, { content }, void 0, { nonce: fixNonce });
|
||||
return { type: 4 };
|
||||
} else {
|
||||
// Send as bot message (ephemeral-like)
|
||||
messageUtil.sendBotMessage(ctx.channel.id, content);
|
||||
return { type: 4 };
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[IP] Command error:', error);
|
||||
const errorMessage = `❌ An error occurred while looking up IP information: ${error.message || 'Unknown error'}`;
|
||||
|
||||
const isEphemeral = args?.find?.((arg: any) => arg.name === "ephemeral")?.value ?? false;
|
||||
|
||||
if (isEphemeral) {
|
||||
return {
|
||||
type: 4,
|
||||
data: {
|
||||
content: errorMessage,
|
||||
flags: 64,
|
||||
},
|
||||
};
|
||||
}
|
||||
showToast(errorMessage, getAssetIDByName("CircleXIcon"));
|
||||
return { type: 4 };
|
||||
}
|
||||
},
|
||||
applicationId: "-1",
|
||||
inputType: 1,
|
||||
type: 1,
|
||||
};
|
||||
Loading…
Add table
Reference in a new issue