Commit 5b96a05c authored by nanahira's avatar nanahira

Merge branch 'v3.1-deck-category' into v3-refactor3

parents 00ea1b2f f8c9ef68
...@@ -26,16 +26,13 @@ ...@@ -26,16 +26,13 @@
</div> </div>
<div class="col-sm-8 input-group input-group-sm"> <div class="col-sm-8 input-group input-group-sm">
<label i18n class="input-group-text" id="basic-addon1">卡组</label> <label i18n class="input-group-text" id="basic-addon1">卡组</label>
<select class="form-select form-select-sm" id="exampleSelect1" name="deck" [(ngModel)]="current_deck"> <select class="form-select form-select-sm" id="exampleSelect1" name="deck" [(ngModel)]="currentDeckSymbol" (change)="onDeckChange()">
<option *ngFor="let deck of decks_grouped['.']" [value]="deck">{{deck}}</option> <optgroup *ngFor="let group of decks_grouped" [label]="group[0] === '.' ? '未分类卡组' : group[0]">
<ng-container *ngFor="let group of decks_grouped | keyvalue"> <option *ngFor="let deck of group[1]" [value]="deck.symbol">{{deck.deck}}</option>
<optgroup *ngIf="group.key !== '.'" [label]='group.key'>
<option *ngFor="let deck of group.value" [value]="group.key + '/' + deck">{{deck}}</option>
</optgroup> </optgroup>
</ng-container>
</select> </select>
<span class="input-group-btn"> <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> </span>
</div> </div>
</div> </div>
...@@ -124,10 +121,10 @@ ...@@ -124,10 +121,10 @@
<small i18n class="form-text text-muted">最多 12 个字</small> <small i18n class="form-text text-muted">最多 12 个字</small>
</ng-container> </ng-container>
<ng-template #private> <ng-template #private>
<label *ngIf="room.private" for="game-create-title"><i class="fa fa-key" aria-hidden="true"></i> <label *ngIf="room.private" for="game-create-password"><i class="fa fa-key" aria-hidden="true"></i>
<span i18n>房间密码</span></label> <span i18n>房间密码</span></label>
<div class="input-group input-group-sm"> <div class="input-group input-group-sm">
<input type="text" maxlength="12" class="form-control" id="game-create-title" name="title" [(ngModel)]="host_password" readonly> <input type="text" maxlength="12" class="form-control" id="game-create-password" name="title" [(ngModel)]="host_password" readonly>
<span i18n-title id="copy-wrapper" class="input-group-btn" data-bs-toggle="tooltip" title="房间密码已复制到剪贴板"> <span i18n-title id="copy-wrapper" class="input-group-btn" data-bs-toggle="tooltip" title="房间密码已复制到剪贴板">
<button i18n-title class="btn btn-secondary fa fa-clipboard" type="button" title="复制" (click)="copy(host_password, $event)"></button> <button i18n-title class="btn btn-secondary fa fa-clipboard" type="button" title="复制" (click)="copy(host_password, $event)"></button>
</span> </span>
......
...@@ -112,6 +112,7 @@ interface YGOProDistroData { ...@@ -112,6 +112,7 @@ interface YGOProDistroData {
replayPath: string; replayPath: string;
systemConf?: string; systemConf?: string;
lastDeckFormat?: string; lastDeckFormat?: string;
lastCategoryFormat?: string;
} }
interface YGOProData { interface YGOProData {
...@@ -123,6 +124,27 @@ let matching: Subscription | undefined; ...@@ -123,6 +124,27 @@ let matching: Subscription | undefined;
let matching_arena: string | undefined; let matching_arena: string | undefined;
let match_started_at: Date; let match_started_at: Date;
export class DeckAndCategory {
category: string;
deck: string;
get param() {
return {
category: this.category === '.' ? '': this.category,
deck: this.deck,
deckPath: this.symbol
}
}
get symbol() {
return path.join(this.category, this.deck);
}
set symbol(str: string) {
this.category = path.dirname(str);
this.deck = path.basename(str, '.ydk');
}
}
@Component({ @Component({
moduleId: module.id, moduleId: module.id,
selector: 'ygopro', selector: 'ygopro',
...@@ -137,10 +159,12 @@ export class YGOProComponent implements OnInit, OnDestroy, AfterViewInit { ...@@ -137,10 +159,12 @@ export class YGOProComponent implements OnInit, OnDestroy, AfterViewInit {
@Output() @Output()
points: EventEmitter<any> = new EventEmitter(); points: EventEmitter<any> = new EventEmitter();
decks: string[] = []; decks: DeckAndCategory[] = [];
decks_grouped: Record<string, string[]> = {}; decks_grouped: [string, DeckAndCategory[]][];
replays: string[] = []; replays: string[] = [];
current_deck: string; currentDeck: DeckAndCategory;
currentDeckSymbol: string;
system_conf?: string; system_conf?: string;
numfont: string[]; numfont: string[];
textfont: string[]; textfont: string[];
...@@ -163,6 +187,7 @@ export class YGOProComponent implements OnInit, OnDestroy, AfterViewInit { ...@@ -163,6 +187,7 @@ export class YGOProComponent implements OnInit, OnDestroy, AfterViewInit {
this.currentServer = this.servers.find(s => s.id === this.selectingServerId); this.currentServer = this.servers.find(s => s.id === this.selectingServerId);
}*/ }*/
lastDeckFormat: RegExp; lastDeckFormat: RegExp;
lastCategoryFormat: RegExp;
default_options: Options = { default_options: Options = {
mode: 1, mode: 1,
rule: this.locale.startsWith('zh') ? 0 : 1, rule: this.locale.startsWith('zh') ? 0 : 1,
...@@ -326,10 +351,13 @@ export class YGOProComponent implements OnInit, OnDestroy, AfterViewInit { ...@@ -326,10 +351,13 @@ export class YGOProComponent implements OnInit, OnDestroy, AfterViewInit {
this.lastDeckFormat = new RegExp(ygoproData.ygopro.lastDeckFormat); this.lastDeckFormat = new RegExp(ygoproData.ygopro.lastDeckFormat);
} }
remote.ipcMain.on('YGOPro', (e: any, type: string) => { if (ygoproData.ygopro.lastCategoryFormat) {
console.log('rrrrr'); this.lastCategoryFormat = new RegExp(ygoproData.ygopro.lastCategoryFormat);
this.request_match(type); }
});
if (ygoproData.ygopro.lastCategoryFormat) {
this.lastCategoryFormat = new RegExp(ygoproData.ygopro.lastCategoryFormat);
}
this.system_conf = this.app.systemConfPath; this.system_conf = this.app.systemConfPath;
console.log(`Will load system conf file from ${this.system_conf}`); console.log(`Will load system conf file from ${this.system_conf}`);
...@@ -464,13 +492,15 @@ export class YGOProComponent implements OnInit, OnDestroy, AfterViewInit { ...@@ -464,13 +492,15 @@ export class YGOProComponent implements OnInit, OnDestroy, AfterViewInit {
this.watchDropdownMenuShow = false; this.watchDropdownMenuShow = false;
} }
} }
onDeckChange() {
this.currentDeck = this.getDeckObject(this.currentDeckSymbol);
console.log(`Current deck changed to ${this.currentDeck.symbol}`);
}
async refresh(init?: boolean) { async refresh(init?: boolean) {
this.decks = await this.get_decks(); this.decks = await this.get_decks();
this.decks_grouped = _.mapValues( this.decks_grouped = this.deckGroup();
_.groupBy(this.decks, (p) => path.dirname(p)), const allDecks = this.decks;
(g) => g.map((p) => path.basename(p, '.ydk'))
);
if (this.lastDeckFormat) { if (this.lastDeckFormat) {
const systemConfString = await this.load_system_conf(); const systemConfString = await this.load_system_conf();
...@@ -480,22 +510,41 @@ export class YGOProComponent implements OnInit, OnDestroy, AfterViewInit { ...@@ -480,22 +510,41 @@ export class YGOProComponent implements OnInit, OnDestroy, AfterViewInit {
const lastDeckMatch = systemConfString.match(this.lastDeckFormat); const lastDeckMatch = systemConfString.match(this.lastDeckFormat);
if (lastDeckMatch) { if (lastDeckMatch) {
lastDeck = lastDeckMatch[1]; lastDeck = lastDeckMatch[1];
// console.log(`Last deck ${lastDeck} read from ${this.system_conf}.`); console.log(`Last deck ${lastDeck} read from ${this.system_conf}.`);
} else { } else {
// console.error(`Deck pattern not found from pattern ${this.system_conf}: ${lastDeckMatch}`); console.error(`Deck pattern not found from pattern ${this.system_conf}: ${lastDeckMatch}`);
} }
} else { } else {
// console.error(`System conf ${this.system_conf} not found.`); console.error(`System conf ${this.system_conf} not found.`);
}
let lastCategory = '.';
if(systemConfString && this.lastCategoryFormat) {
const lastCategoryMatch = systemConfString.match(this.lastCategoryFormat);
if (lastCategoryMatch) {
lastCategory = lastCategoryMatch[1] || '.';
if (lastCategory === '未分类卡组' || lastCategory === '人机卡组') {
lastCategory = '.';
}
console.log(`Last category ${lastCategory} read from ${this.system_conf}.`);
} else {
console.error(`Category pattern not found from pattern ${this.system_conf}: ${lastCategoryMatch}`);
}
} }
if (lastDeck && this.decks.includes(lastDeck)) { const matchingDeck = allDecks.find(d => d.deck === lastDeck && d.category === lastCategory);
// console.log(`Got last deck ${lastDeck}.`); if (matchingDeck) {
this.current_deck = lastDeck; console.log(`Got last deck ${matchingDeck.category}/${matchingDeck.deck}.`);
this.currentDeck = matchingDeck;
} else if (init) {
console.log(`Last deck ${lastCategory}/${lastDeck} not found.`);
this.currentDeck = allDecks[0];
}
} else if (init) { } else if (init) {
this.current_deck = this.decks[0]; this.currentDeck = allDecks[0];
} }
console.log(this.current_deck); if(this.currentDeck) {
this.currentDeckSymbol = this.currentDeck.symbol;
} }
this.replays = await this.get_replays(); this.replays = await this.get_replays();
...@@ -515,15 +564,26 @@ export class YGOProComponent implements OnInit, OnDestroy, AfterViewInit { ...@@ -515,15 +564,26 @@ export class YGOProComponent implements OnInit, OnDestroy, AfterViewInit {
} }
} }
async get_decks(): Promise<string[]> { async get_decks(): Promise<DeckAndCategory[]> {
try { try {
return (await fg('**/*.ydk', { cwd: this.app.ygoproDeckPath })).map((d) => d.slice(0, -4)); return (await fg('**/*.ydk', { cwd: this.app.ygoproDeckPath })).map(path => this.getDeckObject(path));
} catch (error) { } catch (error) {
console.error(`Load deck fail: ${error.toString()}`); console.error(`Load deck fail: ${error.toString()}`);
return []; return [];
} }
} }
getDeckObject(deckPath: string) {
const deck = new DeckAndCategory();
deck.symbol = deckPath;
return deck;
}
deckGroup(): [string, DeckAndCategory[]][] {
const categorizedDecks = this.decks;
return Object.entries(_.groupBy(categorizedDecks, d => d.category));
}
async get_replays(): Promise<string[]> { async get_replays(): Promise<string[]> {
try { try {
let files: string[] = await fs.readdir(this.app.ygoproReplayPath!); let files: string[] = await fs.readdir(this.app.ygoproReplayPath!);
...@@ -588,32 +648,33 @@ export class YGOProComponent implements OnInit, OnDestroy, AfterViewInit { ...@@ -588,32 +648,33 @@ export class YGOProComponent implements OnInit, OnDestroy, AfterViewInit {
return fs.writeFile(this.system_conf, ini.unsafe(ini.stringify(data, <EncodeOptions>{whitespace: true}))); return fs.writeFile(this.system_conf, ini.unsafe(ini.stringify(data, <EncodeOptions>{whitespace: true})));
};*/ };*/
getDeckAndCategoryParam() {
const deck = this.currentDeck;
console.log(`Deck: ${deck.symbol}`)
return deck.param;
}
async join(name: string, server: Server) { async join(name: string, server: Server) {
/*let system_conf = await this.load_system_conf(); /*let system_conf = await this.load_system_conf();
await this.fix_fonts(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.lastip = server.address;
system_conf.lasthost = server.address; system_conf.lasthost = server.address;
system_conf.lastport = server.port.toString(); system_conf.lastport = server.port.toString();
system_conf.roompass = name; system_conf.roompass = name;
system_conf.nickname = this.loginService.user.username; system_conf.nickname = this.loginService.user.username;
await this.save_system_conf(system_conf);*/ 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(['-h', server.address, '-p', server.port.toString(), '-w', name, '-n', this.loginService.user.username, '-d', this.currentDeck, '-j']);
return this.start_game('main', { return this.start_game('main', { server, password: name, username: this.loginService.user.username, ...this.getDeckAndCategoryParam() });
server, };
password: name,
username: this.loginService.user.username,
deck: this.current_deck
});
}
async edit_deck(deck: string) { async edit_deck() {
/*let system_conf = await this.load_system_conf(); /*let system_conf = await this.load_system_conf();
await this.fix_fonts(system_conf); await this.fix_fonts(system_conf);
system_conf.lastdeck = deck; system_conf.lastdeck = deck;
await this.save_system_conf(system_conf);*/ await this.save_system_conf(system_conf);*/
// return this.start_game(['-d', deck]); // return this.start_game(['-d', deck]);
return this.start_game('deck', { deck }); return this.start_game('deck', this.getDeckAndCategoryParam());
} }
async watch_replay(replay: string) { 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