This commit is contained in:
Hri7566 2024-09-15 18:19:17 -04:00
parent 0456fd9226
commit ee3629faa6
13 changed files with 175 additions and 65 deletions

BIN
bun.lockb

Binary file not shown.

View File

@ -8,22 +8,22 @@
"start-discord": "bun src/discord/index.ts"
},
"devDependencies": {
"@types/bun": "^1.1.6"
"@types/bun": "^1.1.9"
},
"peerDependencies": {
"typescript": "^5.3.3"
},
"dependencies": {
"@prisma/client": "^5.16.1",
"@prisma/client": "^5.19.1",
"@trpc/client": "next",
"@trpc/server": "next",
"@types/node": "^20.14.10",
"@types/node": "^20.16.5",
"cli-markdown": "^3.4.0",
"discord.js": "^14.15.3",
"mpp-client-net": "^1.2.0",
"prisma": "^5.16.1",
"trpc-bun-adapter": "^1.1.1",
"yaml": "^2.4.5",
"discord.js": "^14.16.2",
"mpp-client-net": "^1.2.3",
"prisma": "^5.19.1",
"trpc-bun-adapter": "^1.1.2",
"yaml": "^2.5.1",
"zod": "^3.23.8"
}
}

View File

@ -25,6 +25,7 @@ import { fid } from "./util/fid";
import { chance } from "./util/chance";
import { info } from "./general/info";
import { burger } from "./util/burger";
import { daily } from "./pokemon/daily";
// import { give } from "./inventory/give";
interface ICommandGroup {
@ -54,15 +55,23 @@ commandGroups.push(fishingGroup);
const inventoryGroup: ICommandGroup = {
id: "inventory",
displayName: "Inventory",
commands: [inventory, take, eat, sack, pokemon, yeet, burger /* give */]
commands: [inventory, sack, pokemon, take, eat, yeet, burger /* give */]
};
commandGroups.push(inventoryGroup);
const pokemonGroup: ICommandGroup = {
id: "pokemon",
displayName: "Pokémon",
commands: [daily, pokedex]
};
commandGroups.push(pokemonGroup);
const utilGroup: ICommandGroup = {
id: "util",
displayName: "Utility",
commands: [data, setcolor, memory, autofish, pokedex, fid, chance]
commands: [data, setcolor, memory, autofish, fid, chance]
};
commandGroups.push(utilGroup);

View File

@ -1,5 +1,7 @@
import Command from "@server/commands/Command";
import { logger } from "@server/commands/handler";
import { getInventory, updateInventory } from "@server/data/inventory";
import { removeItem } from "@server/items";
import { itemBehaviorMap, runBehavior } from "@server/items/behavior";
export const eat = new Command(
@ -62,45 +64,9 @@ export const eat = new Command(
if (shouldRemove) {
if (foundObject.objtype == "fish") {
i = 0;
for (const fish of inventory.fishSack as TFishSack) {
if (typeof fish.count !== "undefined") {
if (fish.count > 1) {
shouldRemove = false;
((inventory.fishSack as TFishSack)[i]
.count as number)--;
} else {
shouldRemove = true;
}
} else {
shouldRemove = true;
}
if (shouldRemove)
(inventory.fishSack as TFishSack).splice(i, 1);
break;
}
removeItem(inventory.fishSack, foundObject);
} else if (foundObject.objtype == "item") {
i = 0;
for (const item of inventory.items as unknown as IItem[]) {
if (typeof item.count == "number") {
if (item.count > 1) {
shouldRemove = false;
((inventory.items as TInventoryItems)[i]
.count as number)--;
} else {
shouldRemove = true;
}
} else {
shouldRemove = true;
}
if (shouldRemove)
(inventory.items as TInventoryItems).splice(i, 1);
break;
}
removeItem(inventory.items, foundObject);
}
await updateInventory(inventory);

View File

@ -0,0 +1,21 @@
import Command from "@server/commands/Command";
import { logger } from "@server/commands/handler";
import { claimDailyPokemon } from "@server/pokemon/daily";
export const daily = new Command(
"daily",
["daily", "dailypokemon"],
"Claim your daily Pokémon reward",
"daily",
"command.inventory.daily",
async ({ id, command, args, prefix, part, user }) => {
try {
const message = await claimDailyPokemon(user.id);
return message;
} catch (err) {
logger.error("Unable to perform daily claim:", err);
return `Congratulations, you broke the bot. Your daily reward might not work now.`;
}
},
true
);

View File

@ -1,15 +1,16 @@
import type { User } from "@prisma/client";
import prisma from "./prisma";
export async function createInventory(inventory: Partial<IInventory>) {
return await prisma.inventory.create({
return (await prisma.inventory.create({
data: inventory
});
})) as IInventory;
}
export async function getInventory(id: IInventory["id"]) {
return await prisma.inventory.findUnique({
return (await prisma.inventory.findUnique({
where: { id }
});
})) as IInventory;
}
export async function updateInventory(inventory: Partial<IInventory>) {

View File

@ -108,7 +108,11 @@ export function hasFishTime(
export function getSizeString(cm: number) {
const size =
cm < 30
cm < 5
? "microscopic"
: cm < 10
? "tiny"
: cm < 30
? "small"
: cm < 60
? "medium-sized"

View File

@ -23,3 +23,26 @@ export function addItem(arr: IObject[], item: IObject) {
(arr[i].count as number) += inc;
}
}
export function removeItem(arr: IObject[], item: IObject, count = 1) {
let found = false;
let i = 0;
for (i = 0; i < arr.length; i++) {
if (item.id == arr[i].id) {
found = true;
break;
}
}
const foundItem = arr[i];
if (!found || !foundItem) return false;
if (typeof foundItem.count == "number" && foundItem.count > 1) {
foundItem.count -= count;
} else {
arr.splice(i, 1);
}
return true;
}

62
src/api/pokemon/daily.ts Normal file
View File

@ -0,0 +1,62 @@
import { kvGet, kvSet } from "@server/data/keyValueStore";
import { Logger } from "@util/Logger";
import { getRandomPokemon } from "./pokedex";
import { getInventory, updateInventory } from "@server/data/inventory";
import { getUser } from "@server/data/user";
import { addItem } from "@server/items";
import { getHHMMSS } from "@util/time";
const logger = new Logger("Daily Pokemon Manager");
const oneDay = 1000 * 60 * 60 * 24;
export async function claimDailyPokemon(userID: string) {
// Get the last daily timestamp
let timestampS = await kvGet(`pokedaily~${userID}`);
let timestamp = 0;
if (typeof timestampS == "string") {
try {
timestamp = parseInt(timestampS);
} catch (err) {
logger.warn("Unable to parse JSON:", err);
}
}
logger.debug("Time remaining:", Date.now() - timestamp);
// Check if it has been over a day
if (Date.now() - timestamp > oneDay) {
// Give them a random pokemon and set new timestamp
const pokemon = getRandomPokemon();
const item = {
id: pokemon.pokeID.toString(),
name: pokemon.name,
pokeID: pokemon.pokeID,
base: pokemon.base,
type: pokemon.type,
count: 1,
objtype: "pokemon"
} as IPokemon;
const user = await getUser(userID);
if (!user) throw new Error("No user found");
const inventory = await getInventory(user.inventoryId);
if (!inventory) throw new Error("No inventory found");
addItem(inventory.pokemon, pokemon);
await updateInventory(inventory);
kvSet(`pokedaily~${userID}`, Date.now().toString());
return `You claimed your daily Pokémon reward and got: ${
item.emoji || "📦"
}${item.name}${item.count ? ` (x${item.count})` : ""}`;
} else {
// or tell them no
return `You already claimed today! Time remaining: ${getHHMMSS(
oneDay - (Date.now() - timestamp),
false
)}`;
}
}

View File

@ -8,3 +8,8 @@ const logger = new Logger("Pokédex");
export function getPokemonByID(id: number) {
return pokedex.find(p => p.pokeID == id);
}
export function getRandomPokemon() {
const r = Math.floor(Math.random() * pokedex.length);
return pokedex[r];
}

View File

@ -1,8 +1,9 @@
import { Logger } from "@util/Logger";
import { createInterface } from "readline";
import { EventEmitter } from "events";
import { EventEmitter } from "node:events";
import gettRPC from "@util/api/trpc";
import { startAutorestart } from "@util/autorestart";
import { CosmicColor } from "@util/CosmicColor";
const trpc = gettRPC(process.env.CLI_FISHING_TOKEN as string);
@ -15,7 +16,7 @@ const b = new EventEmitter();
const rl = createInterface({
input: process.stdin,
output: process.stdout
});
} as any);
const user = {
_id: "stdin",
@ -26,6 +27,12 @@ const user = {
(globalThis as unknown as any).rl = rl;
rl.setPrompt("> ");
rl.prompt();
setPrompt();
function setPrompt() {
const color = new CosmicColor(user.color);
rl.setPrompt(`\x1b[38;2;${color.r};${color.g};${color.b}m> `);
}
rl.on("line", async line => {
if (line == "stop" || line == "exit") process.exit();
@ -94,6 +101,7 @@ setInterval(async () => {
b.on("color", msg => {
if (typeof msg.color !== "string" || typeof msg.id !== "string") return;
user.color = msg.color;
setPrompt();
});
b.on("sendchat", msg => {

View File

@ -1,22 +1,32 @@
export function getHHMMSS() {
const now = Date.now();
export function getTime(t = Date.now(), twelveHour = true) {
const now = t;
const s = now / 1000;
const m = s / 60;
const h = m / 60;
const hh = Math.floor(h % 12)
const hours = Math.floor(h % (twelveHour ? 12 : 24))
.toString()
.padStart(2, "0");
const mm = Math.floor(m % 60)
const minutes = Math.floor(m % 60)
.toString()
.padStart(2, "0");
const ss = Math.floor(s % 60)
const seconds = Math.floor(s % 60)
.toString()
.padStart(2, "0");
const ms = Math.floor(now % 1000)
const milliseconds = Math.floor(now % 1000)
.toString()
.padStart(3, "0");
return `${hh}:${mm}:${ss}.${ms}`;
return {
hours,
minutes,
seconds,
milliseconds
};
}
export function getHHMMSS(t = Date.now(), twelveHour = true) {
const { hours, minutes, seconds, milliseconds } = getTime(t, twelveHour);
return `${hours}:${minutes}:${seconds}.${milliseconds}`;
}

7
src/util/types.d.ts vendored
View File

@ -21,7 +21,7 @@ interface IContextProps {
type TCommandCallback<User> = (props: IContextProps) => Promise<string | void>;
interface CountComponent {
interface ICountComponent {
count: number;
}
@ -54,7 +54,7 @@ interface IFish extends IObject {
}
interface IPokemon extends IObject {
id: number;
id: string;
pokeID: number;
objtype: "pokemon";
emoji?: string;
@ -78,6 +78,7 @@ type TPokemonSack = JsonArray & IPokemon[];
interface IInventory {
id: number;
balance: number;
location: string;
items: TInventoryItems;
fishSack: TFishSack;
@ -90,7 +91,7 @@ interface IBack<T extends string | unknown> extends Record<string, unknown> {
m: T;
}
interface Backs extends Record<string, IBack<unknown>> {
interface IBacks extends Record<string, IBack<unknown>> {
color: {
m: "color";
};