Camamba Chat Helpers

decorates "knownUsers" and "rooms" objects with functions useful for console and other scripts

Tính đến 22-03-2021. Xem phiên bản mới nhất.

Script này sẽ không được không được cài đặt trực tiếp. Nó là một thư viện cho các script khác để bao gồm các chỉ thị meta // @require https://update.greasyfork.org/scripts/423722/913758/Camamba%20Chat%20Helpers.js

// ==UserScript==
// @name         Camamba Chat Helpers
// @namespace    dannysaurus.camamba
// @version      0.1
// @description  decorates "knownUsers" and "rooms" objects with functions useful for console and other scripts
// @license      MIT License
// @include      https://www.camamba.com/chat/
// @include      https://www.de.camamba.com/chat/
// @include      https://www.camamba.com/chat/
// @include      https://www.de.camamba.com/chat/
// @grant        none
// ==/UserScript==

/* jslint esversion: 9 */
/* global me, camData, rooms, blockList, friendList, friendRequests, adminMessages, jsLang, byId, myRooms, knownUsers, activeRoom, selectedUser, settings, onMessageHandlers, postMessageHandlers */


(function() {
    function decoratUsersObj(users = {}) {

        const userBy = (userPredicateFnc) => {
            let result = Object.values(users).filter(u => userPredicateFnc(u));

            if (result && result.length === 1) {
                result = result[0];
            }

            return decoratUsersObj(result);
        };

        const userById = (id) => {
            return userBy(u => u.id == id);
        };

        const userByName = (name) => {
            const nameLower = String(name).toLowerCase();
            return userBy(u => u.name.toLowerCase().includes(nameLower));
        };

        const userByGender = (gender) => {
            const genderLower = String(gender).toLowerCase();
            return userBy(u => u.gender.toLowerCase().startsWIth(genderLower));
        };

        const userToArray = () => {
            if (Array.isArray(users)) {
                return users;
            }

            if (users.id && users.name) {
                return [ users ];
            }

            return Object.values(users);
        };

        const userByPos = (pos) => {
            return userToArray()[pos];
        };

        const userByIsCammed = (user) => {
            if (!camData) return false;

            const cammedUsersIds = new Set(Object.values(camData).map(camData => String(camData.user)));

            return userBy(u => cammedUsersIds.has(String(u.id)));
        };

        const saveUser = () => {
            userToArray().forEach(user => {
                user.original = {...user};
            });
        };

        const restoreUser = () => {
            userToArray().forEach(user => {
                if (!user.original) return;

                user = {...user, ...user.original};
                delete user.original;
            });
        };

        const usersToString = () => {
            return userToArray().map(u => {

                return Object.entries(u)
                    .map(([prop, val]) => prop + ':' + val)
                    .join('\t');

            }).join('\n');
        };

        return Object.defineProperties(users, {
            by: { value: userBy, configurable: true },
            byId: { value: userById, configurable: true },
            byName: { value: userByName, configurable: true },
            byGender: { value: userByGender, configurable: true},
            byPos: { value: userByPos, configurable: true },
            byIsCammed: { value: userByIsCammed, configurable: true },

            toArray: { value: userToArray, configurable: true },

            save: { value: saveUser, configurable: true },
            restore: { value: restoreUser, configurable: true },

            toString: { value: usersToString, configurable: true },
        });
    }

    function decorateRoomsObj(rooms = {}) {
        const roomsByName = (name) => {
            const nameLower = String(name).toLowerCase();

            const result = {};

            Object.entries(rooms).forEach(([roomId, roomName]) => {

                if (roomName.toLowerCase().includes(nameLower)) {
                    result[roomId] = roomName;
                }
            });

            return result;
        };

        return Object.defineProperties(rooms, {
            byName: { value: roomsByName, configurable: true },
        });
    }

    const patchObject = function(getExpectedObjFnc, patchFnc, timeOutRetryMillis = 200, maxPeriodTryMillis = 5000) {
        const expectedObj = getExpectedObjFnc();

        if (!expectedObj && timeOutRetryMillis <= maxPeriodTryMillis) {
            setTimeout(() => patchObject(getExpectedObjFnc, patchFnc, timeOutRetryMillis), maxPeriodTryMillis - timeOutRetryMillis);
            return;
        }
        patchFnc(expectedObj);
    };

    patchObject(() => knownUsers, users => decoratUsersObj(users));
    patchObject(() => rooms, rooms => decorateRoomsObj(rooms));
})();