Bitcoin Forum
August 29, 2026, 04:05:19 PM *
News: Latest Bitcoin Core release: 31.1 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: [Userscript] Highlight to Profile- highlight any username to get profile links.  (Read 195 times)
MisFoxie (OP)
Full Member
***
Offline

Activity: 254
Merit: 121



View Profile
August 28, 2026, 04:33:09 PM
Merited by irfan_pak10 (1), katanic97 (1)
 #1

Many times, users mention each other but their profile link is not added. However, sometimes we want to visit that profile and at that time we have to copy the username, go to another platform then search for it and then view it. This takes some time and I think it is a bit of a hassle. I suggested this feature before but since I didn’t get any response, I decided to try it myself to see if it was actually possible so I get the help of powerful AI model. I hope you like it.

What this does
When a username is selected, a small box appears just below it showing three types of profiles: a Bitcoin profile, a BPIP profile, and another Bitlist profile.

 Demo:


Install

1. Install Tampermonkey or Violentmonkey (works on desktop Chrome/Firefox/Edge, and on Firefox for Android)
2. Create a new script, paste the code below, save. Or you can directly install from Greasy Fork

https://greasyfork.org/en/scripts/593347-highlight-to-profile-bitcointalk-username-lookup

3. Reload any Bitcointalk page and highlight a username

Code

Code:
// ==UserScript==
// @name         Highlight to Profile - Bitcointalk Username Lookup
// @namespace    https://bitcointalk.org/
// @version      1.1.0
// @description  Highlight any username in a Bitcointalk post to instantly get links to that user's Bitcointalk, BPIP and BitList profiles.
// @author       MisFoxie
// @match        https://bitcointalk.org/*
// @match        http://bitcointalk.org/*
// @run-at       document-idle
// @grant        GM_xmlhttpRequest
// @grant        GM.xmlHttpRequest
// @connect      bpip.org
// @connect      api.ninjastic.space
// @noframes
// ==/UserScript==

/*
 * How the lookup works (endpoints verified live):
 *
 * 1) Ninjastic exact match (JSON, sends access-control-allow-origin: *):
 *      GET https://api.ninjastic.space/users/<username>
 *      -> {"result":"success","message":null,"data":{"author":"LoyceV","author_uid":459836,"posts_count":35579}}
 *      -> {"result":"success","message":"User not found","data":null}
 *    Case-insensitive. Response header x-ratelimit-limit: 100.
 *
 * 2) BPIP username search (HTML, no CORS headers -> needs GM_xmlhttpRequest):
 *      GET https://bpip.org/search.aspx?q=<text>
 *    Result rows contain:
 *      <td data-label="Name"><a href="Profile?p=LoyceV">LoyceV</a> ...</td>
 *      <td data-label="User ID">459836</td>
 *      <td data-label="Position">Legendary</td>
 *    This is a prefix search (max 50 rows), so it also returns near-matches.
 *
 * All three profile links are built from the numeric UID, which is unambiguous
 * and avoids the URL-encoding problems usernames cause:
 *      https://bitcointalk.org/index.php?action=profile;u=<uid>
 *      https://bpip.org/Profile?id=<uid>
 *      https://bitlist.co/user/id/<uid>
 * (bpip.org/Profile?p=<name> works too, but breaks on names with spaces: it
 *  renders the title as "Profile for Sceptical%20Spectacles".)
 *
 * Not used, and why:
 * - BPIP api2/ProfileInfo (the endpoint the official BPIP extension calls)
 *   only accepts numeric user IDs, so it cannot resolve a name to a profile.
 * - BitList has no public API (/api/* and /rpc return 404, and both are
 *   robots-disallowed), so BitList is linked to but never queried. Its route
 *   table (_app/immutable/entry/app.*.js) defines the profile route as
 *   /user/id/[id] -- a numeric Bitcointalk UID, not a username. The older
 *   /user/<username> form does not exist, which is why those links 404'd.
 */

(function () {
    "use strict";

    // ---------------------------------------------------------------- config

    const CFG = {
        NINJASTIC_USER: "https://api.ninjastic.space/users/",
        BPIP_SEARCH: "https://bpip.org/search.aspx?q=",
        BPIP_PROFILE: "https://bpip.org/Profile?id=",
        BCT_PROFILE: "https://bitcointalk.org/index.php?action=profile;u=",
        BITLIST_PROFILE: "https://bitlist.co/user/id/",

        // A selection must look like a username to be worth a request.
        MIN_LEN: 2,
        MAX_LEN: 25,
        // Wait this long after the selection settles before firing requests.
        DEBOUNCE_MS: 350,
        // Never fire more often than this (protects the Ninjastic rate limit).
        MIN_REQUEST_GAP_MS: 700,
        REQUEST_TIMEOUT_MS: 12000,
        MAX_CANDIDATES: 6,
        CACHE_MAX: 300,
    };

    const ICONS = {
        bct: "https://bitcointalk.org/favicon.ico",
        bpip: "https://bpip.org/favicon.ico",
        bitlist: "https://bitlist.co/favicon.ico",
    };

    // ------------------------------------------------------------ GM bridge

    // Tampermonkey exposes GM_xmlhttpRequest, Violentmonkey also exposes
    // GM.xmlHttpRequest. Normalise both into one promise-based helper.
    const gmRequest = (function () {
        const legacy = typeof GM_xmlhttpRequest === "function" ? GM_xmlhttpRequest : null;
        const modern = typeof GM !== "undefined" && GM && typeof GM.xmlHttpRequest === "function"
            ? GM.xmlHttpRequest.bind(GM)
            : null;
        const impl = legacy || modern;

        return function (url) {
            if (!impl) {
                return Promise.reject(new Error("GM_xmlhttpRequest unavailable"));
            }
            return new Promise(function (resolve, reject) {
                impl({
                    method: "GET",
                    url: url,
                    timeout: CFG.REQUEST_TIMEOUT_MS,
                    headers: { Accept: "text/html,application/json;q=0.9,*/*;q=0.8" },
                    onload: function (res) {
                        if (res.status >= 200 && res.status < 300) resolve(res.responseText);
                        else reject(new Error("HTTP " + res.status));
                    },
                    onerror: function () { reject(new Error("Network error")); },
                    ontimeout: function () { reject(new Error("Timed out")); },
                });
            });
        };
    })();

    // ---------------------------------------------------------------- helpers

    function esc(text) {
        return String(text).replace(/[&<>"']/g, function (c) {
            return { "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;" }[c];
        });
    }

    // Bitcointalk usernames allow letters, digits, spaces and punctuation.
    // Reject anything that looks like a sentence rather than a name.
    const STOPWORDS = new Set([
        "a", "an", "and", "are", "as", "at", "be", "but", "by", "for", "from", "has", "have",
        "he", "her", "his", "i", "if", "in", "is", "it", "its", "me", "my", "no", "not", "of",
        "on", "or", "our", "she", "so", "than", "that", "the", "their", "them", "then", "there",
        "they", "this", "to", "up", "was", "we", "were", "what", "when", "which", "who", "will",
        "with", "you", "your",
    ]);

    function looksLikeUsername(text) {
        if (text.length < CFG.MIN_LEN || text.length > CFG.MAX_LEN) return false;
        if (/[\r\n\t]/.test(text)) return false;
        if (/[,.;:!?"\u201c\u201d]\s/.test(text)) return false;
        if (!/^[A-Za-z0-9][A-Za-z0-9 ._\-~!@#$%^&*()+='|\\/\[\]{}<>?]*$/.test(text)) return false;

        const words = text.split(/\s+/);
        if (words.length > 4) return false;
        // Lowercase filler words mean it is prose, not a username. Capitalised
        // words are kept so names like "The Sceptical Chymist" still work.
        if (words.some(function (w) { return STOPWORDS.has(w); })) return false;
        return true;
    }


    const cache = new Map();

    function cacheGet(key) {
        return cache.has(key) ? cache.get(key) : null;
    }

    function cacheSet(key, value) {
        if (cache.size >= CFG.CACHE_MAX) cache.delete(cache.keys().next().value);
        cache.set(key, value);
        return value;
    }

    // ------------------------------------------------------------- lookups

    function ninjasticExact(name) {
        return gmRequest(CFG.NINJASTIC_USER + encodeURIComponent(name))
            .then(function (text) {
                let json;
                try { json = JSON.parse(text); } catch (e) { return null; }
                if (!json || !json.data || !json.data.author_uid) return null;
                return {
                    name: json.data.author,
                    uid: String(json.data.author_uid),
                    position: "",
                    posts: json.data.posts_count,
                    source: "ninjastic",
                };
            })
            .catch(function () { return null; });
    }

    // Parses the BPIP search result table with DOMParser so markup tweaks are
    // less likely to break the script than with regex scraping.
    function parseBpipRows(html) {
        const doc = new DOMParser().parseFromString(html, "text/html");
        const rows = [];

        doc.querySelectorAll("tr").forEach(function (tr) {
            const link = tr.querySelector('td[data-label="Name"] a[href*="Profile?p="]');
            const uidCell = tr.querySelector('td[data-label="User ID"]');
            if (!link || !uidCell) return;

            const uid = uidCell.textContent.trim();
            if (!/^\d+$/.test(uid)) return;

            const posCell = tr.querySelector('td[data-label="Position"]');
            const postsCell = tr.querySelector('td[data-label="Posts"]');
            rows.push({
                name: link.textContent.trim(),
                uid: uid,
                position: posCell ? posCell.textContent.trim() : "",
                posts: postsCell ? postsCell.textContent.trim() : "",
                source: "bpip",
            });
        });

        return rows;
    }

    function bpipSearchRaw(text) {
        return gmRequest(CFG.BPIP_SEARCH + encodeURIComponent(text))
            .then(parseBpipRows)
            .catch(function () { return []; });
    }

    // BPIP's search box matches a single token only: q=Sceptical finds
    // "Sceptical Spectacles", but q=Sceptical%20Spectacles returns 0 rows.
    // Its matching is also prefix-based, so only the *first* word of a
    // multi-word name finds it. Try each word (longest first) until the full
    // selection matches a returned row.
    function bpipSearch(text) {
        const words = text.split(/\s+/).filter(Boolean);
        if (words.length === 1) return bpipSearchRaw(text);

        const key = text.toLowerCase();
        const tokens = words.slice().sort(function (a, b) { return b.length - a.length; });

        function narrow(rows) {
            return rows.filter(function (r) {
                const name = r.name.toLowerCase();
                return name === key || name.startsWith(key) || name.indexOf(key) !== -1;
            });
        }

        // Note: the loop variable is named "idx" rather than a bare letter so
        // the source contains no bracketed single letter, which some forums
        // treat as BBCode italics when the script is pasted into a post.
        function attempt(idx) {
            if (idx >= tokens.length) return Promise.resolve([]);
            return bpipSearchRaw(tokens[idx]).then(function (rows) {
                const hit = narrow(rows);
                return hit.length ? hit : attempt(idx + 1);
            });
        }

        return attempt(0);
    }

    // Exact hit first, then BPIP near-matches, de-duplicated by user ID.
    function lookup(text) {
        const key = text.toLowerCase();
        const hit = cacheGet(key);
        if (hit) return Promise.resolve(hit);

        return Promise.all([ninjasticExact(text), bpipSearch(text)])
            .then(function (results) {
                const exact = results[0];
                const rows = results[1];

                const seen = new Set();
                const candidates = [];

                function push(entry) {
                    if (!entry || seen.has(entry.uid)) return;
                    seen.add(entry.uid);
                    candidates.push(entry);
                }

                push(exact);
                rows.filter(function (r) { return r.name.toLowerCase() === key; }).forEach(push);
                rows.filter(function (r) { return r.name.toLowerCase().startsWith(key); }).forEach(push);
                rows.forEach(push);

                return cacheSet(key, {
                    query: text,
                    exact: candidates.some(function (c) { return c.name.toLowerCase() === key; }),
                    candidates: candidates.slice(0, CFG.MAX_CANDIDATES),
                    truncated: candidates.length > CFG.MAX_CANDIDATES,
                });
            });
    }

    // ------------------------------------------------------------------- UI

    const CSS = [
        ".h2p-box{position:absolute;z-index:2147483000;max-width:330px;font:12px Verdana,Arial,sans-serif;",
        " background:#fff;color:#000;border:1px solid #8fa1c0;border-radius:6px;",
        " box-shadow:0 3px 12px rgba(0,0,0,.28);padding:6px 8px;line-height:1.5}",
        ".h2p-box *{box-sizing:border-box}",
        ".h2p-head{display:flex;align-items:center;gap:6px;margin-bottom:4px;font-weight:bold}",
        ".h2p-head .h2p-q{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}",
        ".h2p-close{cursor:pointer;border:0;background:transparent;font-size:15px;line-height:1;padding:0 2px;color:#666}",
        ".h2p-close:hover{color:#000}",
        ".h2p-row{display:flex;align-items:center;gap:6px;padding:3px 0;border-top:1px solid #eee}",
        ".h2p-row:first-of-type{border-top:0}",
        ".h2p-name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}",
        ".h2p-meta{color:#777;font-size:10px;font-weight:normal}",
        ".h2p-links{display:flex;gap:4px;flex:0 0 auto}",
        ".h2p-links a{display:inline-flex;align-items:center;justify-content:center;",
        " width:26px;height:22px;border:1px solid #cfd8e6;border-radius:4px;background:#f7f9fc;text-decoration:none}",
        ".h2p-links a:hover{background:#e8eff9;border-color:#8fa1c0}",
        ".h2p-links img{width:16px;height:16px;display:block}",
        ".h2p-msg{color:#666;font-style:italic}",
        ".h2p-more{color:#777;font-size:10px;padding-top:3px}",
        "@media (prefers-color-scheme:dark){.h2p-box{background:#20242b;color:#dfe3ea;border-color:#3c4450}",
        " .h2p-row{border-top-color:#333a44}.h2p-links a{background:#2a3038;border-color:#3c4450}",
        " .h2p-links a:hover{background:#343c46}.h2p-close{color:#9aa4b2}.h2p-close:hover{color:#fff}}",
    ].join("\n");

    let styleInjected = false;
    function injectStyle() {
        if (styleInjected) return;
        styleInjected = true;
        const style = document.createElement("style");
        style.textContent = CSS;
        (document.head || document.documentElement).appendChild(style);
    }

    let box = null;

    function hideBox() {
        if (box) {
            box.remove();
            box = null;
        }
    }

    function bindClose() {
        if (!box) return;
        const btn = box.querySelector(".h2p-close");
        if (btn) btn.addEventListener("click", hideBox);
    }

    function showBox(rect, html) {
        injectStyle();
        hideBox();

        box = document.createElement("div");
        box.className = "h2p-box";
        box.innerHTML = html;
        // Interacting with the popup must not clear the selection or re-trigger.
        ["mousedown", "mouseup"].forEach(function (evt) {
            box.addEventListener(evt, function (e) { e.stopPropagation(); });
        });
        box.addEventListener("touchstart", function (e) { e.stopPropagation(); }, { passive: true });

        bindClose();
        document.body.appendChild(box);
        position(rect);
        return box;
    }

    function position(rect) {
        if (!box) return;
        const pad = 6;
        const w = box.offsetWidth;
        const h = box.offsetHeight;

        let left = window.scrollX + rect.left;
        let top = window.scrollY + rect.bottom + pad;

        const maxLeft = window.scrollX + document.documentElement.clientWidth - w - pad;
        if (left > maxLeft) left = maxLeft;
        if (left < window.scrollX + pad) left = window.scrollX + pad;

        // Flip above the selection when there is no room below.
        if (rect.bottom + h + pad > document.documentElement.clientHeight) {
            const above = window.scrollY + rect.top - h - pad;
            if (above > window.scrollY) top = above;
        }

        box.style.left = left + "px";
        box.style.top = top + "px";
    }

    function headerHtml(query, note) {
        return '<div class="h2p-head"><span class="h2p-q" title="' + esc(query) + '">' +
            esc(query) + "</span>" +
            (note ? '<span class="h2p-meta">' + esc(note) + "</span>" : "") +
            '<button class="h2p-close" title="Close" type="button">&times;</button></div>';
    }

    function linkHtml(href, icon, alt, title) {
        return '<a href="' + esc(href) + '" target="_blank" rel="noopener noreferrer" title="' +
            esc(title) + '"><img src="' + icon + '" alt="' + alt + '"></a>';
    }

    function linksHtml(entry) {
        const name = entry.name;
        return '<span class="h2p-links">' +
            linkHtml(CFG.BCT_PROFILE + entry.uid, ICONS.bct, "Bitcointalk",
                "Bitcointalk profile of " + name + " (UID " + entry.uid + ")") +
            linkHtml(CFG.BPIP_PROFILE + encodeURIComponent(entry.uid), ICONS.bpip, "BPIP",
                "BPIP profile of " + name + " (UID " + entry.uid + ")") +
            linkHtml(CFG.BITLIST_PROFILE + encodeURIComponent(entry.uid), ICONS.bitlist, "BitList",
                "BitList profile of " + name + " (UID " + entry.uid + ")") +
            "</span>";
    }

    function resultHtml(result) {
        if (!result.candidates.length) {
            return headerHtml(result.query) + '<div class="h2p-msg">No Bitcointalk user found.</div>';
        }

        let html = headerHtml(result.query, result.exact ? "" : "similar names");

        result.candidates.forEach(function (entry) {
            const meta = [entry.position, "UID " + entry.uid].filter(Boolean).join(" \u00b7 ");
            html += '<div class="h2p-row"><span class="h2p-name">' + esc(entry.name) +
                '<br><span class="h2p-meta">' + esc(meta) + "</span></span>" +
                linksHtml(entry) + "</div>";
        });

        if (result.truncated) {
            html += '<div class="h2p-more">More matches on <a href="' +
                esc(CFG.BPIP_SEARCH + encodeURIComponent(result.query)) +
                '" target="_blank" rel="noopener noreferrer">BPIP search</a></div>';
        }

        return html;
    }

    // -------------------------------------------------------- event handling

    let debounceTimer = null;
    let lastRequestAt = 0;
    let currentQuery = "";
    let requestSeq = 0;

    function selectionRect() {
        const sel = window.getSelection();
        if (!sel || sel.isCollapsed || sel.rangeCount === 0) return null;
        const range = sel.getRangeAt(0);
        const rects = range.getClientRects();
        if (rects.length) return rects[rects.length - 1];
        const r = range.getBoundingClientRect();
        return r && (r.width || r.height) ? r : null;
    }

    function renderInto(html, rect) {
        if (!box) return;
        box.innerHTML = html;
        bindClose();
        position(selectionRect() || rect);
    }

    function handleSelection() {
        const sel = window.getSelection();
        if (!sel || sel.isCollapsed) {
            hideBox();
            currentQuery = "";
            return;
        }

        // Ignore selections inside our own popup or inside form fields.
        const anchor = sel.anchorNode;
        const anchorEl = anchor && anchor.nodeType === 1 ? anchor : anchor && anchor.parentElement;
        if (anchorEl && anchorEl.closest && anchorEl.closest(".h2p-box, input, textarea, select")) return;

        const text = sel.toString().trim().replace(/\s+/g, " ");
        if (!looksLikeUsername(text)) {
            hideBox();
            currentQuery = "";
            return;
        }
        if (text === currentQuery && box) return;

        const rect = selectionRect();
        if (!rect) return;

        currentQuery = text;
        const seq = ++requestSeq;

        const cached = cacheGet(text.toLowerCase());
        if (cached) {
            showBox(rect, resultHtml(cached));
            return;
        }

        showBox(rect, headerHtml(text) + '<div class="h2p-msg">Searching\u2026</div>');

        const wait = Math.max(0, CFG.MIN_REQUEST_GAP_MS - (Date.now() - lastRequestAt));
        setTimeout(function () {
            if (seq !== requestSeq) return;
            lastRequestAt = Date.now();
            lookup(text)
                .then(function (result) {
                    if (seq === requestSeq) renderInto(resultHtml(result), rect);
                })
                .catch(function (err) {
                    if (seq === requestSeq) {
                        renderInto(headerHtml(text) +
                            '<div class="h2p-msg">Lookup failed: ' + esc(err.message) + "</div>", rect);
                    }
                });
        }, wait);
    }

    function scheduleSelectionCheck() {
        clearTimeout(debounceTimer);
        debounceTimer = setTimeout(handleSelection, CFG.DEBOUNCE_MS);
    }

    // Desktop: mouseup ends a drag-selection.
    document.addEventListener("mouseup", scheduleSelectionCheck, true);
    // Mobile: touchend plus selectionchange cover tap-hold and handle dragging.
    document.addEventListener("touchend", scheduleSelectionCheck, true);
    document.addEventListener("selectionchange", scheduleSelectionCheck);
    // Keyboard selection (shift+arrows, ctrl+A, ...).
    document.addEventListener("keyup", function (e) {
        if (e.shiftKey || e.key === "Shift" || e.ctrlKey) scheduleSelectionCheck();
    }, true);

    document.addEventListener("mousedown", function (e) {
        if (box && !box.contains(e.target)) hideBox();
    }, true);

    document.addEventListener("keydown", function (e) {
        if (e.key === "Escape") hideBox();
    }, true);

    function reposition() {
        if (!box) return;
        const r = selectionRect();
        if (r) position(r); else hideBox();
    }

    window.addEventListener("scroll", reposition, true);
    window.addEventListener("resize", reposition);
})();

I did not want this to hammer anyone's site so

Quote
  • Lookups are debounced 350ms after the selection settles, and rate-limited to one per 700ms
  • Results are cached (300 entries) - re-selecting the same name costs zero requests
  • A highlight has to actually look like a username before anything fires. Highlighting ordinary prose like "for the data" sends no requests at all: length limits, a stopword filter and a character whitelist screen it out first


Privacy
Only ninjastic Api and bpip.org and only the text you selected are sent nothing else. No analytics, no accounts, no keys, no external libraries, no data stored anywhere except an in-memory cache that dies when you close the tab.
The whole thing is one file of plain readable JavaScript - please read it before you install it and don't take my word for any of the above.



All Credit goes to BPIP and Ninjastic.space because this tool made entirely based on the data collected by BPIP and Ninjastic.space. I only glued their lookups to a text highlight.

I know there are many bugs I will try to solve it if people get interested in this tool.

Crypto Library
Legendary
*
Offline

Activity: 1694
Merit: 1208


Leading Crypto Sports Betting & Casino Platform


View Profile WWW
August 28, 2026, 04:43:31 PM
 #2

Many times, users mention each other but their profile link is not added. However, sometimes we want to visit that profile and at that time we have to copy the username, go to another platform then search for it and then view it. This takes some time and I think it is a bit of a hassle. I suggested this feature before but since I didn’t get any response, I decided to try it myself to see if it was actually possible so I get the help of powerful AI model. I hope you like it.
Yep, this was very useful and time saving tools.
Few years ago, when artificial intelligence was not that much powerful and also I am not much familiar with it, I created an extension myself: 1 click to Ninjaspace. Then I tried many times to create the same thing for BPIP, but I failed. Then, due to laziness, BPIP was not added later.

Anyway, thanks for making this, this will be more useful,  Grin

..Stake.com..   ▄████████████████████████████████████▄
   ██ ▄▄▄▄▄▄▄▄▄▄            ▄▄▄▄▄▄▄▄▄▄ ██  ▄████▄
   ██ ▀▀▀▀▀▀▀▀▀▀ ██████████ ▀▀▀▀▀▀▀▀▀▀ ██  ██████
   ██ ██████████ ██      ██ ██████████ ██   ▀██▀
   ██ ██      ██ ██████  ██ ██      ██ ██    ██
   ██ ██████  ██ █████  ███ ██████  ██ ████▄ ██
   ██ █████  ███ ████  ████ █████  ███ ████████
   ██ ████  ████ ██████████ ████  ████ ████▀
   ██ ██████████ ▄▄▄▄▄▄▄▄▄▄ ██████████ ██
   ██            ▀▀▀▀▀▀▀▀▀▀            ██ 
   ▀█████████▀ ▄████████████▄ ▀█████████▀
  ▄▄▄▄▄▄▄▄▄▄▄▄███  ██  ██  ███▄▄▄▄▄▄▄▄▄▄▄▄
 ██████████████████████████████████████████
▄▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▄
█  ▄▀▄             █▀▀█▀▄▄
█  █▀█             █  ▐  ▐▌
█       ▄██▄       █  ▌  █
█     ▄██████▄     █  ▌ ▐▌
█    ██████████    █ ▐  █
█   ▐██████████▌   █ ▐ ▐▌
█    ▀▀██████▀▀    █ ▌ █
█     ▄▄▄██▄▄▄     █ ▌▐▌
█                  █▐ █
█                  █▐▐▌
█                  █▐█
▀▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▀█
▄▄█████████▄▄
▄██▀▀▀▀█████▀▀▀▀██▄
▄█▀       ▐█▌       ▀█▄
██         ▐█▌         ██
████▄     ▄█████▄     ▄████
████████▄███████████▄████████
███▀    █████████████    ▀███
██       ███████████       ██
▀█▄       █████████       ▄█▀
▀█▄    ▄██▀▀▀▀▀▀▀██▄  ▄▄▄█▀
▀███████         ███████▀
▀█████▄       ▄█████▀
▀▀▀███▄▄▄███▀▀▀
..PLAY NOW..
snowpega
Sr. Member
****
Offline

Activity: 1036
Merit: 485



View Profile WWW
August 28, 2026, 05:03:19 PM
 #3

Hmm, this seems to be a good tool that can help anyone find anyone's profile data on the BPIP tool if the user is mentioned anywhere in the posts. Aside from this, I honestly don't use extensions, and I try to avoid using them due to some concerns. And right now I am only using one extension, which is the BPIP extension. And if you are more concerned about checking the poster profile, then I personally think the BPIP extension is also enough for you to fetch any user data, right? And if you are more kind of a person who spends more time checking a lot of users' data, then using such kind of tools can be helpful from my point of view.

▄███████████████████████▄
█████████████████████████
██████████▀▄▄▄▀██████████
███████████████████████
████████▀▀▄▄▄▀█████████
███████░░░█████░░░███████
██████░░░▐█████▌░░░██████
██████░░░▐█████▌░░░██████
██████░░░▐█████▌░░░██████
███████░░░█████░░░███████
████████▄▄▀▀▀▄█████████
█████████████████████████
▀███████████████████████▀
████████████████████████████████████████████████████████████████████
Lock.com
 
████████████████████████████████████████████████████████████████████
████
██
██
██
██
██
██
██
██
██
██
██
████
█▀▀











█▄▄
▀▀█











▄▄█
█▀▀











█▄▄
▀▀█











▄▄█
████
██
██
██
██
██
██
██
██
██
██
██
████
████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
 Open-code isolated Crypto Wallet   

████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
████
██
██
██
██
██
██
██
██
██
██
██
████
katanic97
Hero Member
*****
Offline

Activity: 812
Merit: 1338



View Profile WWW
August 28, 2026, 05:24:01 PM
 #4

Excellent tool, i think this will save a lot of time, and quite a lot at that. Tell me, how long did it take you to make this? It doesn’t seem that simple to me, but correct me if i’m wrong Cheesy Very useful!

Rhow
Full Member
***
Offline

Activity: 278
Merit: 123



View Profile
August 28, 2026, 07:28:45 PM
 #5

I remember clearly when @icopress invited me to participate in his campaign, he mentioned my account name and a few other accounts. Out of curiosity, I wanted to see the accounts that @icopress invited to participate in his campaign. There was only a username but no profile link, so I couldn't click on it until I found their profile.

Thank you, because I think this script has solved that problem now.

un_rank
Legendary
*
Offline

Activity: 1554
Merit: 1115



View Profile WWW
August 28, 2026, 08:45:43 PM
 #6

Many times, users mention each other but their profile link is not added. However, sometimes we want to visit that profile and at that time we have to copy the username, go to another platform then search for it and then view it.
You do not have to leave the forum to get a user's profile. If you click on "members" at the top of the screen, then click to search for members. By default it's already set to search by username, so you just input the name you copied and search.
Your userscript works faster than this and is a much better option and is actually a useful tool to have.

- Jay -

█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
█████████████████████▀█▀████████████████▀████████████████▀█████████████████████████████▀████████████████████████████████
█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
███████████████████████████████████████████████████████████████████████████████████████████▀██████▀█████▀████████▀█████
██████████████████████████████████████████████████████████████████████████████████████████████████████████████████
█████████████████████▄█▄████████████████▄████████████████▄█████████████████████████████████▄██████▄█████▄████████████
█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
 
 🍒   ⚽️    IIIIIFASTEST GROWING CASINO & SPORTSBOOK     Play Now    
IjawMan
Sr. Member
****
Online Online

Activity: 546
Merit: 251



View Profile
August 28, 2026, 10:50:44 PM
 #7

Very useful tool just as others have commended.

This will save time and put to an end the era of copying a username of a forum member and pasting it in the search box button to search for the username and then clicking it to the profile area.

Good work.

R


▀▀▀▀▀▀▀██████▄▄
████████████████
▀▀▀▀█████▀▀▀█████
████████▌███▐████
▄▄▄▄█████▄▄▄█████
████████████████
▄▄▄▄▄▄▄██████▀▀
LLBIT|
4,000+ GAMES
███████████████████
██████████▀▄▀▀▀████
████████▀▄▀██░░░███
██████▀▄███▄▀█▄▄▄██
███▀▀▀▀▀▀█▀▀▀▀▀▀███
██░░░░░░░░█░░░░░░██
██▄░░░░░░░█░░░░░▄██
███▄░░░░▄█▄▄▄▄▄████
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
█████████
▀████████
░░▀██████
░░░░▀████
░░░░░░███
▄░░░░░███
▀█▄▄▄████
░░▀▀█████
▀▀▀▀▀▀▀▀▀
█████████
░░░▀▀████
██▄▄▀░███
█░░█▄░░██
░████▀▀██
█░░█▀░░██
██▀▀▄░███
░░░▄▄████
▀▀▀▀▀▀▀▀▀
|||
▄▄████▄▄
▀█▀
▄▀▀▄▀█▀
▄░░▄█░██░█▄░░▄
█░▄█░▀█▄▄█▀░█▄░█
▀▄░███▄▄▄▄███░▄▀
▀▀█░░░▄▄▄▄░░░█▀▀
░░██████░░█
█░░░░▀▀░░░░█
▀▄▀▄▀▄▀▄▀▄
▄░█████▀▀█████░▄
▄███████░██░███████▄
▀▀██████▄▄██████▀▀
▀▀████████▀▀
.
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
░▀▄░▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄░▄▀
███▀▄▀█████████████████▀▄▀
█████▀▄░▄▄▄▄▄███░▄▄▄▄▄▄▀
███████▀▄▀██████░█▄▄▄▄▄▄▄▄
█████████▀▄▄░███▄▄▄▄▄▄░▄▀
███████████░███████▀▄▀
███████████░██▀▄▄▄▄▀
███████████░▀▄▀
████████████▄▀
███████████
▄▄███████▄▄
▄████▀▀▀▀▀▀▀████▄
▄███▀▄▄███████▄▄▀███▄
▄██▀▄█▀▀▀█████▀▀▀█▄▀██▄
▄██▀▄███░░░▀████░███▄▀██▄
███░████░░░░░▀██░████░███
███░████░█▄░░░░▀░████░███
███░████░███▄░░░░████░███
▀██▄▀███░█████▄░░███▀▄██▀
▀██▄▀█▄▄▄██████▄██▀▄██▀
▀███▄▀▀███████▀▀▄███▀
▀████▄▄▄▄▄▄▄████▀
▀▀███████▀▀
OFFICIAL PARTNERSHIP
SOUTHAMPTON FC
FAZE CLAN
SSC NAPOLI
LoyceV
Legendary
*
Offline

Activity: 4144
Merit: 22557


Thick-Skinned Gang Leader and Golden Feather 2021


View Profile WWW
Today at 07:13:12 AM
 #8

When a username is selected, a small box appears just below it
What happens when you select something else? Does this affect the default copy (CTRL-V) feature?

¡uʍop ǝpᴉsdn pɐǝɥ ɹnoʎ ɥʇᴉʍ ʎuunɟ ʞool no⅄
MisFoxie (OP)
Full Member
***
Offline

Activity: 254
Merit: 121



View Profile
Today at 07:29:23 AM
Last edit: Today at 07:41:13 AM by MisFoxie
 #9

When a username is selected, a small box appears just below it
What happens when you select something else? Does this affect the default copy (CTRL-V) feature?
No, It doesn't cause any effects in normal ctrl+c and Ctrl+v..

If something looks like username only then it send request. When a user select more than 4 words nothing will appear. If a username is too long selecting half of the text may bring the actual results.
 
Quote
Highlighting ordinary prose like "for the data" sends no requests at all..

Highlights longer than 25 characters or more than 4 words are ignored on purpose

Sterlino
Newbie
*
Online Online

Activity: 19
Merit: 1


View Profile
Today at 09:53:48 AM
 #10

Your tools seem quite effective. It won't be a waste of time to open different pages and check profiles repeatedly . I am personally thinking of an idea. If a small popup were to appear on the forum user's name, then an overview of the profile would be available. For example:

Registration date
Last active
Recently posted on which board
Most active boards
Merit sent and received activity
Other as per needed.

This type of important information can be found very easily so that overview can be obtained about that user.
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!