diff --git a/src/plugins/corruptMp4s.ts b/src/plugins/corruptMp4s.ts new file mode 100644 index 000000000..aefff6715 --- /dev/null +++ b/src/plugins/corruptMp4s.ts @@ -0,0 +1,104 @@ +/* + * 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 { ApplicationCommandOptionType, sendBotMessage } from "../api/Commands"; +import { findOption } from "../api/Commands/commandHelpers"; +import { ApplicationCommandInputType } from "../api/Commands/types"; +import { Devs } from "../utils/constants"; +import definePlugin from "../utils/types"; +import { findByCode, findByProps } from "../webpack"; + +const DRAFT_TYPE = 0; + +export default definePlugin({ + name: "CorruptMp4s", + description: "Create corrupt mp4s with extremely high or negative duration", + authors: [Devs.Ven], + commands: [{ + name: "corrupt", + description: "Create a corrupt mp4 with extremely high or negative duration", + inputType: ApplicationCommandInputType.BUILT_IN, + options: [ + { + name: "mp4", + description: "the video to corrupt", + type: ApplicationCommandOptionType.ATTACHMENT, + required: true + }, + { + name: "kind", + description: "the kind of corruption", + type: ApplicationCommandOptionType.STRING, + choices: [ + { + name: "infinite", + value: "infinite", + label: "Very high duration" + }, + { + name: "negative", + value: "negative", + label: "Negative duration" + } + ] + } + ], + execute: async (args, ctx) => { + const UploadStore = findByProps("getUploads"); + const upload = UploadStore.getUploads(ctx.channel.id, DRAFT_TYPE)[0]; + + const video = upload?.item?.file as File | undefined; + + if (video?.type !== "video/mp4") + return void sendBotMessage(ctx.channel.id, { + content: "Please upload a mp4 file" + }); + + const corruption = findOption(args, "kind", "negative"); + + const buf = new Uint8Array(await video.arrayBuffer()); + let found = false; + + // adapted from https://github.com/GeopJr/exorcism/blob/c9a12d77ccbcb49c987b385eafae250906efc297/src/App.svelte#L41-L48 + for (let i = 0; i < buf.length; i++) { + if (buf[i] === 0x6d && buf[i + 1] === 0x76 && buf[i + 2] === 0x68 && buf[i + 3] === 0x64) { + let start = i + 18; + buf[start++] = 0x00; + buf[start++] = 0x01; + buf[start++] = corruption === "negative" ? 0xff : 0x7f; + buf[start++] = 0xff; + buf[start++] = 0xff; + buf[start++] = corruption === "negative" ? 0xf0 : 0xff; + found = true; + break; + } + } + + if (!found) { + return void sendBotMessage(ctx.channel.id, { + content: "Could not find signature. Is this even a mp4?" + }); + } + + const newName = video.name.replace(/\.mp4$/i, ".corrupt.mp4"); + const promptToUpload = findByCode("UPLOAD_FILE_LIMIT_ERROR"); + const file = new File([buf], newName, { type: "video/mp4" }); + setImmediate(() => promptToUpload([file], ctx.channel, DRAFT_TYPE)); + } + }] +}); diff --git a/src/plugins/petpet.ts b/src/plugins/petpet.ts index 59b4e56bb..7a794fd47 100644 --- a/src/plugins/petpet.ts +++ b/src/plugins/petpet.ts @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -import { ApplicationCommandInputType, ApplicationCommandOptionType, Argument, CommandContext, findOption } from "../api/Commands"; +import { ApplicationCommandInputType, ApplicationCommandOptionType, Argument, CommandContext, findOption, sendBotMessage } from "../api/Commands"; import { Devs } from "../utils/constants"; import { getGifEncoder } from "../utils/dependencies"; import { lazyWebpack, makeLazy } from "../utils/misc"; @@ -132,8 +132,9 @@ export default definePlugin({ var url = await resolveImage(opts, cmdCtx, noServerPfp); if (!url) throw "No Image specified!"; } catch (err) { - // Todo make this send a clyde message once that PR is done - console.log(err); + sendBotMessage(cmdCtx.channel.id, { + content: String(err), + }); return; }