#4 done. added qbucks, monthly and alltime leaderboards

This commit is contained in:
2025-09-13 17:07:44 +02:00
parent 6a78a7dcea
commit a4f9767f8d
5 changed files with 137 additions and 1 deletions

View File

@@ -35,12 +35,22 @@ Not all Commands can be disabled, the `DISABLEABLE` field below shows if they ca
A full list of Commands can be found [here](#commands-1) A full list of Commands can be found [here](#commands-1)
### Timeouts and whispering messages ### Timeouts and ghost whispers
If you've been timed out, you can ghost whisper a message to the chatterbot and it will relay your message to the chat. If you've been timed out, you can ghost whisper a message to the chatterbot and it will relay your message to the chat.
You can only send one message every 10 minutes. You can only send one message every 10 minutes.
Try to bargain for your release with the chatter that shot you, or just call them names. Try to bargain for your release with the chatter that shot you, or just call them names.
### Leaderboards
There are 3 types of leaderboards: monthlyKD, alltimeKD and qbucks.
The monthlyKD leaderboard (command: `monthlykdleaderboard`) gives you the leaderboard of the top 5 user Kill/Death ratios for the current month.
The alltimeKD leaderboard (command: `alltimekdleaderboard`) gives you the leaderboard of the top 5 user Kill/Death ratios of all time in the channel.
the qbucks leaderboard (command: `qbucksleaderboard`) gives you the current leaderboard of the top 10 qbucks havers.
To appear on the KD leaderboards you need to have been timed out 5 times, in the specified timeframe.
Blasters, Grenade explosions and TNT explosions all count for the KD, Silver bullets do not.
### Items and Itemlock ### Items and Itemlock
Items are commands that can only be used when the chatter has them in their inventory. Items are commands that can only be used when the chatter has them in their inventory.
@@ -106,6 +116,9 @@ COMMAND|FUNCTION|USER|ALIASES|DISABLEABLE
`inventory [target]`|Get inventory contents of target or self|anyone|`inventory` `inv` `pocket`|:white_check_mark: `inventory [target]`|Get inventory contents of target or self|anyone|`inventory` `inv` `pocket`|:white_check_mark:
`give {target} {item} {amount}`|Give targeted user amount of items|anyone|`give`|:white_check_mark: `give {target} {item} {amount}`|Give targeted user amount of items|anyone|`give`|:white_check_mark:
`use {item} ...`|Use item. More info at [The items section](#items)|anyone|`use`|:x: `use {item} ...`|Use item. More info at [The items section](#items)|anyone|`use`|:x:
`monthlyleaderboard`|Get the K/D leaderboard for this month [(info)](#leaderboards)|anyone|`monthlyleaderboard` `kdleaderboard` `leaderboard`|:white_check_mark:
`alltimeleaderboard`|Get the K/D leaderboard of all time [(info)](#leaderboards)|anyone|`alltimeleaderboard` `alltimekdleaderboard`|:white_check_mark:
`qbucksleaderboard`|Get the current qbucks leaderboard [(info)](#leaderboards)|anyone|`qbucksleaderboard` `moneyleaderboard` `baltop`|:white_check_mark:
`admindonate {target} {amount}`|Gives the targeted user amount of qweribucks|admins|`admindonate`|:white_check_mark: `admindonate {target} {amount}`|Gives the targeted user amount of qweribucks|admins|`admindonate`|:white_check_mark:
`admingive {target} {item} {amount}`|Give targeted user amount of new items|admins|`admingive`|:white_check_mark: `admingive {target} {item} {amount}`|Give targeted user amount of new items|admins|`admingive`|:white_check_mark:

View File

@@ -0,0 +1,43 @@
import { Command, sendMessage } from "commands";
import { getAllUserRecords } from "db/dbUser";
import { getTimeoutStats } from "lib/getStats";
import User from "user";
type KD = { user: User; kd: number; };
export default new Command({
name: 'alltimekdleaderboard',
aliases: ['alltimeleaderboard', 'alltimekdleaderboard'],
usertype: 'chatter',
execution: async msg => {
const users = await getAllUserRecords();
if (!users) return;
const userKDs: KD[] = [];
await Promise.all(users.map(async userRecord => {
const user = await User.initUserId(userRecord.id);
if (!user) return;
const data = await getTimeoutStats(user, false);
if (!data) return;
if (data.hit.blaster < 5) return;
let kd = data.shot.blaster / data.hit.blaster;
if (isNaN(kd)) kd = 0;
userKDs.push({ user, kd });
}));
if (userKDs.length === 0) {
await sendMessage(`No users on leaderboard yet!`, msg.messageId);
return;
};
userKDs.sort((a, b) => b.kd - a.kd);
const txt: string[] = [];
for (let i = 0; i < (userKDs.length < 5 ? userKDs.length : 5); i++) {
txt.push(`${i + 1}. ${userKDs[i]?.user.displayName}: ${userKDs[i]?.kd.toFixed(2)}`);
};
await sendMessage(`Alltime leaderboard: ${txt.join(' | ')}`, msg.messageId);
}
});

View File

@@ -0,0 +1,43 @@
import { Command, sendMessage } from "commands";
import { getAllUserRecords } from "db/dbUser";
import { getTimeoutStats } from "lib/getStats";
import User from "user";
type KD = { user: User; kd: number; };
export default new Command({
name: 'monthlykdleaderboard',
aliases: ['monthlyleaderboard', 'kdleaderboard', 'leaderboard'],
usertype: 'chatter',
execution: async msg => {
const users = await getAllUserRecords();
if (!users) return;
const userKDs: KD[] = [];
await Promise.all(users.map(async userRecord => {
const user = await User.initUserId(userRecord.id);
if (!user) return;
const data = await getTimeoutStats(user, true);
if (!data) return;
if (data.hit.blaster < 5) return;
let kd = data.shot.blaster / data.hit.blaster;
if (isNaN(kd)) kd = 0;
userKDs.push({ user, kd });
}));
if (userKDs.length === 0) {
await sendMessage(`No users on leaderboard yet!`, msg.messageId);
return;
};
userKDs.sort((a, b) => b.kd - a.kd);
const txt: string[] = [];
for (let i = 0; i < (userKDs.length < 5 ? userKDs.length : 5); i++) {
txt.push(`${i + 1}. ${userKDs[i]?.user.displayName}: ${userKDs[i]?.kd.toFixed(2)}`);
};
await sendMessage(`Monthly leaderboard: ${txt.join(' | ')}`, msg.messageId);
}
});

View File

@@ -0,0 +1,25 @@
import { Command, sendMessage } from "commands";
import { getBalanceLeaderboard } from "db/dbUser";
import User from "user";
export default new Command({
name: 'qbucksleaderboard',
aliases: ['qbucksleaderboard', 'baltop', 'moneyleaderboard'],
usertype: 'chatter',
execution: async msg => {
const data = await getBalanceLeaderboard();
if (!data) return;
let index = 1;
const txt: string[] = [];
for (const userRecord of data) {
if (userRecord.balance === 0) continue;
const user = await User.initUserId(userRecord.id);
if (!user) continue;
txt.push(`${index}. ${user.displayName}: ${userRecord.balance}`);
index++;
};
await sendMessage(`Balance leaderboard: ${txt.join(' | ')}`, msg.messageId);
}
});

View File

@@ -23,6 +23,10 @@ export async function getUserRecord(user: User): Promise<userRecord> {
}; };
}; };
export async function getAllUserRecords(): Promise<userRecord[]> {
return await pb.getFullList();
};
async function createUserRecord(user: User): Promise<userRecord> { async function createUserRecord(user: User): Promise<userRecord> {
const data = await pb.create({ const data = await pb.create({
id: user.id, id: user.id,
@@ -44,3 +48,11 @@ export async function updateUserRecord(user: User, newData: userRecord): Promise
return false; return false;
}; };
}; };
export async function getBalanceLeaderboard() {
try {
return await pb.getList(1, 10, { sort: '-balance,id' }).then(a => a.items);
} catch (err) {
logger.err(err as string);
};
};