Commit e568febb authored by nanahira's avatar nanahira

migrate to ygopro-lflist-encode

parent 807c8474
...@@ -19,7 +19,8 @@ ...@@ -19,7 +19,8 @@
"moment": "^2.30.1", "moment": "^2.30.1",
"sqlite": "^4.0.15", "sqlite": "^4.0.15",
"sqlite3": "^5.0.0", "sqlite3": "^5.0.0",
"yaml": "^1.10.0" "yaml": "^1.10.0",
"ygopro-lflist-encode": "^1.0.3"
}, },
"devDependencies": { "devDependencies": {
"@types/lodash": "^4.17.7", "@types/lodash": "^4.17.7",
...@@ -1373,6 +1374,21 @@ ...@@ -1373,6 +1374,21 @@
"engines": { "engines": {
"node": ">= 6" "node": ">= 6"
} }
},
"node_modules/ygopro-deck-encode": {
"version": "1.0.15",
"resolved": "https://registry.npmjs.org/ygopro-deck-encode/-/ygopro-deck-encode-1.0.15.tgz",
"integrity": "sha512-NMvgWuC3SKant50RDu0bHa3QIRlwBhdTR3bNDrMpNthTTQmCCq8i2HZaWFiCmYIBi9fR3W9CkFIgK6hI4d+PzQ==",
"license": "MIT"
},
"node_modules/ygopro-lflist-encode": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/ygopro-lflist-encode/-/ygopro-lflist-encode-1.0.3.tgz",
"integrity": "sha512-lsQhnAror2OwdTjYHWgBBlCglGjXhwOblM7TdzZmGAfrGHQMLeVNh0xwxVaiGBBDsTt3a7Nf1N9NezbnOv8NXQ==",
"license": "MIT",
"dependencies": {
"ygopro-deck-encode": "^1.0.15"
}
} }
} }
} }
...@@ -29,7 +29,8 @@ ...@@ -29,7 +29,8 @@
"moment": "^2.30.1", "moment": "^2.30.1",
"sqlite": "^4.0.15", "sqlite": "^4.0.15",
"sqlite3": "^5.0.0", "sqlite3": "^5.0.0",
"yaml": "^1.10.0" "yaml": "^1.10.0",
"ygopro-lflist-encode": "^1.0.3"
}, },
"devDependencies": { "devDependencies": {
"@types/lodash": "^4.17.7", "@types/lodash": "^4.17.7",
......
...@@ -3,9 +3,10 @@ import sqlite3 from "sqlite3"; ...@@ -3,9 +3,10 @@ import sqlite3 from "sqlite3";
import _ from "lodash"; import _ from "lodash";
import Base from "./base"; import Base from "./base";
import { promises as fs } from "fs"; import { promises as fs } from "fs";
import { Banlist, generateBanlistFromCode, mergeBanlists } from "./utility"; import { generateBanlistFromCode } from "./utility";
import { CardPool, DeckGenerator } from "./deck"; import { CardPool, DeckGenerator } from "./deck";
import moment from "moment"; import moment from "moment";
import { YGOProLFListItem } from "ygopro-lflist-encode";
const textsFields = ["id", "name", "desc"] const textsFields = ["id", "name", "desc"]
for (let i = 1; i <= 16; ++i) { for (let i = 1; i <= 16; ++i) {
...@@ -199,17 +200,15 @@ export class DBReader extends Base { ...@@ -199,17 +200,15 @@ export class DBReader extends Base {
const otherCodes: number[] = (await this.cndb.all(sql)).map(m => m.id); const otherCodes: number[] = (await this.cndb.all(sql)).map(m => m.id);
return otherCodes; return otherCodes;
} }
async generateBanlist(codes: number[], extraBanlists: Banlist[] = []) { async generateBanlist(codes: number[], extraBanlists: YGOProLFListItem[] = []) {
const otherCodes = await this.getOtherCardCodes(codes); const otherCodes = await this.getOtherCardCodes(codes);
const generatedBanlist: Banlist = { const generatedBanlist = new YGOProLFListItem({
name: moment().format('YYYY.MM') + ' ' + this.config.fileSymbol, name: moment().format('YYYY.MM') + ' ' + this.config.fileSymbol,
list: [ entries: otherCodes.map((code) => ({ code, limit: 0 }))
otherCodes });
]
};
const banlistString = await generateBanlistFromCode( const banlistString = await generateBanlistFromCode(
extraBanlists?.length extraBanlists?.length
? extraBanlists.map(l => mergeBanlists([generatedBanlist, l], l.name)) ? extraBanlists.map(l => new YGOProLFListItem({ name: l.name }).merge(generatedBanlist, l))
: [generatedBanlist] : [generatedBanlist]
); );
await fs.writeFile(`${this.config.outputPath}/expansions/lflist.conf`, banlistString); await fs.writeFile(`${this.config.outputPath}/expansions/lflist.conf`, banlistString);
...@@ -233,7 +232,7 @@ export class DBReader extends Base { ...@@ -233,7 +232,7 @@ export class DBReader extends Base {
await Promise.all(_.range(deckTexts.length).map(i => fs.writeFile(`${this.config.outputPath}/deck/${this.config.fileSymbol}/${this.config.fileSymbol}_${i}.ydk`, deckTexts[i]))); await Promise.all(_.range(deckTexts.length).map(i => fs.writeFile(`${this.config.outputPath}/deck/${this.config.fileSymbol}/${this.config.fileSymbol}_${i}.ydk`, deckTexts[i])));
} }
async run(cards: Card[], options: { async run(cards: Card[], options: {
extraBanlists?: Banlist[] extraBanlists?: YGOProLFListItem[]
} = {}) { } = {}) {
await Promise.all(cards.map(card => card.loadData(this.cndb))); await Promise.all(cards.map(card => card.loadData(this.cndb)));
const extendedCards = (await Promise.all(cards.map(card => card.getRelatedCards(this.cndb)))).flat(); const extendedCards = (await Promise.all(cards.map(card => card.getRelatedCards(this.cndb)))).flat();
......
import _ from "lodash"; import { YGOProLFList, YGOProLFListItem } from "ygopro-lflist-encode";
import jinja from "jinja-js";
import { promises as fs } from "fs";
export interface Banlist { export type Banlist = Partial<YGOProLFListItem>;
name: string
list: number[][]
}
export async function generateBanlistFromCode(banlists: Banlist[]) { export async function generateBanlistFromCode(banlists: Banlist[]) {
const template = await fs.readFile("./templates/lflist.conf.j2", "utf-8"); const list = new YGOProLFList({
return jinja.render(template, { banlists }); items: banlists.map((item) => new YGOProLFListItem(item))
} });
return list.toText();
export async function readLFList(content: string): Promise<Banlist[]> {
const lines = content.split("\n");
const ret: Banlist[] = [];
let name = "";
let list: number[][] = [];
const nextList = (nextName: string) => {
if (list.length > 0) {
ret.push({ name, list });
}
list = [];
name = nextName;
}
for (let line of lines) {
if (line.startsWith("#")) {
continue;
}
if(line.startsWith("!")) {
nextList(line.slice(1));
continue;
}
// xxxxxxxx 0
// use regex to match
const match = line.match(/^(\d{4,})\s(\d)/);
if(!match) {
continue;
}
const code = parseInt(match[1]);
const status = parseInt(match[2]);
list[status] ??= [];
list[status].push(code);
}
nextList('');
return ret;
} }
export function mergeBanlists(lists: Banlist[], name?: string): Banlist { export async function readLFList(content: string): Promise<YGOProLFListItem[]> {
const ret: Banlist = { name: name || lists[0].name, list: [] }; return new YGOProLFList().fromText(content).items;
const existingCodes = new Set<number>();
for (let status = 0; status < 3; ++status) {
for (let list of lists) {
ret.list[status] ??= [];
for(let code of list.list[status] ?? []) {
if (!existingCodes.has(code)) {
ret.list[status].push(code);
existingCodes.add(code);
}
}
}
}
return ret;
} }
import { Card, DBReader } from "./src/dbreader"; import { Card, DBReader } from "./src/dbreader";
import _ from "lodash"; import _ from "lodash";
import { PackDbFetcher } from "./src/packdbfetcher"; import { PackDbFetcher } from "./src/packdbfetcher";
import { Banlist, mergeBanlists, readLFList } from "./src/utility"; import { readLFList } from "./src/utility";
import moment from "moment"; import moment from "moment";
import fs from 'fs'; import fs from 'fs';
import { YGOProLFListItem } from "ygopro-lflist-encode";
const DATE = process.env.DATE; const DATE = process.env.DATE;
const lflistPath = process.env.LFLIST_PATH || "./lflist.conf"; const lflistPath = process.env.LFLIST_PATH || "./lflist.conf";
...@@ -20,13 +21,13 @@ const fileSymbol = process.env.FILE_SYMBOL || "cn"; ...@@ -20,13 +21,13 @@ const fileSymbol = process.env.FILE_SYMBOL || "cn";
async function getBanlist() { async function getBanlist() {
const lflistData = await fs.promises.readFile(lflistPath, 'utf-8'); const lflistData = await fs.promises.readFile(lflistPath, 'utf-8');
const lflists = (await readLFList(lflistData)).filter(l => !l.name.includes('TCG')).map(l => ({ const lflists = (await readLFList(lflistData)).filter(l => !l.name.includes('TCG')).map(l => ({
...l, list: l,
date: moment(l.name.split(' ')[0], 'YYYY.MM') date: moment(l.name.split(' ')[0], 'YYYY.MM')
})).filter(l => l.date.isBefore(DATE)); })).filter(l => l.date.isBefore(DATE));
const lflist = _.maxBy(lflists, l => l.date.unix()); const lflist = _.maxBy(lflists, l => l.date.unix());
const extraLflistPath = `./extras/${fileSymbol}/lflist.conf`; const extraLflistPath = `./extras/${fileSymbol}/lflist.conf`;
const extraLflistPath2 = process.env.EXTRA_LFLIST_PATH; const extraLflistPath2 = process.env.EXTRA_LFLIST_PATH;
const readExtraLflist = async (path?: string): Promise<Banlist | undefined> => { const readExtraLflist = async (path?: string): Promise<YGOProLFListItem | undefined> => {
if (!path) return undefined; if (!path) return undefined;
try { try {
const content = await fs.promises.readFile(path, 'utf-8'); const content = await fs.promises.readFile(path, 'utf-8');
...@@ -35,14 +36,14 @@ async function getBanlist() { ...@@ -35,14 +36,14 @@ async function getBanlist() {
return undefined; return undefined;
} }
}; };
const mergeAvailable = (lists: Array<Banlist | undefined>): Banlist | undefined => { const mergeAvailable = (lists: Array<YGOProLFListItem | undefined>): YGOProLFListItem | undefined => {
const valid = lists.filter(Boolean) as Banlist[]; const valid = lists.filter(Boolean) as YGOProLFListItem[];
return valid.length ? mergeBanlists(valid) : undefined; return valid.length ? new YGOProLFListItem({name: valid[0].name}).merge(...valid) : undefined;
}; };
const [extraLflist, extraLflist2] = await Promise.all( const [extraLflist, extraLflist2] = await Promise.all(
[extraLflistPath, extraLflistPath2].map(readExtraLflist) [extraLflistPath, extraLflistPath2].map(readExtraLflist)
); );
return mergeAvailable([lflist, extraLflist, extraLflist2]); return mergeAvailable([lflist?.list, extraLflist, extraLflist2]);
} }
async function main() { async function main() {
......
#{% for banlist in banlists %}[{{banlist.name}}]{% endfor %}
{% for banlist in banlists %}
!{{banlist.name}}
#forbidden
{% for code in banlist.list[0] %}
{{code}} 0
{%- endfor %}
#limit
{% for code in banlist.list[1] %}
{{code}} 1
{%- endfor %}
#semi limit
{% for code in banlist.list[2] %}
{{code}} 2
{%- endfor %}
{% endfor %}
#!/bin/bash
rm -rf output
mkdir -p output/env408-zh-CN
env LOCALE=zh-CN NPM_SCRIPT=start:subenv DATE=2006-05-15 CARD_SYMBOL=408环境 FILE_SYMBOL=env408 OVERRIDE_TEXT_DB_PATH=./extras/2012.cdb ./ci-scripts/generate.sh
...@@ -3,18 +3,30 @@ import { generateBanlistFromCode } from "../src/utility"; ...@@ -3,18 +3,30 @@ import { generateBanlistFromCode } from "../src/utility";
const banlists = [ const banlists = [
{ {
name: "test1", name: "test1",
list: [ entries: [
[111, 222, 333], { code: 111, limit: 0 },
[444, 555, 666], { code: 222, limit: 0 },
[777, 888, 999] { code: 333, limit: 0 },
{ code: 444, limit: 1 },
{ code: 555, limit: 1 },
{ code: 666, limit: 1 },
{ code: 777, limit: 2 },
{ code: 888, limit: 2 },
{ code: 999, limit: 2 }
] ]
}, },
{ {
name: "test2", name: "test2",
list: [ entries: [
[111, 222, 333], { code: 111, limit: 0 },
[444, 555, 666], { code: 222, limit: 0 },
[777, 888, 9999] { code: 333, limit: 0 },
{ code: 444, limit: 1 },
{ code: 555, limit: 1 },
{ code: 666, limit: 1 },
{ code: 777, limit: 2 },
{ code: 888, limit: 2 },
{ code: 9999, limit: 2 }
] ]
} }
] ]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment