update: brawl stars player stats (WIP) & brawl stars player bind (2 DC user)
This commit is contained in:
parent
c2a48e6d5f
commit
e21628c09c
BIN
assets/brawl_logo.png
Normal file
BIN
assets/brawl_logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 138 KiB |
16
bun.lock
16
bun.lock
@ -12,7 +12,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "latest",
|
||||
"prisma": "^6.6.0",
|
||||
"prisma": "^6.7.0",
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "^5",
|
||||
@ -78,17 +78,17 @@
|
||||
|
||||
"@prisma/client": ["@prisma/client@6.6.0", "", { "peerDependencies": { "prisma": "*", "typescript": ">=5.1.0" }, "optionalPeers": ["prisma", "typescript"] }, "sha512-vfp73YT/BHsWWOAuthKQ/1lBgESSqYqAWZEYyTdGXyFAHpmewwWL2Iz6ErIzkj4aHbuc6/cGSsE6ZY+pBO04Cg=="],
|
||||
|
||||
"@prisma/config": ["@prisma/config@6.6.0", "", { "dependencies": { "esbuild": ">=0.12 <1", "esbuild-register": "3.6.0" } }, "sha512-d8FlXRHsx72RbN8nA2QCRORNv5AcUnPXgtPvwhXmYkQSMF/j9cKaJg+9VcUzBRXGy9QBckNzEQDEJZdEOZ+ubA=="],
|
||||
"@prisma/config": ["@prisma/config@6.7.0", "", { "dependencies": { "esbuild": ">=0.12 <1", "esbuild-register": "3.6.0" } }, "sha512-di8QDdvSz7DLUi3OOcCHSwxRNeW7jtGRUD2+Z3SdNE3A+pPiNT8WgUJoUyOwJmUr5t+JA2W15P78C/N+8RXrOA=="],
|
||||
|
||||
"@prisma/debug": ["@prisma/debug@6.6.0", "", {}, "sha512-DL6n4IKlW5k2LEXzpN60SQ1kP/F6fqaCgU/McgaYsxSf43GZ8lwtmXLke9efS+L1uGmrhtBUP4npV/QKF8s2ZQ=="],
|
||||
"@prisma/debug": ["@prisma/debug@6.7.0", "", {}, "sha512-RabHn9emKoYFsv99RLxvfG2GHzWk2ZI1BuVzqYtmMSIcuGboHY5uFt3Q3boOREM9de6z5s3bQoyKeWnq8Fz22w=="],
|
||||
|
||||
"@prisma/engines": ["@prisma/engines@6.6.0", "", { "dependencies": { "@prisma/debug": "6.6.0", "@prisma/engines-version": "6.6.0-53.f676762280b54cd07c770017ed3711ddde35f37a", "@prisma/fetch-engine": "6.6.0", "@prisma/get-platform": "6.6.0" } }, "sha512-nC0IV4NHh7500cozD1fBoTwTD1ydJERndreIjpZr/S3mno3P6tm8qnXmIND5SwUkibNeSJMpgl4gAnlqJ/gVlg=="],
|
||||
"@prisma/engines": ["@prisma/engines@6.7.0", "", { "dependencies": { "@prisma/debug": "6.7.0", "@prisma/engines-version": "6.7.0-36.3cff47a7f5d65c3ea74883f1d736e41d68ce91ed", "@prisma/fetch-engine": "6.7.0", "@prisma/get-platform": "6.7.0" } }, "sha512-3wDMesnOxPrOsq++e5oKV9LmIiEazFTRFZrlULDQ8fxdub5w4NgRBoxtWbvXmj2nJVCnzuz6eFix3OhIqsZ1jw=="],
|
||||
|
||||
"@prisma/engines-version": ["@prisma/engines-version@6.6.0-53.f676762280b54cd07c770017ed3711ddde35f37a", "", {}, "sha512-JzRaQ5Em1fuEcbR3nUsMNYaIYrOT1iMheenjCvzZblJcjv/3JIuxXN7RCNT5i6lRkLodW5ojCGhR7n5yvnNKrw=="],
|
||||
"@prisma/engines-version": ["@prisma/engines-version@6.7.0-36.3cff47a7f5d65c3ea74883f1d736e41d68ce91ed", "", {}, "sha512-EvpOFEWf1KkJpDsBCrih0kg3HdHuaCnXmMn7XFPObpFTzagK1N0Q0FMnYPsEhvARfANP5Ok11QyoTIRA2hgJTA=="],
|
||||
|
||||
"@prisma/fetch-engine": ["@prisma/fetch-engine@6.6.0", "", { "dependencies": { "@prisma/debug": "6.6.0", "@prisma/engines-version": "6.6.0-53.f676762280b54cd07c770017ed3711ddde35f37a", "@prisma/get-platform": "6.6.0" } }, "sha512-Ohfo8gKp05LFLZaBlPUApM0M7k43a0jmo86YY35u1/4t+vuQH9mRGU7jGwVzGFY3v+9edeb/cowb1oG4buM1yw=="],
|
||||
"@prisma/fetch-engine": ["@prisma/fetch-engine@6.7.0", "", { "dependencies": { "@prisma/debug": "6.7.0", "@prisma/engines-version": "6.7.0-36.3cff47a7f5d65c3ea74883f1d736e41d68ce91ed", "@prisma/get-platform": "6.7.0" } }, "sha512-zLlAGnrkmioPKJR4Yf7NfW3hftcvqeNNEHleMZK9yX7RZSkhmxacAYyfGsCcqRt47jiZ7RKdgE0Wh2fWnm7WsQ=="],
|
||||
|
||||
"@prisma/get-platform": ["@prisma/get-platform@6.6.0", "", { "dependencies": { "@prisma/debug": "6.6.0" } }, "sha512-3qCwmnT4Jh5WCGUrkWcc6VZaw0JY7eWN175/pcb5Z6FiLZZ3ygY93UX0WuV41bG51a6JN/oBH0uywJ90Y+V5eA=="],
|
||||
"@prisma/get-platform": ["@prisma/get-platform@6.7.0", "", { "dependencies": { "@prisma/debug": "6.7.0" } }, "sha512-i9IH5lO4fQwnMLvQLYNdgVh9TK3PuWBfQd7QLk/YurnAIg+VeADcZDbmhAi4XBBDD+hDif9hrKyASu0hbjwabw=="],
|
||||
|
||||
"@puppeteer/browsers": ["@puppeteer/browsers@2.10.2", "", { "dependencies": { "debug": "^4.4.0", "extract-zip": "^2.0.1", "progress": "^2.0.3", "proxy-agent": "^6.5.0", "semver": "^7.7.1", "tar-fs": "^3.0.8", "yargs": "^17.7.2" }, "bin": { "browsers": "lib/cjs/main-cli.js" } }, "sha512-i4Ez+s9oRWQbNjtI/3+jxr7OH508mjAKvza0ekPJem0ZtmsYHP3B5dq62+IaBHKaGCOuqJxXzvFLUhJvQ6jtsQ=="],
|
||||
|
||||
@ -230,7 +230,7 @@
|
||||
|
||||
"picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
|
||||
|
||||
"prisma": ["prisma@6.6.0", "", { "dependencies": { "@prisma/config": "6.6.0", "@prisma/engines": "6.6.0" }, "optionalDependencies": { "fsevents": "2.3.3" }, "peerDependencies": { "typescript": ">=5.1.0" }, "optionalPeers": ["typescript"], "bin": { "prisma": "build/index.js" } }, "sha512-SYCUykz+1cnl6Ugd8VUvtTQq5+j1Q7C0CtzKPjQ8JyA2ALh0EEJkMCS+KgdnvKW1lrxjtjCyJSHOOT236mENYg=="],
|
||||
"prisma": ["prisma@6.7.0", "", { "dependencies": { "@prisma/config": "6.7.0", "@prisma/engines": "6.7.0" }, "optionalDependencies": { "fsevents": "2.3.3" }, "peerDependencies": { "typescript": ">=5.1.0" }, "optionalPeers": ["typescript"], "bin": { "prisma": "build/index.js" } }, "sha512-vArg+4UqnQ13CVhc2WUosemwh6hr6cr6FY2uzDvCIFwH8pu8BXVv38PktoMLVjtX7sbYThxbnZF5YiR8sN2clw=="],
|
||||
|
||||
"progress": ["progress@2.0.3", "", {}, "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="],
|
||||
|
||||
|
@ -1 +1 @@
|
||||
[{"name":"mcs","type":1,"nsfw":false,"description":"Qeury a Minecraft server","contexts":[0,1,2],"integration_types":[0],"options":[{"name":"ip","description":"Server IP","type":3,"name_localizations":{},"description_localizations":{},"autocomplete":false},{"name":"port","description":"Server Port","type":10,"name_localizations":{},"description_localizations":{},"autocomplete":false}]},{"name":"ping","type":1,"nsfw":false,"description":"Show latency with Discord","contexts":[0,1,2],"integration_types":[0],"options":[]}]
|
||||
[{"name":"mcs","type":1,"nsfw":false,"description":"Qeury a Minecraft server","contexts":[0,1,2],"integration_types":[0],"options":[{"name":"ip","description":"Server IP","type":3,"name_localizations":{},"description_localizations":{},"autocomplete":false},{"name":"port","description":"Server Port","type":10,"name_localizations":{},"description_localizations":{},"autocomplete":false}]},{"name":"brawlbind","type":1,"nsfw":false,"description":"Associate your Discord account with your Brawl Stars account","contexts":[0,1,2],"integration_types":[0],"options":[{"name":"playertag","description":"Your Brawl Stars player tag","required":true,"type":3,"name_localizations":{},"description_localizations":{},"autocomplete":false}]},{"name":"ping","type":1,"nsfw":false,"description":"Show latency with Discord","contexts":[0,1,2],"integration_types":[0],"options":[]},{"name":"brawlstats","type":1,"nsfw":false,"description":"Query your Brawl Stars player stats","contexts":[0,1,2],"integration_types":[0],"options":[]}]
|
@ -5,10 +5,10 @@
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
"@types/bun": "latest",
|
||||
"prisma": "^6.6.0"
|
||||
"prisma": "^6.7.0"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "bun --env-file=.env --hot src/index.ts"
|
||||
"dev": "bun --env-file=.env --watch src/index.ts"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "^5"
|
||||
|
@ -22,3 +22,12 @@ model mcsBind {
|
||||
@@map("mcs_binds")
|
||||
@@index([channelId])
|
||||
}
|
||||
|
||||
model brawlPlayer {
|
||||
id String @id @default(auto()) @map("_id") @db.ObjectId
|
||||
userId String
|
||||
playerTag String
|
||||
|
||||
@@map("brawl_players")
|
||||
@@index([userId])
|
||||
}
|
86
src/commands/brawlBind.ts
Normal file
86
src/commands/brawlBind.ts
Normal file
@ -0,0 +1,86 @@
|
||||
import {
|
||||
Command,
|
||||
Declare,
|
||||
Options,
|
||||
createStringOption,
|
||||
type CommandContext
|
||||
} from 'seyfert';
|
||||
|
||||
import { prisma } from '..';
|
||||
|
||||
const options = {
|
||||
playertag: createStringOption({
|
||||
description: 'Your Brawl Stars player tag',
|
||||
required: true,
|
||||
}),
|
||||
}
|
||||
|
||||
@Declare({
|
||||
name: 'brawlbind',
|
||||
description: 'Associate your Discord account with your Brawl Stars account',
|
||||
})
|
||||
@Options(options)
|
||||
export default class brawlBindCommand extends Command {
|
||||
async run(ctx: CommandContext<typeof options>) {
|
||||
let tag = ctx.options.playertag
|
||||
if (!tag.startsWith("#")) tag = "#" + tag
|
||||
const playerTagRegex = /^#[0-9A-Z]{6,10}$/
|
||||
if (!playerTagRegex.test(ctx.options.playertag)) {
|
||||
await ctx.write({
|
||||
content: 'Invalid player tag (Example: `#A1B2C3D4E`)'
|
||||
})
|
||||
return
|
||||
}
|
||||
const userId: string = ctx.author.id
|
||||
console.log(tag + `\n` + userId)
|
||||
const res = await prisma.brawlPlayer.findFirst({
|
||||
where: {
|
||||
userId: userId
|
||||
}
|
||||
})
|
||||
if (res && res.playerTag !== tag) {
|
||||
try {
|
||||
await prisma.brawlPlayer.update({
|
||||
where: {
|
||||
id: res.id,
|
||||
userId: userId
|
||||
},
|
||||
data: {
|
||||
playerTag: tag
|
||||
}
|
||||
})
|
||||
} catch (e) {
|
||||
await ctx.write({
|
||||
content: `${e}`
|
||||
})
|
||||
return
|
||||
}
|
||||
await ctx.write({
|
||||
content: `Updated your playertag from ${res.playerTag} to \`${tag}\``
|
||||
})
|
||||
return
|
||||
} else if (res && res.playerTag === tag) {
|
||||
await ctx.write({
|
||||
content: `Nothing Changed, playertag already associated to \`${tag}\``
|
||||
})
|
||||
}
|
||||
if (!res) {
|
||||
try {
|
||||
await prisma.brawlPlayer.create({
|
||||
data: {
|
||||
userId: userId,
|
||||
playerTag: tag
|
||||
}
|
||||
})
|
||||
} catch (e) {
|
||||
await ctx.write({
|
||||
content: `${e}`
|
||||
})
|
||||
}
|
||||
await ctx.write({
|
||||
content: `Associated to your playertag \`${tag}\``
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
143
src/commands/brawlStats.ts
Normal file
143
src/commands/brawlStats.ts
Normal file
@ -0,0 +1,143 @@
|
||||
import {
|
||||
AttachmentBuilder,
|
||||
Command,
|
||||
Declare,
|
||||
Embed,
|
||||
Options,
|
||||
createStringOption,
|
||||
type CommandContext
|
||||
} from 'seyfert';
|
||||
|
||||
import { prisma, browser } from '..';
|
||||
|
||||
interface BrawlPlayer {
|
||||
name: string;
|
||||
tag: string;
|
||||
namecolor: string;
|
||||
nameColor: string;
|
||||
icon: any;
|
||||
trophies: number;
|
||||
highestTrophies: number;
|
||||
expLevel: number;
|
||||
expPoints: number;
|
||||
isQualifiedFromChampionshipChallenge: boolean;
|
||||
"3vs3Victories": number;
|
||||
soloVictories: number;
|
||||
duoVictories: number;
|
||||
bestRoboRumbleTime: number;
|
||||
bestTimeAsBigBrawler: number;
|
||||
club: any;
|
||||
brawlers: any[];
|
||||
}
|
||||
|
||||
@Declare({
|
||||
name: 'brawlstats',
|
||||
description: 'Query your Brawl Stars player stats'
|
||||
})
|
||||
|
||||
export default class brawlStatsCommand extends Command {
|
||||
async run(ctx: CommandContext) {
|
||||
const res = await prisma.brawlPlayer.findFirst({
|
||||
where: {
|
||||
userId: ctx.author.id
|
||||
}
|
||||
})
|
||||
if (!res) {
|
||||
await ctx.write({
|
||||
content: `Your Discord account has not associated to a Brawl Stars playertag, use \`brawlbind\` to associate`
|
||||
})
|
||||
return
|
||||
}
|
||||
let tag = res.playerTag.replace('#', '%23')
|
||||
const data = await fetchBrawlPlayer(tag) as BrawlPlayer
|
||||
if (!data || data === null) {
|
||||
await ctx.write({
|
||||
content: `ERROR, CONTACT ADMIN`
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
const page = await browser.newPage();
|
||||
const result = generateBrawlStatsHtml(data)
|
||||
|
||||
await page.setViewport({ width: 650, height: 200 })
|
||||
await page.setContent(result)
|
||||
await page.waitForSelector('body')
|
||||
const screenshot = await page.screenshot({
|
||||
encoding: 'base64',
|
||||
type: 'webp',
|
||||
fullPage: true
|
||||
})
|
||||
await page.close()
|
||||
|
||||
const buffer = Buffer.from(screenshot, 'base64')
|
||||
await ctx.write({
|
||||
files: [
|
||||
new AttachmentBuilder()
|
||||
.setName('brawlstats.png')
|
||||
.setFile('buffer', buffer)
|
||||
]
|
||||
});
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
function generateBrawlStatsHtml(data: BrawlPlayer): string {
|
||||
const stats = [
|
||||
`Player: ${data.name}`,
|
||||
`Trophies: ${data.trophies}`,
|
||||
`3vs3 Victories: ${data['3vs3Victories']}`,
|
||||
`Solo Victories: ${data.soloVictories}`,
|
||||
`Duo Victories: ${data.duoVictories}`,
|
||||
`Total Brawlers: ${data.brawlers.length}`
|
||||
].join('<br>')
|
||||
|
||||
return `
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=auto, initial-scale=1.0">
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<style>
|
||||
body {
|
||||
background-color: #1e1e2e;
|
||||
color: #cdd6f4;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body style="width: 650px">
|
||||
<div class="container mx-auto py-4">
|
||||
<div class="px-6 flex items-center">
|
||||
<img src="https://cdn-assets-eu.frontify.com/s3/frontify-enterprise-files-eu/eyJwYXRoIjoic3VwZXJjZWxsXC9maWxlXC9WeGZCYTJZM2VidFliNHhRNDJhdS5wbmcifQ:supercell:4JRrhrJjKTux8065H80-L2EiHN2bJg9E9QuhQD9ztIs?width=2400" class="h-32 w-32 object-contain mr-6" alt="Brawl Stars Logo" />
|
||||
<div class="text-lg font-bold text-[#cdd6f4]">${stats}</div>
|
||||
</div>
|
||||
</div>
|
||||
<footer class="bg-[#313244] text-center py-2">
|
||||
<p class="text-sm text-[#cdd6f4]">Generated by Fantastic Spoon - Discord</p>
|
||||
<p class="text-sm text-[#cdd6f4]">Open Sourced on git.itzdrli.cc © 2025 itzdrli - All Rights Reserved. </p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>`;
|
||||
}
|
||||
|
||||
async function fetchBrawlPlayer(playerTag: string) {
|
||||
const brawlUrl = `https://api.brawlstars.com/v1/players/${playerTag}`
|
||||
try {
|
||||
const res = await fetch(brawlUrl, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${process.env.BRAWL_KEY}`,
|
||||
'Accept': 'application/json'
|
||||
}
|
||||
})
|
||||
if (!res.ok) {
|
||||
console.error(`Error fetching Brawl Stars player data: ${res.statusText}`)
|
||||
return null
|
||||
}
|
||||
return res.json()
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
return null
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user