Receiving items in mail

This commit is contained in:
Benjamin Elsdon 2022-04-25 13:51:19 +08:00
parent 4e3a1c769f
commit ced5fc38be
9 changed files with 7662 additions and 45 deletions

7544
GM_Handbook.txt Normal file

File diff suppressed because it is too large Load Diff

View File

@ -24,7 +24,7 @@ public class SendMailCommand implements CommandHandler {
sender = Grasscutter.getGameServer().getPlayerByUid(7006); sender = Grasscutter.getGameServer().getPlayerByUid(7006);
} }
sender.sendMail(new Mail(new Mail.MailContent("Test", "This is a test"), sender.sendMail(new Mail(new Mail.MailContent("Test", "This is a test"),
new ArrayList<Mail.MailItem>(){{add(new Mail.MailItem(1062));}}, new ArrayList<Mail.MailItem>(){{add(new Mail.MailItem(23411 ));}},
Instant.now().getEpochSecond() + 4000)); Instant.now().getEpochSecond() + 4000));
sender.dropMessage("Check your inbox"); sender.dropMessage("Check your inbox");

View File

@ -573,15 +573,45 @@ public class GenshinPlayer {
this.sendPacket(new PacketPrivateChatNotify(sender.getUid(), this.getUid(), message.toString())); this.sendPacket(new PacketPrivateChatNotify(sender.getUid(), this.getUid(), message.toString()));
} }
public List<Mail> getMail() { return mail; } // ---------------------MAIL------------------------
public List<Mail> getAllMail() { return this.mail; }
public void sendMail(Mail message) { public void sendMail(Mail message) {
this.mail.add(message); this.mail.add(message);
message._id = this.mail.size() + 1; message._id = this.mail.size() + 1;
this.save(); this.save();
this.sendPacket(new PacketMailChangeNotify(this, message)); this.sendPacket(new PacketMailChangeNotify(this, message));
} }
public boolean deleteMail(int mailId) {
Mail message = getMailById(mailId);
if(message != null) {
this.mail.remove(message);
this.save();
return true;
}
return false;
}
public Mail getMailById(int mailId) {
return this.mail.stream().filter(message -> message._id == mailId).findFirst().orElse(null);
}
public int getMailIndex(Mail message) {
return this.mail.indexOf(message);
}
public boolean replaceMailByIndex(int mailId, Mail message) {
if(getMailById(mailId) != null) {
this.mail.set(mailId, message);
return true;
} else {
return false;
}
}
public void interactWith(int gadgetEntityId) { public void interactWith(int gadgetEntityId) {
GenshinEntity entity = getScene().getEntityById(gadgetEntityId); GenshinEntity entity = getScene().getEntityById(gadgetEntityId);

View File

@ -55,6 +55,10 @@ public class Mail {
this.stateValue = state; this.stateValue = state;
} }
public int getId() {
return this._id;
}
@Entity @Entity
public static class MailContent { public static class MailContent {
public String title; public String title;

View File

@ -15,7 +15,6 @@ public class HandlerGetAllMailReq extends PacketHandler {
@Override @Override
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception { public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
Grasscutter.getLogger().info("Mail Req");
GetAllMailReqOuterClass.GetAllMailReq req = GetAllMailReqOuterClass.GetAllMailReq.parseFrom(payload); GetAllMailReqOuterClass.GetAllMailReq req = GetAllMailReqOuterClass.GetAllMailReq.parseFrom(payload);
session.send(new PacketGetAllMailRsp(session.getPlayer(), req.getIsGiftMail())); session.send(new PacketGetAllMailRsp(session.getPlayer(), req.getIsGiftMail()));
} }

View File

@ -6,7 +6,6 @@ import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.net.packet.PacketOpcodes; import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.GetMailItemReqOuterClass; import emu.grasscutter.net.proto.GetMailItemReqOuterClass;
import emu.grasscutter.server.game.GameSession; import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketGetAllMailRsp;
import emu.grasscutter.server.packet.send.PacketGetMailItemRsp; import emu.grasscutter.server.packet.send.PacketGetMailItemRsp;
@Opcodes(PacketOpcodes.GetMailItemReq) @Opcodes(PacketOpcodes.GetMailItemReq)

View File

@ -1,17 +1,17 @@
package emu.grasscutter.server.packet.send; package emu.grasscutter.server.packet.send;
import com.google.gson.Gson;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.game.GenshinPlayer; import emu.grasscutter.game.GenshinPlayer;
import emu.grasscutter.game.Mail; import emu.grasscutter.game.Mail;
import emu.grasscutter.net.packet.GenshinPacket; import emu.grasscutter.net.packet.GenshinPacket;
import emu.grasscutter.net.packet.PacketOpcodes; import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.*;
import emu.grasscutter.net.proto.GetAllMailRspOuterClass.GetAllMailRsp; import emu.grasscutter.net.proto.GetAllMailRspOuterClass.GetAllMailRsp;
import emu.grasscutter.net.proto.ItemParamOuterClass;
import emu.grasscutter.net.proto.MailDataOuterClass;
import emu.grasscutter.net.proto.MailDataOuterClass.MailData; import emu.grasscutter.net.proto.MailDataOuterClass.MailData;
import emu.grasscutter.net.proto.MailItemOuterClass;
import emu.grasscutter.net.proto.MailTextContentOuterClass.MailTextContent; import emu.grasscutter.net.proto.MailTextContentOuterClass.MailTextContent;
import javax.swing.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Base64; import java.util.Base64;
import java.util.List; import java.util.List;
@ -20,7 +20,6 @@ public class PacketGetAllMailRsp extends GenshinPacket {
public PacketGetAllMailRsp(GenshinPlayer player, boolean isGiftMail) { public PacketGetAllMailRsp(GenshinPlayer player, boolean isGiftMail) {
super(PacketOpcodes.GetAllMailRsp); super(PacketOpcodes.GetAllMailRsp);
Grasscutter.getLogger().info(String.valueOf(isGiftMail));
if (isGiftMail) { if (isGiftMail) {
// TODO: Gift Mail // TODO: Gift Mail
@ -34,11 +33,11 @@ public class PacketGetAllMailRsp extends GenshinPacket {
} }
} else { } else {
if (player.getMail().size() != 0) { // Make sure the player has mail if (player.getAllMail().size() != 0) { // Make sure the player has mail
GetAllMailRsp.Builder proto = GetAllMailRsp.newBuilder(); GetAllMailRsp.Builder proto = GetAllMailRsp.newBuilder();
List<MailData> mailDataList = new ArrayList<MailData>(); List<MailData> mailDataList = new ArrayList<MailData>();
for (Mail message : player.getMail()) { for (Mail message : player.getAllMail()) {
if(message.stateValue == 1) { //Make sure it isn't a gift if(message.stateValue == 1) { //Make sure it isn't a gift
MailTextContent.Builder mailTextContent = MailTextContent.newBuilder(); MailTextContent.Builder mailTextContent = MailTextContent.newBuilder();
mailTextContent.setTitle(message.mailContent.title); mailTextContent.setTitle(message.mailContent.title);
@ -73,7 +72,7 @@ public class PacketGetAllMailRsp extends GenshinPacket {
} }
proto.addAllMailList(mailDataList); proto.addAllMailList(mailDataList);
proto.setIsTruncated(true); proto.setIsTruncated(false); // When enabled this will send a notification to the user that their inbox is full when opening the mailbox.
this.setData(proto.build()); this.setData(proto.build());
} else { } else {

View File

@ -1,13 +1,21 @@
package emu.grasscutter.server.packet.send; package emu.grasscutter.server.packet.send;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.GenshinData;
import emu.grasscutter.game.GenshinPlayer; import emu.grasscutter.game.GenshinPlayer;
import emu.grasscutter.game.Mail;
import emu.grasscutter.game.inventory.GenshinItem;
import emu.grasscutter.game.props.ActionReason;
import emu.grasscutter.net.packet.GenshinPacket; import emu.grasscutter.net.packet.GenshinPacket;
import emu.grasscutter.net.packet.PacketOpcodes; import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.EquipParamOuterClass;
import emu.grasscutter.net.proto.GetMailItemRspOuterClass.GetMailItemRsp; import emu.grasscutter.net.proto.GetMailItemRspOuterClass.GetMailItemRsp;
import emu.grasscutter.net.proto.ItemParamOuterClass; import emu.grasscutter.net.proto.ItemParamOuterClass;
import emu.grasscutter.net.proto.MailItemOuterClass; import emu.grasscutter.net.proto.MailItemOuterClass;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
public class PacketGetMailItemRsp extends GenshinPacket { public class PacketGetMailItemRsp extends GenshinPacket {
@ -17,15 +25,40 @@ public class PacketGetMailItemRsp extends GenshinPacket {
//I'm assuming that this is to receive the attachments on the message. //I'm assuming that this is to receive the attachments on the message.
// TODO: This. // TODO: This.
//GetMailItemRsp.Builder proto = GetMailItemRsp.newBuilder(); List<Mail> claimedMessages = new ArrayList<>();
List<EquipParamOuterClass.EquipParam> claimedItems = new ArrayList<>();
//MailItemOuterClass.MailItem.Builder mailItem = MailItemOuterClass.MailItem.newBuilder(); GetMailItemRsp.Builder proto = GetMailItemRsp.newBuilder();
//ItemParamOuterClass.ItemParam.Builder itemParam = ItemParamOuterClass.ItemParam.newBuilder(); for (int mailId : mailList) {
Mail message = player.getMailById(mailId);
int messageIndex = player.getMailIndex(message);
//mailItem.setItemParam(itemParam); message.isAttachmentGot = true;
claimedMessages.add(message);
//proto.addAllMailIdList(mailList); player.replaceMailByIndex(messageIndex, message);
//proto.addItemList();
for(Mail.MailItem mailItem : message.itemList) {
//TODO: Actually give the item
EquipParamOuterClass.EquipParam.Builder item = EquipParamOuterClass.EquipParam.newBuilder();
item.setItemId(mailItem.itemId);
item.setItemNum(mailItem.itemCount);
claimedItems.add(item.build());
GenshinItem genshinItem = new GenshinItem(GenshinData.getItemDataMap().get(mailItem.itemId));
genshinItem.setCount(mailItem.itemCount);
player.getInventory().addItem(genshinItem);
player.sendPacket(new PacketItemAddHintNotify(genshinItem, ActionReason.MailAttachment));
}
}
proto.addAllMailIdList(claimedMessages.stream().map(Mail::getId).collect(Collectors.toList()));
proto.addAllItemList(claimedItems);
player.save();
Grasscutter.getLogger().info(Grasscutter.getDispatchServer().getGsonFactory().toJson(proto.build()));
this.setData(proto.build());
player.getSession().send(new PacketMailChangeNotify(player, claimedMessages));
} }
} }

View File

@ -1,6 +1,7 @@
package emu.grasscutter.server.packet.send; package emu.grasscutter.server.packet.send;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.game.GenshinPlayer; import emu.grasscutter.game.GenshinPlayer;
import emu.grasscutter.game.Mail; import emu.grasscutter.game.Mail;
import emu.grasscutter.net.packet.GenshinPacket; import emu.grasscutter.net.packet.GenshinPacket;
@ -13,40 +14,48 @@ import java.util.List;
public class PacketMailChangeNotify extends GenshinPacket { public class PacketMailChangeNotify extends GenshinPacket {
public PacketMailChangeNotify(GenshinPlayer player, Mail message) { public PacketMailChangeNotify(GenshinPlayer player, Mail message) {
this (player, new ArrayList<Mail>(){{add(message);}});
}
public PacketMailChangeNotify(GenshinPlayer player, List<Mail> mailList) {
super(PacketOpcodes.MailChangeNotify); super(PacketOpcodes.MailChangeNotify);
MailChangeNotifyOuterClass.MailChangeNotify.Builder proto = MailChangeNotifyOuterClass.MailChangeNotify.newBuilder(); MailChangeNotifyOuterClass.MailChangeNotify.Builder proto = MailChangeNotifyOuterClass.MailChangeNotify.newBuilder();
MailTextContentOuterClass.MailTextContent.Builder mailTextContent = MailTextContentOuterClass.MailTextContent.newBuilder(); for(Mail message : mailList) {
mailTextContent.setTitle(message.mailContent.title); MailTextContentOuterClass.MailTextContent.Builder mailTextContent = MailTextContentOuterClass.MailTextContent.newBuilder();
mailTextContent.setContent(message.mailContent.content); mailTextContent.setTitle(message.mailContent.title);
mailTextContent.setSender(message.mailContent.sender); mailTextContent.setContent(message.mailContent.content);
mailTextContent.setSender(message.mailContent.sender);
List<MailItemOuterClass.MailItem> mailItems = new ArrayList<MailItemOuterClass.MailItem>(); List<MailItemOuterClass.MailItem> mailItems = new ArrayList<MailItemOuterClass.MailItem>();
for(Mail.MailItem item : message.itemList) { for(Mail.MailItem item : message.itemList) {
MailItemOuterClass.MailItem.Builder mailItem = MailItemOuterClass.MailItem.newBuilder(); MailItemOuterClass.MailItem.Builder mailItem = MailItemOuterClass.MailItem.newBuilder();
ItemParamOuterClass.ItemParam.Builder itemParam = ItemParamOuterClass.ItemParam.newBuilder(); ItemParamOuterClass.ItemParam.Builder itemParam = ItemParamOuterClass.ItemParam.newBuilder();
itemParam.setItemId(item.itemId); itemParam.setItemId(item.itemId);
itemParam.setCount(item.itemCount); itemParam.setCount(item.itemCount);
mailItem.setItemParam(itemParam.build()); mailItem.setItemParam(itemParam.build());
mailItems.add(mailItem.build()); mailItems.add(mailItem.build());
}
MailDataOuterClass.MailData.Builder mailData = MailDataOuterClass.MailData.newBuilder();
mailData.setMailId(message._id);
mailData.setMailTextContent(mailTextContent.build());
mailData.addAllItemList(mailItems);
mailData.setSendTime((int)message.sendTime);
mailData.setExpireTime((int)message.expireTime);
mailData.setImportance(message.importance);
mailData.setIsRead(message.isRead);
mailData.setIsAttachmentGot(message.isAttachmentGot);
mailData.setStateValue(message.stateValue);
proto.addMailList(mailData.build());
Grasscutter.getLogger().info(Grasscutter.getDispatchServer().getGsonFactory().toJson(proto.build()));
this.setData(proto.build());
} }
MailDataOuterClass.MailData.Builder mailData = MailDataOuterClass.MailData.newBuilder();
mailData.setMailId(message._id);
mailData.setMailTextContent(mailTextContent.build());
mailData.addAllItemList(mailItems);
mailData.setSendTime((int)message.sendTime);
mailData.setExpireTime((int)message.expireTime);
mailData.setImportance(message.importance);
mailData.setIsRead(false);
mailData.setIsAttachmentGot(false);
mailData.setStateValue(message.stateValue);
proto.addMailList(mailData.build());
this.setData(proto.build());
} }
} }