decorates "knownUsers" and "rooms" objects with functions useful for console and other scripts
Stan na
Ten skrypt nie powinien być instalowany bezpośrednio. Jest to biblioteka dla innych skyptów do włączenia dyrektywą meta // @require https://update.greatest.deepsurf.us/scripts/423722/913809/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 decorateUsersObj(users = {}) {
const toArray = () => {
if (Array.isArray(users)) {
return [...users];
}
if (users.id && users.name) {
return [ users ];
}
return Object.values(users);
};
const toString = () => {
return toArray().map(u => {
return Object.entries(u)
.map(([prop, val]) => prop + ':' + val)
.join('\t');
}).join('\n');
};
const by = (userPredicateFnc) => {
const result = [], excluded = [];
Object.values(users).forEach(u => {
if(userPredicateFnc(u)) {
result.push(u);
} else {
excluded.push(u);
}
});
if (excluded.length) {
result.excluded = decorateUsersObj(excluded);
result.excludedAll = decorateUsersObj([ ...excluded, ...users.excludedAll ]);
}
return decorateUsersObj(result);
};
const byId = (id) => by(u => u.id == id);
const byName = (name) => {
const nameLower = String(name).toLowerCase();
return by(u => u.name.toLowerCase().includes(nameLower));
};
const byGender = (gender) => {
const genderLower = String(gender).toLowerCase();
return by(u => u.gender.toLowerCase().startsWIth(genderLower));
};
const byIsCammed = (user, takeWhenFalse = false) => {
if (!camData) return false;
const cammedUsersIds = new Set(Object.values(camData).map(camData => String(camData.user)));
return (u => cammedUsersIds.has(String(u.id)), takeWhenFalse);
};
const byPos = (pos) => toArray()[pos];
const save = () => {
toArray().forEach(user => {
user.original = {...user};
});
};
const restore = () => {
toArray().forEach(user => {
if (!user.original) return;
Object.assign(user, user.original);
delete user.original;
});
};
return Object.defineProperties(users, Object.fromEntries(Object.entries({
excluded: users.excluded || [],
excludedAll: users.excludedAll || [],
toArray,
toString,
by,
byId,
byName,
byGender,
byPos,
byIsCammed,
byIsNotCammed: () => byIsCammed().excluded,
save,
restore
}).map(([propName, value]) => {
return [propName, { value, 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 => decorateUsersObj(users));
patchObject(() => rooms, rooms => decorateRoomsObj(rooms));
})();