Server/project/src/services/GiftService.ts

222 lines
7.6 KiB
TypeScript

import { inject, injectable } from "tsyringe";
import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
import { ConfigTypes } from "@spt-aki/models/enums/ConfigTypes";
import { GiftSenderType } from "@spt-aki/models/enums/GiftSenderType";
import { GiftSentResult } from "@spt-aki/models/enums/GiftSentResult";
import { MessageType } from "@spt-aki/models/enums/MessageType";
import { Traders } from "@spt-aki/models/enums/Traders";
import { Gift, IGiftsConfig } from "@spt-aki/models/spt/config/IGiftsConfig";
import { ISendMessageDetails } from "@spt-aki/models/spt/dialog/ISendMessageDetails";
import { ILogger } from "@spt-aki/models/spt/utils/ILogger";
import { ConfigServer } from "@spt-aki/servers/ConfigServer";
import { MailSendService } from "@spt-aki/services/MailSendService";
import { HashUtil } from "@spt-aki/utils/HashUtil";
import { TimeUtil } from "@spt-aki/utils/TimeUtil";
@injectable()
export class GiftService
{
protected giftConfig: IGiftsConfig;
constructor(
@inject("WinstonLogger") protected logger: ILogger,
@inject("MailSendService") protected mailSendService: MailSendService,
@inject("HashUtil") protected hashUtil: HashUtil,
@inject("TimeUtil") protected timeUtil: TimeUtil,
@inject("ProfileHelper") protected profileHelper: ProfileHelper,
@inject("ConfigServer") protected configServer: ConfigServer,
)
{
this.giftConfig = this.configServer.getConfig(ConfigTypes.GIFTS);
}
/**
* Does a gift with a specific ID exist in db
* @param giftId Gift id to check for
* @returns True if it exists in db
*/
public giftExists(giftId: string): boolean
{
return !!this.giftConfig.gifts[giftId];
}
/**
* Send player a gift from a range of sources
* @param playerId Player to send gift to / sessionId
* @param giftId Id of gift in configs/gifts.json to send player
* @returns outcome of sending gift to player
*/
public sendGiftToPlayer(playerId: string, giftId: string): GiftSentResult
{
const giftData = this.giftConfig.gifts[giftId];
if (!giftData)
{
return GiftSentResult.FAILED_GIFT_DOESNT_EXIST;
}
if (this.profileHelper.playerHasRecievedGift(playerId, giftId))
{
this.logger.debug(`Player already recieved gift: ${giftId}`);
return GiftSentResult.FAILED_GIFT_ALREADY_RECEIVED;
}
if (giftData.items?.length > 0 && !giftData.collectionTimeHours)
{
this.logger.warning(`Gift ${giftId} has items but no collection time limit, defaulting to 48 hours`);
}
// Handle system messsages
if (giftData.sender === GiftSenderType.SYSTEM)
{
// Has a localisable text id to send to player
if (giftData.localeTextId)
{
this.mailSendService.sendLocalisedSystemMessageToPlayer(
playerId,
giftData.localeTextId,
giftData.items,
giftData.profileChangeEvents,
this.timeUtil.getHoursAsSeconds(giftData.collectionTimeHours),
);
}
else
{
this.mailSendService.sendSystemMessageToPlayer(
playerId,
giftData.messageText,
giftData.items,
this.timeUtil.getHoursAsSeconds(giftData.collectionTimeHours),
);
}
}
// Handle user messages
else if (giftData.sender === GiftSenderType.USER)
{
this.mailSendService.sendUserMessageToPlayer(
playerId,
giftData.senderDetails,
giftData.messageText,
giftData.items,
this.timeUtil.getHoursAsSeconds(giftData.collectionTimeHours),
);
}
else if (giftData.sender === GiftSenderType.TRADER)
{
if (giftData.localeTextId)
{
this.mailSendService.sendLocalisedNpcMessageToPlayer(
playerId,
giftData.trader,
MessageType.MESSAGE_WITH_ITEMS,
giftData.localeTextId,
giftData.items,
this.timeUtil.getHoursAsSeconds(giftData.collectionTimeHours),
);
}
else
{
this.mailSendService.sendDirectNpcMessageToPlayer(
playerId,
giftData.trader,
MessageType.MESSAGE_WITH_ITEMS,
giftData.messageText,
giftData.items,
this.timeUtil.getHoursAsSeconds(giftData.collectionTimeHours),
);
}
}
else
{
// TODO: further split out into different message systems like above SYSTEM method
// Trader / ragfair
const details: ISendMessageDetails = {
recipientId: playerId,
sender: this.getMessageType(giftData),
senderDetails: {
_id: this.getSenderId(giftData),
aid: 1234567, // TODO - pass proper aid value
Info: null },
messageText: giftData.messageText,
items: giftData.items,
itemsMaxStorageLifetimeSeconds: this.timeUtil.getHoursAsSeconds(giftData.collectionTimeHours),
};
if (giftData.trader)
{
details.trader = giftData.trader;
}
this.mailSendService.sendMessageToPlayer(details);
}
this.profileHelper.addGiftReceivedFlagToProfile(playerId, giftId);
return GiftSentResult.SUCCESS;
}
/**
* Get sender id based on gifts sender type enum
* @param giftData Gift to send player
* @returns trader/user/system id
*/
protected getSenderId(giftData: Gift): string
{
if (giftData.sender === GiftSenderType.TRADER)
{
return Traders[giftData.trader];
}
if (giftData.sender === GiftSenderType.USER)
{
return giftData.senderId;
}
}
/**
* Convert GiftSenderType into a dialog MessageType
* @param giftData Gift to send player
* @returns MessageType enum value
*/
protected getMessageType(giftData: Gift): MessageType
{
switch (giftData.sender)
{
case GiftSenderType.SYSTEM:
return MessageType.SYSTEM_MESSAGE;
case GiftSenderType.TRADER:
return MessageType.NPC_TRADER;
case GiftSenderType.USER:
return MessageType.USER_MESSAGE;
default:
this.logger.error(`Gift message type: ${giftData.sender} not handled`);
break;
}
}
/**
* Prapor sends gifts to player for first week after profile creation
* @param sessionId Player id
* @param day What day to give gift for
*/
public sendPraporStartingGift(sessionId: string, day: number): void
{
switch (day)
{
case 1:
if (this.profileHelper.playerHasRecievedGift(sessionId, "PraporGiftDay1"))
{
this.sendGiftToPlayer(sessionId, "PraporGiftDay1");
}
break;
case 2:
if (this.profileHelper.playerHasRecievedGift(sessionId, "PraporGiftDay2"))
{
this.sendGiftToPlayer(sessionId, "PraporGiftDay2");
}
break;
}
}
}