Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 34 additions & 2 deletions frontend/src/components/BotList.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ let {
orangePlayers = $bindable(),
map,
duplicateAgentIds = new Set<string>(),
getLatestBotInfo,
getLatestScriptInfo,
}: {
bots: DraggablePlayer[];
scripts: ToggleableScript[];
Expand All @@ -43,6 +45,8 @@ let {
orangePlayers: DraggablePlayer[];
map: string;
duplicateAgentIds: Set<string>;
getLatestBotInfo?: (tomlPath: string) => Promise<BotInfo | null>;
getLatestScriptInfo?: (tomlPath: string) => Promise<BotInfo | null>;
} = $props();
const flipDurationMs = 100;

Expand Down Expand Up @@ -250,14 +254,42 @@ function toggleScript(id: string) {
enabledScripts[id] = !enabledScripts[id];
}

function handleBotInfoClick(bot: DraggablePlayer) {
async function handleBotInfoClick(bot: DraggablePlayer) {
if (bot.info instanceof BotInfo) {

try {
if (getLatestBotInfo) {
const refreshed = await getLatestBotInfo(bot.info.tomlPath);
if (refreshed) {
selectedAgent = [refreshed, refreshed.config?.settings?.name ?? bot.displayName, (refreshed as any).icon ?? bot.icon];
showInfoModal = true;
return;
}
}
} catch (err) {
toast.error("Failed to get latest bot info: " + err, { duration: 10000 });
}

selectedAgent = [bot.info, bot.displayName, bot.icon];
showInfoModal = true;
}
}

function handleScriptInfoClick(script: ToggleableScript) {
async function handleScriptInfoClick(script: ToggleableScript) {

try {
if (getLatestScriptInfo) {
const refreshed = await getLatestScriptInfo(script.info.tomlPath);
if (refreshed) {
selectedAgent = [refreshed, refreshed.config?.settings?.name ?? script.displayName, (refreshed as any).icon ?? script.icon];
showInfoModal = true;
return;
}
}
} catch (err) {
toast.error("Failed to get latest script info: " + err, { duration: 10000 });
}

selectedAgent = [script.info, script.displayName, script.icon];
showInfoModal = true;
}
Expand Down
97 changes: 97 additions & 0 deletions frontend/src/pages/Home.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,79 @@ async function updateScripts() {
loadingScripts = false;
}

async function getLatestBotInfo(tomlPath: string): Promise<BotInfo | null> {
try {
const result = await App.GetBots([tomlPath]);

const found = result.find((b) => b.tomlPath === tomlPath);
if (!found) return null; // No bot found

const botInfo = new BotInfo(found);

const index = players.findIndex(
(p) => p.info instanceof BotInfo && p.info.tomlPath === tomlPath,
);

if (index !== -1) {
players[index] = {
...players[index],
displayName: found.config.settings.name,
icon: found.icon,
info: botInfo,
tags: found.config.details.tags,
};

players = [...players];
bluePlayers = updateTeam(bluePlayers);
orangePlayers = updateTeam(orangePlayers);
}

return botInfo;
} catch (err) {
console.error("Failed to get latest bot info: ", err);
return null;
}
}

async function getLatestScriptInfo(tomlPath: string): Promise<BotInfo | null> {
try {
const result = await App.GetScripts([tomlPath]);

const found = result.find((s) => s.tomlPath === tomlPath);
if (!found) return null; // No script found

const index = scripts.findIndex((s) => s.info.tomlPath === tomlPath);

if (index !== -1) {
const oldAgentId = scripts[index].info.config.settings.agentId;
const newAgentId = found.config.settings.agentId;

scripts[index] = {
...scripts[index],
displayName: found.config.settings.name,
icon: found.config.settings.logoFile,
info: found,
tags: found.config.details.tags,
};

scripts = [...scripts];

if (enabledScripts[newAgentId] === undefined) {
enabledScripts[newAgentId] = false;
}

if (oldAgentId !== newAgentId && enabledScripts[oldAgentId] === undefined) {
enabledScripts[oldAgentId] = false;
}
}

return found;
} catch (err) {
console.error("Failed to get latest script info: ", err);
return null;
}
}

$effect(() => {
localStorage.setItem("BOT_SEARCH_PATHS", JSON.stringify(paths));
updateBots();
Expand Down Expand Up @@ -373,6 +446,28 @@ async function onMatchStart(randomizeMap: boolean) {
];
}

// Update bots and scripts
const botsInMatch = [
...new Set(
[...bluePlayers, ...orangePlayers]
.filter((p) => p.info instanceof BotInfo)
.map((p) => (p.info as BotInfo).tomlPath),
),
];

const scriptsInMatch = [
...new Set(
scripts // We could reuse this for StartMatchOptions, and not map twice
.filter((x) => enabledScripts[x.info.config.settings.agentId])
.map((x) => x.info.tomlPath),
),
];

await Promise.all([
...botsInMatch.map((tomlPath) => getLatestBotInfo(tomlPath)),
...scriptsInMatch.map((tomlPath) => getLatestScriptInfo(tomlPath)),
]);

const options: StartMatchOptions = {
map: $mapStore,
gameMode: mode,
Expand Down Expand Up @@ -476,6 +571,8 @@ function handleSearch(event: Event) {
selectedTeam={selectedTeam}
map={$mapStore}
{duplicateAgentIds}
getLatestBotInfo={getLatestBotInfo}
getLatestScriptInfo={getLatestScriptInfo}
/>
</div>

Expand Down