// ==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));
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));
})();