Add customizable chat bots and chat commands (!179)

* Use ICommandoCommand interface to register a new command for Commando! Our new and shiny chat bot that takes care of all your commanding needs
* Use IDialogueChatBot to register you new chatty friend bot!
* If you are feeling lazy, you can also use the ISptCommand and register a command that will use "spt" prefix
* spt give command has been added! Feeling like cheating today? hehe use "spt give tplId quantity" and get a new shiny item on your inbox!

Co-authored-by: clodan <clodan@clodan.com>
Reviewed-on: https://dev.sp-tarkov.com/SPT-AKI/Server/pulls/179
Co-authored-by: Alex <clodan@noreply.dev.sp-tarkov.com>
Co-committed-by: Alex <clodan@noreply.dev.sp-tarkov.com>
This commit is contained in:
Alex 2023-12-24 19:54:27 +00:00 committed by chomp
parent ea2257c2fb
commit 26a6553eaa
13 changed files with 501 additions and 151 deletions

View File

@ -11,6 +11,7 @@
"plugin:@typescript-eslint/eslint-recommended"
],
"rules": {
"brace-style": ["error", "allman"],
"@typescript-eslint/no-namespace": "off",
"@typescript-eslint/no-empty-interface": "off",
"@typescript-eslint/no-explicit-any": "off", // We use a bunch of these.

View File

@ -90,7 +90,7 @@ export class DialogueCallbacks implements OnUpdate
sessionID: string,
): IGetBodyResponseData<DialogueInfo[]>
{
return this.httpResponse.getBody(this.dialogueController.generateDialogueList(sessionID));
return this.httpResponse.getBody(this.dialogueController.generateDialogueList(sessionID), 0, null, false);
}
/** Handle client/mail/dialog/view */
@ -100,7 +100,7 @@ export class DialogueCallbacks implements OnUpdate
sessionID: string,
): IGetBodyResponseData<IGetMailDialogViewResponseData>
{
return this.httpResponse.getBody(this.dialogueController.generateDialogueView(info, sessionID));
return this.httpResponse.getBody(this.dialogueController.generateDialogueView(info, sessionID), 0, null, false);
}
/** Handle client/mail/dialog/info */

View File

@ -1,46 +1,44 @@
import { inject, injectable } from "tsyringe";
import { inject, injectAll, injectable } from "tsyringe";
import { IDialogueChatBot } from "@spt-aki/helpers/Dialogue/IDialogueChatBot";
import { DialogueHelper } from "@spt-aki/helpers/DialogueHelper";
import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
import { IGetAllAttachmentsResponse } from "@spt-aki/models/eft/dialog/IGetAllAttachmentsResponse";
import { IGetFriendListDataResponse } from "@spt-aki/models/eft/dialog/IGetFriendListDataResponse";
import { IGetMailDialogViewRequestData } from "@spt-aki/models/eft/dialog/IGetMailDialogViewRequestData";
import { IGetMailDialogViewResponseData } from "@spt-aki/models/eft/dialog/IGetMailDialogViewResponseData";
import { ISendMessageRequest } from "@spt-aki/models/eft/dialog/ISendMessageRequest";
import { Dialogue, DialogueInfo, IAkiProfile, IUserDialogInfo, Message } from "@spt-aki/models/eft/profile/IAkiProfile";
import { ConfigTypes } from "@spt-aki/models/enums/ConfigTypes";
import { GiftSentResult } from "@spt-aki/models/enums/GiftSentResult";
import { MemberCategory } from "@spt-aki/models/enums/MemberCategory";
import { MessageType } from "@spt-aki/models/enums/MessageType";
import { ICoreConfig } from "@spt-aki/models/spt/config/ICoreConfig";
import { ILogger } from "@spt-aki/models/spt/utils/ILogger";
import { ConfigServer } from "@spt-aki/servers/ConfigServer";
import { SaveServer } from "@spt-aki/servers/SaveServer";
import { GiftService } from "@spt-aki/services/GiftService";
import { MailSendService } from "@spt-aki/services/MailSendService";
import { HashUtil } from "@spt-aki/utils/HashUtil";
import { RandomUtil } from "@spt-aki/utils/RandomUtil";
import { TimeUtil } from "@spt-aki/utils/TimeUtil";
@injectable()
export class DialogueController
{
protected coreConfig: ICoreConfig;
protected registeredDialogueChatBots: Map<string, IDialogueChatBot> = new Map<string, IDialogueChatBot>();
constructor(
@inject("WinstonLogger") protected logger: ILogger,
@inject("SaveServer") protected saveServer: SaveServer,
@inject("TimeUtil") protected timeUtil: TimeUtil,
@inject("DialogueHelper") protected dialogueHelper: DialogueHelper,
@inject("ProfileHelper") protected profileHelper: ProfileHelper,
@inject("RandomUtil") protected randomUtil: RandomUtil,
@inject("MailSendService") protected mailSendService: MailSendService,
@inject("GiftService") protected giftService: GiftService,
@inject("HashUtil") protected hashUtil: HashUtil,
@inject("ConfigServer") protected configServer: ConfigServer,
@injectAll("DialogueChatBot") protected dialogueChatBots: IDialogueChatBot[],
)
{
this.coreConfig = this.configServer.getConfig(ConfigTypes.CORE);
for (const dialogueChatBot of dialogueChatBots)
{
if (this.registeredDialogueChatBots.has(dialogueChatBot.getChatBot()._id))
{
this.logger.error(
`Could not register ${dialogueChatBot.getChatBot()._id} as it is already in use. Skipping.`,
);
continue;
}
this.registeredDialogueChatBots.set(dialogueChatBot.getChatBot()._id, dialogueChatBot);
}
}
/** Handle onUpdate spt event */
@ -61,7 +59,11 @@ export class DialogueController
public getFriendList(sessionID: string): IGetFriendListDataResponse
{
// Force a fake friend called SPT into friend list
return { Friends: [this.getSptFriendData()], Ignore: [], InIgnoreList: [] };
return {
Friends: Array.from(this.registeredDialogueChatBots.values()).map((v) => v.getChatBot()),
Ignore: [],
InIgnoreList: [],
};
}
/**
@ -118,7 +120,8 @@ export class DialogueController
// User to user messages are special in that they need the player to exist in them, add if they don't
if (
messageType === MessageType.USER_MESSAGE && !dialog.Users?.find((x) => x._id === profile.characters.pmc._id)
messageType === MessageType.USER_MESSAGE
&& !dialog.Users?.find((x) => x._id === profile.characters.pmc.sessionId)
)
{
if (!dialog.Users)
@ -127,7 +130,7 @@ export class DialogueController
}
dialog.Users.push({
_id: profile.characters.pmc._id,
_id: profile.characters.pmc.sessionId,
info: {
Level: profile.characters.pmc.Info.Level,
Nickname: profile.characters.pmc.Info.Nickname,
@ -193,7 +196,12 @@ export class DialogueController
if (request.type === MessageType.USER_MESSAGE)
{
profile.dialogues[request.dialogId].Users = [];
profile.dialogues[request.dialogId].Users.push(this.getSptFriendData(request.dialogId));
if (this.registeredDialogueChatBots.has(request.dialogId))
{
profile.dialogues[request.dialogId].Users.push(
this.registeredDialogueChatBots.get(request.dialogId).getChatBot(),
);
}
}
}
@ -356,134 +364,14 @@ export class DialogueController
{
this.mailSendService.sendPlayerMessageToNpc(sessionId, request.dialogId, request.text);
// Handle when player types a keyword to sptFriend user
if (request.dialogId.includes("sptFriend"))
if (this.registeredDialogueChatBots.has(request.dialogId))
{
this.handleChatWithSPTFriend(sessionId, request);
return this.registeredDialogueChatBots.get(request.dialogId).handleMessage(sessionId, request);
}
return request.dialogId;
}
/**
* Send responses back to player when they communicate with SPT friend on friends list
* @param sessionId Session Id
* @param request send message request
*/
protected handleChatWithSPTFriend(sessionId: string, request: ISendMessageRequest): void
{
const sender = this.profileHelper.getPmcProfile(sessionId);
const sptFriendUser = this.getSptFriendData();
const giftSent = this.giftService.sendGiftToPlayer(sessionId, request.text);
if (giftSent === GiftSentResult.SUCCESS)
{
this.mailSendService.sendUserMessageToPlayer(
sessionId,
sptFriendUser,
this.randomUtil.getArrayValue([
"Hey! you got the right code!",
"A secret code, how exciting!",
"You found a gift code!",
]),
);
return;
}
if (giftSent === GiftSentResult.FAILED_GIFT_ALREADY_RECEIVED)
{
this.mailSendService.sendUserMessageToPlayer(
sessionId,
sptFriendUser,
this.randomUtil.getArrayValue(["Looks like you already used that code", "You already have that!!"]),
);
return;
}
if (request.text.toLowerCase().includes("love you"))
{
this.mailSendService.sendUserMessageToPlayer(
sessionId,
sptFriendUser,
this.randomUtil.getArrayValue([
"That's quite forward but i love you too in a purely chatbot-human way",
"I love you too buddy :3!",
"uwu",
`love you too ${sender?.Info?.Nickname}`,
]),
);
}
if (request.text.toLowerCase() === "spt")
{
this.mailSendService.sendUserMessageToPlayer(
sessionId,
sptFriendUser,
this.randomUtil.getArrayValue(["Its me!!", "spt? i've heard of that project"]),
);
}
if (["hello", "hi", "sup", "yo", "hey"].includes(request.text.toLowerCase()))
{
this.mailSendService.sendUserMessageToPlayer(
sessionId,
sptFriendUser,
this.randomUtil.getArrayValue([
"Howdy",
"Hi",
"Greetings",
"Hello",
"bonjor",
"Yo",
"Sup",
"Heyyyyy",
"Hey there",
`Hello ${sender?.Info?.Nickname}`,
]),
);
}
if (request.text.toLowerCase() === "nikita")
{
this.mailSendService.sendUserMessageToPlayer(
sessionId,
sptFriendUser,
this.randomUtil.getArrayValue([
"I know that guy!",
"Cool guy, he made EFT!",
"Legend",
"Remember when he said webel-webel-webel-webel, classic nikita moment",
]),
);
}
if (request.text.toLowerCase() === "are you a bot")
{
this.mailSendService.sendUserMessageToPlayer(
sessionId,
sptFriendUser,
this.randomUtil.getArrayValue(["beep boop", "**sad boop**", "probably", "sometimes", "yeah lol"]),
);
}
}
protected getSptFriendData(friendId = "sptFriend"): IUserDialogInfo
{
return {
_id: friendId,
info: {
Level: 1,
MemberCategory: MemberCategory.DEVELOPER,
Nickname: this.coreConfig.sptFriendNickname,
Side: "Usec",
},
};
}
/**
* Get messages from a specific dialog that have items not expired
* @param sessionId Session id

View File

@ -246,6 +246,10 @@ import { VFS } from "@spt-aki/utils/VFS";
import { Watermark, WatermarkLocale } from "@spt-aki/utils/Watermark";
import { WinstonMainLogger } from "@spt-aki/utils/logging/WinstonMainLogger";
import { WinstonRequestLogger } from "@spt-aki/utils/logging/WinstonRequestLogger";
import {SptDialogueChatBot} from "@spt-aki/helpers/Dialogue/SptDialogueChatBot";
import {CommandoDialogueChatBot} from "@spt-aki/helpers/Dialogue/CommandoDialogueChatBot";
import {GiveSptCommand} from "@spt-aki/helpers/Dialogue/Commando/SptCommands/GiveSptCommand";
import {SptCommandoCommands} from "@spt-aki/helpers/Dialogue/Commando/SptCommandoCommands";
/**
* Handle the registration of classes to be used by the Dependency Injection code
@ -357,6 +361,16 @@ export class Container
depContainer.registerType("SaveLoadRouter", "InraidSaveLoadRouter");
depContainer.registerType("SaveLoadRouter", "InsuranceSaveLoadRouter");
depContainer.registerType("SaveLoadRouter", "ProfileSaveLoadRouter");
// Chat Bots
depContainer.registerType("DialogueChatBot", "SptDialogueChatBot");
depContainer.registerType("DialogueChatBot", "CommandoDialogueChatBot");
// Commando Commands
depContainer.registerType("CommandoCommand", "SptCommandoCommands");
// SptCommando Commands
depContainer.registerType("SptCommand", "GiveSptCommand");
}
private static registerUtils(depContainer: DependencyContainer): void
@ -566,6 +580,15 @@ export class Container
});
depContainer.register<BotDifficultyHelper>("BotDifficultyHelper", { useClass: BotDifficultyHelper });
depContainer.register<RepeatableQuestHelper>("RepeatableQuestHelper", { useClass: RepeatableQuestHelper });
// ChatBots
depContainer.register<SptDialogueChatBot>("SptDialogueChatBot", SptDialogueChatBot);
depContainer.register<CommandoDialogueChatBot>("CommandoDialogueChatBot", CommandoDialogueChatBot);
// SptCommando
depContainer.register<SptCommandoCommands>("SptCommandoCommands", SptCommandoCommands);
// SptCommands
depContainer.register<GiveSptCommand>("GiveSptCommand", GiveSptCommand);
}
private static registerLoaders(depContainer: DependencyContainer): void

View File

@ -0,0 +1,7 @@
import { ISendMessageRequest } from "@spt-aki/models/eft/dialog/ISendMessageRequest";
import { IUserDialogInfo } from "@spt-aki/models/eft/profile/IAkiProfile";
export interface ICommandoAction
{
handle(commandHandler: IUserDialogInfo, sessionId: string, request: ISendMessageRequest): string;
}

View File

@ -0,0 +1,9 @@
import { ICommandoAction } from "@spt-aki/helpers/Dialogue/Commando/ICommandoAction";
export interface ICommandoCommand
{
getCommandPrefix(): string;
getCommandHelp(command: string): string;
getCommands(): Set<string>;
getCommandAction(command: string): ICommandoAction;
}

View File

@ -0,0 +1,38 @@
import { ICommandoAction } from "@spt-aki/helpers/Dialogue/Commando/ICommandoAction";
import { ICommandoCommand } from "@spt-aki/helpers/Dialogue/Commando/ICommandoCommand";
import { ISptCommand } from "@spt-aki/helpers/Dialogue/Commando/SptCommands/ISptCommand";
import { ISendMessageRequest } from "@spt-aki/models/eft/dialog/ISendMessageRequest";
import { IUserDialogInfo } from "@spt-aki/models/eft/profile/IAkiProfile";
import { injectAll, injectable } from "tsyringe";
@injectable()
export class SptCommandoCommands implements ICommandoCommand
{
constructor(
@injectAll("SptCommand") protected sptCommands: ISptCommand[]
)
{
}
public getCommandHelp(command: string): string
{
return this.sptCommands.find(c => c.getCommand() === command)?.getCommandHelp();
}
public getCommandPrefix(): string
{
return "spt";
}
public getCommands(): Set<string>
{
return new Set(this.sptCommands.map(c => c.getCommand()));
}
public getCommandAction(command: string): ICommandoAction
{
return this.sptCommands.find(c => c.getCommand() === command);
}
}

View File

@ -0,0 +1,128 @@
import { ISptCommand } from "@spt-aki/helpers/Dialogue/Commando/SptCommands/ISptCommand";
import { ItemHelper } from "@spt-aki/helpers/ItemHelper";
import { PresetHelper } from "@spt-aki/helpers/PresetHelper";
import { Item } from "@spt-aki/models/eft/common/tables/IItem";
import { ISendMessageRequest } from "@spt-aki/models/eft/dialog/ISendMessageRequest";
import { IUserDialogInfo } from "@spt-aki/models/eft/profile/IAkiProfile";
import { BaseClasses } from "@spt-aki/models/enums/BaseClasses";
import { ILogger } from "@spt-aki/models/spt/utils/ILogger";
import { MailSendService } from "@spt-aki/services/MailSendService";
import { HashUtil } from "@spt-aki/utils/HashUtil";
import { JsonUtil } from "@spt-aki/utils/JsonUtil";
import { inject, injectable } from "tsyringe";
@injectable()
export class GiveSptCommand implements ISptCommand
{
public constructor(
@inject("WinstonLogger") protected logger: ILogger,
@inject("ItemHelper") protected itemHelper: ItemHelper,
@inject("HashUtil") protected hashUtil: HashUtil,
@inject("JsonUtil") protected jsonUtil: JsonUtil,
@inject("PresetHelper") protected presetHelper: PresetHelper,
@inject("MailSendService") protected mailSendService: MailSendService,
)
{
}
public getCommand(): string
{
return "give";
}
public getCommandHelp(): string
{
return "Usage: spt give tplId quantity";
}
public handle(commandHandler: IUserDialogInfo, sessionId: string, request: ISendMessageRequest): string
{
const giveCommand = request.text.split(" ");
if (giveCommand[1] !== "give")
{
this.logger.error("Invalid action received for give command!");
return request.dialogId;
}
if (!giveCommand[2])
{
this.mailSendService.sendUserMessageToPlayer(
sessionId,
commandHandler,
"Invalid use of give command! Template ID is missing. Use \"Help\" for more info",
);
return request.dialogId;
}
const tplId = giveCommand[2];
if (!giveCommand[3])
{
this.mailSendService.sendUserMessageToPlayer(
sessionId,
commandHandler,
"Invalid use of give command! Quantity is missing. Use \"Help\" for more info",
);
return request.dialogId;
}
const quantity = giveCommand[3];
if (Number.isNaN(+quantity))
{
this.mailSendService.sendUserMessageToPlayer(
sessionId,
commandHandler,
"Invalid use of give command! Quantity is not a valid integer. Use \"Help\" for more info",
);
return request.dialogId;
}
const checkedItem = this.itemHelper.getItem(tplId);
if (!checkedItem[0])
{
this.mailSendService.sendUserMessageToPlayer(
sessionId,
commandHandler,
"Invalid template ID requested for give command. The item doesnt exists on the DB.",
);
return request.dialogId;
}
const itemsToSend: Item[] = [];
if (this.itemHelper.isOfBaseclass(checkedItem[1]._id, BaseClasses.WEAPON))
{
const preset = this.presetHelper.getDefaultPreset(checkedItem[1]._id);
if (!preset)
{
this.mailSendService.sendUserMessageToPlayer(
sessionId,
commandHandler,
"Invalid weapon template ID requested. There are no default presets for this weapon.",
);
return request.dialogId;
}
itemsToSend.push(...this.jsonUtil.clone(preset._items));
}
else if (this.itemHelper.isOfBaseclass(checkedItem[1]._id, BaseClasses.AMMO_BOX))
{
for (let i = 0; i < +quantity; i++)
{
const ammoBoxArray: Item[] = [];
ammoBoxArray.push({ _id: this.hashUtil.generate(), _tpl: checkedItem[1]._id });
this.itemHelper.addCartridgesToAmmoBox(ammoBoxArray, checkedItem[1]);
itemsToSend.push(...ammoBoxArray);
}
}
else
{
const item: Item = {
_id: this.hashUtil.generate(),
_tpl: checkedItem[1]._id,
upd: { StackObjectsCount: +quantity },
};
itemsToSend.push(...this.itemHelper.splitStack(item));
}
this.mailSendService.sendSystemMessageToPlayer(sessionId, "Give command!", itemsToSend);
return request.dialogId;
}
}

View File

@ -0,0 +1,7 @@
import { ICommandoAction } from "@spt-aki/helpers/Dialogue/Commando/ICommandoAction";
export interface ISptCommand extends ICommandoAction
{
getCommand(): string;
getCommandHelp(): string;
}

View File

@ -0,0 +1,88 @@
import { inject, injectAll, injectable } from "tsyringe";
import { ICommandoAction } from "@spt-aki/helpers/Dialogue/Commando/ICommandoAction";
import { ICommandoCommand } from "@spt-aki/helpers/Dialogue/Commando/ICommandoCommand";
import { IDialogueChatBot } from "@spt-aki/helpers/Dialogue/IDialogueChatBot";
import { ISendMessageRequest } from "@spt-aki/models/eft/dialog/ISendMessageRequest";
import { IUserDialogInfo } from "@spt-aki/models/eft/profile/IAkiProfile";
import { MemberCategory } from "@spt-aki/models/enums/MemberCategory";
import { ILogger } from "@spt-aki/models/spt/utils/ILogger";
import { MailSendService } from "@spt-aki/services/MailSendService";
@injectable()
export class CommandoDialogueChatBot implements IDialogueChatBot
{
// A map that contains the command prefix. That contains a map that contains the prefix commands with their respective actions.
protected registeredCommands: Map<string, Map<string, ICommandoAction>> = new Map<string, Map<string, ICommandoAction>>();
public constructor(
@inject("WinstonLogger") protected logger: ILogger,
@inject("MailSendService") protected mailSendService: MailSendService,
@injectAll("CommandoCommand") protected commandoCommands: ICommandoCommand[]
)
{
for (const commandoCommand of commandoCommands)
{
if (this.registeredCommands.has(commandoCommand.getCommandPrefix()) || commandoCommand.getCommandPrefix().toLowerCase() === "help")
{
this.logger.error(`Could not registered command prefix ${commandoCommand.getCommandPrefix()} as it already has been registered. Skipping.`);
continue;
}
const commandMap = new Map<string, ICommandoAction>();
this.registeredCommands.set(commandoCommand.getCommandPrefix(), commandMap);
for (const command of commandoCommand.getCommands())
{
commandMap.set(command, commandoCommand.getCommandAction(command))
}
}
}
public getChatBot(): IUserDialogInfo
{
return {
_id: "sptCommando",
info: {
Level: 1,
MemberCategory: MemberCategory.DEVELOPER,
Nickname: "Commando",
Side: "Usec",
},
};
}
public handleMessage(sessionId: string, request: ISendMessageRequest): string
{
if ((request.text ?? "").length === 0)
{
this.logger.error("Commando command came in as empty text! Invalid data!");
return request.dialogId;
}
const splitCommand = request.text.split(" ");
if (this.registeredCommands.has(splitCommand[0]) && this.registeredCommands.get(splitCommand[0]).has(splitCommand[1]))
return this.registeredCommands.get(splitCommand[0]).get(splitCommand[1]).handle(this.getChatBot(), sessionId, request);
if (splitCommand[0].toLowerCase() === "help")
{
const helpMessage = this.commandoCommands.filter(c => this.registeredCommands.has(c.getCommandPrefix()))
.filter(c => Array.from(c.getCommands()).some(com => this.registeredCommands.get(c.getCommandPrefix()).has(com)))
.map(c => `Help for ${c.getCommandPrefix()}:\n${Array.from(c.getCommands()).map(command => c.getCommandHelp(command)).join("\n")}`)
.join("\n");
this.mailSendService.sendUserMessageToPlayer(
sessionId,
this.getChatBot(),
helpMessage
);
return request.dialogId;
}
this.mailSendService.sendUserMessageToPlayer(
sessionId,
this.getChatBot(),
`Im sorry soldier, I dont recognize the command you are trying to use! Type "help" to see available commands.`
);
}
}

View File

@ -0,0 +1,8 @@
import { ISendMessageRequest } from "@spt-aki/models/eft/dialog/ISendMessageRequest";
import { IUserDialogInfo } from "@spt-aki/models/eft/profile/IAkiProfile";
export interface IDialogueChatBot
{
getChatBot(): IUserDialogInfo;
handleMessage(sessionId: string, request: ISendMessageRequest): string;
}

View File

@ -0,0 +1,151 @@
import { inject, injectable } from "tsyringe";
import { IDialogueChatBot } from "@spt-aki/helpers/Dialogue/IDialogueChatBot";
import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
import { ISendMessageRequest } from "@spt-aki/models/eft/dialog/ISendMessageRequest";
import { IUserDialogInfo } from "@spt-aki/models/eft/profile/IAkiProfile";
import { ConfigTypes } from "@spt-aki/models/enums/ConfigTypes";
import { GiftSentResult } from "@spt-aki/models/enums/GiftSentResult";
import { MemberCategory } from "@spt-aki/models/enums/MemberCategory";
import { ICoreConfig } from "@spt-aki/models/spt/config/ICoreConfig";
import { ConfigServer } from "@spt-aki/servers/ConfigServer";
import { GiftService } from "@spt-aki/services/GiftService";
import { MailSendService } from "@spt-aki/services/MailSendService";
import { RandomUtil } from "@spt-aki/utils/RandomUtil";
@injectable()
export class SptDialogueChatBot implements IDialogueChatBot
{
protected coreConfig: ICoreConfig;
public constructor(
@inject("ProfileHelper") protected profileHelper: ProfileHelper,
@inject("RandomUtil") protected randomUtil: RandomUtil,
@inject("MailSendService") protected mailSendService: MailSendService,
@inject("GiftService") protected giftService: GiftService,
@inject("ConfigServer") protected configServer: ConfigServer
)
{
this.coreConfig = this.configServer.getConfig(ConfigTypes.CORE);
}
public getChatBot(): IUserDialogInfo
{
return {
_id: "sptFriend",
info: {
Level: 1,
MemberCategory: MemberCategory.DEVELOPER,
Nickname: this.coreConfig.sptFriendNickname,
Side: "Usec",
},
};
}
/**
* Send responses back to player when they communicate with SPT friend on friends list
* @param sessionId Session Id
* @param request send message request
*/
public handleMessage(sessionId: string, request: ISendMessageRequest): string
{
const sender = this.profileHelper.getPmcProfile(sessionId);
const sptFriendUser = this.getChatBot();
const giftSent = this.giftService.sendGiftToPlayer(sessionId, request.text);
if (giftSent === GiftSentResult.SUCCESS)
{
this.mailSendService.sendUserMessageToPlayer(
sessionId,
sptFriendUser,
this.randomUtil.getArrayValue([
"Hey! you got the right code!",
"A secret code, how exciting!",
"You found a gift code!",
])
);
return;
}
if (giftSent === GiftSentResult.FAILED_GIFT_ALREADY_RECEIVED)
{
this.mailSendService.sendUserMessageToPlayer(
sessionId,
sptFriendUser,
this.randomUtil.getArrayValue(["Looks like you already used that code", "You already have that!!"])
);
return;
}
if (request.text.toLowerCase().includes("love you"))
{
this.mailSendService.sendUserMessageToPlayer(
sessionId,
sptFriendUser,
this.randomUtil.getArrayValue([
"That's quite forward but i love you too in a purely chatbot-human way",
"I love you too buddy :3!",
"uwu",
`love you too ${sender?.Info?.Nickname}`,
])
);
}
if (request.text.toLowerCase() === "spt")
{
this.mailSendService.sendUserMessageToPlayer(
sessionId,
sptFriendUser,
this.randomUtil.getArrayValue(["Its me!!", "spt? i've heard of that project"])
);
}
if (["hello", "hi", "sup", "yo", "hey"].includes(request.text.toLowerCase()))
{
this.mailSendService.sendUserMessageToPlayer(
sessionId,
sptFriendUser,
this.randomUtil.getArrayValue([
"Howdy",
"Hi",
"Greetings",
"Hello",
"bonjor",
"Yo",
"Sup",
"Heyyyyy",
"Hey there",
`Hello ${sender?.Info?.Nickname}`,
])
);
}
if (request.text.toLowerCase() === "nikita")
{
this.mailSendService.sendUserMessageToPlayer(
sessionId,
sptFriendUser,
this.randomUtil.getArrayValue([
"I know that guy!",
"Cool guy, he made EFT!",
"Legend",
"Remember when he said webel-webel-webel-webel, classic nikita moment",
])
);
}
if (request.text.toLowerCase() === "are you a bot")
{
this.mailSendService.sendUserMessageToPlayer(
sessionId,
sptFriendUser,
this.randomUtil.getArrayValue(["beep boop", "**sad boop**", "probably", "sometimes", "yeah lol"])
);
}
return request.dialogId;
}
}

View File

@ -36,14 +36,16 @@ export class HttpResponseUtil
/**
* Game client needs server responses in a particular format
* @param data
* @param err
* @param errmsg
* @returns
* @param data
* @param err
* @param errmsg
* @returns
*/
public getBody<T>(data: T, err = 0, errmsg = null): IGetBodyResponseData<T>
public getBody<T>(data: T, err = 0, errmsg = null, sanitize = true): IGetBodyResponseData<T>
{
return this.clearString(this.getUnclearedBody(data, err, errmsg));
return sanitize
? this.clearString(this.getUnclearedBody(data, err, errmsg))
: (this.getUnclearedBody(data, err, errmsg) as any);
}
public getUnclearedBody(data: any, err = 0, errmsg = null): string