Server/project/src/controllers/DialogueController.ts

269 lines
9.1 KiB
TypeScript
Raw Normal View History

2023-03-03 15:23:46 +00:00
import { inject, injectable } from "tsyringe";
import { DialogueHelper } from "../helpers/DialogueHelper";
import { IGetAllAttachmentsResponse } from "../models/eft/dialog/IGetAllAttachmentsResponse";
import { IGetFriendListDataResponse } from "../models/eft/dialog/IGetFriendListDataResponse";
import {
IGetMailDialogViewResponseData
} from "../models/eft/dialog/IGetMailDialogViewResponseData";
import { DialogueInfo, IAkiProfile, IUserDialogInfo, Message } from "../models/eft/profile/IAkiProfile";
2023-03-03 15:23:46 +00:00
import { MessageType } from "../models/enums/MessageType";
import { SaveServer } from "../servers/SaveServer";
import { TimeUtil } from "../utils/TimeUtil";
@injectable()
export class DialogueController
{
constructor(
@inject("SaveServer") protected saveServer: SaveServer,
@inject("TimeUtil") protected timeUtil: TimeUtil,
@inject("DialogueHelper") protected dialogueHelper: DialogueHelper
)
{ }
/** Handle onUpdate spt event */
2023-03-03 15:23:46 +00:00
public update(): void
{
const profiles = this.saveServer.getProfiles();
for (const sessionID in profiles)
{
this.removeExpiredItemsFromMessages(sessionID);
2023-03-03 15:23:46 +00:00
}
}
/**
* Handle client/friend/list
* @returns IGetFriendListDataResponse
*/
2023-03-03 15:23:46 +00:00
// eslint-disable-next-line @typescript-eslint/no-unused-vars
public getFriendList(sessionID: string): IGetFriendListDataResponse
{
return {
"Friends": [],
"Ignore": [],
"InIgnoreList": []
};
}
/**
* Handle client/mail/dialog/list
2023-03-03 15:23:46 +00:00
* Create array holding trader dialogs and mail interactions with player
* Set the content of the dialogue on the list tab.
* @param sessionID Session Id
* @returns array of dialogs
*/
public generateDialogueList(sessionID: string): DialogueInfo[]
{
const data: DialogueInfo[] = [];
for (const dialogueId in this.saveServer.getProfile(sessionID).dialogues)
{
data.push(this.getDialogueInfo(dialogueId, sessionID));
}
return data;
}
/**
* Get the content of a dialogue
* @param dialogueID Dialog id
* @param sessionID Session Id
* @returns DialogueInfo
*/
public getDialogueInfo(dialogueID: string, sessionID: string): DialogueInfo
{
const dialogue = this.saveServer.getProfile(sessionID).dialogues[dialogueID];
const result: DialogueInfo = {
2023-03-03 15:23:46 +00:00
"_id": dialogueID,
"type": dialogue.type ? dialogue.type : MessageType.NPC_TRADER,
2023-03-03 15:23:46 +00:00
"message": this.dialogueHelper.getMessagePreview(dialogue),
"new": dialogue.new,
"attachmentsNew": dialogue.attachmentsNew,
"pinned": dialogue.pinned,
Users: dialogue.Users ? dialogue.Users : undefined
2023-03-03 15:23:46 +00:00
};
return result;
2023-03-03 15:23:46 +00:00
}
/**
* Handle client/mail/dialog/view
2023-03-03 15:23:46 +00:00
* Handle player clicking 'messenger' and seeing all the messages they've recieved
* Set the content of the dialogue on the details panel, showing all the messages
* for the specified dialogue.
* @param dialogueID Dialog id
* @param sessionID Session id
* @returns IGetMailDialogViewResponseData object
*/
public generateDialogueView(dialogueID: string, sessionID: string): IGetMailDialogViewResponseData
{
const profile = this.saveServer.getProfile(sessionID);
const dialogue = profile.dialogues[dialogueID];
2023-03-03 15:23:46 +00:00
dialogue.new = 0;
// Set number of new attachments, but ignore those that have expired.
dialogue.attachmentsNew = this.getUnreadMessagesWithAttachmentsCount(sessionID, dialogueID);
return {
messages: dialogue.messages,
profiles: this.getProfilesForMail(profile, dialogue.Users),
2023-03-03 15:23:46 +00:00
hasMessagesWithRewards: this.messagesHaveUncollectedRewards(dialogue.messages)
};
}
protected getProfilesForMail(pmcProfile: IAkiProfile, dialogUsers: IUserDialogInfo[]): IUserDialogInfo[]
{
const result: IUserDialogInfo[] = [];
if (dialogUsers)
{
result.push(...dialogUsers);
const profile = pmcProfile.characters.pmc;
result.push({
_id: pmcProfile.info.id,
info: {
Nickname: profile.Info.Nickname,
Side: profile.Info.Side,
Level: profile.Info.Level,
MemberCategory: profile.Info.MemberCategory
}
});
}
return result;
}
2023-03-03 15:23:46 +00:00
/**
* Get a count of messages with attachments from a particular dialog
* @param sessionID Session id
* @param dialogueID Dialog id
* @returns Count of messages with attachments
*/
protected getUnreadMessagesWithAttachmentsCount(sessionID: string, dialogueID: string): number
{
let newAttachmentCount = 0;
const activeMessages = this.getActiveMessagesFromDialog(sessionID, dialogueID);
for (const message of activeMessages)
{
if (message.hasRewards && !message.rewardCollected)
{
newAttachmentCount++;
}
}
return newAttachmentCount;
}
/**
* Does array have messages with uncollected rewards (includes expired rewards)
* @param messages Messages to check
* @returns true if uncollected rewards found
*/
protected messagesHaveUncollectedRewards(messages: Message[]): boolean
{
return messages.some(x => x.items?.data?.length > 0);
}
/** Handle client/mail/dialog/remove */
2023-03-03 15:23:46 +00:00
public removeDialogue(dialogueID: string, sessionID: string): void
{
delete this.saveServer.getProfile(sessionID).dialogues[dialogueID];
}
public setDialoguePin(dialogueID: string, shouldPin: boolean, sessionID: string): void
{
this.saveServer.getProfile(sessionID).dialogues[dialogueID].pinned = shouldPin;
}
/** Handle client/mail/dialog/read */
2023-03-03 15:23:46 +00:00
public setRead(dialogueIDs: string[], sessionID: string): void
{
const dialogueData = this.saveServer.getProfile(sessionID).dialogues;
for (const dialogID of dialogueIDs)
{
dialogueData[dialogID].new = 0;
dialogueData[dialogID].attachmentsNew = 0;
}
}
/**
* Handle client/mail/dialog/getAllAttachments
2023-03-03 15:23:46 +00:00
* Get all uncollected items attached to mail in a particular dialog
* @param dialogueID Dialog to get mail attachments from
* @param sessionID Session id
* @returns
*/
public getAllAttachments(dialogueID: string, sessionID: string): IGetAllAttachmentsResponse
{
// Removes corner 'new messages' tag
this.saveServer.getProfile(sessionID).dialogues[dialogueID].attachmentsNew = 0;
const activeMessages = this.getActiveMessagesFromDialog(sessionID, dialogueID);
const messagesWithAttachments = this.getMessagesWithAttachments(activeMessages);
return {
messages: messagesWithAttachments,
profiles: [],
hasMessagesWithRewards: this.messagesHaveUncollectedRewards(messagesWithAttachments)
};
}
/**
* Get messages from a specific dialog that have items not expired
* @param sessionId Session id
* @param dialogueId Dialog to get mail attachments from
* @returns Message array
*/
protected getActiveMessagesFromDialog(sessionId: string, dialogueId: string): Message[]
{
const timeNow = this.timeUtil.getTimestamp();
return this.saveServer.getProfile(sessionId).dialogues[dialogueId].messages.filter(x => timeNow < (x.dt + x.maxStorageTime));
}
/**
* Return array of messages with uncollected items (includes expired)
* @param messages Messages to parse
* @returns messages with items to collect
*/
protected getMessagesWithAttachments(messages: Message[]): Message[]
{
return messages.filter(x => x.items?.data?.length > 0);
}
/**
* Delete expired items from all messages in player profile. triggers when updating traders.
* @param sessionId Session id
2023-03-03 15:23:46 +00:00
*/
protected removeExpiredItemsFromMessages(sessionId: string): void
2023-03-03 15:23:46 +00:00
{
for (const dialogueId in this.saveServer.getProfile(sessionId).dialogues)
2023-03-03 15:23:46 +00:00
{
this.removeExpiredItemsFromMessage(sessionId, dialogueId);
}
}
/**
* Removes expired items from a message in player profile
* @param sessionId Session id
* @param dialogueId Dialog id
*/
protected removeExpiredItemsFromMessage(sessionId: string, dialogueId: string): void
{
for (const message of this.saveServer.getProfile(sessionId).dialogues[dialogueId].messages)
{
if (this.messageHasExpired(message))
2023-03-03 15:23:46 +00:00
{
message.items = {};
2023-03-03 15:23:46 +00:00
}
}
}
/**
* Has a dialog message expired
* @param message Message to check expiry of
* @returns true or false
*/
protected messageHasExpired(message: Message): boolean
{
return (this.timeUtil.getTimestamp()) > (message.dt + message.maxStorageTime);
}
2023-03-03 15:23:46 +00:00
}