/* eslint-env jquery */ // ==UserScript== // @name CS.RIN.RU Enhanced // @name:fr CS.RIN.RU Amélioré // @name:pt CS.RIN.RU Melhorado // @namespace Royalgamer06 // @version 1.2.6 // @description Enhance your experience at CS.RIN.RU - Steam Underground Community. // @description:fr Améliorez votre expérience sur CS.RIN.RU - Steam Underground Community. // @description:pt Melhorar a sua experiência no CS.RIN.RU - Steam Underground Community. // @author Royalgamer06 (modified by SubZeroPL) // @match *://cs.rin.ru/forum/* // @match *://csrinrutkb3tshptdctl5lyei4et35itl22qvk5ktdcat6aeavy6nhid.onion/forum/* // @require https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js // @icon https://raw.githubusercontent.com/SubZeroPL/cs-rin-ru-enhanced-mod/master/image.png // @grant GM_addStyle // @grant GM_xmlhttpRequest // @grant GM_setValue // @grant GM_getValue // @grant GM_deleteValue // @grant GM_notification // @grant GM_addElement // @run-at document-idle // @homepageURL https://github.com/SubZeroPL/cs-rin-ru-enhanced-mod // @supportURL https://cs.rin.ru/forum/viewtopic.php?f=14&t=75717 // @updateURL https://raw.githubusercontent.com/SubZeroPL/cs-rin-ru-enhanced-mod/master/cs-rin-ru-enhanced-mod.user.js // @downloadURL https://raw.githubusercontent.com/SubZeroPL/cs-rin-ru-enhanced-mod/master/cs-rin-ru-enhanced-mod.user.js // ==/UserScript== /* Creator: Royalgamer06 (https://cs.rin.ru/forum/memberlist.php?mode=viewprofile&u=477885) Contributor: SubZeroPL (https://cs.rin.ru/forum/memberlist.php?mode=viewprofile&u=505897) who has now taken over the project Contributor: Redpoint (https://cs.rin.ru/forum/memberlist.php?mode=viewprofile&u=1365721) has created some functionality Contributor: Altansar (https://cs.rin.ru/forum/memberlist.php?mode=viewprofile&u=1280185) has created some functionality Contributor: odusi (https://cs.rin.ru/forum/memberlist.php?mode=viewprofile&u=582752) has created the original function for the special search. We have kindly given his permission to use his work Contributor: Mandus (https://cs.rin.ru/forum/memberlist.php?mode=viewprofile&u=1487447) has created the original function to copy the link from a message */ const BRANCH = "master" const CONFIG_PAGE_CSS = `https://raw.githubusercontent.com/SubZeroPL/cs-rin-ru-enhanced-mod/${BRANCH}/config.css`; const CONFIG_PAGE_JS = `https://raw.githubusercontent.com/SubZeroPL/cs-rin-ru-enhanced-mod/${BRANCH}/config.js`; const CONFIG_PAGE = `https://raw.githubusercontent.com/SubZeroPL/cs-rin-ru-enhanced-mod/${BRANCH}/config.html` const AJAX_LOADER = `
`);
} else {
$(this).append(`
`);
const child = $(this).find("[title='Reply with mentioning']");
$(this).find('[title="Reply with mentioning"]').on("click", function () {
let postBody = `@[url=${FORUM_BASE_URL}memberlist.php?mode=viewprofile&u=${authorID}]${decodeURI(author)}[/url], `;
if (options.mentioning === 2) { //Author and post
postBody += `Re: [url=${FORUM_BASE_URL}viewtopic.php?p=${postID}#p${postID}]Post[/url]. `;
}
$("[name=message]")[0].value += postBody;
const mentioned = $('Mentioned!');
mentioned.css({
'position': 'absolute',
'top': child.offset().top - mentioned.outerHeight() - 20,
'left': child.offset().left + (child.outerWidth() / 2) - (mentioned.outerWidth() / 2) - 12
});
$('body').append(mentioned);
setTimeout(function () {
mentioned.fadeOut();
}, 2000);
});
}
});
}
}
}
function tagify() {
if (options.custom_tags) {
$(".titles, .topictitle").each(function () {
const titleElem = this;
const parentElem = titleElem.parentElement
if (titleElem.id !== "colorize") {
titleElem.id = "colorize";
const tags = $(titleElem).text().match(/\[([^\]]+)]/g);
if (tags) {
tags.forEach(function (tag) {
const color = colorize(tag, parentElem);
titleElem.innerHTML = titleElem.innerHTML.replace(tag, "[" + tag.replace(/[\[\]]/g, "") + "]");
});
}
}
});
}
}
// 0=not hide, 1=hide all, 2=hide only green, 3=show only red
function hideScs() {
if (options.hide_scs > 0 && (options.apply_in_scs || $("a.titles").html() !== "Steam Content Sharing")) {
let regex;
switch (options.hide_scs) {
case 1:
regex = /topic_tags\/scs_/;
break;
case 2:
regex = /topic_tags\/scs_on/;
break;
case 3:
regex = /topic_tags\/scs_[oy][^f]/;
break;
}
$(".topictitle img").each(function () {
if (this.src.match(regex)) {
this.parentElement.parentElement.parentElement.style.display = "none";
}
});
}
}
function hexToRgb(hex) {
const r = parseInt(hex.substring(0, 2), 16);
const g = parseInt(hex.substring(2, 4), 16);
const b = parseInt(hex.substring(4, 6), 16);
return [r, g, b];
}
function colorize(str, parentElem) {
let lstr = str.toLowerCase();
let hash = 0;
for (let i = 0; i < lstr.length; i++) {
hash = lstr.charCodeAt(i) + ((hash << 5) - hash);
}
let color = Math.floor(Math.abs((Math.sin(hash) * 10000) % 1 * 16777216)).toString(16);
let rgb = hexToRgb(color);
while (!getComputedStyle(parentElem).getPropertyValue("background-color").match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/)) {
parentElem = parentElem.parentElement
}
let bgColour = getComputedStyle(parentElem).getPropertyValue("background-color");
let matches = bgColour.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
const bgRgb = [parseInt(matches[1]), parseInt(matches[2]), parseInt(matches[3])]
while (Math.abs(rgb[0] + rgb[1] + rgb[2] - (bgRgb[0] + bgRgb[1] + bgRgb[2])) < 300) {
hash = (hash << 5) - hash;
color = Math.floor(Math.abs((Math.sin(hash) * 10000) % 1 * 16777216)).toString(16);
rgb = hexToRgb(color);
}
return '#' + color.padStart(6, '0');
}
function URLContains(match) {
return window.location.href.indexOf(match) > -1;
}
function URLParam(name) {
return (location.search.split(name + '=')[1] || '').split('&')[0];
}
/*
Made by SubZeroPL
%RT added by Altansar
Remade to apply to all pages by Redpoint
*/
function setupPageTitle() {
const currentTitle = document.title;
const cs = currentTitle.split("•")[0] + " •";
const remainder = currentTitle.substring(currentTitle.indexOf("•") + 1);
const fullTitle = remainder.split(/[-•]/);
let sectionTitle;
let pageTitle;
if (fullTitle.length === 1) {
sectionTitle = "";
pageTitle = $("a.titles").length > 0 ? $("a.titles").text() : fullTitle[0].trim();
} else {
sectionTitle = fullTitle[0].trim();
pageTitle = $("a.titles").length > 0 ? $("a.titles").text() : fullTitle[1].trim();
}
const pageTitleWithoutTags = pageTitle.replace(/\[[^\]]*]/g, '');
document.title = options.title_format
.replace("%C", cs)
.replace("%S", sectionTitle)
.replace("%T", pageTitle)
.replace("%RT", pageTitleWithoutTags);
}
setupPageTitle();
/*
Made by SubZeroPL
displays preview of first post from topic that mouse cursor points
*/
/*
* Displays a preview of the post.
* @param {HTMLElement} element - The element to attach the hover event listener to.
* @param {string} link - The link to the topic to be previewed.
* @param {function} getIndex - A predefined function that returns the correct index of the post given a list of posts.
* These are defined `setup{Type}Preview()` functions.
*/
function previewElement(element, link, getIndex) {
let tid, showPreview;
$(element).off("mouseover").on("mouseover", () => {
showPreview = true;
$("div#topic_preview").hide();
tid = setTimeout(() => {
if (!showPreview) return;
const previewWidth = window.innerWidth * 0.75;
const previewHeight = window.innerHeight * 0.75;
const x = (window.innerWidth / 2) - (previewWidth / 2);
const y = (window.innerHeight / 2) - (previewHeight / 2) + window.scrollY;
GM_xmlhttpRequest({
url: link, onerror: (r) => {
console.log("Error loading page: " + r);
}, onload: (r) => {
if (!showPreview) return;
const parser = new DOMParser();
const dom = parser.parseFromString(r.responseText, "text/html").body.children;
const posts = $(dom).find("div#pagecontent table.tablebg");
const body = posts[getIndex(posts, link)].outerHTML;
// Use custom parseHTML function instead of $.parseHTML
const bodyObj = parser.parseFromString(body, "text/html").body.children[0];
if ($("div#topic_preview").length > 0) {
const tip = $("div#topic_preview");
tip.html(bodyObj);
tip.css('left', `${x}px`);
tip.css('top', `${y}px`);
tip.css('width', `${previewWidth}px`);
tip.css('height', `${previewHeight}px`);
tip.show();
tip.scrollTop(0);
} else {
const tip = document.createElement('div');
tip.id = "topic_preview";
tip.appendChild(bodyObj);
tip.style.position = "absolute";
tip.style.top = `${y}px`;
tip.style.left = `${x}px`;
tip.style.width = `${previewWidth}px`;
tip.style.maxWidth = `${previewWidth}px`;
tip.style.height = `${previewHeight}px`;
tip.style.maxHeight = `${previewHeight}px`;
tip.style.overflow = "auto";
$("body").append(tip);
$(tip).on("mouseleave", () => {
$(tip).hide();
clearTimeout(tid);
});
}
addUsersTag();
steamDBLink();
}
});
}, options.topic_preview_timeout * 1000);
});
$(element).off("mouseleave").on("mouseleave", () => {
clearTimeout(tid);
showPreview = false;
});
}
function setupTopicPreview() {
if (!options.topic_preview) return;
$("a.topictitle").each((_, e) => {
const topic = $(e)[0];
const topicLink = topic.href.split("&view=unread")[0].split("&p=")[0];
let link = options.topic_preview_option === 0 ? topicLink :
options.topic_preview_option === 1 ? topicLink + "&view=unread#unread" :
options.topic_preview_option === 2 ? $(topic).parent().next().next().next().next().children().next().children().next().attr("href") :
'Invalid option';
const getIndex = () => options.topic_preview_option === 2 ? posts.length - 2 : 1;
previewElement(topic, link, getIndex);
});
}
setupTopicPreview();
function setupPostPreview() {
if (!options.post_preview) return;
$("a.postlink-local").each((_, e) => {
const post = $(e)[0]
const link = post.href;
if (!link.includes("viewtopic.php")) return;
const getIndex = (posts, link) => {
for (let i = 0; i < posts.length; i++) {
const postLink = $(posts[i]).find("a[href*='viewtopic.php']:not([class])")[0]
if (postLink.href === link) {
return i;
}
}
return -1;
}
previewElement(post, link, getIndex)
});
}
setupPostPreview()
function setupProfilePreview() {
if (!options.profile_preview) return;
$("a.postlink-local").each((_, e) => {
const profile = $(e)[0]
const link = profile.href;
if (!link.includes("memberlist.php")) return;
const getIndex = () => 0;
previewElement(profile, link, getIndex)
});
}
setupProfilePreview()
/*
Made by Redpoint
And adapted for cs.rin.ru enhanced by Altansar
*/
function addUsersTag() {
if (options.add_users_tag) {
const steamLink = $('a[href^="https://store.steampowered.com/app/"], a[href^="http://store.steampowered.com/app/"]').first()[0];
if (steamLink != null) {
const genreDescription = $(":contains('Genre(s):')").filter((i, e) => $(e).text() === "Genre(s):");
if (genreDescription.length > 0 && genreDescription.next().next().text() !== "User-defined Tag(s): ") { // If we are on the game presentation page
// Get the link to the Steam game page
const link = steamLink.href;
// Send a request to the Steam game page and bypass CSP
GM_xmlhttpRequest({
method: "GET", url: link, onload: function (response) {
// Parse the response as HTML
const parser = new DOMParser();
const doc = parser.parseFromString(response.responseText, "text/html");
// Get the genre tags from the response
const tags = doc.querySelectorAll("#glanceCtnResponsiveRight > div.glance_tags_ctn.popular_tags_ctn > div.glance_tags.popular_tags > a.app_tag");
// Extract the text content of each tag and join them with a comma and a space
const genres = Array.from(tags).map(tag => tag.textContent.trim()).join(", ");
if (genreDescription.next().next().text() === "User-defined Tag(s): ") {
return;
}
// Modify the original page by adding a new line with the genres
const br = $('span[style="font-weight: bold"]:contains("Genre(s):")').next()[0];
const span = document.createElement("span");
span.style.fontWeight = "bold";
span.textContent = "User-defined Tag(s): ";
const text = document.createTextNode(genres);
br.parentNode.insertBefore(document.createElement("br"), br);
br.parentNode.insertBefore(span, br);
br.parentNode.insertBefore(text, br);
}
});
}
}
}
}
addUsersTag()
/*
Originally made by Altansar
Completely remade by Redpoint
*/
function steamDBLink() {
if (!options.steam_db_link || this.value === "Show") {
return;
}
let postlinks = $(".postlink");
if (postlinks.length === 0) {
return;
}
for (let i = 0; i < postlinks.length; i++) {
let steamLink = postlinks[i].href;
if (steamLink.match("://store.steampowered.com/app")) {
let slash = steamLink.endsWith('/');
steamLink = slash ? steamLink.slice(0, -1) : steamLink;
let splits = steamLink.split("/");
if (splits[splits.length - 1].match(/^[0-9]+$/)) {
steamLink = splits[splits.length - 1];
} else if (splits[splits.length - 2].match(/^[0-9]+$/)) {
steamLink = splits[splits.length - 2];
}
let DBlink = `https://steamdb.info/app/${steamLink}${slash ? '/' : ''}`;
let j = i;
while ((j + 1 < postlinks.length) && (postlinks[j].getBoundingClientRect().y === postlinks[j + 1].getBoundingClientRect().y) && (postlinks[j].nextSibling !== null && postlinks[j].nextSibling.tagName !== "BR")) {
j++;
}
if ((j + 1 === postlinks.length) || !postlinks[j + 1].text.match(DBlink)) {
postlinks[j].insertAdjacentHTML("afterend", "" + DBlink + ""); // Write the link (right part)
postlinks[j].insertAdjacentHTML("afterend", "
`);
const bar = this;
$(this).find('[title="Copy the link into the clipboard"]').on("click", function () {
const url = FORUM_BASE_URL + `viewtopic.php?p=${postId}#p${postId}`;
navigator.clipboard.writeText(url);
const copied = $('Copied!');
const child = $(bar).find("[title='Copy the link into the clipboard']");
copied.css({
'position': 'absolute',
'top': child.offset().top - copied.outerHeight() - 20,
'left': child.offset().left + (child.outerWidth() / 2) - (copied.outerWidth() / 2) - 12
});
$('body').append(copied);
setTimeout(function () {
copied.fadeOut();
}, 2000);
});
});
}
}
addLink();
/*
Originally made by Redpoint
And adapted for cs.rin.ru enhanced by Altansar
*/
function AddShoutbox() {
if (options.add_small_shoutbox && !URLContains("chat.php")) {
// Create a button to show/hide chat
let button = document.createElement("button");
button.innerHTML = "Show Chat";
//button.style.cssText = "position: fixed; bottom: 0%; right: 0%; width: 5%; height: 3%;";
button.style.cssText = "position: fixed; bottom: 0%; right: 0%; min-height: 40px; min-width: 50px; width: 5%; height: 3%; z-index: 9999;";
button.addEventListener("click", function () {
if (document.getElementById("chatDiv") === null) {
button.innerHTML = "Hide Chat";
createChatContainer();
fetchChat();
GM_setValue("chatActive", true)
} else {
document.getElementById("chatDiv").remove();
button.innerHTML = "Show Chat";
GM_setValue("chatActive", false)
}
});
document.addEventListener("visibilitychange", () => {
if (document.getElementById("chatDiv") !== null) {
const script = document.getElementById("chatDiv").children[1];
if (document.hidden) {
script.setAttribute("data-original-text", script.textContent);
script.textContent = "";
} else {
script.textContent = script.getAttribute("data-original-text");
script.removeAttribute('data-original-text');
}
}
});
document.body.appendChild(button);
const isChatActive = GM_getValue("chatActive", false);
if (isChatActive) { //open the chat if it was open when last used
button.click();
}
}
}
AddShoutbox();
/*
Made by Altansar
*/
function createChatContainer() {
// Create a container for the chat
let chatContainer = document.createElement("div");
chatContainer.style.cssText = "position: fixed; bottom: 0%; right: 0%; width: 25%; min-width: 425px; height: 70%; overflow-y: scroll; background-color:#1c1c1c; border:0.5em solid black";
chatContainer.id = "chatDiv";
document.body.appendChild(chatContainer);
//Loading text
const loading = document.createTextNode("Loading...");
const p = document.createElement("p");
p.appendChild(loading);
chatContainer.appendChild(p);
p.style.cssText = "position: absolute; left: 0; right: 0; top: 20%; transform: translateY(-50%); text-align: center; color: white; font-size: 500%;";
}
/*
Made by Redpoint
*/
function fetchChat() {
fetch(FORUM_BASE_URL + "chat.php")
.then(response => response.text())
.then(text => {
let chatContainer = document.getElementById("chatDiv");
chatContainer.innerHTML = "";
let parser = new DOMParser();
let doc = parser.parseFromString(text, "text/html");
let originalScript = doc.querySelector("#wrapcentre > script");
let chatElement = doc.querySelector("#wrapcentre > div > table > tbody");
if (chatElement) {
chatContainer.appendChild(chatElement);
}
chatContainer.style.backgroundColor = "#1c1c1c";
let script = document.createElement("script");
script.innerHTML = originalScript.innerHTML;
chatContainer.appendChild(script);
})
.then(() => {
colorizeFriendsMe();
});
}
/*
Made by Altansar
*/
function changeTopicLink() {
if (options.change_topic_link === 1) {
document.querySelectorAll(".titles:not(:first-child), .topictitle").forEach(element => {
if (element.getAttribute("href")) {
if (!element.getAttribute("href").includes("&view=unread#unread")) {
//If we don't already have added unread
element.setAttribute("href", element.getAttribute('href') + "&view=unread#unread")
}
}
});
}
if (options.change_topic_link === 2) {
document.querySelectorAll(".titles:not(:first-child), .topictitle").forEach(element => {
if (element.getAttribute("href")) {
if (!element.getAttribute("href").includes("&p=")) {
element.setAttribute("href", $(element).parent().next().next().next().next().children().next().children().next().attr("href"))
}
}
});
}
}
changeTopicLink();
function createProfileLink(link) {
const bar = $(".genmed")[2];
const a = document.createElement("a");
a.href = link;
a.id = "profile_link";
const img = document.createElement("img");
img.src = document.querySelector("#menubar > table:nth-child(3) > tbody > tr > td:nth-child(1) > a:nth-child(1) > img").src;
img.width = 12;
img.height = 13;
a.appendChild(img);
a.appendChild(document.createTextNode(" Profile"));
const sep = document.createTextNode(` ${String.fromCharCode(160)}:: ${String.fromCharCode(160)}`);
$(bar).find("a")[1].before(a, sep);
colorizeThePages();
}
function addProfileButton() {
if (!options.add_profile_button) return;
let profileLink = GM_getValue("profileLink", null);
if (!profileLink) {
const username_element_mainpage = $(SELECTORS.USERNAME_ON_MAINPAGE)
const username_element_other = $(SELECTORS.USERNAME_ON_OTHER_PAGES)
if (username_element_mainpage.length !== 0 && username_element_mainpage[0].innerText === USERNAME) {
profileLink = username_element_mainpage[0].href;
GM_setValue("profileLink", profileLink);
createProfileLink(profileLink);
} else if (username_element_other.length !== 0 && username_element_other[0].innerText === USERNAME) {
profileLink = username_element_other[0].href;
GM_setValue("profileLink", profileLink);
createProfileLink(profileLink);
} else {
GM_xmlhttpRequest({
method: "GET", url: FORUM_BASE_URL + `memberlist.php?sk=c&sd=a&username=${USERNAME}&mode=searchuser`, onload: function (response) {
// Parse the response as HTML
const parser = new DOMParser();
const doc = parser.parseFromString(response.responseText, "text/html");
profileLink = $(doc).find(`table tbody tr.row2 td.genmed a:contains(${USERNAME})`)[0].href;
GM_setValue("profileLink", profileLink);
createProfileLink(profileLink);
}
});
}
} else {
createProfileLink(profileLink);
}
}
addProfileButton();
/*
Made by Altansar/
*/
function changeColorOfNewMessage() {
if (options.colorize_new_messages) {
const messagesField = $(SELECTORS.NEW_MESSAGES)[0];
const defaultColor = getComputedStyle($('div#wrapcentre p.searchbar span a')[0]).color;
const matches = messagesField.innerText.match(/^(?=.*\b[1-9]\d*\b).*/); // check if there is at least one number greater than 0 - this should be language-agnostic
if (matches) { // thet means there are either new or unread messages
messagesField.style.color = "red"; // We colorize in the color wanted by users
} else {
messagesField.style.color = defaultColor; // We decolorize the messages
}
}
}
changeColorOfNewMessage();
function colorizeThePages() {
if (options.colorize_the_page) {
document.querySelector("#menubar > table:nth-child(1) > tbody > tr > td:nth-child(1) > a:nth-child(1)").style.color = "#FFA07A"; // Forum Rules
document.querySelector("#menubar > table:nth-child(1) > tbody > tr > td:nth-child(1) > a:nth-child(2)").style.color = "#FFC200"; // Donate
document.querySelector("#menubar > table:nth-child(1) > tbody > tr > td:nth-child(2) > a:nth-child(1)").style.color = "#98FB98"; // Chat
document.querySelector("#menubar > table:nth-child(1) > tbody > tr > td:nth-child(2) > a:nth-child(2)").style.color = "#90EE90"; // FAQ
if (CONNECTED) document.querySelector("#menubar > table:nth-child(1) > tbody > tr > td:nth-child(2) > a:nth-child(3)").style.color = "#4169E1"; // Members
document.querySelector("#menubar > table:nth-child(3) > tbody > tr > td:nth-child(1) > a:nth-child(1)").style.color = "#87CEEB"; // User Control Panel
const profileLink = document.querySelector("a#profile_link");
if (options.add_profile_button && profileLink) {
profileLink.style.color = "#F08080"; // Profile
}
document.querySelector("#menubar > table:nth-child(3) > tbody > tr > td:nth-child(2) > a:nth-child(1)").style.color = "#87CEFA"; // Search
document.querySelector("#menubar > table:nth-child(3) > tbody > tr > td:nth-child(2) > a:nth-child(2)").style.color = "#FF0000"; // Logout
document.querySelector("#logodesc > table > tbody > tr > td:nth-child(2) > h1").style.color = '#' + Math.floor(Math.random() * 16777215).toString(16); // Random colour for the title
}
}
colorizeThePages();
// Color friends
async function colorizeFriendsMe() {
if (options.colorize_friends_me > 0) {
// Add legends friends
if ((URLContains("index.php") || (window.location.pathname.startsWith('/forum/') && window.location.pathname.endsWith('/forum/'))) && options.colorize_friends_me > 1) {
if (document.querySelectorAll(".gensmall")[3].lastElementChild.text !== "Friends") {
const friends = document.createElement('a');
friends.setAttribute('href', './ucp.php?i=zebra&mode=friends');
friends.style.color = color.color_of_friends;
friends.innerText = 'Friends';
const selector = document.querySelectorAll(".gensmall")[3];
selector.append(", ");
selector.append(friends);
}
}
// Colorize friends
await retrievesFriendsLists();
const links = document.querySelectorAll("a[href^='./memberlist.php'], .postauthor, .gen, .postlink-local, .quotetitle");
links.forEach(link => {
let nickname = link.innerText;
if (link.classList.contains('quotetitle')) nickname = nickname.substring(0, nickname.length - 7)
if (USERNAME === nickname && (options.colorize_friends_me === 1 || options.colorize_friends_me === 3)) {
link.id = "colorize";
link.style.color = color.color_of_me;
}
if (FRIENDS_LIST.includes(nickname) && options.colorize_friends_me > 1) {
link.id = "colorize";
link.style.color = color.color_of_friends;
}
});
}
}
colorizeFriendsMe();
function searchURL() {
const searchBar = document.querySelector("#searchBar");
// Config values
const searchSubforums = options.special_search_parameter.searchSubforums;
const searchTopicLocation = options.special_search_parameter.searchTopicLocation;
const sortResultsBy = options.special_search_parameter.sortResultsBy;
const sortOrderBy = options.special_search_parameter.sortOrderBy;
const limitToPrevious = options.special_search_parameter.limitToPrevious;
const returnFirst = options.special_search_parameter.returnFirst;
// Fetch the values from search options
let searchScope = document.getElementById("searchScope").value; // Everywhere/This forum/This topic
let searchTerms = document.getElementById("searchTerms").value; // Any/All
let searchLocation = document.getElementById("searchLocation").checked ? "firstpost" : (searchTopicLocation === "all" || searchTopicLocation === "msgonly") ? searchTopicLocation : "all"; // Search
let showResultsAsPosts = document.getElementById("showAsPosts").checked ? "posts" : "topics"; // Display
let searchAuthor = document.getElementById("searchAuthor").value; // Author
let forumID = "";
let topicID = "0";
// Check the searchScope and parse URL if required
if (searchScope === "thisForum") {
let urlParams = new URLSearchParams(window.location.search);
forumID = urlParams.get("f");
if (forumID) {
forumID = "&fid%5B%5D=" + forumID;
}
}
if (searchScope === "thisTopic") {
let urlParams = new URLSearchParams(window.location.search);
topicID = urlParams.get("t");
}
window.location.href = `./search.php?keywords=${encodeURIComponent(searchBar.value).replace(/%20/g, "+")}&terms=${searchTerms}&author=${encodeURIComponent(searchAuthor).replace(/%20/g, "+")}${forumID}&sc=${searchSubforums}&sf=${searchLocation}&sk=${sortResultsBy}&sd=${sortOrderBy}&sr=${showResultsAsPosts}&st=${limitToPrevious}&ch=${returnFirst}&t=${topicID}`;
}
async function specialSearch() {
if (options.special_search) {
// Get row to insert searchBar
const cell = document.querySelector("#menubar > table:nth-child(3) > tbody > tr > td:nth-child(2)");
const container = document.createElement("div");
container.style.position = "relative";
container.style.display = "inline-block";
// Different locations based on which page the user is on
let searchScopeOptions;
if (window.location.href.includes("viewtopic.php")) {
searchScopeOptions = `
`;
} else if (window.location.href.includes("viewforum.php")) {
searchScopeOptions = `
`;
} else {
searchScopeOptions = `
`;
}
// Getting config values
let specialSearchParametersJSON = options.special_search_parameter;
const searchLocationChecked = specialSearchParametersJSON.searchTopicLocation === "titleonly" || specialSearchParametersJSON.searchTopicLocation === "firstpost" ? "checked" : "";
const showAsPostsChecked = specialSearchParametersJSON.showResultsAsPosts ? "checked" : "";
const searchTermsSelected = specialSearchParametersJSON.searchTermsSpecificity;
// Creating search bar and search options
container.innerHTML = `
`;
cell.prepend(container);
// Getting reference of the search bar and the search options
const searchBar = document.querySelector("#searchBar");
const searchOptions = document.querySelector("#searchOptions");
// Add event listener for search bar
searchBar.addEventListener("click", function (event) {
// Makes it so search options will not disappear first
event.stopPropagation();
// Toggles the display of search options when search bar is clicked
searchOptions.style.display = "block";
});
// Add event listener for search options so search options will not disappear when clicked on
searchOptions.addEventListener("click", function (event) {
event.stopPropagation();
});
// Add event listener to document (disappear when anything other than the search bar/options is clicked)
document.addEventListener("click", function () {
// Hides the search options when click is outside the search bar
if (searchOptions.style.display === "block") {
searchOptions.style.display = "none";
}
});
// Add event listener for the Esc key to hide search options
document.addEventListener("keydown", function (event) {
if (event.key === "Escape") { // Check if the pressed key is Escape
searchOptions.style.display = "none"; // Hide the search options
}
});
// Redirect to search on Enter key press
searchBar.addEventListener("keydown", function (ev) {
if (ev.code === "Enter") {
searchURL()
}
});
// Add functionality for search button
document.querySelector("#searchButton").addEventListener("click", searchURL);
if (specialSearchParametersJSON.showFriends) {
await retrievesFriendsLists();
// Retrieve reference to "searchAuthor" input
const searchAuthorInput = document.querySelector("#searchAuthor");
// Create friends list
const friendsClass = document.createElement("class")
friendsClass.id = "friends-lists-search"
// Create a new paragraph element
const friendTitle = document.createElement('p');
// Add content to paragraph
friendTitle.textContent = "Friends (" + FRIENDS_LIST.length + "):";
const friendsLists = document.createElement("ul");
if (FRIENDS_LIST.length === 0) {
const friendItem = document.createElement("li");
friendItem.textContent = "Go make some friends :)";
friendsLists.appendChild(friendItem);
}
// Browse the friends table and create a list item for each word
FRIENDS_LIST.forEach(friend => {
const friendItem = document.createElement("li");
friendItem.textContent = friend;
// Add a click event listener to each list item
friendItem.addEventListener("click", function () {
searchAuthorInput.value = friend;
});
friendsLists.appendChild(friendItem);
});
// When you click on search author input
searchAuthorInput.addEventListener("click", function (event) {
friendsClass.style.display = "block"; //Display list of friends
});
const parentElement = document.getElementById('searchOptions');
const children = Array.from(parentElement.children);
const selectedChildren = children.slice(0, children.length - 2);
// Add event listener to all first child of the special search bar (disappear you click on element on the special search bar who are not the friend list, the button or the input)
selectedChildren.forEach(option => {
option.addEventListener('click', function () {
friendsClass.style.display = "none"; //Hide the friend lists
});
});
// Add paragraph to specific class
friendsClass.appendChild(friendTitle);
friendsClass.appendChild(friendsLists);
searchOptions.appendChild(friendsClass); // Append the friend list by default
friendsClass.style.display = "none"; // Hide the friend list by default
document.addEventListener("click", function () {
// Hides the search options when click is outside the search bar
if (searchOptions.style.display === "block") {
friendsClass.style.display = "none"; //Hide the friend lists
}
});
}
}
}
specialSearch();
/*
Originally made by ucsanytaef
And adapted for cs.rin.ru enhanced by Altansar (nothing to adapt xD)
*/
function showAllSpoilers() {
if (options.show_all_spoilers) { //If show all spoilers is active
const spoilers = document.querySelectorAll('input[type="button"][value="Show"]');
spoilers.forEach(spoiler => {
spoiler.click();
});
}
}
showAllSpoilers();
function addLinkToQuote(message, id) {
const link = `${FORUM_BASE_URL}viewtopic.php?p=${id}#p${id}`;
const firstQuoteIndex = message.indexOf('[quote');
const firstQuoteEndIndex = message.indexOf(']', firstQuoteIndex) + 1;
if (firstQuoteIndex !== -1) {
const beforeQuote = message.slice(0, firstQuoteIndex);
const quoteTag = message.slice(firstQuoteIndex, firstQuoteEndIndex);
const afterQuote = message.slice(firstQuoteEndIndex);
message = `${beforeQuote}[url=${link}]${quoteTag}[/url]${afterQuote}`;
}
return message
}
function AddLinkQuote() {
if (options.add_link_quote) {
const searchParams = new URLSearchParams(window.location.search);
const id = searchParams.get('p');
const topic = searchParams.get('t'); // A new parameter appears when previewing a post
const mode = searchParams.get('mode'); // Mode can be quote, reply or edit (for posts) or compose (for PMs)
const sid = searchParams.get('sid'); // Appears when previewing PMs
const messageTextArea = document.querySelector('textarea[name="message"]');
if (messageTextArea && id && !topic && mode !== "edit" && !sid) { // Make sure the ID exists and the post is not a preview and is not being edited and it is not a PM being previewed
messageTextArea.value = addLinkToQuote(messageTextArea.value, id);
}
}
}
AddLinkQuote();
// Quick reply panel
if (options.quick_reply && quickReplyPanel) {
let button = document.createElement("button");
button.innerHTML = "Show Quick Reply Panel";
button.style.cssText = "position: fixed; bottom: 0%; left: 0%; min-height: 40px; min-width: 50px; width: 10%; height: 3%; z-index: 9999;";
button.addEventListener("click", function () {
if (quickReplyPanel.style.position !== "sticky") {
quickReplyPanel.style.position = "sticky";
quickReplyPanel.style.bottom = "0px";
button.innerHTML = "Hide Quick Reply Panel";
} else {
quickReplyPanel.style.position = "static";
button.innerHTML = "Show Quick Reply Panel";
}
});
document.body.appendChild(button);
}
function quotify() {
if (quickReplyPanel) {
$("a:has([title='Reply with quote'])").each(function () {
const quoteLink = this.href;
if (!quoteLink.includes("posting.php")) return;
this.href = "javascript:void(0)";
const postElem = $(this).parents().eq(7);
const postID = $(postElem).find("a[name]").last().attr("name").slice(1);
const author = $(postElem).find(".postauthor").text();
const authorID = $(postElem).find("[title=Profile]").parent().attr("href").split("u=")[1];
const child = $(this).find("[title='Reply with quote']");
$(this).find('[title="Reply with quote"]').on("click", function () {
console.log(postID);
console.log(quoteLink);
GM_xmlhttpRequest({
url: quoteLink, onload: function (response) {
let postBody = $(response.responseText).find("[name=message]").text();
if (options.add_link_quote) {
postBody = addLinkToQuote(postBody, postID)
}
$("[name=message]")[0].value += postBody;
const quoted = $('Quoted!');
quoted.css({
'position': 'absolute',
'top': child.offset().top - quoted.outerHeight() - 20,
'left': child.offset().left + (child.outerWidth() / 2) - (quoted.outerWidth() / 2) - 12
});
$('body').append(quoted);
setTimeout(function () {
quoted.fadeOut();
}, 2000);
}
});
});
});
}
}
quotify()
function collapseQuotes() {
if (!options.collapse_quotes) return;
const quoteDivs = $('.quotecontent');
quoteDivs.each(function () {
// Create the new divs
const outerDiv = $('');
const innerDiv = $('');
const button = $('');
const contentDiv = $('');
const hiddenDiv = $('');
// Move the original quote content into the hidden div
hiddenDiv.append($(this).contents());
// Append elements to create the structure
innerDiv.append(button);
contentDiv.append(hiddenDiv);
outerDiv.append(innerDiv).append(contentDiv);
// Insert the new structure before the original div
$(this).before(outerDiv);
// Remove the original div
$(this).remove();
// Add click event to the button
button.click(function () {
const hiddenContent = $(this).parent().next().find('div').first();
if (hiddenContent.css('display') === 'none') {
hiddenContent.css('display', 'block');
$(this).val('Hide');
} else {
hiddenContent.css('display', 'none');
$(this).val('Show');
}
});
});
}
collapseQuotes()
/*
function addFriendButton() {
if(true) {
if (URLContains("viewtopic.php")) {
//