3
0
Fork 0
mirror of https://github.com/ZeppelinBot/Zeppelin.git synced 2025-03-14 21:31:50 +00:00

Add !slowmode command

This commit is contained in:
Dragory 2020-08-09 17:28:21 +03:00
parent 2d8decdb4f
commit 5215dd0738
No known key found for this signature in database
GPG key ID: 5F387BA66DF8AAC1
10 changed files with 122 additions and 2 deletions

BIN
assets/icons/snowflake.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><path fill="#88C9F9" d="M19 27.586V8.415l4.828-4.829s.707-.707 0-1.415c-.707-.707-1.414 0-1.414 0L19 5.586V1s0-1-1-1-1 1-1 1v4.586l-3.414-3.415s-.707-.707-1.414 0c-.707.708 0 1.415 0 1.415L17 8.415v19.171l-4.828 4.828s-.707.707 0 1.414 1.414 0 1.414 0L17 30.414V35s0 1 1 1 1-1 1-1v-4.586l3.414 3.414s.707.707 1.414 0 0-1.414 0-1.414L19 27.586z"/><path fill="#88C9F9" d="M34.622 20.866c-.259-.966-1.225-.707-1.225-.707l-6.595 1.767-16.603-9.586-1.767-6.595s-.259-.966-1.225-.707C6.24 5.297 6.5 6.263 6.5 6.263l1.25 4.664-3.972-2.294s-.866-.5-1.366.366c-.5.866.366 1.366.366 1.366l3.971 2.293-4.664 1.249s-.967.259-.707 1.225c.259.967 1.225.708 1.225.708l6.596-1.767 16.603 9.586 1.767 6.596s.259.966 1.225.707c.966-.26.707-1.225.707-1.225l-1.25-4.664 3.972 2.293s.867.5 1.367-.365c.5-.867-.367-1.367-.367-1.367l-3.971-2.293 4.663-1.249c0-.001.966-.26.707-1.226z"/><path fill="#88C9F9" d="M33.915 13.907l-4.664-1.25 3.972-2.293s.867-.501.367-1.367c-.501-.867-1.367-.366-1.367-.366l-3.971 2.292 1.249-4.663s.259-.966-.707-1.225c-.966-.259-1.225.707-1.225.707l-1.767 6.595-16.604 9.589-6.594-1.768s-.966-.259-1.225.707c-.26.967.707 1.225.707 1.225l4.663 1.249-3.971 2.293s-.865.501-.365 1.367c.5.865 1.365.365 1.365.365l3.972-2.293-1.25 4.663s-.259.967.707 1.225c.967.26 1.226-.706 1.226-.706l1.768-6.597 16.604-9.585 6.595 1.768s.966.259 1.225-.707c.255-.967-.71-1.225-.71-1.225z"/></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -1,10 +1,14 @@
import {
channelMentionRegex,
convertDelayStringToMS,
disableCodeBlocks,
disableInlineCode,
isSnowflake,
isValidSnowflake,
resolveMember,
resolveUser,
resolveUserId,
roleMentionRegex,
UnknownUser,
} from "./utils";
import { GuildChannel, Member, TextChannel, User } from "eris";
@ -63,6 +67,23 @@ export const commandTypes = {
return result;
},
async anyId(value: string, context: CommandContext<any>) {
const userId = resolveUserId(context.pluginData.client, value);
if (userId) return userId;
const channelIdMatch = value.match(channelMentionRegex);
if (channelIdMatch) return channelIdMatch[1];
const roleIdMatch = value.match(roleMentionRegex);
if (roleIdMatch) return roleIdMatch[1];
if (isValidSnowflake(value)) {
return value;
}
throw new TypeConversionError(`Could not parse ID: \`${disableInlineCode(value)}\``);
},
};
export const commandTypeHelpers = {
@ -73,4 +94,5 @@ export const commandTypeHelpers = {
resolvedUserLoose: createTypeHelper<Promise<User | UnknownUser>>(commandTypes.resolvedUserLoose),
resolvedMember: createTypeHelper<Promise<Member | null>>(commandTypes.resolvedMember),
messageTarget: createTypeHelper<Promise<MessageTarget>>(commandTypes.messageTarget),
anyId: createTypeHelper<Promise<string>>(commandTypes.anyId),
};

View file

@ -31,6 +31,7 @@ import { InviteInfoCmd } from "./commands/InviteInfoCmd";
import { ChannelInfoCmd } from "./commands/ChannelInfoCmd";
import { MessageInfoCmd } from "./commands/MessageInfoCmd";
import { InfoCmd } from "./commands/InfoCmd";
import { SnowflakeInfoCmd } from "./commands/SnowflakeInfoCmd";
const defaultOptions: PluginOptions<UtilityPluginType> = {
config: {
@ -44,6 +45,7 @@ const defaultOptions: PluginOptions<UtilityPluginType> = {
can_channelinfo: false,
can_messageinfo: false,
can_userinfo: false,
can_snowflake: false,
can_reload_guild: false,
can_nickname: false,
can_ping: false,
@ -71,6 +73,7 @@ const defaultOptions: PluginOptions<UtilityPluginType> = {
can_channelinfo: true,
can_messageinfo: true,
can_userinfo: true,
can_snowflake: true,
can_nickname: true,
can_vcmove: true,
can_help: true,
@ -124,6 +127,7 @@ export const UtilityPlugin = zeppelinPlugin<UtilityPluginType>()("utility", {
ChannelInfoCmd,
MessageInfoCmd,
InfoCmd,
SnowflakeInfoCmd,
],
onLoad(pluginData) {

View file

@ -2,7 +2,7 @@ import { utilityCmd } from "../types";
import { commandTypeHelpers as ct } from "../../../commandTypes";
import { sendErrorMessage } from "../../../pluginUtils";
import { getInviteInfoEmbed } from "../functions/getInviteInfoEmbed";
import { parseInviteCodeInput, resolveInvite, resolveUser } from "../../../utils";
import { isValidSnowflake, parseInviteCodeInput, resolveInvite, resolveUser } from "../../../utils";
import { getUserInfoEmbed } from "../functions/getUserInfoEmbed";
import { resolveMessageTarget } from "../../../utils/resolveMessageTarget";
import { canReadChannel } from "../../../utils/canReadChannel";
@ -11,6 +11,7 @@ import { getChannelInfoEmbed } from "../functions/getChannelInfoEmbed";
import { getServerInfoEmbed } from "../functions/getServerInfoEmbed";
import { getChannelId } from "knub/dist/utils";
import { getGuildPreview } from "../functions/getGuildPreview";
import { getSnowflakeInfoEmbed } from "../functions/getSnowflakeInfoEmbed";
export const InfoCmd = utilityCmd({
trigger: "info",
@ -93,6 +94,13 @@ export const InfoCmd = utilityCmd({
}
}
// 7. Arbitrary ID
if (isValidSnowflake(value)) {
const embed = getSnowflakeInfoEmbed(pluginData, value, true);
message.channel.createMessage({ embed });
return;
}
// 7. No can do
sendErrorMessage(pluginData, message.channel, "Could not find anything with that value");
},

View file

@ -0,0 +1,21 @@
import { utilityCmd } from "../types";
import { commandTypeHelpers as ct } from "../../../commandTypes";
import { sendErrorMessage } from "../../../pluginUtils";
import { getChannelInfoEmbed } from "../functions/getChannelInfoEmbed";
import { getSnowflakeInfoEmbed } from "../functions/getSnowflakeInfoEmbed";
export const SnowflakeInfoCmd = utilityCmd({
trigger: ["snowflake", "snowflakeinfo"],
description: "Show information about a snowflake ID",
usage: "!snowflake 534722016549404673",
permission: "can_snowflake",
signature: {
id: ct.anyId(),
},
run({ message, args, pluginData }) {
const embed = getSnowflakeInfoEmbed(pluginData, args.id);
message.channel.createMessage({ embed });
},
});

View file

@ -0,0 +1,44 @@
import { Message, GuildTextableChannel, EmbedOptions } from "eris";
import { PluginData } from "knub";
import { UtilityPluginType } from "../types";
import { UnknownUser, trimLines, embedPadding, resolveMember, resolveUser, preEmbedPadding } from "src/utils";
import moment from "moment-timezone";
import { CaseTypes } from "src/data/CaseTypes";
import humanizeDuration from "humanize-duration";
import { snowflakeToTimestamp } from "../../../utils/snowflakeToTimestamp";
const SNOWFLAKE_ICON = "https://cdn.discordapp.com/attachments/740650744830623756/742020790471491668/snowflake.png";
export function getSnowflakeInfoEmbed(
pluginData: PluginData<UtilityPluginType>,
snowflake: string,
showUnknownWarning = false,
): EmbedOptions {
const embed: EmbedOptions = {
fields: [],
};
embed.author = {
name: `Snowflake: ${snowflake}`,
icon_url: SNOWFLAKE_ICON,
};
if (showUnknownWarning) {
embed.description =
"This is a valid [snowflake ID](https://discord.com/developers/docs/reference#snowflakes), but I don't know what it's for.";
}
const createdAtMS = snowflakeToTimestamp(snowflake);
const createdAt = moment(createdAtMS, "x");
const snowflakeAge = humanizeDuration(Date.now() - createdAtMS, {
largest: 2,
round: true,
});
embed.fields.push({
name: preEmbedPadding + "Basic information",
value: `Created: **${snowflakeAge} ago** (\`${createdAt.format("MMM D, YYYY [at] H:mm [UTC]")}\`)`,
});
return embed;
}

View file

@ -17,6 +17,7 @@ export const ConfigSchema = t.type({
can_channelinfo: t.boolean,
can_messageinfo: t.boolean,
can_userinfo: t.boolean,
can_snowflake: t.boolean,
can_reload_guild: t.boolean,
can_nickname: t.boolean,
can_ping: t.boolean,

View file

@ -58,6 +58,19 @@ export const WEEKS = 7 * 24 * HOURS;
export const EMPTY_CHAR = "\u200b";
// https://discord.com/developers/docs/reference#snowflakes
export const MIN_SNOWFLAKE = 0b000000000000000000000000000000000000000000_00001_00001_000000000001;
// 0b111111111111111111111111111111111111111111_11111_11111_111111111111 without _ which BigInt doesn't support
export const MAX_SNOWFLAKE = BigInt("0b1111111111111111111111111111111111111111111111111111111111111111");
const snowflakePattern = /^[1-9]\d+$/;
export function isValidSnowflake(str: string) {
if (!str.match(snowflakePattern)) return false;
if (parseInt(str, 10) < MIN_SNOWFLAKE) return false;
if (BigInt(str) > MAX_SNOWFLAKE) return false;
return true;
}
export const DISCORD_HTTP_ERROR_NAME = "DiscordHTTPError";
export const DISCORD_REST_ERROR_NAME = "DiscordRESTError";

View file

@ -1,7 +1,13 @@
import { isValidSnowflake } from "../utils";
/**
* @return Unix timestamp in milliseconds
*/
export function snowflakeToTimestamp(snowflake: string) {
if (!isValidSnowflake(snowflake)) {
throw new Error(`Invalid snowflake: ${snowflake}`);
}
// https://discord.com/developers/docs/reference#snowflakes-snowflake-id-format-structure-left-to-right
return Number(BigInt(snowflake) >> 22n) + 1420070400000;
return Number(BigInt(snowflake) >> 22n) + 1_420_070_400_000;
}