Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- const fs = require('fs');
- const path = require('path');
- const jsdom = require('jsdom');
- const { JSDOM } = jsdom;
- const dataDir = path.join('ktst');
- const ws = fs.createWriteStream('ktst-passive.tsv', 'utf-8');
- let pk = 0;
- ws.on('error', function (err) {
- console.error(err);
- process.exit(1);
- });
- ws.write([
- 'pk',
- 'logID',
- 'turn',
- 'action',
- 'parent',
- 'target',
- 'effect',
- 'type',
- 'direction',
- 'cycle',
- 'actual',
- 'cycle * actual',
- 'passive'].join('\t') + '\n');
- const list = fs.readdirSync(dataDir);
- console.log(list.length + ' files');
- for (let i = 0; i < list.length; i++) {
- readLog(path.join(dataDir, list[i]));
- }
- function readLog(fullpath) {
- fs.stat(fullpath, (err, stats) => {
- if (err) {
- return;
- }
- let m = fullpath.match(/([0-9]+)\.html$/);
- if (!stats.isFile() || !m) {
- return;
- }
- if (m[1] != 12648) {
- //return;
- }
- _readLog(fullpath, m[1])
- .then(result => console.log(result.fullpath));
- });
- }
- function _readLog(fullpath, battleId) {
- return new Promise((resolve, reject) => {
- fs.readFile(fullpath, 'utf8', function(err, data) {
- if (err) {
- reject(err);
- return;
- }
- const result = parse(data, battleId);
- result.fullpath = fullpath;
- resolve(result);
- });
- });
- }
- function parseFormation(mae, naka, usiro) {
- const line = [mae, naka, usiro];
- return {
- line: line,
- zenTarget: line.reduce((pre, cur) => pre + cur),
- retuTarget: line.sort((pre, cur) => cur - pre)[0],
- kanTarget: line.filter(cur => cur).length,
- }
- }
- function parse(data, battleId) {
- const result = {};
- const formation = {};
- const document = new JSDOM(data).window.document;
- const contents = document.querySelector('body > .AL > div[style]');
- if (!contents) {
- return result;
- }
- let cursor = contents.firstElementChild;
- let m;
- const state = {
- battleId: battleId,
- turn: 0,
- formation: {
- }
- };
- while (cursor) {
- if (cursor.tagName == 'TABLE' && cursor.className == 'FRB1') {
- const title = cursor.querySelector('.B7i');
- if (title && (m = title.textContent.match(/(\d+)/))) {
- state.turn = ~~ m[1];
- }
- const left = cursor.querySelector('td[width = "490"] > .SE > table > tbody');
- const right = cursor.querySelector('td[width = "490"] > .SE2 > table > tbody');
- if (left && right) {
- state.formation.left = parseFormation(
- left.querySelectorAll('td[width = "100"][align = "right"]').length,
- left.querySelectorAll('td[width = "100"][align = "center"]').length,
- left.querySelectorAll('td[width = "100"]:not([align])').length
- );
- state.formation.right = parseFormation(
- right.querySelectorAll('td[width = "100"]:not([align])').length,
- right.querySelectorAll('td[width = "100"][align = "center"]').length,
- right.querySelectorAll('td[width = "100"][align = "right"]').length
- );
- }
- cursor
- .querySelectorAll('.FRB2 > div[align = LEFT]')
- .forEach(e => parseBA2(state, e, 'root', '', ''));
- }
- else if (cursor.tagName == 'DIV') {
- cursor
- .querySelectorAll('.FRS2 > .BA2')
- .forEach(e => parseBA2(state, e, 'root', '', ''));
- }
- cursor = cursor.nextElementSibling;
- }
- return result;
- }
- function parseBA2(state, cursor, parent, currentTarget, currentEffect) {
- let m;
- const regPassiveName = /の([^!]+)/,
- regActiveName = /^([^!]+)/,
- regSkillEffect = /^(.+?):([^!]+?)!$/;
- if (!cursor) {
- return;
- }
- cursor = cursor.firstElementChild;
- while (cursor) {
- if (cursor.nodeType == 1) {
- /*
- () は走査のルート要素
- 行動前
- (.FRS2 > b.BA2) > b.BA2
- アクティブ
- (.FRS2 > b.BA2) > dl. > dl.BA2
- パッシブ
- > dl.BA2
- 通常攻撃
- (.FRS2 > b.BA2) > dl. > dl.BA2
- パッシブ
- 通常攻撃の兄弟要素 dl.BA2
- ターン開始
- (.FRB2 > div[align = LEFT]) > b.BA2
- */
- if (cursor.textContent == '通常攻撃!' && cursor.className == 'HK2') {
- parent = '通常攻撃';
- currentTarget = '敵';
- currentEffect = '攻撃';
- }
- else if (cursor.className == 'F7') {
- m = cursor.textContent.match(regActiveName);
- parent = m[1];
- }
- else if (cursor.tagName == 'B' && cursor.className == 'HK2') {
- m = cursor.textContent.match(regPassiveName);
- if (m[1] == "' Θ '") {
- logger(state, 'action', parent, currentTarget, currentEffect, m[1]);
- }
- parent = m[1];
- }
- else if (cursor.className == 'P2') {
- m = cursor.textContent.match(regSkillEffect);
- currentTarget = m[1];
- currentEffect = m[2];
- }
- else if (cursor.className == 'BA2') {
- parseBA2(state, cursor, parent, currentTarget, currentEffect);
- }
- else if (cursor.tagName == 'DL') {
- parseBA2(state, cursor, parent, currentTarget, currentEffect);
- }
- }
- else if (cursor.nodeType == 3) {
- if (cursor.textContent.match(/のダメージ!$/)) {
- logger(state, 'hit', parent, currentTarget, currentEffect, '');
- }
- }
- cursor = cursor.nextSibling;
- }
- }
- function logger(state, action, parent, target, effect, skill) {
- if (!state.formation) {
- return;
- }
- pk++;
- const foe = state.formation.left;
- const ally = state.formation.right;
- let actual = 1;
- let type = '単';
- let cycle = 1;
- let direction = '';
- let m;
- if (m = target.match(/(\d+)/)) {
- cycle = ~~ m[1];
- }
- if (m = target.match(/敵/)) {
- direction = '敵';
- }
- else if (m = target.match(/味/)) {
- direction = '味';
- }
- else if (m = target.match(/他/)) {
- direction = '他';
- }
- if (target.match(/貫/)) {
- actual = (direction == '敵') ? foe.kanTarget : ally.kanTarget;
- type = '貫';
- }
- if (target.match(/列/)) {
- actual = (direction == '敵') ? foe.retuTarget : ally.retuTarget;
- type = '列';
- }
- else if (m = effect.match(/(\d+)連鎖/)) {
- actual = ~~ m[1];
- type = '連鎖';
- }
- else if (m = effect.match(/(\d+)連撃/)) {
- actual = ~~ m[1];
- type = '連撃';
- }
- else if (m = target.match(/全/)) {
- type = '全';
- if (direction == '敵') {
- actual = foe.zenTarget;
- }
- else if (direction == '味') {
- actual = ally.zenTarget;
- }
- else if (direction == '他') {
- actual = -1 + foe.zenTarget + ally.zenTarget;
- }
- }
- ws.write([
- pk,
- state.battleId,
- state.turn,
- action,
- "'" + parent,
- target,
- effect,
- type,
- direction,
- cycle,
- actual,
- cycle * actual,
- "'" + skill].join('\t') + '\n');
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement