cytube_user_check

複数のアカウントを利用して動画登録しているユーザーを定期的に検知する

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         cytube_user_check
// @namespace    https://cytube.mm428.net/
// @version      1.00
// @description  複数のアカウントを利用して動画登録しているユーザーを定期的に検知する
// @author       fetcH
// @grant        none
// @match        https://cytube.mm428.net/r/*
// ==/UserScript==


(function() {
    // チェック対象のユーザー権限
    /*----------------------
     * var Rank = {
     *     Guest: 0,
     *     Member: 1,
     *     Leader: 1.5,
     *     Moderator: 2,
     *     Admin: 3,
     *     Owner: 10,
     *     Siteadmin: 255
     * };
     */
    const TARGET_USER_RANK = Rank.Owner;

    // チェック間隔(秒)
    const CHECK_INTERVAL_SEC = 180;

    // 自動動画削除機能
    const AUTO_MOVIE_DELETE = true;

    // 表示場所作成
    const view_div = $('<div>').attr({
        id: 'vidchk',
        class: 'linewrap'
    });
    $('#chatwrap').append(view_div);

    //

    // リストを定期的にチェック
    setInterval(function(){

        // プレイリストの登録数上限を取得する
        // 無制限なら0
        // 日本語前提の処理
        const queue_limit = (() => {
            let limit = $("#plcount").text().split(':')[1];
            if (limit == '無し') {
                return 0;
            }
            limit = parseInt(limit.split('項目')[0], 10);
            return limit;
        })();
        //console.log(queue_limit);

        if (queue_limit == 0) {
            return;
        }

        // ユーザーの動画登録情報取得
        const user_list = {}; // ユーザー名別の情報
        const ip_list = {}; // ip別の情報
        // 参加ユーザー情報をまとめる
        Array.from(document.getElementById("userlist").children).forEach((child) => {
            const userlist_item = $(child);
            const name = userlist_item.children()[1].innerText;
            const data = userlist_item.data();
            const ip = data.meta.ip ?? name; // 権限が足りないとipが取得できないので名前をip代わりとする
            user_list[name] = {
                name: name,
                ip: ip,
                rank: data.rank,
                movies: []
            };
            if (!ip_list.hasOwnProperty(ip)) {
                ip_list[ip] = {
                    ip: ip,
                    aliases: []
                };
            }
            ip_list[ip].aliases.push(name);
        });
        //console.log(ip_list);

        // ユーザーの動画登録情報をまとめる
        Array.from(document.getElementById("queue").children).forEach((child) => {
            const playlist_item = $(child);
            const name = playlist_item.data().queueby;
            const title = playlist_item.data().media.title;
            const uid = playlist_item.data().uid;
            //console.log(playlist_item.data());
            if (user_list.hasOwnProperty(name)) {
                user_list[name].movies.push({queueby: name, title: title, uid: uid});
            }
        });
        //console.log(user_list);

        // 複数アカウントで登録しているIPに対する処理
        const limit_over_ip_list = [];
        for (const ip in ip_list) {
            // 複数アカウントで動画登録しているか判定する
            const ip_info = ip_list[ip];
            const aliases = [];
            let movies = [];
            for (const name of ip_info.aliases) {
                // 指定権限のユーザー以下を対象とする
                if (user_list[name].rank <= TARGET_USER_RANK) {
                    if (1 <= user_list[name].movies.length) {
                        aliases.push(name);
                        movies = movies.concat(user_list[name].movies);
                    }
                }
            }

            // 複数アカウントでの動画登録者を表示
            if (2 <= aliases.length) {
                if (queue_limit < movies.length) {
                    const movie_cnt = `動画登録数=${movies.length}`;
                    const ip = `IP=${ip_info.ip}`;
                    const user_names = `ユーザー名=${aliases.join(', ')}`;
                    const movie_names = movies.map((movie) => { return movie.title; }).join("\n");
                    limit_over_ip_list.push(`<div>${movie_cnt}:${ip}:${user_names}</div>`);
                    // 動画名はコンソールに表示
                    console.log(`${movie_cnt}\n${ip}\n${user_names}\n${movie_names}\n\n\n`);

                    // 動画自動削除
                    if (AUTO_MOVIE_DELETE) {
                        const keep_name = aliases[0];
                        const delete_movies = movies.filter((movie) => { return movie.queueby != keep_name; });
                        const delete_movie_names = delete_movies.map((movie) => { return `${movie.title}(${movie.queueby})`; }).join("\n");
                        socket.emit("chatMsg", {
                            msg: "【複垢動画登録検知】以下をプレイリストから削除しました",
                            meta: {}
                        });
                        for (const del of delete_movies) {
                            socket.emit("delete", del.uid);
                            socket.emit("chatMsg", {
                                msg: `【User:${del.queueby}】${del.title}`,
                                meta: {}
                            });
                        }
                        console.log(`DELETE MOVIES\n${ip}\n${user_names}\n${delete_movie_names}`);
                    }
                }
            }
        }

        // 垢BAN対象者を表示
        view_div.html(limit_over_ip_list.join(""));
    }, CHECK_INTERVAL_SEC * 1000);
})();