diff --git a/package.json b/package.json index 50fb6bb59..08e2b200d 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,6 @@ "homepage": "https://github.com/hydrabolt/discord.js#readme", "runkitExampleFilename": "./docs/examples/ping.js", "dependencies": { - "long": "^3.0.0", "pako": "^1.0.0", "prism-media": "^0.0.2", "snekfetch": "^3.0.0", diff --git a/src/structures/shared/Search.js b/src/structures/shared/Search.js index a852a5086..3adca7fcc 100644 --- a/src/structures/shared/Search.js +++ b/src/structures/shared/Search.js @@ -1,4 +1,4 @@ -const long = require('long'); +const Util = require('../../util/Util'); const { TypeError } = require('../../errors'); /** @@ -40,17 +40,17 @@ module.exports = function search(target, options) { if (typeof options === 'string') options = { content: options }; if (options.before) { if (!(options.before instanceof Date)) options.before = new Date(options.before); - options.maxID = long.fromNumber(options.before.getTime() - 14200704e5).shiftLeft(22).toString(); + options.maxID = Util.binaryToID((options.before.getTime() - 14200704e5).toString(2) + '0'.repeat(22)); } if (options.after) { if (!(options.after instanceof Date)) options.after = new Date(options.after); - options.minID = long.fromNumber(options.after.getTime() - 14200704e5).shiftLeft(22).toString(); + options.minID = Util.binaryToID((options.after.getTime() - 14200704e5).toString(2) + '0'.repeat(22)); } if (options.during) { if (!(options.during instanceof Date)) options.during = new Date(options.during); const t = options.during.getTime() - 14200704e5; - options.minID = long.fromNumber(t).shiftLeft(22).toString(); - options.maxID = long.fromNumber(t + 864e5).shiftLeft(22).toString(); + options.minID = Util.binaryToID(t.toString(2) + '0'.repeat(22)); + options.maxID = Util.binaryToID((t + 864e5).toString(2) + '0'.repeat(22)); } if (options.channel) options.channel = target.client.channels.resolveID(options.channel); if (options.author) options.author = target.client.users.resolveID(options.author); diff --git a/src/util/Snowflake.js b/src/util/Snowflake.js index f16839108..27f9f7440 100644 --- a/src/util/Snowflake.js +++ b/src/util/Snowflake.js @@ -1,4 +1,4 @@ -const Long = require('long'); +const Util = require('../util/Util'); // Discord epoch (2015-01-01T00:00:00.000Z) const EPOCH = 1420070400000; @@ -31,8 +31,9 @@ class SnowflakeUtil { */ static generate() { if (INCREMENT >= 4095) INCREMENT = 0; - const BINARY = `${pad((Date.now() - EPOCH).toString(2), 42)}0000100000${pad((INCREMENT++).toString(2), 12)}`; - return Long.fromString(BINARY, 2).toString(); + // eslint-disable-next-line max-len + const BINARY = `${(Date.now() - EPOCH).toString(2).padStart(42, '0')}0000100000${(INCREMENT++).toString(2).padStart(12, '0')}`; + return Util.binaryToID(BINARY); } /** @@ -52,7 +53,7 @@ class SnowflakeUtil { * @returns {DeconstructedSnowflake} Deconstructed snowflake */ static deconstruct(snowflake) { - const BINARY = pad(Long.fromString(snowflake).toString(2), 64); + const BINARY = Util.idToBinary(snowflake).toString(2).padStart(64, '0'); const res = { timestamp: parseInt(BINARY.substring(0, 42), 2) + EPOCH, workerID: parseInt(BINARY.substring(42, 47), 2), @@ -68,8 +69,4 @@ class SnowflakeUtil { } } -function pad(v, n, c = '0') { - return String(v).length >= n ? String(v) : (String(c).repeat(n) + v).slice(-n); -} - module.exports = SnowflakeUtil; diff --git a/src/util/Util.js b/src/util/Util.js index ecc1b93e1..46ce22367 100644 --- a/src/util/Util.js +++ b/src/util/Util.js @@ -1,4 +1,3 @@ -const Long = require('long'); const snekfetch = require('snekfetch'); const { Colors, DefaultOptions, Endpoints } = require('./Constants'); const { Error: DiscordError, RangeError, TypeError } = require('../errors'); @@ -299,7 +298,9 @@ class Util { */ static discordSort(collection) { return collection - .sort((a, b) => a.rawPosition - b.rawPosition || Long.fromString(a.id).sub(Long.fromString(b.id)).toNumber()); + .sort((a, b) => a.rawPosition - b.rawPosition || + parseInt(a.id.slice(0, -10)) - parseInt(b.id.slice(0, -10)) || + parseInt(a.id.slice(10)) - parseInt(b.id.slice(10))); } static setPosition(item, position, relative, sorted, route, reason) { @@ -316,6 +317,54 @@ class Util { } return f; } + + /** + * Transform a snowflake from a decimal string to a bit string + * @param {string} num Snowflake to be transformed + * @returns {string} + * @private + */ + static idToBinary(num) { + let bin = ''; + let high = parseInt(num.slice(0, -10)) || 0; + let low = parseInt(num.slice(-10)); + while (low > 0 || high > 0) { + bin = String(low & 1) + bin; + low = Math.floor(low / 2); + if (high > 0) { + low += 5000000000 * (high % 2); + high = Math.floor(high / 2); + } + } + return bin; + } + + + /** + * Transform a snowflake from a bit string to a decimal string + * @param {string} num Bit string to be transformed + * @returns {string} + * @private + */ + static binaryToID(num) { + let dec = ''; + + while (num.length > 50) { + const high = parseInt(num.slice(0, -32), 2); + const low = parseInt((high % 10).toString(2) + num.slice(-32), 2); + + dec = (low % 10).toString() + dec; + num = Math.floor(high / 10).toString(2) + Math.floor(low / 10).toString(2).padStart(32, '0'); + } + + num = parseInt(num, 2); + while (num > 0) { + dec = (num % 10).toString() + dec; + num = Math.floor(num / 10); + } + + return dec; + } } module.exports = Util;