BeyondDimension / SteamTools

🛠「Watt Toolkit」是一个开源跨平台的多功能 Steam 工具箱。
https://steampp.net
GNU General Public License v3.0
20.23k stars 1.32k forks source link

👑[Enhancement] 好友增删检查 #3534

Open cyb233 opened 4 days ago

cyb233 commented 4 days ago

🥰 需求描述(Description)

曾经在油猴安装过一款脚本,用途是每次访问Steam页面时缓存好友列表,并在下一次访问时检查新增和删除的好友,它可以检查出被哪个好友默默地删除了,但这个脚本对应的GitHub仓库和油猴主页均已删除,我认为或许可以优化并添加进脚本市场,或直接作为插件实现整理进工具

🧐 解决方案(Solution)

🚑 其他信息(Other Information)

image image image

相关脚本源码
    
// ==UserScript==
// @name         Steam Friends Checker
// @namespace    https://walkedby.com/
// @version      1.3.7
// @description  [No longer update]This is made for someone really cares about his steam friends, when someone deleted you, it will notice to you.
// @author       Gordon Walkedby
// @match        https://*.steamcommunity.com/*
// @match        https://*.steampowered.com/*
// @exclude      https://steamcommunity.com//chat/
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_xmlhttpRequest
// @connect       steampowered.com
// @connect       steamcommunity.com
// @supportURL  https://github.com/gordonwalkedby/SteamFriendsChecker
// @description:zh    【不再更新】这是为那些特别关心他们的 Steam 好友列表的人设计的,如果有人删了好友,脚本就会发出提醒并记录删的是谁。
// ==/UserScript==
(function () {
    "use strict";
    var url = location.href.toLowerCase();
    var steamid = "";
    var familyView = 0;
    function print(p) {
        console.log('STEAM好友检查器(' + steamid + '):' + p);
    }
    function GetStorage(name) {
        return GM_getValue(name + steamid, "");
    }
    function GetStorageN(name) {
        var n = parseInt(GetStorage(name));
        if (n == NaN) {
            return 0;
        }
        return n;
    }
    function SetStorage(name, value) {
        GM_setValue(name + steamid, value);
    }
    var onFriendsPage = false;
    var onFriendsPageRoot = false;
    var onStorePage = url.indexOf('steampowered.com') > 3;
    if (url.indexOf('/friends') > 3) {
        if (document.body.innerHTML.indexOf('<a data-navid="following/" class="icon_item icon_all_following" ') > 10) {
            onFriendsPage = true;
            if ((url.length - url.lastIndexOf("/friends")) < 10) {
                onFriendsPageRoot = true;
            }
        }
    }
    var element = document.getElementById('responsive_page_menu');
    if (element == null) {
        print("没有找到 id responsive_page_menu");
        return false;
    }
    var s = element.innerHTML;
    var matches = s.match(/data-miniprofile="[0-9]+/);
    if (matches == null) {
        print("没有找到 data-miniprofile=");
        return false;
    }
    steamid = matches[0].replace(/[^0-9]+/, "");
    s = GetStorage("userinfo13");
    var user;
    function nowTime() {
        return (new Date).toLocaleString();
    }
    element = document.getElementById("header_parental_link");
    if (element != null) {
        familyView = 1;
        print("该账号使用家庭保护。");
        var cc = element.getAttribute("class");
        if (cc != null && cc.indexOf("green") > 0) {
            familyView = 2;
            print("家庭保护视图已经启动,Steam好友检查器不进行工作");
            return false;
        }
    }
    var firstTime = false;
    if (s.length > 10) {
        user = JSON.parse(s);
    }
    else {
        user = {
            id: steamid,
            friends: [],
            lostfriendrecords: [],
            newfriendsrecords: [],
            showtip: { added: false, lost: false, wait: false },
            checks: { added: true, lost: true, wait: true },
            inittime: nowTime(),
            resettime: ""
        };
        firstTime = true;
        print("初始化操作");
    }
    function GetFriend(idd) {
        var i;
        for (i = 0; i < user.friends.length; i++) {
            var f = user.friends[i];
            if (f.id == idd) {
                return f;
            }
        }
        return null;
    }
    function SaveInfo() {
        SetStorage("userinfo13", JSON.stringify(user));
    }
    var langbase = /** @class */ (function () {
        function langbase() {
            this.tipLost = "LOST SOMEONE!";
            this.tipADDED = "NEW FACE!";
            this.tipWAIT = "GOT REQUEST!";
            this.titleCHECK = "Check time:";
            this.titleLOST = "Friends you lost in these days:";
            this.titleADDED = "Friends you get in these days:";
            this.testADDED = "Pretend add 3 fake friends.";
            this.testLOST = "Pretend lose 3 fake friends.";
            this.testBOTH = "Pretend add 3 fake friends and lose 3 fake friends.";
            this.titleINIT = "Inited time:";
            this.titleCLEARED = "History cleared:";
            this.titleDOCLEAR = "Clear History";
            this.titleTEST = "Tests:";
            this.titleVIEW = "View Friends Checker";
            this.titleWBY = "Steam Friends Checker by Gordon Walkedby";
            this.titleELSE = "If you want to check more historic friends,you can try this.";
            this.titleSettings = "Settings:";
            this.setCheckADDED = "Check and notice added friends";
            this.setCheckLOST = "Check and notice lost friends";
            this.setCheckWAIT = "Notice to you when got new friend requests";
        }
        return langbase;
    }());
    var lang = new langbase;
    switch (document.getElementsByTagName('html')[0].getAttribute("lang")) {
        case 'zh-cn':
            lang.tipLost = "丢失好友!";
            lang.tipADDED = "新好友!";
            lang.tipWAIT = "好友请求!";
            lang.titleCHECK = "检查时间:";
            lang.titleLOST = "最近你失去的好友:";
            lang.titleADDED = "最近你得到的好友:";
            lang.testADDED = "假装新增三个好友";
            lang.testLOST = "假装失去三个好友";
            lang.testBOTH = "假装失去三个,又新增另外三个好友";
            lang.titleINIT = "初始化时间:";
            lang.titleCLEARED = "上次历史清空时间:";
            lang.titleDOCLEAR = "清空历史记录";
            lang.titleTEST = "测试:";
            lang.titleVIEW = "打开好友检查器";
            lang.titleWBY = "Steam 好友检查器 by 戈登走過去";
            lang.titleELSE = "如果你想查看你更多的历史好友,你可以看看这个。";
            lang.titleSettings = "设置:";
            lang.setCheckADDED = "对新增的好友进行检查和通知";
            lang.setCheckLOST = "对丢失的好友进行检查和通知";
            lang.setCheckWAIT = "在你有未处理的好友请求时进行通知";
            break;
        case 'zh-tw':
            lang.tipLost = "遺失好友!";
            lang.tipADDED = "新好友!";
            lang.tipWAIT = "好友請求!";
            lang.titleCHECK = "檢查時間:";
            lang.titleLOST = "最近你失去的好友:";
            lang.titleADDED = "最近你得到的好友:";
            lang.testADDED = "假裝新增三個好友";
            lang.testLOST = "假裝失去三個好友";
            lang.testBOTH = "假裝失去三個,又新增另外三個好友";
            lang.titleINIT = "初始化時間:";
            lang.titleCLEARED = "上次歷史清空時間:";
            lang.titleDOCLEAR = "清空歷史記錄";
            lang.titleTEST = "測試:";
            lang.titleVIEW = "打開好友檢查器";
            lang.titleWBY = "Steam好友檢查器by戈登走過去";
            lang.titleELSE = "如果你想查看你更多的歷史好友,你可以看看這個。";
            lang.titleSettings = "設定:";
            lang.setCheckADDED = "對新增的好友進行檢查和通知";
            lang.setCheckLOST = "對遺失的好友進行檢查和通知";
            lang.setCheckWAIT = "在你有未處理的好友請求時進行通知";
            break;
        default:
            break;
    }
    var shown = { added: false, lost: false, wait: false };
    user.showtip.wait = false;
    var needshow = user.showtip;
    function ShowTip() {
        if (onFriendsPage) {
        }
        else {
            var ar = document.querySelector('#header_notification_area');
            if (null == ar) {
                print("无法找到 #header_notification_area");
                return false;
            }
            if (user.checks.added && needshow.added && shown.added == false) {
                print("应该展示绿色");
                ar.innerHTML += "<a href='https://steamcommunity.com/my/friends/#sfcview' style='background-color: #90dd11;color: black;'> " + lang.tipADDED + " </a>";
                shown.added = true;
            }
            if (user.checks.lost && needshow.lost && shown.lost == false) {
                print("应该展示黄色");
                ar.innerHTML += "<a href='https://steamcommunity.com/my/friends/#sfcview' style='background-color: #dd1;color: black;'> " + lang.tipLost + " </a>";
                shown.lost = true;
            }
            if (user.checks.wait && needshow.wait && shown.wait == false) {
                print("应该展示蓝色");
                ar.innerHTML += "<a href='https://steamcommunity.com/my/friends/pending' style='background-color: #11badd;color: black;'> " + lang.tipWAIT + " </a>";
                shown.wait = true;
            }
        }
        SaveInfo();
    }
    ShowTip();
    var elements = document.getElementsByClassName('popup_menu_item notification_ctn header_notification_invites active_inbox_item');
    if (user.checks.wait && elements.length > 0) {
        var i;
        for (i = 0; i < elements.length; i++) {
            var e = elements.item(i);
            if (e != null) {
                var m = e.getAttribute('data-notification-type');
                if (m != null) {
                    if (m = "6") {
                        m = e.textContent;
                        if (m != null) {
                            m = m.replace(/[^0-9]+/gmi, "");
                            if (parseInt(m) > 0) {
                                print("检测到有未处理的好友邀请");
                                needshow.wait = true;
                                ShowTip();
                                break;
                            }
                        }
                    }
                }
            }
        }
    }
    if (onFriendsPage) {
        elements = document.getElementsByClassName('friends_nav');
        if (elements.length > 0) {
            var e = elements.item(0);
            if (e != null) {
                e.innerHTML = "<button id='sfcview' type='button'>" + lang.titleVIEW + "</button>" + e.innerHTML;
                var h = document.querySelector("#sfcview");
                if (h == null) {
                    print("找不到 #sfcview");
                    return false;
                }
                h.addEventListener('click', function () {
                    ShowonFriendPage();
                });
            }
        }
        else {
            print("找不到 friends_nav");
        }
    }
    function ClickViewButton() {
        var h = document.querySelector("#sfcview");
        if (h == null) {
            print("找不到 #sfcview");
            return false;
        }
        h.click();
    }
    function ShowonFriendPage() {
        if (!onFriendsPage) {
            return false;
        }
        element = document.querySelector('#subpage_container');
        if (element == null) {
            print("不能找到 #subpage_container");
            return false;
        }
        print("应该展示好友记录");
        var out = "<div id='steamfriendschecker' style='color:white;'>";
        out += "<h1><u><a href='https://walkedby.com/steamfriendschecker/' target='_blank'>" + lang.titleWBY + "</a></u></h1><br>";
        out += "<button type='button' id='clearfriendslog'>" + lang.titleDOCLEAR + "</button>";
        var s, i, i2, fr, f;
        if (user.checks.added) {
            out += "<h1>" + lang.titleADDED + "</h1>";
            s = "<ul>";
            for (i = user.newfriendsrecords.length - 1; i >= 0; i--) {
                fr = user.newfriendsrecords[i];
                s += "<li><h2>" + lang.titleCHECK + " " + fr.time + "</h2><ul>";
                for (i2 = 0; i2 < fr.ids.length; i2++) {
                    f = fr.ids[i2];
                    s += "<li><a target='_blank' href='https://steamcommunity.com/profiles/[U:1:" + f.id + "]'>" + f.name + " (" + f.id + ")</a></li>";
                }
                s += "</ul></li>";
            }
            s += "</ul>";
            out += s;
        }
        s = "";
        if (user.checks.lost) {
            out += "<br><h1>" + lang.titleLOST + "</h1>";
            s = "<ul>";
            for (i = user.lostfriendrecords.length - 1; i >= 0; i--) {
                fr = user.lostfriendrecords[i];
                s += "<li><h2>" + lang.titleCHECK + " " + fr.time + "</h2><ul>";
                for (i2 = 0; i2 < fr.ids.length; i2++) {
                    f = fr.ids[i2];
                    s += "<li><a target='_blank' href='https://steamcommunity.com/profiles/[U:1:" + f.id + "]'>" + f.name + " (" + f.id + ")</a></li>";
                }
                s += "</ul></li>";
            }
            s += "</ul>";
            out += s;
        }
        s = "";
        out += "<h1>" + lang.titleTEST + "</h1>";
        out += "<button type='button' id='fakelosefriends'>" + lang.testLOST + "</button>";
        if (user.friends.length > 3) {
            out += "<br><button type='button' id='fakeaddfriends'>" + lang.testADDED + "</button>";
            out += "<br><button type='button' id='fakeaddlosefriends'>" + lang.testBOTH + "</button>";
        }
        out += "<h1>" + lang.titleSettings + "</h1>";
        out += "<input id='setCheckADDED' type='checkbox'>" + lang.setCheckADDED;
        out += "<br><input id='setCheckLOST' type='checkbox'>" + lang.setCheckLOST;
        out += "<br><input id='setCheckWAIT' type='checkbox'>" + lang.setCheckWAIT;
        out += "<br><br>";
        if (user.resettime.length > 2) {
            out += "<h2>" + lang.titleCLEARED + " " + user.resettime + "</h2>";
        }
        out += "<h2>" + lang.titleINIT + " " + user.inittime + "</h2>";
        out += "<br><u><a target='_blank' href='https://steamid.uk'>" + lang.titleELSE + "</a></u>";
        out += "<br><br><br></div>";
        element.innerHTML = out;
        user.showtip.added = false;
        user.showtip.lost = false;
        user.showtip.wait = false;
        SaveInfo();
        var input = document.querySelector('#setCheckADDED');
        if (input == null) {
            print("不能找到 #setCheckADDED");
            return false;
        }
        input.checked = user.checks.added;
        input.addEventListener('click', function (ev) {
            user.checks.added = this.checked;
            SaveInfo();
        });
        input = document.querySelector('#setCheckLOST');
        if (input == null) {
            print("不能找到 #setCheckADDED");
            return false;
        }
        input.checked = user.checks.lost;
        input.addEventListener('click', function (ev) {
            user.checks.lost = this.checked;
            SaveInfo();
        });
        input = document.querySelector('#setCheckWAIT');
        if (input == null) {
            print("不能找到 #setCheckWAIT");
            return false;
        }
        input.checked = user.checks.wait;
        input.addEventListener('click', function (ev) {
            user.checks.wait = this.checked;
            SaveInfo();
        });
        if (user.friends.length > 3) {
            element = document.querySelector('#fakeaddfriends');
            if (element == null) {
                print("不能找到 #fakeaddfriends");
                return false;
            }
            element.addEventListener("click", function () {
                FakeAdd(true, false);
                location.href = "https://store.steampowered.com/";
            });
            element = document.querySelector('#fakeaddlosefriends');
            if (element == null) {
                print("不能找到 #fakeaddlosefriends");
                return false;
            }
            element.addEventListener("click", function () {
                FakeAdd(true, true);
                location.href = "https://store.steampowered.com/";
            });
        }
        element = document.querySelector('#fakelosefriends');
        if (element == null) {
            print("不能找到 #fakelosefriends");
            return false;
        }
        element.addEventListener("click", function () {
            FakeAdd(false, true);
            location.href = "https://store.steampowered.com/";
        });
        element = document.querySelector('#clearfriendslog');
        if (element == null) {
            print("不能找到 #clearfriendslog");
            return false;
        }
        element.addEventListener("click", function () {
            user.lostfriendrecords = [];
            user.newfriendsrecords = [];
            user.resettime = nowTime();
            SaveInfo();
            location.href = 'https://steamcommunity.com/my/friends';
        });
    }
    function FakeAdd(add, minus) {
        if (add) {
            var fs = [], i;
            for (i = 3; i < user.friends.length; i++) {
                fs.push(user.friends[i]);
            }
            user.friends = fs;
        }
        if (minus) {
            user.friends.push({ id: "63149100", name: "aaa" });
            user.friends.push({ id: "63149101", name: "bbb" });
            user.friends.push({ id: "63149103", name: "ccc" });
        }
        SaveInfo();
    }
    function DealFriendsDom(dom) {
        var l = dom.length;
        if (l < 100) {
            print("出错:好友dom长度过短,长度为:" + l.toString());
            return false;
        }
        dom = dom.replace(/\r|\n|\t/gm, " ");
        dom = dom.replace(/ +/gm, " ");
        if (dom.match(/<span id="header_parental_link" class=".+? green"/)) {
            print("有家庭视图阻拦");
            return false;
        }
        matches = dom.match(/data-miniprofile="[0-9]+" data-search=".*? ;/gmi);
        if (matches == null) {
            if (familyView == 0) {
                if (dom.indexOf("data-miniprofile=\"" + steamid + "\">") > 100) {
                    print("一个好友都没有,不做处理。");
                    matches = [];
                    return false;
                }
                else {
                    print("出错:好友dom无法匹配任何好友信息,长度:" + l.toString());
                    return false;
                }
            }
            else {
                print("一个好友都没有,但是已经开启好友视图,不做处理。");
                return false;
            }
        }
        var i, i2, name, id, f;
        var fr = { time: nowTime(), ids: [] };
        for (i = 0; i < matches.length; i++) {
            var m = matches[i];
            id = m.substr(0, m.indexOf("data-sea"));
            id = id.replace(/[^0-9]/g, "");
            if (id != steamid) {
                name = m.replace(/.*?data-search="/, "");
                name = name.substr(0, name.length - 2).trim();
                f = { id: id, name: name };
                var tmp = GetFriend(id);
                if (tmp == null) {
                    user.friends.push(f);
                    fr.ids.push(f);
                }
            }
        }
        if (firstTime == false) {
            if (user.checks.added && fr.ids.length > 0) {
                needshow.added = true;
                ShowTip();
                user.newfriendsrecords.push(fr);
                print("新好友个数:" + fr.ids.length.toString());
            }
            var frs = [];
            var fr2 = { time: nowTime(), ids: [] };
            for (i = 0; i < user.friends.length; i++) {
                id = user.friends[i].id;
                if (dom.indexOf("data-miniprofile=\"" + id) > 100) {
                    frs.push(user.friends[i]);
                }
                else {
                    fr2.ids.push(user.friends[i]);
                }
            }
            if (fr2.ids.length > 0) {
                needshow.lost = true;
                ShowTip();
                user.lostfriendrecords.push(fr2);
                print("删好友个数:" + fr2.ids.length.toString());
                user.friends = frs;
            }
        }
        print("目前好友个数: " + user.friends.length.toString());
        SaveInfo();
        if (url.indexOf('#sfcview') > 0) {
            ClickViewButton();
        }
    }
    if (onFriendsPageRoot) {
        DealFriendsDom(document.body.innerHTML);
    }
    else {
        var request = {
            url: "https://steamcommunity.com/my/friends?ajax=1",
            method: 'GET',
            timeout: 8000,
            headers: {
                "Content-Type": "application/x-www-form-urlencoded",
                "Referer": "https://steamcommunity.com/"
            },
            onload: function (response) {
                var dom = response.responseText;
                DealFriendsDom(dom);
            },
            onerror: function (response) {
                print("好友页面请求出错:" + response.error);
            },
            ontimeout: function () {
                print("好友页面请求超时");
            }
        };
        GM_xmlhttpRequest(request);
    }
})();
    
  
Mossimos commented 2 days ago

已修改脚本 添加同域 不转发请求 支持 更新 GM 0.35 版本 以及安装脚本即可正常使用。脚本中默认关闭 修改为了默认打开 展示

cyb233 commented 1 day ago

或许可以新增一个ISSUE_TEMPLATE,使用script作为label,提交脚本源URL或脚本代码——或者直接建立一个仓库专门维护脚本,方便提交issues或pr

rmbadmin commented 1 day ago

或许可以新增一个ISSUE_TEMPLATE,使用script作为label,提交脚本源URL或脚本代码——或者直接建立一个仓库专门维护脚本,方便提交issues或pr

单独建立一个脚本维护的仓库确实是很好的提议,也能缓解我们自己处理不过来的问题