Skip to content

Commit

Permalink
Add ability to pause your bots
Browse files Browse the repository at this point in the history
  • Loading branch information
StanislavNikolov committed Aug 14, 2023
1 parent eeebe28 commit 82ef5f5
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 25 deletions.
5 changes: 4 additions & 1 deletion backend/arena.ts
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ async function pickBotByNumberOfGamesPlayed(): Promise<number> {
const stats = await sql`
SELECT bots.id, LEAST(COUNT(*), 100)::int AS cnt FROM bots
LEFT JOIN games ON games.wid = bots.id OR games.bid = bots.id
WHERE paused = FALSE
GROUP BY bots.id
ORDER BY cnt
` as { id: number, cnt: number }[];
Expand All @@ -260,7 +261,9 @@ async function pickBotThatHasCloseElo(otherBotId: number): Promise<number> {
const otherElo = await getElo(otherBotId);
const stats = await sql`
SELECT bot_id, coalesce(SUM(change), 0)::int AS elo
FROM elo_updates WHERE bot_id != ${otherBotId}
FROM elo_updates
JOIN bots ON bots.id = bot_id
WHERE bot_id != ${otherBotId} AND paused = FALSE
GROUP BY bot_id
` as { bot_id: number, elo: number }[];

Expand Down
4 changes: 4 additions & 0 deletions backend/db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ await sql`
);
`;

await sql`
ALTER TABLE bots ADD COLUMN IF NOT EXISTS paused BOOLEAN DEFAULT FALSE;
`;

await sql`
CREATE TABLE IF NOT EXISTS games (
id SERIAL PRIMARY KEY,
Expand Down
16 changes: 15 additions & 1 deletion backend/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,14 +115,15 @@ app.get('/api/my-bots/', async c => {
const dev = await sql`SELECT devs.id, devs.name, devs.email FROM devs JOIN dev_tokens ON dev_tokens.dev_id = devs.id WHERE token = ${token}`;
if (dev.length == 0) return c.json({ bots: [] });

const bots = await sql`SELECT bots.id FROM bots WHERE dev_id = ${dev[0].id}`;
const bots = await sql`SELECT bots.id FROM bots WHERE paused = FALSE AND dev_id = ${dev[0].id}`;
return c.json({ id: dev[0].id, name: dev[0].name, email: dev[0].email, bots: bots.map(({id}) => id) });
});

app.get("/api/bots/", async c => {
const bots = await sql`
SELECT bots.id, name, SUM(change)::float AS elo FROM bots
LEFT JOIN elo_updates ON elo_updates.bot_id = bots.id
WHERE paused = FALSE
GROUP BY bots.id
ORDER BY elo DESC
`;
Expand Down Expand Up @@ -207,12 +208,25 @@ app.get("/api/bot/:botId/", async c => {
return c.json(bot);
});

app.delete("/api/bot/:botId/", async c => {
const token = getCookie(c, 'token');
if (!token) return c.text('Not logged in', 401);

const { botId } = c.req.param();
const res = await sql`SELECT bots.id FROM bots JOIN dev_tokens ON dev_tokens.dev_id = bots.dev_id WHERE token = ${token} AND bots.id = ${botId}`;
if (res.length === 0) return c.text('Not your bot', 401);

await sql`UPDATE bots SET paused = TRUE WHERE id = ${botId}`;
return c.text('');
});

app.get("/api/devs/", async c => {
const devs = await sql`
SELECT devs.id, devs.name, MAX(b.elo) as elo FROM devs
JOIN (
SELECT bots.id, name, SUM(change)::float AS elo, dev_id FROM bots
LEFT JOIN elo_updates ON elo_updates.bot_id = bots.id
WHERE paused = FALSE
GROUP BY bots.id
ORDER BY elo DESC
) b ON b.dev_id = devs.id
Expand Down
47 changes: 37 additions & 10 deletions frontend/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ interface Bot {
name: string;
elo: number;
};

let globalBots: Bot[] = [];

function renderLeaderboardItem(place: number, name: string, elo: number, href: string) {
let icon = `<b>${place}</b>`
Expand All @@ -54,6 +54,24 @@ function renderLeaderboardItem(place: number, name: string, elo: number, href: s
`;
}

function renderEditableLeaderboardItem(place: number, name: string, elo: number, id: number, href: string) {
let icon = `<b>${place}</b>`
if (place <= 3) {
icon = `<img src="/public/medal-${place}.svg"></img>`
}

return `
<div class="my-bot" href="${href}" data-bot-id="${id}">
<a href="${href}" class="leaderboard-item">
<span class="place">${icon}</span>
<span>${sanitizeHTML(name)}</span>
<span class="elo">${elo.toFixed(0)} ELO</span>
</a>
<a class="delete">❌</a>
</div>
`;
}

function renderOldGame(g: OldGame) {
return `
<a class="game" href="/game/${g.id}/">
Expand All @@ -79,22 +97,24 @@ function renderLiveGame(g) {
`;
}

async function updateBotLeaderboard() {
const req = await fetch('/api/bots/')
const bots = await req.json() as Bot[];

$("#bot-list").innerHTML = bots
function rerenderAllBots() {
$("#bot-list").innerHTML = globalBots
.map((bot, idx) => renderLeaderboardItem(idx + 1, bot.name, bot.elo, `/bot/${bot.id}/`))
.join('');

if (globalMyBots.id != null) {
$("#my-bot-list").innerHTML = bots
$("#my-bot-list").innerHTML = globalBots
.map((bot, idx) => { bot.origIdx = idx; return bot; })
.filter(b => globalMyBots.bots.includes(b.id))
.map(bot => renderLeaderboardItem(bot.origIdx + 1, bot.name, bot.elo, `/bot/${bot.id}/`))
.map(bot => renderEditableLeaderboardItem(bot.origIdx + 1, bot.name, bot.elo, bot.id, `/bot/${bot.id}/`))
.join('');
}
}

async function updateBotLeaderboard() {
const req = await fetch('/api/bots/')
globalBots = await req.json() as Bot[];
rerenderAllBots();
setTimeout(updateBotLeaderboard, 2000);
}

Expand Down Expand Up @@ -158,10 +178,8 @@ async function updateLiveGames() {
async function updateMyBots() {
const req = await fetch('/api/my-bots/')
globalMyBots = await req.json();
console.log(globalMyBots);

if (!globalMyBots.id) {
console.log('asd')
$("#my-bot-list").innerHTML = `
<div id="login-info"> If you have uploaded any bots, <a id="login-txt">click here</a> to log in and see them.</div>`;

Expand All @@ -172,6 +190,8 @@ async function updateMyBots() {
$("input[name='devname']").disabled = true;
$("input[name='email']").value = globalMyBots.email;
$("input[name='email']").disabled = true;

rerenderAllBots();
}
}

Expand Down Expand Up @@ -217,4 +237,11 @@ $("form").addEventListener("submit", async (ev) => {

$("#faq-btn").addEventListener("click", () => {
$("#faq").showModal();
});

$("#my-bot-list").addEventListener("click", async (ev) => {
if (!ev.target.classList.contains("delete")) return;
const botId = ev.target?.closest(".my-bot").getAttribute("data-bot-id");
await fetch(`/api/bot/${botId}/`, { method: "DELETE" });
await updateMyBots();
});
35 changes: 22 additions & 13 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -67,19 +67,21 @@
flex-direction: column;
}

.my-bot {
display: flex;
align-items: center;
}

.leaderboard-item {
display: flex;
align-items: center;
background-color: var(--hl-color);
padding: 4px;
margin: 4px 2px;
margin: 4px 4px;
border-radius: 4px;
text-decoration: none;
color: #7a4e3c;
}
.leaderboard-item:hover {
cursor: pointer;
background-color: #ddc1a7;
flex-grow: 1;
}
.place {
display: inline-block;
Expand All @@ -98,6 +100,16 @@
margin-left: auto;
font-size: smaller;
}
.delete {
background-color: var(--hl-color);
padding: 4px 8px;
font-size: smaller;
border-radius: 4px;
height: calc(2rem);
align-items: center;
display: flex;
text-decoration: none;
}

h2 {
text-align: center;
Expand All @@ -120,12 +132,6 @@
background-repeat: no-repeat;
background-size: cover;
background-position: center;

/* display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
color: #ecc39f; */
}

#side-links {
Expand Down Expand Up @@ -193,9 +199,12 @@
border-radius: 4px;
border-bottom: 1px solid var(--hl-color);
}
.game:hover {
background-color: #ddc1a7;

.game:hover, .leaderboard-item:hover, .delete:hover {
cursor: pointer;
background-color: var(--hover-color)
}

.bot {
display: inline-block;
width: 50%;
Expand Down

0 comments on commit 82ef5f5

Please sign in to comment.