diff --git a/package.json b/package.json index 146b882..599ba48 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "aslobot-matrix", - "version": "0.6.0", + "version": "0.7.0", "description": "", "license": "ISC", "author": "", diff --git a/src/config.preset.json b/src/config.preset.json index 899e234..66ea18d 100644 --- a/src/config.preset.json +++ b/src/config.preset.json @@ -14,7 +14,12 @@ "gain": 5, "startingRequirement": 50, "multiplier": 1.25, - "timeout": 60000 + "timeout": 300000 + }, + "money": { + "gain": 2, + "startingValue": 10, + "timeout": 3600000 }, "ai": { "api": { diff --git a/src/helpers.ts b/src/helpers.ts index 3a4bfd4..c396e7b 100644 --- a/src/helpers.ts +++ b/src/helpers.ts @@ -4,14 +4,31 @@ import { type IUser, type TRole } from "./store/types.js"; import type { ILevel } from "./types.js"; const getUserById = (userId: string): IUser => { - return ( - state.users.find((user) => user.id === userId) ?? { + const user = state.users.find((user) => user.id === userId); + if (!user) { + return { id: ":", role: "NONE", experience: 0, + money: 0, + aiCost: 0, lastMessageTimestamp: 0, - } - ); + lastExperienceGainTimestamp: 0, + lastMoneyGainTimestamp: 0, + }; + } + + if (!user.experience) { + user.experience = 0; + } + if (!user.money) { + user.money = 0; + } + if (!user.aiCost) { + user.aiCost = 0; + } + + return user; }; const checkRoles = (roles: TRole[], userId: string) => { diff --git a/src/modules/ai/ai.ts b/src/modules/ai/ai.ts index dae808d..8668f49 100644 --- a/src/modules/ai/ai.ts +++ b/src/modules/ai/ai.ts @@ -3,6 +3,9 @@ import type { ICallbackStore } from "../types.js"; import { config } from "../../config.js"; import { getTextGemini, getImageGemini } from "../../services/ai/ai.js"; import { alts } from "./alts.js"; +import type { IAdminInstructions } from "./types.js"; +import { getUserById } from "../../helpers.js"; +import { prices } from "./prices.js"; let client: MatrixClient; @@ -15,40 +18,58 @@ const registerModuleAI = ( callbackStore.messageCallbacks.push({ startConditions: [`${config.app.triggerPrefix}ai `], callbackFunc: onAI, + allowedRoles: ["USER", "MODERATOR", "ADMIN"], }); callbackStore.messageCallbacks.push({ - startConditions: [ - ...alts.map((alt) => `${alt.key} when`), - ...alts.map((alt) => `${alt.key} ked`), - `!img`, - ], + startConditions: [`${config.app.triggerPrefix}img `], callbackFunc: onImageGen, + allowedRoles: ["USER", "MODERATOR", "ADMIN"], }); }; -const onAI = async (text: string, roomId: string) => { +const onAI = async (text: string, roomId: string, sender: string) => { + const user = getUserById(sender); + if (text.trim().length < 5) { return; } - const responseAI = await getTextGemini(text.replace("!ai ", "")); - client.sendTextMessage(roomId, responseAI); + let textMod = text.replace("!ai", "").trim().toLowerCase(); + let instructions = { + prefferedLanguages: ["english", "slovak"], + adminText: "Be concise, try to keep text as short as possible", + alts: alts, + } as IAdminInstructions; + + textMod = `Admin Instructions:\n${instructions}\nPrompt:\n${textMod}`; + + const responseAI = await getTextGemini(textMod); + + user.aiCost += responseAI.tokens * prices.text; + + client.sendTextMessage(roomId, responseAI.text); }; -const onImageGen = async (text: string, roomId: string) => { +const onImageGen = async (text: string, roomId: string, sender: string) => { + const user = getUserById(sender); + let textMod = text.replace("!img", "").trim().toLowerCase(); alts.forEach((alt) => { - textMod = textMod.replaceAll(alt.key, alt.alt); + alt.keys.forEach((key) => { + textMod = textMod.replaceAll(key, alt.alt); + }); }); - const buffer = await getImageGemini(textMod); - if (!buffer || buffer.length < 10) { + const responseAI = await getImageGemini(textMod); + + user.aiCost += responseAI.tokens * prices.image; + if (!responseAI.image || responseAI.image.length < 10) { return; } const imageName = `photo-img-gen.png`; - const uploadResult = await client.uploadContent(buffer, { + const uploadResult = await client.uploadContent(responseAI.image, { type: "image/png", name: imageName, }); @@ -59,7 +80,7 @@ const onImageGen = async (text: string, roomId: string) => { url: uploadResult.content_uri, info: { mimetype: "image/png", - size: buffer.length, + size: responseAI.image.length, }, }); }; diff --git a/src/modules/ai/alts.ts b/src/modules/ai/alts.ts index 00689ad..f7b8ead 100644 --- a/src/modules/ai/alts.ts +++ b/src/modules/ai/alts.ts @@ -2,164 +2,73 @@ import type { IAIAlt } from "./types.js"; const alts: IAIAlt[] = [ { - key: "satek", + keys: [ + "satek", + "sateg", + "sadeg", + "coty", + "satko", + "sadko", + "vlado", + "vladko", + "vladimir", + "macak", + "macag", + ], alt: "black cat", }, { - key: "sateg", - alt: "black cat", - }, - { - key: "sadeg", - alt: "black cat", - }, - { - key: "satko", - alt: "black cat", - }, - { - key: "sadko", - alt: "black cat", - }, - { - key: "vlado", - alt: "black cat", - }, - { - key: "vladko", - alt: "black cat", - }, - { - key: "vladimir", - alt: "black cat", - }, - { - key: "macag", - alt: "black cat", - }, - { - key: "vladko", - alt: "black cat", - }, - { - key: "macica", + keys: ["macica", "macico"], alt: "white cat", }, { - key: "macico", - alt: "white cat", - }, - { - key: "gabor", + keys: ["gabor", "gaber", "martin", "marting"], alt: "hedgehog", }, { - key: "martin", - alt: "hedgehog", - }, - { - key: "madys", + keys: [ + "madys", + "mandak", + "mandag", + "mando", + "mandik", + "madik", + "madeg", + "madek", + ], alt: "beaver", }, { - key: "mandak", - alt: "beaver", - }, - { - key: "mando", - alt: "beaver", - }, - { - key: "mandik", - alt: "beaver", - }, - { - key: "madik", - alt: "beaver", - }, - { - key: "madeg", - alt: "beaver", - }, - { - key: "janys", + keys: ["janys", "jano", "janeg", "janek", "aslanek", "aslan", "aslo"], alt: "lion", }, { - key: "jano", - alt: "lion", - }, - { - key: "janeg", - alt: "lion", - }, - { - key: "aslan", - alt: "lion", - }, - { - key: "aslo", - alt: "lion", - }, - { - key: "marek", + keys: ["marek", "mareg", "macek", "maceg", "rod"], alt: "purple snake", }, { - key: "mareg", - alt: "purple snake", - }, - { - key: "maceg", - alt: "purple snake", - }, - { - key: "rod", - alt: "purple snake", - }, - { - key: "lara", + keys: ["lara", "kostur", "kosturik"], alt: "ginger dog", }, { - key: "kostur", - alt: "ginger dog", + keys: ["tato"], + alt: "green troll", }, { - key: "kosturik", - alt: "ginger dog", + keys: ["mama", "monika", "monik"], + alt: "god's peasant", }, { - key: "tato", - alt: "troll", + keys: ["puk", "pucik", "pucig"], + alt: "fat rat", }, { - key: "mama", - alt: "angel", + keys: ["becky", "beky", "beki"], + alt: "35 year old pink haired giantess", }, { - key: "monik", - alt: "angel", - }, - { - key: "puk", - alt: "rat", - }, - { - key: "becky", - alt: "giantess", - }, - { - key: "beky", - alt: "giantess", - }, - { - key: "beki", - alt: "giantess", - }, - { - key: "veronik", - alt: "lgbt princess", + keys: ["veronika", "veronik", "wewe", "wonka"], + alt: "lgbt princess with curly hair", }, ]; diff --git a/src/modules/ai/prices.ts b/src/modules/ai/prices.ts new file mode 100644 index 0000000..e323018 --- /dev/null +++ b/src/modules/ai/prices.ts @@ -0,0 +1,6 @@ +const prices = { + text: 0.000002, + image: 0.00003, +}; + +export { prices }; diff --git a/src/modules/ai/types.ts b/src/modules/ai/types.ts index c7b0c35..7f57e3b 100644 --- a/src/modules/ai/types.ts +++ b/src/modules/ai/types.ts @@ -1,6 +1,12 @@ interface IAIAlt { - key: string; + keys: string[]; alt: string; } -export { type IAIAlt }; +interface IAdminInstructions { + prefferedLanguages: string[]; + adminText: string; + alts: IAIAlt[]; +} + +export { type IAIAlt, type IAdminInstructions }; diff --git a/src/modules/base/base.ts b/src/modules/base/base.ts index 59d8664..8c682b8 100644 --- a/src/modules/base/base.ts +++ b/src/modules/base/base.ts @@ -61,17 +61,21 @@ const onHelp = (_text: string, roomId: string) => { client.sendHtmlMessage( roomId, "", - `
Your Role: ${user.role}
+Your Money: ${user.money}
+Your AI Cost: ${user.aiCost}$
+Your Level: ${level.level}
+ Next level progress: ${level.experienceInLevel}/${level.expToNextLevel}xp`, ); }; @@ -58,4 +65,28 @@ const onLeaderboard = (_text: string, roomId: string) => { ); }; +const onAILeaderboard = (_text: string, roomId: string) => { + const mapUsersToLeaderboard = (user: IUser): string => { + const cost = user.aiCost; + const userName = getUserName(user); + const userNameMod = + userName.charAt(0).toUpperCase() + userName.slice(1); + + return `