mirror of
https://github.com/Melledy/LunarCore.git
synced 2025-12-23 10:44:36 +01:00
Implement basic mail system
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
package emu.lunarcore.command.commands;
|
||||
|
||||
import emu.lunarcore.command.Command;
|
||||
import emu.lunarcore.command.CommandArgs;
|
||||
import emu.lunarcore.command.CommandHandler;
|
||||
import emu.lunarcore.game.mail.Mail;
|
||||
import emu.lunarcore.game.player.Player;
|
||||
|
||||
@Command(label = "mail", aliases = {"m"}, permission = "player.mail", desc = "/mail [content]. Sends the targeted player a system mail.")
|
||||
public class MailCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, CommandArgs args) {
|
||||
// Check target
|
||||
if (args.getTarget() == null) {
|
||||
this.sendMessage(sender, "Error: Targeted player not found or offline");
|
||||
return;
|
||||
}
|
||||
|
||||
String content = String.join(" ", args.getList());
|
||||
Mail mail = new Mail("Test", "System Mail", content);
|
||||
|
||||
args.getTarget().getMailbox().sendMail(mail);
|
||||
|
||||
sender.sendMessage("Sending mail to " + args.getTarget().getName());
|
||||
}
|
||||
|
||||
}
|
||||
83
src/main/java/emu/lunarcore/game/mail/Mail.java
Normal file
83
src/main/java/emu/lunarcore/game/mail/Mail.java
Normal file
@@ -0,0 +1,83 @@
|
||||
package emu.lunarcore.game.mail;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.bson.types.ObjectId;
|
||||
|
||||
import dev.morphia.annotations.Entity;
|
||||
import dev.morphia.annotations.Id;
|
||||
import dev.morphia.annotations.Indexed;
|
||||
import emu.lunarcore.LunarRail;
|
||||
import emu.lunarcore.game.inventory.GameItem;
|
||||
import emu.lunarcore.game.player.Player;
|
||||
import emu.lunarcore.proto.ClientMailOuterClass.ClientMail;
|
||||
import emu.lunarcore.proto.ItemListOuterClass.ItemList;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Entity(value = "mail", useDiscriminator = false)
|
||||
public class Mail {
|
||||
@Id private ObjectId id;
|
||||
@Indexed private int ownerUid; // Uid of player that this mail belongs to
|
||||
|
||||
@Setter
|
||||
private transient int uniqueId;
|
||||
|
||||
private String title;
|
||||
private String sender;
|
||||
private String content;
|
||||
private long time;
|
||||
private long expiry;
|
||||
private boolean isRead;
|
||||
private List<GameItem> attachments;
|
||||
|
||||
@Deprecated // Morphia only!
|
||||
public Mail() {}
|
||||
|
||||
public Mail(String title, String sender, String content) {
|
||||
this.title = title;
|
||||
this.sender = sender;
|
||||
this.content = content;
|
||||
this.time = System.currentTimeMillis() / 1000;
|
||||
this.expiry = this.time + TimeUnit.DAYS.toSeconds(30);
|
||||
}
|
||||
|
||||
public void setOwner(Player player) {
|
||||
this.ownerUid = player.getUid();
|
||||
}
|
||||
|
||||
public void setRead() {
|
||||
if (!this.isRead) {
|
||||
this.isRead = true;
|
||||
this.save();
|
||||
}
|
||||
}
|
||||
|
||||
// Database
|
||||
|
||||
public void save() {
|
||||
LunarRail.getGameDatabase().save(this);
|
||||
}
|
||||
|
||||
public void delete() {
|
||||
LunarRail.getGameDatabase().delete(this);
|
||||
}
|
||||
|
||||
// Proto
|
||||
|
||||
public ClientMail toProto() {
|
||||
var proto = ClientMail.newInstance()
|
||||
.setId(this.getUniqueId())
|
||||
.setTitle(this.getTitle())
|
||||
.setContent(this.getContent())
|
||||
.setSender(this.getSender())
|
||||
.setTime(this.getTime())
|
||||
.setExpireTime(this.getExpiry())
|
||||
.setIsRead(this.isRead())
|
||||
.setAttachment(ItemList.newInstance());
|
||||
|
||||
return proto;
|
||||
}
|
||||
}
|
||||
94
src/main/java/emu/lunarcore/game/mail/Mailbox.java
Normal file
94
src/main/java/emu/lunarcore/game/mail/Mailbox.java
Normal file
@@ -0,0 +1,94 @@
|
||||
package emu.lunarcore.game.mail;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import emu.lunarcore.LunarRail;
|
||||
import emu.lunarcore.game.player.BasePlayerManager;
|
||||
import emu.lunarcore.game.player.Player;
|
||||
import emu.lunarcore.server.packet.send.PacketNewMailScNotify;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import us.hebi.quickbuf.RepeatedInt;
|
||||
|
||||
@Getter(AccessLevel.PRIVATE)
|
||||
public class Mailbox extends BasePlayerManager implements Iterable<Mail> {
|
||||
private final Int2ObjectMap<Mail> map;
|
||||
private int lastMailId;
|
||||
|
||||
public Mailbox(Player player) {
|
||||
super(player);
|
||||
|
||||
this.map = new Int2ObjectOpenHashMap<>();
|
||||
}
|
||||
|
||||
private int getNextMailId() {
|
||||
return ++lastMailId;
|
||||
}
|
||||
|
||||
public synchronized int size() {
|
||||
return getMap().size();
|
||||
}
|
||||
|
||||
public synchronized void readMail(int id) {
|
||||
Mail mail = getMap().get(id);
|
||||
if (mail != null) {
|
||||
mail.setRead();
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void sendMail(Mail mail) {
|
||||
// Set owner for mail first before we save
|
||||
mail.setOwner(this.getPlayer());
|
||||
|
||||
// Put mail into our backing hash map
|
||||
this.putMail(mail);
|
||||
|
||||
// Save mail to database
|
||||
mail.save();
|
||||
|
||||
// Send packet
|
||||
this.getPlayer().sendPacket(new PacketNewMailScNotify(mail));
|
||||
}
|
||||
|
||||
public synchronized IntList deleteMail(RepeatedInt idList) {
|
||||
IntList deleteList = new IntArrayList();
|
||||
|
||||
for (int id : idList) {
|
||||
Mail mail = getMap().remove(id);
|
||||
if (mail != null) {
|
||||
// Delete from database
|
||||
mail.delete();
|
||||
// Add to delete result list
|
||||
deleteList.add(mail.getUniqueId());
|
||||
}
|
||||
}
|
||||
|
||||
return deleteList;
|
||||
}
|
||||
|
||||
// Internal method to put mail into the hash map
|
||||
private void putMail(Mail mail) {
|
||||
mail.setUniqueId(this.getNextMailId());
|
||||
getMap().put(mail.getUniqueId(), mail);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Iterator<Mail> iterator() {
|
||||
return getMap().values().iterator();
|
||||
}
|
||||
|
||||
// Database
|
||||
|
||||
public void loadFromDatabase() {
|
||||
Stream<Mail> stream = LunarRail.getGameDatabase().getObjects(Mail.class, "ownerUid", this.getPlayer().getUid());
|
||||
|
||||
stream.forEach(this::putMail);
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,7 @@ import emu.lunarcore.game.chat.ChatMessage;
|
||||
import emu.lunarcore.game.enums.PropState;
|
||||
import emu.lunarcore.game.gacha.PlayerGachaInfo;
|
||||
import emu.lunarcore.game.inventory.Inventory;
|
||||
import emu.lunarcore.game.mail.Mailbox;
|
||||
import emu.lunarcore.game.scene.Scene;
|
||||
import emu.lunarcore.game.scene.entity.EntityProp;
|
||||
import emu.lunarcore.game.scene.entity.GameEntity;
|
||||
@@ -81,6 +82,7 @@ public class Player {
|
||||
private transient final AvatarStorage avatars;
|
||||
private transient final Inventory inventory;
|
||||
private transient final ChatManager chatManager;
|
||||
private transient final Mailbox mailbox;
|
||||
private transient final ChallengeManager challengeManager;
|
||||
|
||||
// Database persistent data
|
||||
@@ -101,6 +103,7 @@ public class Player {
|
||||
this.avatars = new AvatarStorage(this);
|
||||
this.inventory = new Inventory(this);
|
||||
this.chatManager = new ChatManager(this);
|
||||
this.mailbox = new Mailbox(this);
|
||||
this.challengeManager = new ChallengeManager(this);
|
||||
}
|
||||
|
||||
@@ -515,6 +518,7 @@ public class Player {
|
||||
// Load avatars and inventory first
|
||||
this.getAvatars().loadFromDatabase();
|
||||
this.getInventory().loadFromDatabase();
|
||||
this.getMailbox().loadFromDatabase();
|
||||
this.getChallengeManager().loadFromDatabase();
|
||||
|
||||
// Load Etc
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package emu.lunarcore.server.packet.recv;
|
||||
|
||||
import emu.lunarcore.proto.DelMailCsReqOuterClass.DelMailCsReq;
|
||||
import emu.lunarcore.server.game.GameSession;
|
||||
import emu.lunarcore.server.packet.CmdId;
|
||||
import emu.lunarcore.server.packet.Opcodes;
|
||||
import emu.lunarcore.server.packet.PacketHandler;
|
||||
import emu.lunarcore.server.packet.send.PacketDelMailScRsp;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
|
||||
@Opcodes(CmdId.DelMailCsReq)
|
||||
public class HandlerDelMailCsReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] data) throws Exception {
|
||||
var req = DelMailCsReq.parseFrom(data);
|
||||
|
||||
IntList deleted = session.getPlayer().getMailbox().deleteMail(req.getIdList());
|
||||
|
||||
session.send(new PacketDelMailScRsp(deleted));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,13 +4,14 @@ import emu.lunarcore.server.game.GameSession;
|
||||
import emu.lunarcore.server.packet.CmdId;
|
||||
import emu.lunarcore.server.packet.Opcodes;
|
||||
import emu.lunarcore.server.packet.PacketHandler;
|
||||
import emu.lunarcore.server.packet.send.PacketGetMailScRsp;
|
||||
|
||||
@Opcodes(CmdId.GetMailCsReq)
|
||||
public class HandlerGetMailCsReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] data) throws Exception {
|
||||
session.send(CmdId.GetMailScRsp);
|
||||
session.send(new PacketGetMailScRsp(session.getPlayer()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package emu.lunarcore.server.packet.recv;
|
||||
|
||||
import emu.lunarcore.proto.MarkReadMailCsReqOuterClass.MarkReadMailCsReq;
|
||||
import emu.lunarcore.server.game.GameSession;
|
||||
import emu.lunarcore.server.packet.CmdId;
|
||||
import emu.lunarcore.server.packet.Opcodes;
|
||||
import emu.lunarcore.server.packet.PacketHandler;
|
||||
|
||||
@Opcodes(CmdId.MarkReadMailCsReq)
|
||||
public class HandlerMarkReadMailCsReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] data) throws Exception {
|
||||
var req = MarkReadMailCsReq.parseFrom(data);
|
||||
|
||||
session.getPlayer().getMailbox().readMail(req.getId());
|
||||
session.send(CmdId.MarkReadMailScRsp);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package emu.lunarcore.server.packet.send;
|
||||
|
||||
import emu.lunarcore.proto.DelMailScRspOuterClass.DelMailScRsp;
|
||||
import emu.lunarcore.server.packet.BasePacket;
|
||||
import emu.lunarcore.server.packet.CmdId;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
|
||||
public class PacketDelMailScRsp extends BasePacket {
|
||||
|
||||
public PacketDelMailScRsp(IntList deleteList) {
|
||||
super(CmdId.DelMailScRsp);
|
||||
|
||||
var data = DelMailScRsp.newInstance();
|
||||
|
||||
deleteList.forEach(data::addIdList);
|
||||
|
||||
this.setData(data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package emu.lunarcore.server.packet.send;
|
||||
|
||||
import emu.lunarcore.game.mail.Mail;
|
||||
import emu.lunarcore.game.player.Player;
|
||||
import emu.lunarcore.proto.GetMailScRspOuterClass.GetMailScRsp;
|
||||
import emu.lunarcore.server.packet.BasePacket;
|
||||
import emu.lunarcore.server.packet.CmdId;
|
||||
|
||||
public class PacketGetMailScRsp extends BasePacket {
|
||||
|
||||
public PacketGetMailScRsp(Player player) {
|
||||
super(CmdId.GetMailScRsp);
|
||||
|
||||
var data = GetMailScRsp.newInstance()
|
||||
.setIsEnd(true)
|
||||
.setTotalNum(player.getMailbox().size());
|
||||
|
||||
for (Mail mail : player.getMailbox()) {
|
||||
data.addMailList(mail.toProto());
|
||||
}
|
||||
|
||||
this.setData(data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package emu.lunarcore.server.packet.send;
|
||||
|
||||
import emu.lunarcore.game.mail.Mail;
|
||||
import emu.lunarcore.proto.NewMailScNotifyOuterClass.NewMailScNotify;
|
||||
import emu.lunarcore.server.packet.BasePacket;
|
||||
import emu.lunarcore.server.packet.CmdId;
|
||||
|
||||
public class PacketNewMailScNotify extends BasePacket {
|
||||
|
||||
public PacketNewMailScNotify(Mail mail) {
|
||||
super(CmdId.NewMailScNotify);
|
||||
|
||||
var data = NewMailScNotify.newInstance()
|
||||
.addMailIdList(mail.getUniqueId());
|
||||
|
||||
this.setData(data);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user