diff --git a/src/app/pages/tournaments/tournaments.component.html b/src/app/pages/tournaments/tournaments.component.html
index 6ce1fe6..b611ae9 100644
--- a/src/app/pages/tournaments/tournaments.component.html
+++ b/src/app/pages/tournaments/tournaments.component.html
@@ -192,12 +192,12 @@
Join with a bot
-
Select one of your bots to enter this tournament. Its token will be rotated to authenticate the join.
+ Select an official (engine-backed) bot to enter this tournament. These are the bots that actually play their moves.
@if (botsLoading) {
Loading bots…
} @else if (userBots.length === 0) {
- You have no bots yet. Go to Bots in the nav to create one first.
+ No official bots are available. The official-bots engine service must be running to register them.
} @else {
@for (bot of userBots; track bot.id) {
diff --git a/src/app/pages/tournaments/tournaments.component.ts b/src/app/pages/tournaments/tournaments.component.ts
index adfbd83..cd60d7b 100644
--- a/src/app/pages/tournaments/tournaments.component.ts
+++ b/src/app/pages/tournaments/tournaments.component.ts
@@ -158,7 +158,7 @@ export class TournamentsComponent implements OnInit {
this.joinDialogTournamentId = tournamentId;
this.joinError = null;
this.botsLoading = true;
- this.botService.list()
+ this.botService.listOfficial()
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe({
next: bots => { this.userBots = bots; this.botsLoading = false; },
@@ -176,30 +176,22 @@ export class TournamentsComponent implements OnInit {
if (!this.joinDialogTournamentId || this.joiningBotId) return;
this.joiningBotId = bot.id;
this.joinError = null;
- this.botService.rotateToken(bot.id).subscribe({
- next: token => {
- this.tournamentService.joinWithBotToken(this.joinDialogTournamentId!, token).subscribe({
- next: () => {
- this.joiningBotId = null;
- const tid = this.joinDialogTournamentId!;
- this.closeJoinDialog();
- this.tournamentService.get(tid)
- .pipe(takeUntilDestroyed(this.destroyRef))
- .subscribe(updated => {
- this.created = this.created.map(x => x.id === tid ? updated : x);
- this.started = this.started.map(x => x.id === tid ? updated : x);
- if (this.selectedTournament?.id === tid) this.selectedTournament = updated;
- });
- },
- error: err => {
- this.joiningBotId = null;
- this.joinError = err.error?.message ?? err.error?.error ?? 'Failed to join tournament.';
- }
- });
- },
- error: () => {
+ this.tournamentService.join(this.joinDialogTournamentId, bot.id, bot.name).subscribe({
+ next: () => {
this.joiningBotId = null;
- this.joinError = 'Failed to get bot token.';
+ const tid = this.joinDialogTournamentId!;
+ this.closeJoinDialog();
+ this.tournamentService.get(tid)
+ .pipe(takeUntilDestroyed(this.destroyRef))
+ .subscribe(updated => {
+ this.created = this.created.map(x => x.id === tid ? updated : x);
+ this.started = this.started.map(x => x.id === tid ? updated : x);
+ if (this.selectedTournament?.id === tid) this.selectedTournament = updated;
+ });
+ },
+ error: err => {
+ this.joiningBotId = null;
+ this.joinError = err.error?.message ?? err.error?.error ?? 'Failed to join tournament.';
}
});
}
diff --git a/src/app/services/bot.service.ts b/src/app/services/bot.service.ts
index fa77c29..47b04f8 100644
--- a/src/app/services/bot.service.ts
+++ b/src/app/services/bot.service.ts
@@ -7,11 +7,16 @@ import { Bot, BotWithToken } from '../models/bot.models';
export class BotService {
private readonly http = inject(HttpClient);
private readonly base = '/api/account/bots';
+ private readonly officialBase = '/api/account/official-bots';
list(): Observable {
return this.http.get(this.base);
}
+ listOfficial(): Observable {
+ return this.http.get(this.officialBase);
+ }
+
create(name: string): Observable {
return this.http.post(this.base, { name });
}
diff --git a/src/app/services/tournament.service.ts b/src/app/services/tournament.service.ts
index 493d400..289a27d 100644
--- a/src/app/services/tournament.service.ts
+++ b/src/app/services/tournament.service.ts
@@ -40,10 +40,8 @@ export class TournamentService {
return this.http.post(`${this.base}/${id}/start`, null);
}
- joinWithBotToken(id: string, botToken: string): Observable {
- return this.http.post(`${this.base}/${id}/join`, null, {
- headers: new HttpHeaders({ Authorization: `Bearer ${botToken}` })
- });
+ join(id: string, botId: string, botName: string): Observable {
+ return this.http.post(`${this.base}/${id}/join`, { botId, botName });
}
roundPairings(id: string, round: number): Observable {