Jump to content

Recommended Posts

Posted

I have few JS polyfills saved, maybe one of them can help with Discord's 'are you human' Pop-up?


Posted

I have these JS polyfills saved:
Array.at
Change Array by Copy .toSorted
findLast
findLastIndex
Object.fromEntries
Object.hasOwn
randomUUID
String.at
structuredClone
Promise.withResolvers

Which one of these might work to disable a 'are you human' Pop-up?

If there are no suggested candidates to start with, I will have to try them all.

Posted

I'd start with all-of-the-below then watch the Javascript Console (Ctrl-Shift-J) for items in red to provide hints for where to go from there.

 

// ==UserScript==
// @name Inject Change Array by Copy All-in-One Polyfill [110]
// @version 0.0.1
// @match *://*/*
// @run-at document-start
// @grant none
// ==/UserScript==

((arrayPrototype, typedArrayPrototype) => {
    "use strict";

    const typedArrayLength = Function.call.bind(
        Object.getOwnPropertyDescriptor(typedArrayPrototype, "length").get
    );

    function toIntegerOrInfinity(arg) {
        let n = Number(arg);
        if (Number.isNaN(n) || n === 0) {
            return 0;
        }
        if (n === Number.POSITIVE_INFINITY) {
            return Number.POSITIVE_INFINITY;
        }
        if (n === Number.NEGATIVE_INFINITY) {
            return Number.NEGATIVE_INFINITY;
        }
        let i = Math.floor(Math.abs(n));
        if (n < 0) {
            i = -i;
        }
        return i;
    }

    function toObject(val) {
        if (val === null || val === undefined) {
            throw new TypeError(`${val} is not an object`);
        }
        return Object(val);
    }

    function lengthOfArrayLike(arr) {
        if (!(typeof arr === "object" && arr !== null)) {
            throw new TypeError();
        }
        let len = toIntegerOrInfinity(arr["length"]);
        if (!Number.isFinite(len)) {
            len = 0;
        }
        return Math.max(0, Math.min(len, Number.MAX_SAFE_INTEGER));
    }

    /** @typedef {Int8Array|Uint8Array|Uint8ClampedArray|Int16Array|Uint16Array|Int32Array|Uint32Array|Float32Array|Float64Array|BigInt64Array|BigUint64Array} TypedArray */

    /**
     * @param {unknown} v
     * @returns {TypedArray}
     */
    function assertTypedArray(v) {
        typedArrayPrototype.keys.call(v);
        // @ts-expect-error
        return v;
    }

    /**
     * @param {TypedArray} arr
     * @returns {TypedArray[typeof Symbol.toStringTag]}
     */
    function typedArrayNameInternalSlot(arr) {
        return Object.getOwnPropertyDescriptor(typedArrayPrototype, Symbol.toStringTag)
            .get.call(arr);
    }

    /**
     * @param {TypedArray} example
     * @param {number} length
     * @returns {TypedArray}
     */
    function typedArrayCreate(example, length) {
        assertTypedArray(example);
        const arrayName = typedArrayNameInternalSlot(example);
        switch (arrayName) {
            case 'Int8Array':
                return new Int8Array(length);
            case 'Uint8Array':
                return new Uint8Array(length);
            case 'Uint8ClampedArray':
                return new Uint8ClampedArray(length);
            case 'Int16Array':
                return new Int16Array(length);
            case 'Uint16Array':
                return new Uint16Array(length);
            case 'Int32Array':
                return new Int32Array(length);
            case 'Uint32Array':
                return new Uint32Array(length);
            case 'Float32Array':
                return new Float32Array(length);
            case 'Float64Array':
                return new Float64Array(length);
            case 'BigInt64Array':
                return new BigInt64Array(length);
            case 'BigUint64Array':
                return new BigUint64Array(length);
            default:
                /** @type {never} */
                const n = arrayName;
                throw new Error(`Unexpected TypedArray name ${n}`);
        }
    }

    /**
     * @param {TypedArray} example
     * @returns {boolean}
     */
    function isBigIntArray(example) {
        assertTypedArray(example);
        const arrayName = typedArrayNameInternalSlot(example);
        switch (arrayName) {
            case 'BigInt64Array':
            case 'BigUint64Array':
                return true;
        }
        return false;
    }

    function transfer({ count, src, srcStart, srcStep = 1, target, targetStart, targetStep = srcStep }) {
        let from = srcStart;
        let to = targetStart;
        for (let i = 0; i < count; i++) {
            target[to] = src[from];
            from += srcStep;
            to += targetStep;
        }
    }

    /**
     * @param {TypedArray} example
     * @param {unknown} value
     * @description convert `value` to bigint or number based on the the type of array
     * @returns {bigint | number}
     * @throws if one of the override methods throws. e.g. `@@toPrimitive`, `valueOf`, `toString`
     */
    function typedArrayNumberConversion(example, value) {
        let asNumber;
        {
            if (isBigIntArray(example)) {
                asNumber = 0n;
            } else {
                asNumber = -0; // important to use `-0` and not `0`
            }
            // @ts-ignore : using `+=` to emulate ToBigInt or ToNumber
            asNumber += value;
        }
        return asNumber;
    }

    defineArrayMethods({
        toReversed() {
            const o = toObject(this);
            const len = lengthOfArrayLike(o);
            const a = new Array(len);
            transfer({ src: o, srcStart: len - 1, srcStep: -1, target: a, targetStart: 0, targetStep: 1, count: len });
            return a;
        },
    });

    defineTypedArrayMethods({
        toReversed() {
            const o = assertTypedArray(this);
            const len = typedArrayLength(o);
            const a = typedArrayCreate(o, len);
            transfer({ src: o, srcStart: len - 1, srcStep: -1, target: a, targetStart: 0, targetStep: 1, count: len });
            return a;
        },
    });

    defineArrayMethods({
        toSorted(compareFn) {
            if (compareFn !== void 0 && typeof compareFn !== "function") {
                throw new TypeError();
            }
            const o = toObject(this);
            const len = lengthOfArrayLike(o);
            const a = new Array(len);;
            transfer({ src: o, srcStart: 0, target: a, targetStart: 0, count: len });
            arrayPrototype.sort.call(a, compareFn);
            return a;
        },
    });

    defineTypedArrayMethods({
        toSorted(compareFn) {
            if (compareFn !== void 0 && typeof compareFn !== "function") {
                throw new TypeError();
            }
            const o = assertTypedArray(this);
            const len = typedArrayLength(o);
            const a = typedArrayCreate(o, len);
            transfer({ src: o, srcStart: 0, target: a, targetStart: 0, count: len });
            typedArrayPrototype.sort.call(a, compareFn);
            return a;
        },
    });

    function calculateSplice({ start, len, deleteCount, values, argsCount }) {
        const relativeStart = toIntegerOrInfinity(start);
        let actualStart;
        if (relativeStart === -Infinity) {
            actualStart = 0;
        } else if (relativeStart < 0) {
            actualStart = Math.max(len + relativeStart, 0);
        } else {
            actualStart = Math.min(relativeStart, len);
        }
        const insertCount = values.length;
        let actualDeleteCount;
        if (/* start is not present */ argsCount === 0) {
            actualDeleteCount = 0;
        } else if (/* deleteCount is not present */ argsCount === 1) {
            actualDeleteCount = len - actualStart;
        } else {
            const dc = toIntegerOrInfinity(deleteCount);
            actualDeleteCount = Math.max(0, Math.min(dc, len - actualStart));
        }
        const newLen = len + insertCount - actualDeleteCount;
        return { actualStart, newLen, actualDeleteCount };
    }

    function doSplice({ src, target, actualStart, actualDeleteCount, values, newLen }) {
        let i = 0;
        while (i < actualStart) {
            target = src;
            i++;
        }
        for (const E of values) {
            target = E;
            i++;
        }
        let r = actualStart + actualDeleteCount;
        while (i < newLen) {
            let fromValue = src[r];
            target = fromValue;
            i++;
            r++;
        }
    }

    defineArrayMethods({
        toSpliced(start, deleteCount, ...values) {
            const o = toObject(this);
            const len = lengthOfArrayLike(o);
            const { actualStart, actualDeleteCount, newLen } = calculateSplice({ start, deleteCount, len, values, argsCount: arguments.length });
            if (newLen > Number.MAX_SAFE_INTEGER) {
                throw new TypeError();
            }
            const a = new Array(newLen);
            doSplice({ src: o, target: a, actualStart, actualDeleteCount, values, newLen });
            return a;
        }
    });

    defineArrayMethods({
        with(index, value) {
            const o = toObject(this);
            const len = lengthOfArrayLike(o);
            const relativeIndex = toIntegerOrInfinity(index);
            const actualIndex = relativeIndex < 0 ? len + relativeIndex : relativeIndex;
            if (actualIndex < 0 || actualIndex >= len) {
                throw new RangeError();
            }
            const a = new Array(len);
            for (let k = 0; k < len; k++) {
                const v = k === actualIndex ? value : o[k];
                a[k] = v;
            }
            return a;
        }
    });

    defineTypedArrayMethods({
        with(index, value) {
            const o = assertTypedArray(this);
            const len = typedArrayLength(o);
            const relativeIndex = toIntegerOrInfinity(index);
            const actualIndex = relativeIndex < 0 ? len + relativeIndex : relativeIndex;
            const asNumber = typedArrayNumberConversion(o, value);
            if (actualIndex < 0 || actualIndex >= len) {
                throw new RangeError();
            }
            const a = typedArrayCreate(o, len);
            for (let k = 0; k < len; k++) {
                const v = k === actualIndex ? asNumber : o[k];
                a[k] = v;
            }
            return a;
        }
    });

    /** @type {(def: { [N in "with" | "toReversed" | "toSorted" | "toSpliced"]?: typeof Array.prototype[N] }) => void} */
    function defineArrayMethods(def) {
        defineMethods(arrayPrototype, def).forEach(name => {
            if (name !== 'with') { // 'with' is already a keyword
                arrayPrototype[Symbol.unscopables][name] = true;
            }
        });
    }

    /** @type {(def: { [N in "with" | "toReversed" | "toSorted"]?: (this: TypedArray, ...args: Parameters<Uint8Array[N]>) => TypedArray }) => void} */
    function defineTypedArrayMethods(def) {
        defineMethods(typedArrayPrototype, def);
    }

    function defineMethods(obj, def) {
        return Object.entries(def).map(([name, method]) => {
            Object.defineProperty(obj, name, {
                value: method,
                enumerable: false,
                configurable: true,
                writable: true,
            });
            return name;
        });
    }
})(Array.prototype, Object.getPrototypeOf(Int8Array.prototype));

 

// ==UserScript==
// @name Inject Promise.withResolvers() Polyfill [119]
// @version 0.0.1
// @match *://*/*
// @run-at document-start
// @grant none
// ==/UserScript==

Promise.withResolvers || (Promise.withResolvers = function withResolvers() {
  var a, b, c = new this(function (resolve, reject) {
    a = resolve;
    b = reject;
  });
  return {resolve: a, reject: b, promise: c};
});

 

// ==UserScript==
// @name Inject structuredClone() [major] Polyfill [98]
// @version 0.0.1
// @match *://*/*
// @run-at document-start
// @grant none
// ==/UserScript==

'use strict';

const VOID       = -1;
const PRIMITIVE  = 0;
const ARRAY      = 1;
const OBJECT     = 2;
const DATE       = 3;
const REGEXP     = 4;
const MAP        = 5;
const SET        = 6;
const ERROR      = 7;
const BIGINT     = 8;
// const SYMBOL = 9;

const EMPTY = '';

const {toString} = {};
const {keys} = Object;

const typeOf = value => {
  const type = typeof value;
  if (type !== 'object' || !value)
    return [PRIMITIVE, type];

  const asString = toString.call(value).slice(8, -1);
  switch (asString) {
    case 'Array':
      return [ARRAY, EMPTY];
    case 'Object':
      return [OBJECT, EMPTY];
    case 'Date':
      return [DATE, EMPTY];
    case 'RegExp':
      return [REGEXP, EMPTY];
    case 'Map':
      return [MAP, EMPTY];
    case 'Set':
      return [SET, EMPTY];
  }

  if (asString.includes('Array'))
    return [ARRAY, asString];

  if (asString.includes('Error'))
    return [ERROR, asString];

  return [OBJECT, asString];
};

const shouldSkip = ([TYPE, type]) => (
  TYPE === PRIMITIVE &&
  (type === 'function' || type === 'symbol')
);

const serializer = (strict, json, $, _) => {

  const as = (out, value) => {
    const index = _.push(out) - 1;
    $.set(value, index);
    return index;
  };

  const pair = value => {
    if ($.has(value))
      return $.get(value);

    let [TYPE, type] = typeOf(value);
    switch (TYPE) {
      case PRIMITIVE: {
        let entry = value;
        switch (type) {
          case 'bigint':
            TYPE = BIGINT;
            entry = value.toString();
            break;
          case 'function':
          case 'symbol':
            if (strict)
              throw new TypeError('unable to serialize ' + type);
            entry = null;
            break;
          case 'undefined':
            return as([VOID], value);
        }
        return as([TYPE, entry], value);
      }
      case ARRAY: {
        if (type)
          return as([type, [...value]], value);

        const arr = [];
        const index = as([TYPE, arr], value);
        for (const entry of value)
          arr.push(pair(entry));
        return index;
      }
      case OBJECT: {
        if (type) {
          switch (type) {
            case 'BigInt':
              return as([type, value.toString()], value);
            case 'Boolean':
            case 'Number':
            case 'String':
              return as([type, value.valueOf()], value);
          }
        }

        if (json && ('toJSON' in value))
          return pair(value.toJSON());

        const entries = [];
        const index = as([TYPE, entries], value);
        for (const key of keys(value)) {
          if (strict || !shouldSkip(typeOf(value[key])))
            entries.push([pair(key), pair(value[key])]);
        }
        return index;
      }
      case DATE:
        return as([TYPE, value.toISOString()], value);
      case REGEXP: {
        const {source, flags} = value;
        return as([TYPE, {source, flags}], value);
      }
      case MAP: {
        const entries = [];
        const index = as([TYPE, entries], value);
        for (const [key, entry] of value) {
          if (strict || !(shouldSkip(typeOf(key)) || shouldSkip(typeOf(entry))))
            entries.push([pair(key), pair(entry)]);
        }
        return index;
      }
      case SET: {
        const entries = [];
        const index = as([TYPE, entries], value);
        for (const entry of value) {
          if (strict || !shouldSkip(typeOf(entry)))
            entries.push(pair(entry));
        }
        return index;
      }
    }

    const {message} = value;
    return as([TYPE, {name: type, message}], value);
  };

  return pair;
};

/**
 * @typedef {Array<string,any>} Record a type representation
 */

/**
 * Returns an array of serialized Records.
 * @param {any} value a serializable value.
 * @param {{json?: boolean, lossy?: boolean}?} options an object with a `lossy` or `json` property that,
 *  if `true`, will not throw errors on incompatible types, and behave more
 *  like JSON stringify would behave. Symbol and Function will be discarded.
 * @returns {Record[]}
 */
const serialize = (value, {json, lossy} = {}) => {
  const _ = [];
  return serializer(!(json || lossy), !!json, new Map, _)(value), _;
};

const env = typeof self === 'object' ? self : globalThis;

const deserializer = ($, _) => {
  const as = (out, index) => {
    $.set(index, out);
    return out;
  };

  const unpair = index => {
    if ($.has(index))
      return $.get(index);

    const [type, value] = _[index];
    switch (type) {
      case PRIMITIVE:
      case VOID:
        return as(value, index);
      case ARRAY: {
        const arr = as([], index);
        for (const index of value)
          arr.push(unpair(index));
        return arr;
      }
      case OBJECT: {
        const object = as({}, index);
        for (const [key, index] of value)
          object[unpair(key)] = unpair(index);
        return object;
      }
      case DATE:
        return as(new Date(value), index);
      case REGEXP: {
        const {source, flags} = value;
        return as(new RegExp(source, flags), index);
      }
      case MAP: {
        const map = as(new Map, index);
        for (const [key, index] of value)
          map.set(unpair(key), unpair(index));
        return map;
      }
      case SET: {
        const set = as(new Set, index);
        for (const index of value)
          set.add(unpair(index));
        return set;
      }
      case ERROR: {
        const {name, message} = value;
        return as(new env[name](message), index);
      }
      case BIGINT:
        return as(BigInt(value), index);
      case 'BigInt':
        return as(Object(BigInt(value)), index);
    }
    return as(new env[type](value), index);
  };

  return unpair;
};

/**
 * @typedef {Array<string,any>} Record a type representation
 */

/**
 * Returns a deserialized value from a serialized array of Records.
 * @param {Record[]} serialized a previously serialized value.
 * @returns {any}
 */
const deserialize = serialized => deserializer(new Map, serialized)(0);

if (!("structuredClone" in env)) env.structuredClone = (any, options) => deserialize(serialize(any, options));

 

 

Posted
7 hours ago, we3fan said:

Change Array by Copy .toSorted

You seem to be missing:
   1)  .toReversed
   2)  .toSpliced
   3)  .with

The previous post "all-in-one" should cover all four.

But these three as individual polyfills are below, in case you want them.

 

// ==UserScript==
// @name Inject Change Array by Copy .toReversed() Polyfill [110]
// @version 0.0.1
// @match *://*/*
// @run-at document-start
// @grant none
// ==/UserScript==

if (!Array.prototype.toReversed) {
  Array.prototype.toReversed = function () {
    return this.slice().reverse();
  };
}

 

// ==UserScript==
// @name Inject Change Array by Copy .toSpliced() Polyfill [110]
// @version 0.0.1
// @match *://*/*
// @run-at document-start
// @grant none
// ==/UserScript==

if (!Array.prototype.toSpliced) {
  Array.prototype.toSpliced = function (start, deleteCount, ...items) {
    const copy = this.slice();
    copy.splice(start, deleteCount, ...items);
    return copy;
  };
}

 

// ==UserScript==
// @name Inject Change Array by Copy .with() Polyfill [110]
// @version 0.0.1
// @match *://*/*
// @run-at document-start
// @grant none
// ==/UserScript==

if (!Array.prototype.with) {
  Array.prototype.with = function (index, value) {
    const copy = this.slice();
    copy[index] = value;
    return copy;
  };
}

Posted

I've just switched over to 360Chrome v13.5.1030 Redux after a trouble-free run with v13.5.1030 rebuild 6, for the last 3 years.

Many thanks to NotHereToPlayGames for sharing his knowledge and efforts. :worship:

Ironically, the problem that pushed me to upgrade was being unable to use the MSFN forum.


I was hoping someone could tell me how to transfer my passwords from rebuild 6 to Redux?

Posted

Hi obstinateXP,

1. Optional: Make backup of rebuild 6 first, Application + User Data folders, backup 360Loader.exe + 360Loader.ini also just in case.
2. Copy rebuild 6 to new location, replace all contents from rebuild 6\Chrome\Application with Redux\Chrome\Application.
3. Replace 360Loader.exe from rebuild 6 with 360Loader.exe from Redux; replace 360Loader.ini also if you want or keep your old one from rebuild 6.
4. Rename rebuild 6 to Redux, done.

Posted

Thanks ArcticFoxie,

With no Polyfills, it shows this (I hid some of the messages I thought were irrelevant):
IIOWs.png
The last message "PUT https ... 9216  400" shows when I 'Add Friend' and when the 'are you human' Pop-up shows.

With these 3 Polyfills (Change Array by Copy All-in-One + Promise.withResolvers + structuredClone major) active, it shows this (I hid some of the messages I thought were irrelevant):
wwKUA.png
33h4v.png
This time it didn't show the "PUT https ... 9216  400" message when I 'Added Friend' and when the 'are you human' Pop-up showed.

I enabled  chrome://flags/#enable-experimental-web-platform-features  so:
Change Array by Copy All-in-One + Promise.withResolvers + structuredClone major + chrome://flags/#enable-experimental-web-platform-features Enabled - but it still showed the 'are you human' Pop-up, so I Disabled  chrome://flags/#enable-experimental-web-platform-features  again (default).

Posted
On 3/6/2025 at 11:36 PM, NotHereToPlayGames said:

It's gonna require someone with a Discord account to track down.

The JS Console doesn't give us enough info?

Posted
On 3/7/2025 at 4:23 AM, we3fan said:

Hi obstinateXP,

1. Optional: Make backup of rebuild 6 first, Application + User Data folders, backup 360Loader.exe + 360Loader.ini also just in case.
2. Copy rebuild 6 to new location, replace all contents from rebuild 6\Chrome\Application with Redux\Chrome\Application.
3. Replace 360Loader.exe from rebuild 6 with 360Loader.exe from Redux; replace 360Loader.ini also if you want or keep your old one from rebuild 6.
4. Rename rebuild 6 to Redux, done.

Thanks, but unfortunately this doesn't really work for me. Using my old 'User Data' folder causes Redux to have the same problem as rebuild 6. I can see the home page of the forum, but I can't access any topics or threads. I just get a completely blank page if I try. I can't log in either. Redux without my 'User Data' folder swapped in, works fine. I'm using it to write this post.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...