您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
複数のアカウントを利用して動画登録しているユーザーを定期的に検知する
// ==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); })();