Feature: Improve numerous endpoints + add function for sending messages to player (!39)

Co-authored-by: Dev <dev@noreply.dev.sp-tarkov.com>
Reviewed-on: https://dev.sp-tarkov.com/SPT-AKI/Server/pulls/39
This commit is contained in:
chomp 2023-03-07 22:25:23 +00:00
parent 40296579c9
commit e4bc6c8d68
22 changed files with 331 additions and 63 deletions

View File

@ -4,7 +4,10 @@ import { DialogueController } from "../controllers/DialogueController";
import { OnUpdate } from "../di/OnUpdate"; import { OnUpdate } from "../di/OnUpdate";
import { IEmptyRequestData } from "../models/eft/common/IEmptyRequestData"; import { IEmptyRequestData } from "../models/eft/common/IEmptyRequestData";
import { IChatServer } from "../models/eft/dialog/IChatServer"; import { IChatServer } from "../models/eft/dialog/IChatServer";
import { IClearMailMessageRequest } from "../models/eft/dialog/IClearMailMessageRequest";
import { IDeleteFriendRequest } from "../models/eft/dialog/IDeleteFriendRequest";
import { IFriendRequestData } from "../models/eft/dialog/IFriendRequestData"; import { IFriendRequestData } from "../models/eft/dialog/IFriendRequestData";
import { IFriendRequestSendResponse } from "../models/eft/dialog/IFriendRequestSendResponse";
import { IGetAllAttachmentsRequestData } from "../models/eft/dialog/IGetAllAttachmentsRequestData"; import { IGetAllAttachmentsRequestData } from "../models/eft/dialog/IGetAllAttachmentsRequestData";
import { IGetAllAttachmentsResponse } from "../models/eft/dialog/IGetAllAttachmentsResponse"; import { IGetAllAttachmentsResponse } from "../models/eft/dialog/IGetAllAttachmentsResponse";
import { IGetChatServerListRequestData } from "../models/eft/dialog/IGetChatServerListRequestData"; import { IGetChatServerListRequestData } from "../models/eft/dialog/IGetChatServerListRequestData";
@ -17,6 +20,7 @@ import {
} from "../models/eft/dialog/IGetMailDialogViewResponseData"; } from "../models/eft/dialog/IGetMailDialogViewResponseData";
import { IPinDialogRequestData } from "../models/eft/dialog/IPinDialogRequestData"; import { IPinDialogRequestData } from "../models/eft/dialog/IPinDialogRequestData";
import { IRemoveDialogRequestData } from "../models/eft/dialog/IRemoveDialogRequestData"; import { IRemoveDialogRequestData } from "../models/eft/dialog/IRemoveDialogRequestData";
import { IRemoveMailMessageRequest } from "../models/eft/dialog/IRemoveMailMessageRequest";
import { ISendMessageRequest } from "../models/eft/dialog/ISendMessageRequest"; import { ISendMessageRequest } from "../models/eft/dialog/ISendMessageRequest";
import { ISetDialogReadRequestData } from "../models/eft/dialog/ISetDialogReadRequestData"; import { ISetDialogReadRequestData } from "../models/eft/dialog/ISetDialogReadRequestData";
import { IGetBodyResponseData } from "../models/eft/httpResponse/IGetBodyResponseData"; import { IGetBodyResponseData } from "../models/eft/httpResponse/IGetBodyResponseData";
@ -76,21 +80,25 @@ export class DialogueCallbacks implements OnUpdate
return this.httpResponse.getBody([chatServer]); return this.httpResponse.getBody([chatServer]);
} }
/** Handle client/mail/dialog/list */
public getMailDialogList(url: string, info: IGetMailDialogListRequestData, sessionID: string): IGetBodyResponseData<DialogueInfo[]> public getMailDialogList(url: string, info: IGetMailDialogListRequestData, sessionID: string): IGetBodyResponseData<DialogueInfo[]>
{ {
return this.httpResponse.getBody(this.dialogueController.generateDialogueList(sessionID)); return this.httpResponse.getBody(this.dialogueController.generateDialogueList(sessionID));
} }
/** Handle client/mail/dialog/view */
public getMailDialogView(url: string, info: IGetMailDialogViewRequestData, sessionID: string): IGetBodyResponseData<IGetMailDialogViewResponseData> public getMailDialogView(url: string, info: IGetMailDialogViewRequestData, sessionID: string): IGetBodyResponseData<IGetMailDialogViewResponseData>
{ {
return this.httpResponse.getBody(this.dialogueController.generateDialogueView(info.dialogId, sessionID)); return this.httpResponse.getBody(this.dialogueController.generateDialogueView(info.dialogId, sessionID));
} }
/** Handle client/mail/dialog/info */
public getMailDialogInfo(url: string, info: IGetMailDialogInfoRequestData, sessionID: string): IGetBodyResponseData<DialogueInfo> public getMailDialogInfo(url: string, info: IGetMailDialogInfoRequestData, sessionID: string): IGetBodyResponseData<DialogueInfo>
{ {
return this.httpResponse.getBody(this.dialogueController.getDialogueInfo(info.dialogId, sessionID)); return this.httpResponse.getBody(this.dialogueController.getDialogueInfo(info.dialogId, sessionID));
} }
/** Handle client/mail/dialog/remove */
public removeDialog(url: string, info: IRemoveDialogRequestData, sessionID: string): IGetBodyResponseData<any[]> public removeDialog(url: string, info: IRemoveDialogRequestData, sessionID: string): IGetBodyResponseData<any[]>
{ {
this.dialogueController.removeDialogue(info.dialogId, sessionID); this.dialogueController.removeDialogue(info.dialogId, sessionID);
@ -124,6 +132,7 @@ export class DialogueCallbacks implements OnUpdate
return this.httpResponse.getBody(this.dialogueController.getAllAttachments(info.dialogId, sessionID)); return this.httpResponse.getBody(this.dialogueController.getAllAttachments(info.dialogId, sessionID));
} }
/** Handle client/friend/request/list/outbox */
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
public listOutbox(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<any[]> public listOutbox(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<any[]>
{ {
@ -137,7 +146,13 @@ export class DialogueCallbacks implements OnUpdate
} }
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
public friendRequest(url: string, request: IFriendRequestData, sessionID: string): INullResponseData public sendFriendRequest(url: string, request: IFriendRequestData, sessionID: string): IGetBodyResponseData<IFriendRequestSendResponse>
{
return this.httpResponse.getBody({status: 0, requestid: "12345", retryAfter: 600});
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
public deleteFriend(url: string, request: IDeleteFriendRequest, sessionID: string): INullResponseData
{ {
return this.httpResponse.nullResponse(); return this.httpResponse.nullResponse();
} }
@ -148,6 +163,18 @@ export class DialogueCallbacks implements OnUpdate
return this.httpResponse.getBody(1); return this.httpResponse.getBody(1);
} }
// eslint-disable-next-line @typescript-eslint/no-unused-vars
public clearMail(url: string, request: IClearMailMessageRequest, sessionID: string): IGetBodyResponseData<any[]>
{
return this.httpResponse.emptyArrayResponse();
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
public removeMail(url: string, request: IRemoveMailMessageRequest, sessionID: string): IGetBodyResponseData<any[]>
{
return this.httpResponse.emptyArrayResponse();
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
public async onUpdate(timeSinceLastRun: number): Promise<boolean> public async onUpdate(timeSinceLastRun: number): Promise<boolean>
{ {

View File

@ -5,6 +5,9 @@ import { IEmptyRequestData } from "../models/eft/common/IEmptyRequestData";
import { IPmcData } from "../models/eft/common/IPmcData"; import { IPmcData } from "../models/eft/common/IPmcData";
import { IGetBodyResponseData } from "../models/eft/httpResponse/IGetBodyResponseData"; import { IGetBodyResponseData } from "../models/eft/httpResponse/IGetBodyResponseData";
import { INullResponseData } from "../models/eft/httpResponse/INullResponseData"; import { INullResponseData } from "../models/eft/httpResponse/INullResponseData";
import { IAcceptGroupInviteRequest } from "../models/eft/match/IAcceptGroupInviteRequest";
import { IAcceptGroupInviteResponse } from "../models/eft/match/IAcceptGroupInviteResponse";
import { ICancelGroupInviteRequest } from "../models/eft/match/ICancelGroupInviteRequest";
import { ICreateGroupRequestData } from "../models/eft/match/ICreateGroupRequestData"; import { ICreateGroupRequestData } from "../models/eft/match/ICreateGroupRequestData";
import { IEndOfflineRaidRequestData } from "../models/eft/match/IEndOfflineRaidRequestData"; import { IEndOfflineRaidRequestData } from "../models/eft/match/IEndOfflineRaidRequestData";
import { IGetGroupStatusRequestData } from "../models/eft/match/IGetGroupStatusRequestData"; import { IGetGroupStatusRequestData } from "../models/eft/match/IGetGroupStatusRequestData";
@ -15,6 +18,8 @@ import {
import { IJoinMatchRequestData } from "../models/eft/match/IJoinMatchRequestData"; import { IJoinMatchRequestData } from "../models/eft/match/IJoinMatchRequestData";
import { IJoinMatchResult } from "../models/eft/match/IJoinMatchResult"; import { IJoinMatchResult } from "../models/eft/match/IJoinMatchResult";
import { IPutMetricsRequestData } from "../models/eft/match/IPutMetricsRequestData"; import { IPutMetricsRequestData } from "../models/eft/match/IPutMetricsRequestData";
import { IRemovePlayerFromGroupRequest } from "../models/eft/match/IRemovePlayerFromGroupRequest";
import { ISendGroupInviteRequest } from "../models/eft/match/ISendGroupInviteRequest";
import { IUpdatePingRequestData } from "../models/eft/match/IUpdatePingRequestData"; import { IUpdatePingRequestData } from "../models/eft/match/IUpdatePingRequestData";
import { DatabaseServer } from "../servers/DatabaseServer"; import { DatabaseServer } from "../servers/DatabaseServer";
import { HttpResponseUtil } from "../utils/HttpResponseUtil"; import { HttpResponseUtil } from "../utils/HttpResponseUtil";
@ -62,21 +67,26 @@ export class MatchCallbacks
} }
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
public sendGroupInvite(url: string, info: any, sessionID: string): INullResponseData public sendGroupInvite(url: string, info: ISendGroupInviteRequest, sessionID: string): IGetBodyResponseData<string>
{ {
return this.httpResponse.nullResponse(); return this.httpResponse.getBody("2427943f23698ay9f2863735");
} }
/** Handle client/match/group/invite/accept */
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
public acceptGroupInvite(url: string, info: any, sessionID: string): INullResponseData public acceptGroupInvite(url: string, info: IAcceptGroupInviteRequest, sessionID: string): IGetBodyResponseData<IAcceptGroupInviteResponse[]>
{ {
return this.httpResponse.nullResponse(); const result = [];
result.push({});
return this.httpResponse.getBody(result);
} }
/** Handle client/match/group/invite/cancel */
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
public cancelGroupInvite(url: string, info: any, sessionID: string): INullResponseData public cancelGroupInvite(url: string, info: ICancelGroupInviteRequest, sessionID: string): IGetBodyResponseData<boolean>
{ {
return this.httpResponse.nullResponse(); return this.httpResponse.getBody(true);
} }
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
@ -143,6 +153,12 @@ export class MatchCallbacks
return this.httpResponse.nullResponse(); return this.httpResponse.nullResponse();
} }
// eslint-disable-next-line @typescript-eslint/no-unused-vars
public removePlayerFromGroup(url: string, info: IRemovePlayerFromGroupRequest, sessionID: string): INullResponseData
{
return this.httpResponse.nullResponse();
}
public endOfflineRaid(url: string, info: IEndOfflineRaidRequestData, sessionID: string): INullResponseData public endOfflineRaid(url: string, info: IEndOfflineRaidRequestData, sessionID: string): INullResponseData
{ {
this.matchController.endOfflineRaid(info, sessionID); this.matchController.endOfflineRaid(info, sessionID);

View File

@ -6,7 +6,7 @@ import { IGetFriendListDataResponse } from "../models/eft/dialog/IGetFriendListD
import { import {
IGetMailDialogViewResponseData IGetMailDialogViewResponseData
} from "../models/eft/dialog/IGetMailDialogViewResponseData"; } from "../models/eft/dialog/IGetMailDialogViewResponseData";
import { DialogueInfo, Message } from "../models/eft/profile/IAkiProfile"; import { DialogueInfo, IAkiProfile, IUserDialogInfo, Message } from "../models/eft/profile/IAkiProfile";
import { MessageType } from "../models/enums/MessageType"; import { MessageType } from "../models/enums/MessageType";
import { SaveServer } from "../servers/SaveServer"; import { SaveServer } from "../servers/SaveServer";
import { TimeUtil } from "../utils/TimeUtil"; import { TimeUtil } from "../utils/TimeUtil";
@ -67,14 +67,17 @@ export class DialogueController
{ {
const dialogue = this.saveServer.getProfile(sessionID).dialogues[dialogueID]; const dialogue = this.saveServer.getProfile(sessionID).dialogues[dialogueID];
return { const result: DialogueInfo = {
"_id": dialogueID, "_id": dialogueID,
"type": MessageType.NPC_TRADER, "type": dialogue.type ? dialogue.type : MessageType.NPC_TRADER,
"message": this.dialogueHelper.getMessagePreview(dialogue), "message": this.dialogueHelper.getMessagePreview(dialogue),
"new": dialogue.new, "new": dialogue.new,
"attachmentsNew": dialogue.attachmentsNew, "attachmentsNew": dialogue.attachmentsNew,
"pinned": dialogue.pinned "pinned": dialogue.pinned,
Users: dialogue.Users ? dialogue.Users : undefined
}; };
return result;
} }
/** /**
@ -87,7 +90,8 @@ export class DialogueController
*/ */
public generateDialogueView(dialogueID: string, sessionID: string): IGetMailDialogViewResponseData public generateDialogueView(dialogueID: string, sessionID: string): IGetMailDialogViewResponseData
{ {
const dialogue = this.saveServer.getProfile(sessionID).dialogues[dialogueID]; const profile = this.saveServer.getProfile(sessionID);
const dialogue = profile.dialogues[dialogueID];
dialogue.new = 0; dialogue.new = 0;
// Set number of new attachments, but ignore those that have expired. // Set number of new attachments, but ignore those that have expired.
@ -95,11 +99,32 @@ export class DialogueController
return { return {
messages: dialogue.messages, messages: dialogue.messages,
profiles: [], profiles: this.getProfilesForMail(profile, dialogue.Users),
hasMessagesWithRewards: this.messagesHaveUncollectedRewards(dialogue.messages) 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;
}
/** /**
* Get a count of messages with attachments from a particular dialog * Get a count of messages with attachments from a particular dialog
* @param sessionID Session id * @param sessionID Session id

View File

@ -6,6 +6,7 @@ import { PlayerScavGenerator } from "../generators/PlayerScavGenerator";
import { HealthHelper } from "../helpers/HealthHelper"; import { HealthHelper } from "../helpers/HealthHelper";
import { InRaidHelper } from "../helpers/InRaidHelper"; import { InRaidHelper } from "../helpers/InRaidHelper";
import { ItemHelper } from "../helpers/ItemHelper"; import { ItemHelper } from "../helpers/ItemHelper";
import { NotificationSendHelper } from "../helpers/NotificationSendHelper";
import { ProfileHelper } from "../helpers/ProfileHelper"; import { ProfileHelper } from "../helpers/ProfileHelper";
import { QuestHelper } from "../helpers/QuestHelper"; import { QuestHelper } from "../helpers/QuestHelper";
import { TraderHelper } from "../helpers/TraderHelper"; import { TraderHelper } from "../helpers/TraderHelper";
@ -15,7 +16,10 @@ import { BodyPartHealth } from "../models/eft/common/tables/IBotBase";
import { Item } from "../models/eft/common/tables/IItem"; import { Item } from "../models/eft/common/tables/IItem";
import { IRegisterPlayerRequestData } from "../models/eft/inRaid/IRegisterPlayerRequestData"; import { IRegisterPlayerRequestData } from "../models/eft/inRaid/IRegisterPlayerRequestData";
import { ISaveProgressRequestData } from "../models/eft/inRaid/ISaveProgressRequestData"; import { ISaveProgressRequestData } from "../models/eft/inRaid/ISaveProgressRequestData";
import { IUserDialogInfo } from "../models/eft/profile/IAkiProfile";
import { ConfigTypes } from "../models/enums/ConfigTypes"; import { ConfigTypes } from "../models/enums/ConfigTypes";
import { MemberCategory } from "../models/enums/MemberCategory";
import { MessageType } from "../models/enums/MessageType";
import { Traders } from "../models/enums/Traders"; import { Traders } from "../models/enums/Traders";
import { IAirdropConfig } from "../models/spt/config/IAirdropConfig"; import { IAirdropConfig } from "../models/spt/config/IAirdropConfig";
import { IInRaidConfig } from "../models/spt/config/IInRaidConfig"; import { IInRaidConfig } from "../models/spt/config/IInRaidConfig";
@ -24,6 +28,7 @@ import { ConfigServer } from "../servers/ConfigServer";
import { DatabaseServer } from "../servers/DatabaseServer"; import { DatabaseServer } from "../servers/DatabaseServer";
import { SaveServer } from "../servers/SaveServer"; import { SaveServer } from "../servers/SaveServer";
import { InsuranceService } from "../services/InsuranceService"; import { InsuranceService } from "../services/InsuranceService";
import { LocaleService } from "../services/LocaleService";
import { JsonUtil } from "../utils/JsonUtil"; import { JsonUtil } from "../utils/JsonUtil";
import { TimeUtil } from "../utils/TimeUtil"; import { TimeUtil } from "../utils/TimeUtil";
@ -42,10 +47,12 @@ export class InraidController
@inject("JsonUtil") protected jsonUtil: JsonUtil, @inject("JsonUtil") protected jsonUtil: JsonUtil,
@inject("TimeUtil") protected timeUtil: TimeUtil, @inject("TimeUtil") protected timeUtil: TimeUtil,
@inject("DatabaseServer") protected databaseServer: DatabaseServer, @inject("DatabaseServer") protected databaseServer: DatabaseServer,
@inject("LocaleService") protected localeService: LocaleService,
@inject("QuestHelper") protected questHelper: QuestHelper, @inject("QuestHelper") protected questHelper: QuestHelper,
@inject("ItemHelper") protected itemHelper: ItemHelper, @inject("ItemHelper") protected itemHelper: ItemHelper,
@inject("ProfileHelper") protected profileHelper: ProfileHelper, @inject("ProfileHelper") protected profileHelper: ProfileHelper,
@inject("PlayerScavGenerator") protected playerScavGenerator: PlayerScavGenerator, @inject("PlayerScavGenerator") protected playerScavGenerator: PlayerScavGenerator,
@inject("NotificationSendHelper") protected notificationSendHelper: NotificationSendHelper,
@inject("HealthHelper") protected healthHelper: HealthHelper, @inject("HealthHelper") protected healthHelper: HealthHelper,
@inject("TraderHelper") protected traderHelper: TraderHelper, @inject("TraderHelper") protected traderHelper: TraderHelper,
@inject("InsuranceService") protected insuranceService: InsuranceService, @inject("InsuranceService") protected insuranceService: InsuranceService,
@ -128,9 +135,22 @@ export class InraidController
} }
else else
{ {
if (locationName === "Laboratory") if (locationName.toLowerCase() === "laboratory")
{ {
// TODO: dump of prapor/therapist dialogues that are sent when you die in lab with insured items const localeDb = this.localeService.getLocaleDb();
const failedText = localeDb["5a8fd75188a45036844e0b0c"];
const senderDetails: IUserDialogInfo = {
_id: Traders.PRAPOR,
info: {
Nickname: "Prapor",
Level: 1,
Side: "Bear",
MemberCategory: MemberCategory.TRADER
}
};
this.notificationSendHelper.sendMessageToPlayer(sessionID, senderDetails, failedText, MessageType.NPC_TRADER);
} }
} }

View File

@ -54,6 +54,7 @@ export class DialogueHelper
{ {
dialogue = { dialogue = {
_id: dialogueID, _id: dialogueID,
type: MessageType.NPC_TRADER,
messages: [], messages: [],
pinned: false, pinned: false,
new: 0, new: 0,
@ -124,24 +125,11 @@ export class DialogueHelper
hasRewards: rewards.length > 0, hasRewards: rewards.length > 0,
rewardCollected: false, rewardCollected: false,
items: items, items: items,
maxStorageTime: messageContent.maxStorageTime maxStorageTime: messageContent.maxStorageTime,
systemData: messageContent.systemData ? messageContent.systemData : undefined,
profileChangeEvents: (messageContent.profileChangeEvents?.length === 0) ? messageContent.profileChangeEvents : undefined
}; };
if (messageContent.systemData)
{
message.systemData = messageContent.systemData;
}
if (messageContent.text || messageContent.text === "")
{
message.text = messageContent.text;
}
if (messageContent.profileChangeEvents || messageContent.profileChangeEvents?.length === 0)
{
message.profileChangeEvents = messageContent.profileChangeEvents;
}
dialogue.messages.push(message); dialogue.messages.push(message);
// Offer Sold notifications are now separate from the main notification // Offer Sold notifications are now separate from the main notification
@ -159,19 +147,30 @@ export class DialogueHelper
/** /**
* Get the preview contents of the last message in a dialogue. * Get the preview contents of the last message in a dialogue.
* @param dialogue * @param dialogue
* @returns * @returns MessagePreview
*/ */
public getMessagePreview(dialogue: Dialogue): MessagePreview public getMessagePreview(dialogue: Dialogue): MessagePreview
{ {
// The last message of the dialogue should be shown on the preview. // The last message of the dialogue should be shown on the preview.
const message = dialogue.messages[dialogue.messages.length - 1]; const message = dialogue.messages[dialogue.messages.length - 1];
const result: MessagePreview = {
return {
dt: message.dt, dt: message.dt,
type: message.type, type: message.type,
templateId: message.templateId, templateId: message.templateId,
uid: dialogue._id uid: dialogue._id
}; };
if (message.text)
{
result.text = message.text;
}
if (message.systemData)
{
result.systemData = message.systemData;
}
return result;
} }
/** /**

View File

@ -1,19 +1,29 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { INotification } from "../models/eft/notifier/INotifier"; import { INotification } from "../models/eft/notifier/INotifier";
import { Dialogue, IUserDialogInfo, Message } from "../models/eft/profile/IAkiProfile";
import { MemberCategory } from "../models/enums/MemberCategory";
import { MessageType } from "../models/enums/MessageType";
import { SaveServer } from "../servers/SaveServer";
import { WebSocketServer } from "../servers/WebSocketServer"; import { WebSocketServer } from "../servers/WebSocketServer";
import { NotificationService } from "../services/NotificationService"; import { NotificationService } from "../services/NotificationService";
import { HashUtil } from "../utils/HashUtil";
@injectable() @injectable()
export class NotificationSendHelper export class NotificationSendHelper
{ {
constructor( constructor(
@inject("WebSocketServer") protected webSocketServer: WebSocketServer, @inject("WebSocketServer") protected webSocketServer: WebSocketServer,
@inject("HashUtil") protected hashUtil: HashUtil,
@inject("SaveServer") protected saveServer: SaveServer,
@inject("NotificationService") protected notificationService: NotificationService @inject("NotificationService") protected notificationService: NotificationService
) )
{} {}
/** /**
* Send notification message to the appropriate channel * Send notification message to the appropriate channel
* @param sessionID
* @param notificationMessage
*/ */
public sendMessage(sessionID: string, notificationMessage: INotification): void public sendMessage(sessionID: string, notificationMessage: INotification): void
{ {
@ -26,4 +36,70 @@ export class NotificationSendHelper
this.notificationService.add(sessionID, notificationMessage); this.notificationService.add(sessionID, notificationMessage);
} }
} }
/**
* Send a message directly to the player
* @param sessionId Session id
* @param senderDetails Who is sendin the message to player
* @param messageText Text to send player
* @param messageType Underlying type of message being sent
*/
public sendMessageToPlayer(sessionId: string, senderDetails: IUserDialogInfo, messageText: string, messageType: MessageType): void
{
const dialog = this.getDialog(sessionId, messageType, senderDetails);
dialog.new += 1;
const message: Message = {
_id: this.hashUtil.generate(),
uid: dialog._id,
type: messageType,
dt: Math.round(Date.now() / 1000),
text: messageText,
hasRewards: undefined,
rewardCollected: undefined,
items: undefined
};
dialog.messages.push(message);
const notification: INotification = {
type: "new_message",
eventId: message._id,
dialogId: message.uid,
message: message
};
this.sendMessage(sessionId, notification);
}
/**
* Helper function for sendMessageToPlayer(), get new dialog for storage in profile or find existing by sender id
* @param sessionId Session id
* @param messageType Type of message to generate
* @param senderDetails Who is sending the message
* @returns Dialogue
*/
protected getDialog(sessionId: string, messageType: MessageType, senderDetails: IUserDialogInfo): Dialogue
{
// Use trader id if sender is trader, otherwise use nickname
const key = (senderDetails.info.MemberCategory === MemberCategory.TRADER) ? senderDetails._id : senderDetails.info.Nickname;
const dialogueData = this.saveServer.getProfile(sessionId).dialogues;
const isNewDialogue = !(key in dialogueData);
let dialogue: Dialogue = dialogueData[key];
// Existing dialog not found, make new one
if (isNewDialogue)
{
dialogue = {
_id: key,
type: messageType,
messages: [],
pinned: false,
new: 0,
attachmentsNew: 0,
Users: (senderDetails.info.MemberCategory === MemberCategory.TRADER) ? undefined : [senderDetails]
};
dialogueData[key] = dialogue;
}
return dialogue;
}
} }

View File

@ -0,0 +1,4 @@
export interface IClearMailMessageRequest
{
dialogId: string
}

View File

@ -0,0 +1,5 @@
export interface IDeleteFriendRequest
{
// eslint-disable-next-line @typescript-eslint/naming-convention
friend_id: string
}

View File

@ -0,0 +1,6 @@
export interface IFriendRequestSendResponse
{
status: number
requestid: string
retryAfter: number
}

View File

@ -1,9 +1,9 @@
import { MessageType } from "../../enums/MessageType" import { MessageType } from "../../enums/MessageType";
export interface IGetMailDialogViewRequestData export interface IGetMailDialogViewRequestData
{ {
type: MessageType type: MessageType
dialogId: string dialogId: string
limit: number limit: number
time: number time: number // decimal
} }

View File

@ -1,9 +1,8 @@
import { IPmcData } from "../common/IPmcData" import { Message } from "../profile/IAkiProfile";
import { Message } from "../profile/IAkiProfile"
export interface IGetMailDialogViewResponseData export interface IGetMailDialogViewResponseData
{ {
messages: Message[] messages: Message[]
profiles: IPmcData[] profiles: any[]
hasMessagesWithRewards: boolean hasMessagesWithRewards: boolean
} }

View File

@ -0,0 +1,4 @@
export interface IRemoveMailMessageRequest
{
dialogId: string
}

View File

@ -0,0 +1,4 @@
export interface IAcceptGroupInviteRequest
{
requestId: string
}

View File

@ -0,0 +1,19 @@
export interface IAcceptGroupInviteResponse
{
_id: string
aid: number
Info: PlayerInviteInfo
isLeader: boolean
isReady: boolean
}
export interface PlayerInviteInfo
{
Nickname: string
Side: string
Level: number
MemberCategory: number
GameVersion: string
SavageLockTime: number
SavageNickname: string
}

View File

@ -0,0 +1,4 @@
export interface ICancelGroupInviteRequest
{
requestId: string
}

View File

@ -0,0 +1,4 @@
export interface IRemovePlayerFromGroupRequest
{
aidToKick: string
}

View File

@ -0,0 +1,5 @@
export interface ISendGroupInviteRequest
{
to: string
inLobby: boolean
}

View File

@ -1,3 +1,4 @@
import { Message } from "../profile/IAkiProfile";
export interface INotifierChannel export interface INotifierChannel
{ {
server: string server: string
@ -8,7 +9,6 @@ export interface INotifierChannel
ws: string ws: string
} }
import { Message } from "../profile/IAkiProfile"
export interface INotification export interface INotification
{ {

View File

@ -1,6 +1,7 @@
import { MessageType } from "../../enums/MessageType" import { MemberCategory } from "../../../models/enums/MemberCategory";
import { IPmcData } from "../common/IPmcData" import { MessageType } from "../../enums/MessageType";
import { Item } from "../common/tables/IItem" import { IPmcData } from "../common/IPmcData";
import { Item } from "../common/tables/IItem";
export interface IAkiProfile export interface IAkiProfile
{ {
@ -19,8 +20,8 @@ export interface IAkiProfile
export class TraderPurchaseData export class TraderPurchaseData
{ {
count: number count: number;
purchaseTimestamp: number purchaseTimestamp: number;
} }
export interface Info export interface Info
@ -48,11 +49,27 @@ export interface WeaponBuild
export interface Dialogue export interface Dialogue
{ {
_id: string
messages: Message[]
pinned: boolean
new: number
attachmentsNew: number attachmentsNew: number
type: MessageType
new: number
_id: string
Users?: IUserDialogInfo[]
pinned: boolean
messages: Message[]
}
export interface IUserDialogInfo
{
_id: string
info: IUserDialogDetails
}
export interface IUserDialogDetails
{
Nickname: string
Side: string
Level: number
MemberCategory: MemberCategory
} }
// @Cleanup: Maybe the same as Dialogue? // @Cleanup: Maybe the same as Dialogue?
@ -60,10 +77,11 @@ export interface DialogueInfo
{ {
attachmentsNew: number attachmentsNew: number
new: number new: number
_id: string
type: MessageType type: MessageType
pinned: boolean pinned: boolean
Users?: any[]
message: MessagePreview message: MessagePreview
_id: string
} }
export interface Message export interface Message
@ -74,7 +92,7 @@ export interface Message
dt: number dt: number
UtcDateTime?: number UtcDateTime?: number
Member?: IUpdatableChatMember Member?: IUpdatableChatMember
templateId: string templateId?: string
text?: string text?: string
hasRewards: boolean hasRewards: boolean
rewardCollected: boolean rewardCollected: boolean
@ -91,6 +109,7 @@ export interface MessagePreview
dt: number dt: number
templateId: string templateId: string
text?: string text?: string
systemData?: ISystemData
} }
export interface MessageItems export interface MessageItems

View File

@ -1,19 +1,19 @@
import { IGetBodyResponseData } from "../../eft/httpResponse/IGetBodyResponseData";
import { INullResponseData } from "../../eft/httpResponse/INullResponseData";
import { IGetMailDialogViewRequestData } from "../../eft/dialog/IGetMailDialogViewRequestData";
import { IGetMailDialogInfoRequestData } from "../../eft/dialog/IGetMailDialogInfoRequestData";
import { IRemoveDialogRequestData } from "../../eft/dialog/IRemoveDialogRequestData";
import { IGetMailDialogListRequestData } from "../../eft/dialog/IGetMailDialogListRequestData";
import { IEmptyRequestData } from "../../eft/common/IEmptyRequestData"; import { IEmptyRequestData } from "../../eft/common/IEmptyRequestData";
import { IFriendRequestData } from "../../eft/dialog/IFriendRequestData"; import { IFriendRequestData } from "../../eft/dialog/IFriendRequestData";
import { IPinDialogRequestData } from "../../eft/dialog/IPinDialogRequestData";
import { ISetDialogReadRequestData } from "../../eft/dialog/ISetDialogReadRequestData";
import { IGetAllAttachmentsRequestData } from "../../eft/dialog/IGetAllAttachmentsRequestData"; import { IGetAllAttachmentsRequestData } from "../../eft/dialog/IGetAllAttachmentsRequestData";
import { IGetAllAttachmentsResponse } from "../../eft/dialog/IGetAllAttachmentsResponse";
import { IGetChatServerListRequestData } from "../../eft/dialog/IGetChatServerListRequestData"; import { IGetChatServerListRequestData } from "../../eft/dialog/IGetChatServerListRequestData";
import { IGetFriendListDataResponse } from "../../eft/dialog/IGetFriendListDataResponse"; import { IGetFriendListDataResponse } from "../../eft/dialog/IGetFriendListDataResponse";
import { ISendMessageRequest } from "../../eft/dialog/ISendMessageRequest"; import { IGetMailDialogInfoRequestData } from "../../eft/dialog/IGetMailDialogInfoRequestData";
import { IGetMailDialogListRequestData } from "../../eft/dialog/IGetMailDialogListRequestData";
import { IGetMailDialogViewRequestData } from "../../eft/dialog/IGetMailDialogViewRequestData";
import { IGetMailDialogViewResponseData } from "../../eft/dialog/IGetMailDialogViewResponseData"; import { IGetMailDialogViewResponseData } from "../../eft/dialog/IGetMailDialogViewResponseData";
import { IGetAllAttachmentsResponse } from "../../eft/dialog/IGetAllAttachmentsResponse"; import { IPinDialogRequestData } from "../../eft/dialog/IPinDialogRequestData";
import { IRemoveDialogRequestData } from "../../eft/dialog/IRemoveDialogRequestData";
import { ISendMessageRequest } from "../../eft/dialog/ISendMessageRequest";
import { ISetDialogReadRequestData } from "../../eft/dialog/ISetDialogReadRequestData";
import { IGetBodyResponseData } from "../../eft/httpResponse/IGetBodyResponseData";
import { INullResponseData } from "../../eft/httpResponse/INullResponseData";
import { DialogueInfo } from "../../eft/profile/IAkiProfile"; import { DialogueInfo } from "../../eft/profile/IAkiProfile";
export interface IDialogueCallbacks export interface IDialogueCallbacks
@ -30,7 +30,7 @@ export interface IDialogueCallbacks
getAllAttachments(url: string, info: IGetAllAttachmentsRequestData, sessionID: string): IGetBodyResponseData<IGetAllAttachmentsResponse>; getAllAttachments(url: string, info: IGetAllAttachmentsRequestData, sessionID: string): IGetBodyResponseData<IGetAllAttachmentsResponse>;
listOutbox(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<any[]>; listOutbox(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<any[]>;
listInbox(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<any[]>; listInbox(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<any[]>;
friendRequest(url: string, request: IFriendRequestData, sessionID: string): INullResponseData; sendFriendRequest(url: string, request: IFriendRequestData, sessionID: string): INullResponseData;
sendMessage(url: string, request: ISendMessageRequest, sessionID: string): IGetBodyResponseData<number>; sendMessage(url: string, request: ISendMessageRequest, sessionID: string): IGetBodyResponseData<number>;
update(): boolean; update(): boolean;
} }

View File

@ -76,6 +76,14 @@ export class DialogStaticRouter extends StaticRouter
return this.dialogueCallbacks.setRead(url, info, sessionID); return this.dialogueCallbacks.setRead(url, info, sessionID);
} }
), ),
new RouteAction(
"/client/mail/dialog/remove",
// eslint-disable-next-line @typescript-eslint/no-unused-vars
(url: string, info: any, sessionID: string, output: string): any =>
{
return this.dialogueCallbacks.removeMail(url, info, sessionID);
}
),
new RouteAction( new RouteAction(
"/client/mail/dialog/getAllAttachments", "/client/mail/dialog/getAllAttachments",
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
@ -92,6 +100,14 @@ export class DialogStaticRouter extends StaticRouter
return this.dialogueCallbacks.sendMessage(url, info, sessionID); return this.dialogueCallbacks.sendMessage(url, info, sessionID);
} }
), ),
new RouteAction(
"/client/mail/dialog/clear",
// eslint-disable-next-line @typescript-eslint/no-unused-vars
(url: string, info: any, sessionID: string, output: string): any =>
{
return this.dialogueCallbacks.clearMail(url, info, sessionID);
}
),
new RouteAction( new RouteAction(
"/client/friend/list", "/client/friend/list",
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
@ -121,7 +137,15 @@ export class DialogStaticRouter extends StaticRouter
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
(url: string, info: any, sessionID: string, output: string): any => (url: string, info: any, sessionID: string, output: string): any =>
{ {
return this.dialogueCallbacks.friendRequest(url, info, sessionID); return this.dialogueCallbacks.sendFriendRequest(url, info, sessionID);
}
),
new RouteAction(
"/client/friend/delete",
// eslint-disable-next-line @typescript-eslint/no-unused-vars
(url: string, info: any, sessionID: string, output: string): any =>
{
return this.dialogueCallbacks.deleteFriend(url, info, sessionID);
} }
) )
] ]

View File

@ -172,6 +172,14 @@ export class MatchStaticRouter extends StaticRouter
{ {
return this.matchCallbacks.getRaidConfiguration(url, info, sessionID); return this.matchCallbacks.getRaidConfiguration(url, info, sessionID);
} }
),
new RouteAction(
"/client/match/group/player/remove",
// eslint-disable-next-line @typescript-eslint/no-unused-vars
(url: string, info: any, sessionID: string, output: string): any =>
{
return this.matchCallbacks.removePlayerFromGroup(url, info, sessionID);
}
) )
] ]
); );