Merge branch 'dev'
This commit is contained in:
commit
1a8a272c87
|
@ -2,7 +2,3 @@
|
|||
channel:
|
||||
id: "✧𝓓𝓔𝓥 𝓡𝓸𝓸𝓶✧"
|
||||
allowColorChanging: true
|
||||
- uri: wss://mppclone.com:8443
|
||||
channel:
|
||||
id: "test/fishing"
|
||||
allowColorChanging: true
|
||||
|
|
16
package.json
16
package.json
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
);
|
|
@ -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>) {
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
)}`;
|
||||
}
|
||||
}
|
|
@ -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];
|
||||
}
|
||||
|
|
|
@ -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 => {
|
||||
|
|
|
@ -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}`;
|
||||
}
|
||||
|
|
|
@ -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";
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue