Last active
March 4, 2022 14:43
-
-
Save sinsinpub/ed0643b62ef386037de532de4ecd98d3 to your computer and use it in GitHub Desktop.
From KanColle wikiwiki, extract and print Kanmusu quotes JSON at console for KC3Kai.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name KanColle wikiwiki subtitles crawler | |
// @author sin_sin | |
// @namespace https://gist.github.com/sinsinpub | |
// @version 0.7 | |
// @description Extract and print Kanmusu quotes JSON at devtools console for KC3Kai. | |
// @copyright 2017-2021, sin_sin | |
// @match https://wikiwiki.jp/kancolle/ | |
// @include https://wikiwiki.jp/kancolle/* | |
// @icon https://cdn.wikiwiki.jp/to/w/common/user-favicon.ico | |
// @grant unsafeWindow | |
// @grant GM_setClipboard | |
// @run-at document-end | |
// ==/UserScript== | |
(function() { | |
'use strict'; | |
const $ = unsafeWindow.$ || document.querySelector.bind(document); | |
const removeFootnote = function(txt) { | |
return (txt || "").replace(/\*[0-9]{1,2}\b/g, "").trim(); | |
}; | |
const removeSpoilerTag = function(txt) { | |
return (txt || "").replace(/^silver$/, "").replace("&color(foreground[,background]){text};", ""); | |
}; | |
const getTextByTitle = function(table, title, row = 1, etype = "td,th", returnElm = false) { | |
const td = $(etype, table).filter( | |
(i, el) => ( | |
title.startsWith("*") ? | |
$(el).text().includes(title.substr(1)) : | |
title.startsWith("=") ? | |
$(el).text() === title.substr(1) : | |
$(el).text().startsWith(title) | |
) | |
); | |
if(td.length > 0) { | |
if(returnElm) { | |
return td.length === 1 ? td : td.first(); | |
} | |
if(row > 1) { | |
let tr = td.first().parent(); | |
for(let i = 1; i < row; i++) tr = tr.next(); | |
return removeFootnote(tr.children().first().text()); | |
} else if(!row) { | |
return removeFootnote(td.text()); | |
} else { | |
return removeFootnote(td.first().next().text()); | |
} | |
} | |
return ""; | |
}; | |
const parseOldFormatTable = function(subObj) { | |
const quotesTd = getTextByTitle($("body"), "セリフ", 1, "th", true); | |
if(quotesTd.length > 0) { | |
const quotesTable = quotesTd.parent().parent().parent(); | |
subObj.ID.Intro = getTextByTitle(quotesTable, "*ログイン"); | |
subObj.ID["Poke(1)"] = getTextByTitle(quotesTable, "*詳細閲覧", 1); | |
subObj.ID["Poke(2)"] = getTextByTitle(quotesTable, "*詳細閲覧", 2); | |
subObj.ID["Poke(3)"] = getTextByTitle(quotesTable, "*クリック時"); | |
if(!subObj.ID["Poke(3)"]) { | |
subObj.ID["Poke(3)"] = getTextByTitle(quotesTable, "*詳細閲覧", 3); | |
if(subObj.ID["Poke(3)"].endsWith("クリック時")) subObj.ID["Poke(3)"] = ""; | |
} | |
subObj.ID.Construction = getTextByTitle(quotesTable, "建造完了"); | |
subObj.ID.Return = getTextByTitle(quotesTable, "帰投"); | |
subObj.ID.Ranking = getTextByTitle(quotesTable, "戦績表示"); | |
subObj.ID["Equip(1)"] = getTextByTitle(quotesTable, "改装", 1); | |
subObj.ID["Equip(2)"] = getTextByTitle(quotesTable, "改装", 2); | |
subObj.ID["Equip(3)"] = getTextByTitle(quotesTable, "改装", 3); | |
if(subObj.ID["Equip(3)"].endsWith("アイテム発見)")) { | |
subObj.ID["Equip(3)"] = getTextByTitle(quotesTable, "*アイテム発見"); | |
} | |
subObj.ID.Supply = getTextByTitle(quotesTable, "補給"); | |
subObj.ID["Docking(1)"] = getTextByTitle(quotesTable, "*小破以下"); | |
subObj.ID["Docking(2)"] = getTextByTitle(quotesTable, "*中破以上"); | |
subObj.ID.Join = getTextByTitle(quotesTable, "編成"); | |
subObj.ID.Sortie = getTextByTitle(quotesTable, "出撃", 1); | |
if(subObj.ID.Sortie === subObj.ID.Join) { | |
subObj.ID.Sortie = getTextByTitle(quotesTable, "出撃", 2); | |
} | |
subObj.ID.Battle = getTextByTitle(quotesTable, "開戦"); | |
subObj.ID.Attack = getTextByTitle(quotesTable, "攻撃", 1); | |
if(subObj.ID.Attack === subObj.ID.Battle) { | |
subObj.ID.Attack = getTextByTitle(quotesTable, "攻撃", 2); | |
} | |
subObj.ID["Yasen(1)"] = getTextByTitle(quotesTable, "夜戦開始"); | |
subObj.ID["Yasen(2)"] = getTextByTitle(quotesTable, "*夜戦攻撃"); | |
subObj.ID["Damaged(1)"] = getTextByTitle(quotesTable, "小破", 1); | |
subObj.ID["Damaged(2)"] = getTextByTitle(quotesTable, "小破", 2); | |
if(subObj.ID["Damaged(2)"].endsWith("旗艦大破")) { | |
subObj.ID["Damaged(2)"] = getTextByTitle(quotesTable, "*旗艦大破"); | |
//subObj.ID["Damaged(1)"] = getTextByTitle(quotesTable, "小破", 1); | |
} | |
subObj.ID["Damaged(3)"] = getTextByTitle(quotesTable, "中破"); | |
subObj.ID.Sunk = removeSpoilerTag(getTextByTitle(quotesTable, "轟沈")); | |
subObj.ID.MVP = getTextByTitle(quotesTable, "勝利MVP"); | |
subObj.ID.Wedding = removeSpoilerTag(getTextByTitle(quotesTable, "ケッコンカッコカリ")); | |
subObj.ID.Married = removeSpoilerTag(getTextByTitle(quotesTable, "ケッコン後母港")); | |
subObj.ID.Idle = getTextByTitle(quotesTable, "放置時"); | |
const libDesc = getTextByTitle($("body"), "図鑑説明", 1, "th", true); | |
if(libDesc) subObj.ID.Library = removeFootnote(libDesc.parent().next().children().first().text()); | |
const timeAlert0400 = getTextByTitle(quotesTable, "時報", 5); | |
if(timeAlert0400) { | |
for(let i = 0; i < 24; i++) { | |
subObj.ID["H" + (i < 10 ? "0" : "") + i + "00"] = getTextByTitle(quotesTable, "時報", i + 1); | |
} | |
} | |
return true; | |
} | |
return false | |
}; | |
// new quotes table formation, all remodels are merged into one table. TODO list all lines for every remodels | |
// https://wikiwiki.jp/kancolle/%E8%AD%B0%E8%AB%96%E6%8E%B2%E7%A4%BA%E6%9D%BF/%E8%89%A6%E5%A8%98%E3%83%9C%E3%82%A4%E3%82%B9%E4%B8%80%E8%A6%A7%E8%A1%A8%E3%81%AE%E5%88%A5%E8%A1%A8%E5%8C%96 | |
const parseNewFormatTable = function(subObj) { | |
const newTableHead = getTextByTitle($("body"), "定型ボイス一覧", 1, "h3", true); | |
if(newTableHead.length > 0) { | |
const quotesTable = newTableHead.parent(); | |
subObj.ID.Intro = getTextByTitle(quotesTable, "入手/"); | |
subObj.ID["Poke(1)"] = getTextByTitle(quotesTable, "詳細"); | |
subObj.ID["Poke(2)"] = getTextByTitle(quotesTable, "母港2"); | |
subObj.ID["Poke(3)"] = getTextByTitle(quotesTable, "母港3"); | |
subObj.ID.Construction = getTextByTitle(quotesTable, "建造完了"); | |
subObj.ID.Return = getTextByTitle(quotesTable, "帰投"); | |
subObj.ID.Ranking = getTextByTitle(quotesTable, "戦績表示"); | |
subObj.ID["Equip(1)"] = getTextByTitle(quotesTable, "改修/"); | |
subObj.ID["Equip(2)"] = getTextByTitle(quotesTable, "装備2"); | |
subObj.ID["Equip(3)"] = getTextByTitle(quotesTable, "*/発見"); | |
subObj.ID.Supply = getTextByTitle(quotesTable, "補給"); | |
subObj.ID["Docking(1)"] = getTextByTitle(quotesTable, "*(小破以下)"); | |
subObj.ID["Docking(2)"] = getTextByTitle(quotesTable, "*(中破以上)"); | |
subObj.ID.Join = getTextByTitle(quotesTable, "=編成"); | |
subObj.ID.Sortie = getTextByTitle(quotesTable, "=出撃", 1); | |
subObj.ID.Battle = getTextByTitle(quotesTable, "昼戦開始"); | |
subObj.ID.Attack = getTextByTitle(quotesTable, "昼戦攻撃"); | |
subObj.ID["Yasen(1)"] = getTextByTitle(quotesTable, "夜戦開始"); | |
subObj.ID["Yasen(2)"] = getTextByTitle(quotesTable, "夜戦攻撃"); | |
subObj.ID["Damaged(1)"] = getTextByTitle(quotesTable, "小破", 1); | |
subObj.ID["Damaged(2)"] = getTextByTitle(quotesTable, "小破", 2); | |
subObj.ID["Damaged(3)"] = getTextByTitle(quotesTable, "中破/"); | |
subObj.ID.Sunk = removeSpoilerTag(getTextByTitle(quotesTable, "轟沈")); | |
subObj.ID.MVP = getTextByTitle(quotesTable, "勝利MVP"); | |
subObj.ID.Wedding = removeSpoilerTag(getTextByTitle(quotesTable, "ケッコンカッコカリ")); | |
subObj.ID.Married = removeSpoilerTag(getTextByTitle(quotesTable, "ケッコン後母港")); | |
subObj.ID.Idle = getTextByTitle(quotesTable, "放置時"); | |
const libDesc = getTextByTitle($("body"), "図鑑説明", 1, "th", true); | |
if(libDesc) subObj.ID.Library = removeFootnote(libDesc.parent().next().children().first().text()); | |
const timeAlert0400 = getTextByTitle(quotesTable, "時報ボイス一覧", 1, "h3", true); | |
if(timeAlert0400) { | |
const hourlinesTable = timeAlert0400.next(); | |
for(let i = 0; i < 24; i++) { | |
const timeName = (i < 10 ? "0" : "") + i; | |
subObj.ID["H" + timeName + "00"] = getTextByTitle(hourlinesTable, timeName); | |
} | |
} | |
return true; | |
} | |
return false | |
}; | |
const subObj = {"ID":{}}; | |
let quotesFound = parseNewFormatTable(subObj); | |
if(!quotesFound) quotesFound = parseOldFormatTable(subObj); | |
// only run at shipgirl page | |
if(!quotesFound) { | |
unsafeWindow.console.debug("Quotes table not found"); | |
} else { | |
const subJson = JSON.stringify(subObj, null, '\t'); | |
unsafeWindow.console.info(subJson); | |
unsafeWindow.subtitles = subObj; | |
if(subObj.ID.Intro) { | |
GM_setClipboard(subJson); | |
unsafeWindow.console.debug("Quotes JSON copied to clipboard"); | |
} | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment