summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/api/routes/guilds/#guild_id/emojis.ts26
-rw-r--r--src/api/util/utility/Base64.ts11
-rw-r--r--src/util/util/Array.ts20
3 files changed, 55 insertions, 2 deletions
diff --git a/src/api/routes/guilds/#guild_id/emojis.ts b/src/api/routes/guilds/#guild_id/emojis.ts
index 491c9be2..67c888b7 100644
--- a/src/api/routes/guilds/#guild_id/emojis.ts
+++ b/src/api/routes/guilds/#guild_id/emojis.ts
@@ -29,8 +29,9 @@ import {
 	User,
 	EmojiCreateSchema,
 	EmojiModifySchema,
+	arrayBufferMatchesArr,
 } from "@fosscord/util";
-import { route } from "@fosscord/api";
+import { route, toByteArray } from "@fosscord/api";
 
 const router = Router();
 
@@ -85,6 +86,27 @@ router.post(
 		const user = await User.findOneOrFail({ where: { id: req.user_id } });
 		body.image = (await handleFile(`/emojis/${id}`, body.image)) as string;
 
+		// Rory - 20/01/2023 - Check for animated emojis
+		let animated = false;
+		let buffer = toByteArray(body.image);
+		if (
+			arrayBufferMatchesArr(
+				buffer,
+				[0x47, 0x49, 0x46, 0x38, 0x39, 0x61],
+				0,
+			)
+		)
+			animated = true; //gif87
+		if (
+			arrayBufferMatchesArr(
+				buffer,
+				[0x47, 0x49, 0x46, 0x38, 0x37, 0x61],
+				0,
+			)
+		)
+			animated = true; //gif89
+		// TODO: identify more formats
+
 		const emoji = await Emoji.create({
 			id: id,
 			guild_id: guild_id,
@@ -92,7 +114,7 @@ router.post(
 			require_colons: body.require_colons ?? undefined, // schema allows nulls, db does not
 			user: user,
 			managed: false,
-			animated: false, // TODO: Add support animated emojis
+			animated,
 			available: true,
 			roles: [],
 		}).save();
diff --git a/src/api/util/utility/Base64.ts b/src/api/util/utility/Base64.ts
index 892e0ada..a1e7931f 100644
--- a/src/api/util/utility/Base64.ts
+++ b/src/api/util/utility/Base64.ts
@@ -64,3 +64,14 @@ export const bton = (base64: string) => {
 
 	return sign ? -number : number;
 };
+
+// Rory - 20/01/2023 - Add utility functions to aid with identification of file types in emojis
+export const toByteArray = (str: string) => {
+	let binary_string = atob(str);
+	let len = binary_string.length;
+	let bytes = new Uint8Array(len);
+	for (let i = 0; i < len; i++) {
+		bytes[i] = binary_string.charCodeAt(i);
+	}
+	return bytes;
+};
diff --git a/src/util/util/Array.ts b/src/util/util/Array.ts
index 1935fa7a..e1008aa2 100644
--- a/src/util/util/Array.ts
+++ b/src/util/util/Array.ts
@@ -19,3 +19,23 @@
 export function containsAll(arr: any[], target: any[]) {
 	return target.every((v) => arr.includes(v));
 }
+
+// Rory - 20/01/2023 - Add utility functions to aid with identification of file types in emojis
+export function arrayBufferMatchesArr(
+	haystack: Uint8Array,
+	needle: number[],
+	offset: number,
+) {
+	return arrayBufferMatches(haystack, new Uint8Array(needle), 0);
+}
+
+export function arrayBufferMatches(
+	haystack: Uint8Array,
+	needle: Uint8Array,
+	offset: number,
+) {
+	for (let i = 0; i < needle.length; i++) {
+		if (haystack[i + offset] !== needle[i]) return false;
+	}
+	return true;
+}