Commit a870d6d9 authored by nanahira's avatar nanahira

add deck category

parent d9b054c4
Pipeline #26353 passed with stages
in 7 minutes and 16 seconds
......@@ -43,7 +43,7 @@
</li>
</ul>
<span i18n *ngIf="grouped_apps.ygopro">YGOPro 各发行版</span>
<ul *ngIf="grouped_apps.recommend" class="nav nav-pills flex-column">
<ul *ngIf="grouped_apps.ygopro" class="nav nav-pills flex-column">
<li *ngFor="let app of grouped_apps.ygopro" class="nav-item">
<a (click)="$event.preventDefault(); chooseApp(app)" [href]="'https://mycard.moe/' + app.id" class="nav-link" [class.active]="app===currentApp">
<img *ngIf="app.icon" class="icon" [src]="app.icon">
......
......@@ -18,18 +18,24 @@
</div>
<div class="row small-gutters">
<div class="col-sm-4 input-group input-group-sm">
<div class="col-sm-3 input-group input-group-sm">
<label i18n class="input-group-addon" id="server-label">环境</label>
<select class="form-control form-control-sm" id="selectServer" name="server" [disabled]="!appsService.allReady(app)" [(ngModel)]="currentServer">
<option *ngFor="let server of selectableServers" [ngValue]="server">{{server.name}}</option>
</select>
</div>
<div class="col-sm-8 input-group input-group-sm">
<div *ngIf="lastCategoryFormat" class="col-sm-3 input-group input-group-sm">
<label i18n class="input-group-addon" id="basic-addon1">分类</label>
<select class="form-control form-control-sm" id="exampleSelect1" name="category" [(ngModel)]="currentCategory" (ngModelChange)="refreshCurrentCategoryDecks()">
<option *ngFor="let category of categories" [ngValue]="category">{{category.title}}</option>
</select>
</div>
<div class="input-group input-group-sm" [class.col-sm-4]="!!lastCategoryFormat" [class.col-sm-7]="!lastCategoryFormat">
<label i18n class="input-group-addon" id="basic-addon1">卡组</label>
<select class="form-control form-control-sm" id="exampleSelect1" name="deck" [(ngModel)]="current_deck">
<option *ngFor="let deck of decks" [ngValue]="deck">{{deck}}</option>
<select class="form-control form-control-sm" id="exampleSelect1" name="deck" [(ngModel)]="currentDeck">
<option *ngFor="let deck of currentCategoryDecks" [ngValue]="deck">{{deck}}</option>
</select> <span class="input-group-btn">
<button id="edit_deck_button" i18n [disabled]="!appsService.allReady(app)" class="btn btn-secondary btn-sm" (click)="edit_deck(current_deck)">编辑</button>
<button id="edit_deck_button" i18n [disabled]="!appsService.allReady(app)" class="btn btn-secondary btn-sm" (click)="edit_deck()">编辑</button>
</span>
</div>
</div>
......
......@@ -9,7 +9,7 @@ import * as $ from 'jquery';
import * as path from 'path';
import 'rxjs/Rx';
import {ISubscription} from 'rxjs/Subscription';
import {App} from './app';
import {App, Category} from './app';
import {AppsService} from './apps.service';
import {LoginService} from './login.service';
import {SettingsService} from './settings.sevices';
......@@ -98,6 +98,7 @@ interface YGOProDistroData {
replayPath: string;
systemConf?: string;
lastDeckFormat?: string;
lastCategoryFormat?: string;
}
interface YGOProData {
......@@ -110,6 +111,12 @@ let matching: ISubscription | undefined;
let matching_arena: string | undefined;
let match_started_at: Date;
interface DeckCategory {
title: string;
decks: string[]
selected?: string;
}
@Component({
moduleId: module.id,
selector: 'ygopro',
......@@ -128,10 +135,12 @@ export class YGOProComponent implements OnInit, OnDestroy, OnChanges {
@Output()
points: EventEmitter<Points> = new EventEmitter();
decks: string[] = [];
categories: DeckCategory[] = [];
replays: string[] = [];
replays2: string[] = [];
current_deck: string;
currentCategory: DeckCategory = { title: '', decks: [], selected: undefined };
currentCategoryDecks: string[] = [];
currentDeck: string;
system_conf: string;
numfont: string[];
textfont: string[];
......@@ -157,6 +166,7 @@ export class YGOProComponent implements OnInit, OnDestroy, OnChanges {
rooms_loading = true;
lastDeckFormat: RegExp;
lastCategoryFormat: RegExp;
default_options: Options = {
mode: 1,
......@@ -339,6 +349,15 @@ export class YGOProComponent implements OnInit, OnDestroy, OnChanges {
this.lastDeckFormat = undefined;
}
// lastCategoryFormat
if (ygoproData.ygopro.lastCategoryFormat) {
// console.log(`Category format pattern: ${ygoproData.ygopro.lastCategoryFormat}`)
this.lastCategoryFormat = new RegExp(ygoproData.ygopro.lastCategoryFormat);
} else {
this.lastCategoryFormat = undefined;
}
// this.lastCategoryFormat = undefined;
this.system_conf = this.app.systemConfPath;
console.log(`Will load system conf file from ${this.system_conf}`);
await this.refresh(true);
......@@ -477,11 +496,12 @@ export class YGOProComponent implements OnInit, OnDestroy, OnChanges {
async refresh(init?: boolean) {
this.decks = await this.get_decks();
this.categories = await this.get_decks();
if (this.lastDeckFormat) {
const systemConfString = await this.load_system_conf();
let lastDeck: string;
let lastCategory: string;
if (systemConfString) {
// console.log(`System conf string: ${systemConfString}`);
const lastDeckMatch = systemConfString.match(this.lastDeckFormat);
......@@ -491,15 +511,33 @@ export class YGOProComponent implements OnInit, OnDestroy, OnChanges {
} else {
// console.error(`Deck pattern not found from pattern ${this.system_conf}: ${lastDeckMatch}`);
}
if (this.lastCategoryFormat) {
const lastCategoryMatch = systemConfString.match(this.lastCategoryFormat);
if (lastCategoryMatch) {
lastCategory = lastCategoryMatch[1];
// console.log(`Last category ${lastCategoryMatch[1]} read from ${this.system_conf}.`);
} else {
// console.error(`Category pattern not found from pattern ${this.system_conf}: ${lastCategoryMatch}`);
}
}
} else {
// console.error(`System conf ${this.system_conf} not found.`);
}
const matchingCategory = this.categories.find(category => category.title === lastCategory);
if (lastDeck && this.decks.includes(lastDeck)) {
// console.log(`Got last deck ${lastDeck}.`);
this.current_deck = lastDeck;
} else if (init) {
this.current_deck = this.decks[0];
if (matchingCategory) {
this.currentCategory = matchingCategory;
} else {
this.currentCategory = this.categories[0];
}
this.currentCategoryDecks = this.currentCategory.decks;
if (this.currentCategoryDecks.includes(lastDeck)) {
this.currentDeck = lastDeck;
} else if (init || !this.currentCategoryDecks.includes(this.currentDeck)) {
this.currentDeck = this.currentCategoryDecks[0];
}
}
......@@ -521,39 +559,49 @@ export class YGOProComponent implements OnInit, OnDestroy, OnChanges {
}
};
async get_decks(): Promise<string[]> {
async get_decks(): Promise<DeckCategory[]> {
try {
/*
const deckPath = this.app.ygoproDeckPath;
let result: string[] = [];
let result: DeckCategory[] = [{
title: '',
decks: [],
}];
const files: string[] = await fs.readdir(deckPath);
for (const file of files) {
if (file.startsWith('.git')) { // fuck
continue;
}
if (path.extname(file) === '.ydk') {
result.push(path.basename(file, '.ydk'));
} else {
result[0].decks.push(path.basename(file, '.ydk'));
} else if (this.lastCategoryFormat) {
const fullPath = path.join(deckPath, file);
const stat = await fs.stat(fullPath);
if (stat.isDirectory()) {
const innerDecks = (await fs.readdir(fullPath))
.filter((iFile) => path.extname(iFile) === '.ydk')
.map((iFile) => path.join(file, path.basename(iFile, '.ydk')));
result = result.concat(innerDecks);
.map((iFile) => path.basename(iFile, '.ydk'));
result.push({
title: file,
decks: innerDecks,
})
}
}
}
return result;
*/
let files: string[] = await fs.readdir(this.app.ygoproDeckPath);
return files.filter(file => path.extname(file) === '.ydk').map(file => path.basename(file, '.ydk'));
} catch (error) {
console.error(`Load deck fail: ${error.toString()}`);
return [];
return [{
title: '',
decks: [],
}];
}
}
refreshCurrentCategoryDecks() {
this.currentCategoryDecks = this.currentCategory.decks;
this.currentDeck = this.currentCategoryDecks[0];
}
async get_replays(): Promise<string[]> {
try {
let files: string[] = await fs.readdir(this.app.ygoproReplayPath);
......@@ -626,27 +674,35 @@ export class YGOProComponent implements OnInit, OnDestroy, OnChanges {
return fs.writeFile(this.system_conf, ini.unsafe(ini.stringify(data, <EncodeOptions>{whitespace: true})));
};*/
async startYGOPro(action: string, param: any) {
if (this.currentCategory.title) {
return this.start_game(`${action}_ex`, { ...param, category: this.currentCategory.title, deck: this.currentDeck });
} else {
return this.start_game(action, { ...param, deck: this.currentDeck });
}
}
async join(name: string, server: Server) {
/*let system_conf = await this.load_system_conf();
await this.fix_fonts(system_conf);
system_conf.lastdeck = this.current_deck;
system_conf.lastdeck = this.currentDeck;
system_conf.lastip = server.address;
system_conf.lasthost = server.address;
system_conf.lastport = server.port.toString();
system_conf.roompass = name;
system_conf.nickname = this.loginService.user.username;
await this.save_system_conf(system_conf);*/
// return this.start_game(['-h', server.address, '-p', server.port.toString(), '-w', name, '-n', this.loginService.user.username, '-d', this.current_deck, '-j']);
return this.start_game('main', {server, password: name, username: this.loginService.user.username, deck: this.current_deck});
// return this.start_game(['-h', server.address, '-p', server.port.toString(), '-w', name, '-n', this.loginService.user.username, '-d', this.currentDeck, '-j']);
return this.startYGOPro('main', {server, password: name, username: this.loginService.user.username});
};
async edit_deck(deck: string) {
async edit_deck() {
/*let system_conf = await this.load_system_conf();
await this.fix_fonts(system_conf);
system_conf.lastdeck = deck;
await this.save_system_conf(system_conf);*/
// return this.start_game(['-d', deck]);
return this.start_game('deck', { deck })
return this.startYGOPro('deck', {})
}
async watch_replay(replay: string) {
......
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