// ==UserScript== // @name ニコニコ静画、クッキー☆連投荒らしNG // @namespace http://tampermonkey.net/ // @version 0.514 // @description 申し訳ないが連投荒らしはNG // @author cbxm // @match https://seiga.nicovideo.jp/tag/%E3%82%AF%E3%83%83%E3%82%AD%E3%83%BC%E2%98%86* // @grant GM.xmlHttpRequest // @grant GM.getValue // @grant GM.setValue // @run-at document-start // @downloadURL none // ==/UserScript== (async () => { "use strict"; ; ; class Util { //xmlString=未探査部分 static XmlToObj(xmlString) { const F = (xmlString, obj) => { //タグを抜き出す let tagMatchs = null; while (true) { tagMatchs = xmlString.match(/<([^>]+)>/); //タグがないということはそれが値になる if (tagMatchs == null) { return xmlString; } if (tagMatchs[1][tagMatchs[1].length - 1] == "/") { xmlString = xmlString.replace(/<[^>]+>([^]*)/, "$1"); } else { break; } } const tag = tagMatchs[1]; //タグの内側とその先を抜き出す const matchChildlen = []; while (true) { const matchs = xmlString.match(new RegExp(`^[^<]*<${tag}>([^]+?)<\/${tag}>([^]*)`)); if (matchs == null) { break; } matchChildlen.push(matchs[1]); xmlString = matchs[2]; } //タグあったのにマッチしなかったおかしい if (matchChildlen.length == 0) { return obj; } //そのタグが一つしかないとき、オブジェクトになる if (matchChildlen.length == 1) { //子を探す obj[tag] = F(matchChildlen[0], {}); } //そのタグが複数あるとき、配列になる if (matchChildlen.length > 1) { obj = []; for (let i = 0; i < matchChildlen.length; i++) { //子を探す obj[i] = F(matchChildlen[i], {}); } } //兄弟を探す F(xmlString, obj); return obj; }; //初期化でを取り除く xmlString = xmlString.replace(/\s*<[^>]+>([^]+)/, "$1"); return F(xmlString, {}); } static HtmlToDocument(str) { const parser = new DOMParser(); return parser.parseFromString(str, "text/html"); } static HtmlToChildNodes(str) { return this.HtmlToDocument(str).body.childNodes; } static Wait(ms) { return new Promise(r => setTimeout(r, ms)); } } ; class Fetcher { static GMFetchText(url) { return new Promise(r => { GM.xmlHttpRequest({ url: url, method: "GET", onload: (response) => { r(response.responseText); } }); }); } static async FetchIllustDatas(ids) { if (ids.length == 0) { return { illusts: [], userIds: [] }; } const url = `http:\/\/seiga.nicovideo.jp/api/illust/info?id_list=${ids.join()}`; const res = await this.GMFetchText(url); const obj = Util.XmlToObj(res); const list = Array.isArray(obj.response.image_list) ? obj.response.image_list : [obj.response.image_list.image]; const illusts = []; for (let i = 0; i < list.length; i++) { illusts[i] = { id: list[i].id, created: new Date(list[i].created) }; } return { illusts: illusts, userIds: list.map(l => l.user_id) }; } static async FetchUserName(userId) { const url = "http://seiga.nicovideo.jp/api/user/info?id=" + userId; const json = Util.XmlToObj(await this.GMFetchText(url)); return json.response.user.nickname; } static async FetchUserId(illustId) { const url = "https://seiga.nicovideo.jp/api/illust/info?id=im" + illustId; const resultText = await this.GMFetchText(url); const json = Util.XmlToObj(resultText); return json.response.image.user_id; } } ; class Storage { constructor(storageName) { this.storageName = ""; this.storageName = storageName; } async GetStorageData(defaultValue = null) { const text = await GM.getValue(this.storageName, null); return text != null ? JSON.parse(decodeURIComponent(text)) : defaultValue; } async SetStorageData(data) { await GM.setValue(this.storageName, encodeURIComponent(JSON.stringify(data))); } } ; class Observer { static Wait(predicate, parent = document, option = null) { return new Promise(r => { if (option == null) { option = { childList: true, subtree: true }; } const mutationObserver = new MutationObserver((mrs) => { if (predicate(mrs)) { mutationObserver.disconnect(); r(mrs); return; } }); mutationObserver.observe(parent, option); }); } ; static WaitAddedNode(predicate, parent, option = null) { return new Promise(r => { if (option == null) { option = { childList: true, subtree: true }; } const mutationObserver = new MutationObserver((mrs) => { //console.log(document.head.innerHTML); //console.log(document.body.innerHTML); for (let node of mrs) { node.addedNodes.forEach(added => { //console.log(added); if (predicate(added)) { mutationObserver.disconnect(); r(added); return; } }); } }); mutationObserver.observe(parent, option); }); } ; static async DefinitelyGetElementById(id, parent = document, option = null) { const e = document.getElementById(id); if (e != null) { return e; } return this.WaitAddedNode(e => e.id != null && e.id == id, parent, option); } //getElementsByClassNameをつかうけど単体なので注意 static async DefinitelyGetElementByClassName(className, parent = document, option = null) { const e = document.getElementsByClassName(className)[0]; if (e != null) { return e; } return this.WaitAddedNode(e => e.className != null && e.className == className, parent, option); } //getElementsByTagNameをつかうけど単体なので注意 static async DefinitelyGetElementByTagName(tagName, parent = document, option = null) { tagName = tagName.toUpperCase(); const e = document.getElementsByTagName(tagName)[0]; if (e != null) { return e; } return this.WaitAddedNode(e => e.tagName != null && e.tagName == tagName, parent, option); } } ; //暫定OK、暫定荒らし、確定OK、確定荒らし //type Status = "OK" | "NG" | "LOK" | "LNG" let Status; (function (Status) { Status[Status["NONE"] = 0] = "NONE"; Status[Status["OK"] = 1] = "OK"; Status[Status["NG"] = 2] = "NG"; Status[Status["WHITE"] = 3] = "WHITE"; Status[Status["BLACK"] = 4] = "BLACK"; Status[Status["MAX"] = 5] = "MAX"; })(Status || (Status = {})); class Main { constructor() { this.cache = []; this.illustInfos = []; this.selectedList = []; this.cacheStorage = new Storage("NICONICO_RENTO_ARASI_NG_DATA_CACHE"); this.optionStorage = new Storage("NICONICO_RENTO_ARASI_NG_OPTION_CACHE"); } async GetStorageData() { this.cache = (await this.cacheStorage.GetStorageData([])) .map(c => { if (typeof c.status == "string") { if (c.status == "LOK") { c.status = Status.WHITE; } else if (c.status == "LNG") { c.status = Status.BLACK; } else if (c.status == "OK") { c.status = Status.OK; } else if (c.status == "NG") { c.status = Status.NG; } else { c.status = Status.OK; } } return c; }); //console.log(this.cache); const defaultOption = { judge: { time: 1 * 60 * 60 * 1000, postCount: 3 } }; this.option = await this.optionStorage.GetStorageData(defaultOption); //console.log(this.option); } GetInfo(illustId) { for (let c of this.cache) { for (let illust of c.illusts) { if (illust.id == illustId) { return { user: c, illust: illust }; } } } return undefined; } ChackArasi(user) { if (user.illusts.length == 0 || user.status == Status.BLACK || user.status == Status.WHITE || user.status == Status.NG) { return; } for (let illust of user.illusts) { if (typeof illust.created == "string") { illust.created = new Date(illust.created); } } //新しい順 const sorted = user.illusts.sort((a, b) => b.created.getTime() - a.created.getTime()); for (let i = 0; i < sorted.length; i++) { const currentDate = sorted[i].created; let j = i + 1; let postCount = 1; while (true) { if (j >= sorted.length || currentDate.getTime() - sorted[j].created.getTime() > this.option.judge.time) { break; } j++; postCount++; } if (postCount >= this.option.judge.postCount) { user.status = Status.NG; return; } } } ; GetIllustIds(itemListElement) { //document.getElementsByClassName("item_list")[0] const illustIdElements = itemListElement.getElementsByTagName("a"); const illustIds = []; for (let i = 0; i < illustIdElements.length; i++) { const idMatchs = illustIdElements[i].href.match(/im(\d+)/); if (idMatchs == null) { continue; } const id = idMatchs[1]; illustIds.push(id); } return illustIds; } DrawList() { const list = document.getElementById("scrollUL"); const onlyCurrentPageCheckbox = document.getElementById("onlyCurrentPageCheckbox"); const listStatusSelect = document.getElementById("listStatusSelect"); if (list == undefined || onlyCurrentPageCheckbox == undefined || listStatusSelect == undefined) { return; } const status = Status[listStatusSelect.value]; list.innerHTML = ""; for (let user of this.cache) { if (user.status == status) { const info = this.illustInfos.find(info => info.user == user); let sampleIllustId = info != undefined ? info.illustId : undefined; if (onlyCurrentPageCheckbox.checked && sampleIllustId == undefined) { continue; } if (sampleIllustId == undefined) { sampleIllustId = user.illusts[0].id; } const div = document.createElement("div"); div.style.height = "70px"; div.style.display = "flex"; div.style.flexDirection = "column"; div.className = "userInfoItem"; list.appendChild(div); const nameIdDiv = document.createElement("div"); nameIdDiv.style.top = "relative"; nameIdDiv.style.position = "4px"; div.appendChild(nameIdDiv); const nameSpan = document.createElement("span"); nameSpan.className = "userName"; nameSpan.textContent = info == undefined ? "" : info.name; nameSpan.style.fontSize = "130%"; nameSpan.style.color = "black"; nameSpan.style.width = "66px"; nameSpan.style.height = "24px"; nameSpan.style.padding = "3px"; nameIdDiv.appendChild(nameSpan); const idSpan = document.createElement("span"); idSpan.className = "userId"; idSpan.textContent = user.userId; idSpan.style.fontSize = "130%"; idSpan.style.color = "black"; idSpan.style.width = "66px"; idSpan.style.padding = "3px"; nameIdDiv.appendChild(idSpan); const userAndSampleImgDiv = document.createElement("div"); div.appendChild(userAndSampleImgDiv); const aUser = document.createElement("a"); aUser.href = `https:\/\/seiga.nicovideo.jp/user/illust/${user.userId}`; userAndSampleImgDiv.appendChild(aUser); const imgUser = document.createElement("img"); imgUser.src = `https:\/\/secure-dcdn.cdn.nimg.jp/nicoaccount/usericon/${Math.floor(parseInt(user.userId) / 10000)}/${user.userId}.jpg`; imgUser.style.height = "40px"; imgUser.style.position = "relative"; imgUser.style.padding = "0 20px 0 10px"; imgUser.style.top = "-5px"; aUser.appendChild(imgUser); imgUser.addEventListener("error", () => { imgUser.src = "https:\/\/secure-dcdn.cdn.nimg.jp/nicoaccount/usericon/defaults/blank.jpg"; }); const aSample = document.createElement("a"); aSample.href = `https:/\/seiga.nicovideo.jp/seiga/im${sampleIllustId}`; userAndSampleImgDiv.appendChild(aSample); const imgSample = document.createElement("img"); imgSample.src = `https:\/\/lohas.nicoseiga.jp\/\/thumb/${sampleIllustId}c`; imgSample.style.height = "30px"; imgSample.style.position = "relative"; imgSample.style.top = "-5px"; aSample.appendChild(imgSample); const bigSample = document.createElement("img"); bigSample.src = `https:\/\/lohas.nicoseiga.jp\/\/thumb/${sampleIllustId}c`; bigSample.style.height = "100px"; bigSample.style.pointerEvents = "none"; bigSample.style.position = "absolute"; bigSample.style.zIndex = "10"; imgSample.addEventListener("mouseover", () => { const clientRect = imgSample.getBoundingClientRect(); const x = window.pageXOffset + clientRect.left + imgSample.width / 2 - 50; const y = window.pageYOffset + clientRect.top + imgSample.height / 2 - 50; bigSample.style.top = y + "px"; bigSample.style.left = x + "px"; document.body.appendChild(bigSample); }); imgSample.addEventListener("mouseleave", () => { bigSample.remove(); }); div.addEventListener("click", e => this.ClickList(e.currentTarget)); } } } ClickList(target) { if (target != null) { if (this.selectedList.includes(target)) { target.style.backgroundColor = ""; this.selectedList = this.selectedList.filter(s => s != target); } else { target.style.backgroundColor = "rgba(0, 140, 255, 0.5)"; this.selectedList.push(target); } } } async SetOptionButton() { const parent = await Observer.DefinitelyGetElementByClassName("sg_pankuzu"); if (document.getElementById("optionSpan") != null) { return; } const span = document.createElement("span"); span.id = "optionSpan"; parent.appendChild(span); const button = document.createElement("input"); button.type = "button"; button.value = "クッキー☆連投NG"; button.style.backgroundColor = "yellow"; button.style.padding = "1px 5px"; button.style.fontSize = "110%"; button.style.cssText += "color: black !important;"; button.addEventListener("click", () => dialog.style.visibility = (dialog.style.visibility == "hidden") ? "visible" : "hidden"); span.appendChild(button); const dialog = document.createElement("div"); dialog.style.backgroundColor = "white"; dialog.style.visibility = "hidden"; dialog.style.position = "absolute"; dialog.style.padding = "5px"; dialog.style.zIndex = "10"; dialog.style.border = "2px solid"; span.appendChild(dialog); const setJudgeRigorFlex = document.createElement("div"); setJudgeRigorFlex.style.padding = "10px 10px"; dialog.appendChild(setJudgeRigorFlex); const setJudgeTime = document.createElement("input"); setJudgeTime.type = "time"; setJudgeTime.style.height = "20px"; setJudgeTime.style.fontSize = "120%"; const hour = ('00' + Math.floor(this.option.judge.time / 60 / 1000 / 60).toString()).slice(-2); const minutes = ('00' + (this.option.judge.time / 60 / 1000 % 60).toString()).slice(-2); setJudgeTime.value = `${hour}:${minutes}`; setJudgeTime.addEventListener("change", async () => { const [h, m] = setJudgeTime.value.split(":").map(s => parseInt(s)); const ms = ((h * 60) + m) * 60 * 1000; if (ms >= 1) { this.option.judge.time = ms; await this.optionStorage.SetStorageData(this.option); } else { const hour = ('00' + Math.floor(this.option.judge.time / 60 / 1000 / 60).toString()).slice(-2); const minutes = ('00' + (this.option.judge.time / 60 / 1000 % 60).toString()).slice(-2); setJudgeTime.value = `${hour}:${minutes}`; } }); setJudgeRigorFlex.appendChild(setJudgeTime); const setJudgeText1 = document.createElement("span"); setJudgeText1.textContent = "以内に"; setJudgeText1.style.color = "black"; setJudgeText1.style.fontSize = "15px"; setJudgeRigorFlex.appendChild(setJudgeText1); const setJudgePostCount = document.createElement("input"); setJudgePostCount.type = "number"; setJudgePostCount.value = this.option.judge.postCount.toString(); setJudgePostCount.style.width = "40px"; setJudgePostCount.min = "2"; setJudgePostCount.style.height = "20px"; setJudgePostCount.style.fontSize = "120%"; setJudgePostCount.addEventListener("change", async () => { const num = parseInt(setJudgePostCount.value); if (num >= 2) { this.option.judge.postCount = num; await this.optionStorage.SetStorageData(this.option); } else { this.option.judge.postCount = 2; setJudgePostCount.value = this.option.judge.postCount.toString(); } }); setJudgeRigorFlex.appendChild(setJudgePostCount); const setJudgeText2 = document.createElement("span"); setJudgeText2.textContent = "回投稿で仮荒らし認定"; setJudgeText2.style.color = "black"; setJudgeText2.style.fontSize = "15px"; setJudgeRigorFlex.appendChild(setJudgeText2); const div1 = document.createElement("div"); dialog.appendChild(div1); const list1 = document.createElement("div"); list1.style.display = "flex"; div1.appendChild(list1); const listStatusSelect = document.createElement("select"); listStatusSelect.id = "listStatusSelect"; listStatusSelect.style.margin = "5px"; list1.appendChild(listStatusSelect); for (let i = 1; i < Status.MAX; i++) { const option = document.createElement("option"); option.value = Status[i]; option.textContent = Status[i]; listStatusSelect.appendChild(option); } listStatusSelect.addEventListener("change", () => { while (this.selectedList.length != 0) { const element = this.selectedList.pop(); if (element != undefined) { element.style.backgroundColor = ""; } } this.DrawList(); }); const onlyCurrentPageCheckbox = document.createElement("input"); onlyCurrentPageCheckbox.type = "checkbox"; onlyCurrentPageCheckbox.id = "onlyCurrentPageCheckbox"; onlyCurrentPageCheckbox.checked = true; onlyCurrentPageCheckbox.style.padding = "3px"; list1.appendChild(onlyCurrentPageCheckbox); onlyCurrentPageCheckbox.addEventListener("change", () => this.DrawList()); const onlyCurrentPageLabel = document.createElement("label"); onlyCurrentPageLabel.htmlFor = "onlyCurrentPageCheckbox"; onlyCurrentPageLabel.textContent = "このページだけ"; onlyCurrentPageLabel.style.color = "black"; onlyCurrentPageLabel.style.padding = "3px"; list1.appendChild(onlyCurrentPageLabel); const allSelect = document.createElement("input"); allSelect.type = "button"; allSelect.value = "全選択"; allSelect.style.color = "black"; allSelect.style.margin = "3px"; list1.appendChild(allSelect); allSelect.addEventListener("click", () => { const infos = Array.from(document.getElementsByClassName("userInfoItem")); for (let info of infos) { this.ClickList(info); } }); const list2 = document.createElement("div"); list2.style.position = "relative"; list2.style.display = "flex"; div1.appendChild(list2); const userInfoList = document.createElement("ul"); userInfoList.id = "scrollUL"; userInfoList.style.overflowY = "scroll"; userInfoList.style.overflowX = "hidden"; userInfoList.style.height = "300px"; userInfoList.style.width = "250px"; list2.appendChild(userInfoList); const buttonList = document.createElement("ul"); buttonList.style.width = "90px"; list2.appendChild(buttonList); this.DrawList(); for (let i = 1; i < Status.MAX; i++) { const div = document.createElement("div"); const toButton = document.createElement("input"); toButton.type = "button"; toButton.style.padding = "3px"; toButton.style.fontSize = "130%"; toButton.style.margin = "3px"; toButton.value = "→ " + Status[i]; toButton.name = Status[i]; div.appendChild(toButton); buttonList.appendChild(div); toButton.addEventListener("click", async () => { while (this.selectedList.length != 0) { const element = this.selectedList.pop(); if (element != undefined) { element.style.backgroundColor = ""; const userId = element.getElementsByClassName("userId")[0].textContent; const user = this.cache.find(c => c.userId == userId); if (user != undefined) { user.status = Status[toButton.name]; } } } for (let info of this.illustInfos) { this.UpdateIllust(info); this.DrawBlackWhiteButton(info); } this.DrawList(); await this.cacheStorage.SetStorageData(this.cache); }); } const div = document.createElement("div"); buttonList.appendChild(div); const selectedCacheClearButton = document.createElement("input"); selectedCacheClearButton.type = "button"; selectedCacheClearButton.style.padding = "3px"; selectedCacheClearButton.style.fontSize = "120%"; selectedCacheClearButton.style.margin = "3px"; selectedCacheClearButton.style.marginTop = "10px"; selectedCacheClearButton.style.backgroundColor = "yellow"; selectedCacheClearButton.style.cssText += "color: black !important"; selectedCacheClearButton.value = "→DELETE"; div.appendChild(selectedCacheClearButton); selectedCacheClearButton.addEventListener("click", async () => { if (!window.confirm("選択したアイテムのキャッシュクリアしていいですか?\nホワイト・ブラックリストも削除されます。")) { return; } while (this.selectedList.length != 0) { const element = this.selectedList.pop(); if (element != undefined) { const userId = element.getElementsByClassName("userId")[0].textContent; this.cache = this.cache.filter(c => c.userId != userId); const infos = this.illustInfos.filter(c => c.user != undefined && c.user.userId == userId); for (let info of infos) { if (info != undefined && info.user != undefined) { info.user.status = Status.WHITE; this.UpdateIllust(info); this.DrawBlackWhiteButton(info); } } this.illustInfos = this.illustInfos.filter(c => c.user != undefined && c.user.userId != userId); } } this.DrawList(); await this.cacheStorage.SetStorageData(this.cache); }); const div2 = document.createElement("div"); buttonList.appendChild(div2); const allCacheClearButton = document.createElement("input"); allCacheClearButton.type = "button"; allCacheClearButton.style.padding = "3px"; allCacheClearButton.style.fontSize = "120%"; allCacheClearButton.style.margin = "3px"; allCacheClearButton.style.marginTop = "10px"; allCacheClearButton.style.backgroundColor = "red"; allCacheClearButton.value = "ALL\nDELETE"; div2.appendChild(allCacheClearButton); allCacheClearButton.addEventListener("click", async () => { if (!window.confirm("全キャッシュクリアしていいですか?\nホワイト・ブラックリストも削除されます。")) { return; } for (let info of this.illustInfos) { if (info.user != undefined) { info.user.status = Status.WHITE; this.UpdateIllust(info); this.DrawBlackWhiteButton(info); } } this.illustInfos = []; this.cache = []; this.DrawList(); await this.cacheStorage.SetStorageData(this.cache); }); const div3 = document.createElement("div"); buttonList.appendChild(div3); const reStartButton = document.createElement("input"); reStartButton.type = "button"; reStartButton.style.padding = "3px"; reStartButton.style.fontSize = "120%"; reStartButton.style.margin = "3px"; reStartButton.style.marginTop = "20px"; reStartButton.style.backgroundColor = "green"; reStartButton.style.cssText += "color: white !important"; reStartButton.value = "RE START"; div3.appendChild(reStartButton); reStartButton.addEventListener("click", async () => { await this.Run(); this.DrawList(); }); } UpdateIllust(info) { if (info.user == undefined) { return; } if (info.user.status == Status.OK || info.user.status == Status.WHITE) { info.element.getElementsByTagName("img")[0].style.filter = "brightness(1)"; if (info.element.parentElement == null) { info.parent.appendChild(info.element); } } if (info.user.status == Status.NG) { info.element.getElementsByTagName("img")[0].style.filter = "brightness(0.3)"; info.parent.appendChild(info.element); } if (info.user.status == Status.BLACK) { info.element.remove(); } } DrawBlackWhiteButton(illustInfo) { if (illustInfo.user == undefined || illustInfo.user.status == Status.BLACK || illustInfo.user.status == Status.WHITE) { if (illustInfo.user != undefined && illustInfo.user.status == Status.WHITE) { const list = Array.from(illustInfo.element.getElementsByClassName("toListButton")); for (let l of list) { l.remove(); } } return; } if (illustInfo.element.getElementsByClassName("toListButton").length > 0) { return; } const whiteButton = document.createElement("input"); const blackButton = document.createElement("input"); whiteButton.style.position = "relative"; whiteButton.style.left = "110px"; whiteButton.style.top = "-30px"; whiteButton.style.width = "40px"; whiteButton.style.height = "25px"; whiteButton.style.visibility = "hidden"; //上記のスタイルを両方に適用 blackButton.style.cssText = whiteButton.style.cssText; whiteButton.type = "button"; blackButton.type = "button"; whiteButton.className = "toListButton"; blackButton.className = "toListButton"; whiteButton.name = "white"; blackButton.name = "black"; whiteButton.style.cssText += `background-color : white !important;`; blackButton.style.cssText += `background-color : black !important;`; whiteButton.style.left = "110px"; blackButton.style.left = "115px"; whiteButton.addEventListener("click", async () => { if (illustInfo.user != undefined) { illustInfo.user.status = Status.WHITE; for (let info of this.illustInfos) { if (info.user == illustInfo.user) { info.element.getElementsByTagName("img")[0].style.filter = "brightness(1)"; const buttons = info.element.getElementsByClassName("toListButton"); while (buttons.length != 0) { buttons[0].remove(); } } } this.DrawList(); await this.cacheStorage.SetStorageData(this.cache); } }); blackButton.addEventListener("click", async () => { if (illustInfo.user != undefined) { illustInfo.user.status = Status.BLACK; for (let info of this.illustInfos) { if (info.user == illustInfo.user) { info.element.remove(); } } this.DrawList(); await this.cacheStorage.SetStorageData(this.cache); } }); illustInfo.element.addEventListener("mouseover", () => { blackButton.style.visibility = "visible"; whiteButton.style.visibility = "visible"; }); illustInfo.element.addEventListener("mouseleave", () => { blackButton.style.visibility = "hidden"; whiteButton.style.visibility = "hidden"; }); illustInfo.element.appendChild(whiteButton); illustInfo.element.appendChild(blackButton); } async AddInfos(illustListElement) { var _a; const illustElements = Array.from(illustListElement.getElementsByClassName("list_item")); const illustIds = this.GetIllustIds(illustListElement); const names = Array.from(illustListElement.getElementsByClassName("user")); //キャッシュからの情報と合わせて追加(もうこれ分かんねぇこともある) for (let i = 0; i < illustIds.length; i++) { if (this.illustInfos.some(info => info.illustId == illustIds[i])) { continue; } const info = this.GetInfo(illustIds[i]); this.illustInfos.push({ name: (_a = names[i].textContent) !== null && _a !== void 0 ? _a : "", illustId: illustIds[i], illust: info == undefined ? undefined : info.illust, user: info == undefined ? undefined : info.user, element: illustElements[i], parent: illustListElement }); } } //メインクラス、メイン関数の肥大化もう始まってる! async Run(illustListElements) { await Observer.DefinitelyGetElementByClassName("illust_list"); await Observer.DefinitelyGetElementById("footer"); illustListElements = illustListElements !== null && illustListElements !== void 0 ? illustListElements : Array.from(document.getElementsByClassName("item_list")); for (let illustListElement of illustListElements) { await this.AddInfos(illustListElement); } //console.log("infos", this.illustInfos); //これもう分かんねぇやつら const unkownInfos = this.illustInfos.filter(info => info.user == undefined); //この戻り値なんかダサい・・・ダサくない? const result = await Fetcher.FetchIllustDatas(unkownInfos.map(info => info.illustId)); //これもう分かんねぇやつらとキャッシュまで!?の情報更新 for (let i = 0; i < unkownInfos.length; i++) { unkownInfos[i].illust = result.illusts[i]; let user = this.cache.find((c) => c.userId == result.userIds[i]); if (user == undefined) { user = { userId: result.userIds[i], illusts: [], status: Status.OK }; this.cache.push(user); } user.illusts.push(result.illusts[i]); unkownInfos[i].user = user; } console.log(result); //ブラック,ホワイトリストにないイラストエレメントにボタン追加 for (let illustInfo of this.illustInfos) { this.DrawBlackWhiteButton(illustInfo); } //情報取ってきた投稿者の荒らし判定更新 ↓これは重複排除 for (let c of [...new Set(unkownInfos.map(u => u.user))]) { if (c != undefined) { this.ChackArasi(c); } } await this.cacheStorage.SetStorageData(this.cache); this.SetOptionButton(); //消すもしくは最後尾に暗くして追加 for (let info of this.illustInfos) { this.UpdateIllust(info); } } } ; const main = new Main(); await main.GetStorageData(); await main.Run(); const illustList = await Observer.DefinitelyGetElementByClassName("illust_list"); const mutationObserver = new MutationObserver(async (mrs) => { for (let mr of mrs) { for (let i = 0; i < mr.addedNodes.length; i++) { const element = mr.addedNodes[i]; if (element.classList != null && element.classList.contains("item_list")) { await main.Run([element]); } } } }); mutationObserver.observe(illustList, { childList: true, subtree: true }); })(); //# sourceMappingURL=script.js.map