This commit is contained in:
coooookies 2022-05-03 05:14:22 +08:00
commit ea7abbfc84
16 changed files with 958 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/.idea/
/target/

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2022 ButterCookies
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

BIN
README.md Normal file

Binary file not shown.

48
README.zh-CN.md Normal file
View File

@ -0,0 +1,48 @@
# MeaNotice - Grasscutter 定时公告插件
MeaNotice 是一个使用于 [Grasscutter](https://github.com/Grasscutters/Grasscutter) 的插件,你可以使用这个插件在游戏内发送定时公告。
[English](./README.md) | 简体中文
## 开始
### 安装插件
1. [下载插件本体](https://github.com/Coooookies/MeaNotice/releases)
2. 将插件本体放置在 `服务器根目录/plugins` 目录下
3. 启动服务器,插件将会在你的服务器根目录下创建一个 `MeaNotice` 文件夹.
```
Root
│ lib
│ keys
│ resources
│ plugins
│ ...
└───MeaNotice
└───config.json
```
### 配置
```json
{
"interval": 30000,
"notices": [
"Welcome to this server! If you want to learn how to use commands, please type /help in chatroom.",
"Hey! Do you need help? Add UID1 as a friend, the admin will help you."
]
}
```
```
说明:
interval: 必填项,用于设置定时公告的时间间隔,单位为毫秒,默认为 30000 毫秒30 秒)。
notices: 用于设置定时公告的内容,格式为字符串数组,每条公告都会以上到下顺序发送给玩家。
```
### 命令 & 权限
命令:
```
/meanotice reload
重载插件配置
```
权限:
```
mea.notice | 控制插件功能
```

69
pom.xml Normal file
View File

@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>io.github</groupId>
<artifactId>MeaMailPlus</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
<dependencies>
<dependency>
<groupId>emu.grasscutter</groupId>
<artifactId>Grasscutter-api</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>D:/Grasscutter/GrasscutterFork/grasscutter-1.0.3-dev.jar</systemPath>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.9.0</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,76 @@
package io.github.gmw;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.command.CommandMap;
import emu.grasscutter.plugin.Plugin;
import emu.grasscutter.server.game.GameServerPacketHandler;
import io.github.gmw.module.ConfigParser;
import io.github.gmw.module.PluginCommand;
import io.github.gmw.packetHandler.PlayerBornHook;
import io.github.gmw.packetHandler.PlayerJoinHook;
import io.github.gmw.module.TaskManager;
public class MeaMailPlusCore extends Plugin {
private static MeaMailPlusCore instance;
public ConfigParser config;
public TaskManager task;
@Override
public void onLoad() {
this.logger("Loading...");
instance = this;
this.config = new ConfigParser();
this.config.loadConfig();
this.config.loadTemplates();
this.task = new TaskManager();
this.logger("Loaded!");
}
@Override
public void onEnable() {
CommandMap.getInstance().registerCommand("meamail", new PluginCommand());
// register packet handler
GameServerPacketHandler packetHandler = Grasscutter.getGameServer().getPacketHandler();
packetHandler.registerPacketHandler(PlayerJoinHook.class);
packetHandler.registerPacketHandler(PlayerBornHook.class);
this.task.enable();
}
@Override
public void onDisable() {
CommandMap.getInstance().unregisterCommand("meamail");
this.task.disable();
}
public static MeaMailPlusCore getInstance() {
return instance;
}
public void reloadConfig() {
this.task.disable();
this.config.loadConfig();
this.config.loadTemplates();
this.task.enable();
}
public void logger(String message) {
this.logger(message, "info");
}
public void logger(String message, String type) {
if (Grasscutter.getLogger() == null) return;
String msg = "[MeaMailPlusCore] " + message;
switch (type) {
case "info" -> Grasscutter.getLogger().info(msg);
case "warn" -> Grasscutter.getLogger().warn(msg);
case "error" -> Grasscutter.getLogger().error(msg);
}
}
}

View File

@ -0,0 +1,42 @@
package io.github.gmw.config;
public final class MeaMailConfig {
public int[] updateTime = {4,0,0};
public int[] initialMail = {1001};
public int[] birthDayMail = {1004};
public DailySignInMailTask[] dailySignInMail = {
new DailySignInMailTask(1002,0)
};
public DailyRepetitionTask[] dailyRepetitionMail = {
new DailyRepetitionTask(1003,0,false, new int[]{12, 0, 0})
};
public static class DailyRepetitionTask extends MailTask {
public boolean onlineOnly;
public int[] triggerTime;
public DailyRepetitionTask(int templateId, int minLevel, boolean onlineOnly, int[] triggerTime) {
super(templateId, minLevel);
this.onlineOnly = onlineOnly;
this.triggerTime = triggerTime;
}
}
public static class DailySignInMailTask extends MailTask {
public DailySignInMailTask(int templateId, int minLevel) {
super(templateId, minLevel);
}
}
public static class MailTask {
public int templateId;
public int minLevel; // 0 - 60
public MailTask(int templateId, int minLevel) {
this.templateId = templateId;
this.minLevel = minLevel;
}
}
}

View File

@ -0,0 +1,32 @@
package io.github.gmw.config;
public final class MeaMailTemplate {
public int templateId = 0;
public String title = "";
public String sender = "Server";
public long expireTime = 0;
public long remainTime = 2592000; // 31 days
public int importance = 0; // Starred mail, 0 = No star, 1 = Star.
public MailBody body = new MailBody();
public static class MailBody {
public String content = "";
public ItemInfo[] items = {};
public static class ItemInfo {
public int id;
public int count;
public int level;
public ItemInfo(int id, int count) {
this(id, count, 1);
}
public ItemInfo(int id, int count, int level) {
this.id = id;
this.count = count;
this.level = level;
}
}
}
}

View File

@ -0,0 +1,191 @@
package io.github.gmw.module;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Calendar;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import io.github.gmw.MeaMailPlusCore;
import io.github.gmw.config.MeaMailConfig;
import io.github.gmw.config.MeaMailTemplate;
public class ConfigParser {
private MeaMailConfig config;
private ArrayList<MeaMailTemplate> templates;
private final String configPath = "./plugins/MeaMailPlus";
private final String templatePath = this.configPath + "/template";
private final File configFile = new File( this.configPath + "/config.json");
private static final Gson gson = new GsonBuilder().setPrettyPrinting().create();
public void loadTemplates() {
switch (this.createConfigFolder(this.templatePath)){
case -1: return;
case 0: { // Without Template
this.createTemplate();
break;
}
case 1: {
break;
}
}
ArrayList<MeaMailTemplate> templates = new ArrayList<>();
File[] files = new File(this.templatePath)
.listFiles();
if (files == null) return; // No Template
else {
for (File file : files) {
try (FileReader fileReader = new FileReader(file)) {
MeaMailTemplate template = gson.fromJson(fileReader, MeaMailTemplate.class);
templates.add(template); // 加入模板列表
MeaMailPlusCore.getInstance()
.logger("Loaded template: " + file.getName() + " (TemplateId: " + template.templateId + ")");
} catch (Exception e) {
MeaMailPlusCore.getInstance()
.logger("Unable to load template file: " + file.getName(),"error");
}
}
}
this.templates = templates;
MeaMailPlusCore.getInstance()
.logger("Loaded " + templates.size() + " templates. :D");
}
// get template by templateId
public MeaMailTemplate getTemplate(int templateId) {
for (MeaMailTemplate template : this.templates) {
if (template.templateId == templateId) return template;
}
return null;
}
public void createTemplate() {
MeaMailTemplate template_initialMail = new MeaMailTemplate();
MeaMailTemplate template_dailySignInMail = new MeaMailTemplate();
MeaMailTemplate template_dailyRepetitionMail = new MeaMailTemplate();
MeaMailTemplate template_birthDayMail = new MeaMailTemplate();
template_initialMail.templateId = 1001;
template_initialMail.remainTime = 2592000; // 一个月后过期
template_initialMail.title = "Thank you for using MeaMailPlus!";
template_initialMail.sender= "MeaKiritaniIwako";
template_initialMail.importance = 1;
template_initialMail.body.content =
"Hi!\n\n" +
"Thank you for using MeaMailPlus! You can use MeaMailPlus to send mail to your friends more conveniently.\r\n\r\n" +
"Github HomePage" +
"<type=\"browser\" text=\"Github\" href=\"https://discord.gg/T5vZU6UyeG\"/>\r\n" +
"Grasscutter Discord" +
"<type=\"browser\" text=\"Discord\" href=\"https://discord.gg/T5vZU6UyeG\"/>";
template_initialMail.body.items = new MeaMailTemplate.MailBody.ItemInfo[]{
new MeaMailTemplate.MailBody.ItemInfo(80544, 1, 20),
new MeaMailTemplate.MailBody.ItemInfo(223, 150)
};
template_dailySignInMail.templateId = 1002;
template_dailySignInMail.remainTime = 604800; // 1 week
template_dailySignInMail.title = "Daily-Bonus";
template_dailySignInMail.body.content = "Have a nice day";
template_dailySignInMail.body.items = new MeaMailTemplate.MailBody.ItemInfo[]{
new MeaMailTemplate.MailBody.ItemInfo(223, 20),
new MeaMailTemplate.MailBody.ItemInfo(224, 20)
};
template_dailyRepetitionMail.templateId = 1003;
template_dailyRepetitionMail.remainTime = 1209600; // 2 weeks later
template_dailyRepetitionMail.title = "Have a question?";
template_dailyRepetitionMail.sender= "TeamDarkshin";
template_dailyRepetitionMail.body.content =
"Join Grasscutter Discord server to ask questions and get answers:" +
"<type=\"browser\" text=\"Discord\" href=\"https://discord.gg/T5vZU6UyeG\"/>";
template_birthDayMail.templateId = 1004;
template_birthDayMail.remainTime = 2592000; // 1 month
template_birthDayMail.title = "Best Wishes on Your Birthday";
template_birthDayMail.sender = "Mailing System";
template_birthDayMail.importance = 1;
template_birthDayMail.body.content =
"Happy Birthday,Traveler! Please find your gift attached to this message.\r\n" +
"Thank you for all your support. We wish you a wonderful day, wherever in this world you may roam.";
template_birthDayMail.body.items = new MeaMailTemplate.MailBody.ItemInfo[]{
new MeaMailTemplate.MailBody.ItemInfo(118003, 1)
};
this.saveTemplate("InitialMail", template_initialMail);
this.saveTemplate("DailySignInMail", template_dailySignInMail);
this.saveTemplate("DailyRepetitionMail", template_dailyRepetitionMail);
this.saveTemplate("BirthDayMail", template_birthDayMail);
}
public boolean saveTemplate(String fileName, MeaMailTemplate templateClass) {
try (FileWriter file = new FileWriter(this.templatePath + "/" + fileName + ".json")) {
file.write(gson.toJson(templateClass));
return true;
} catch (Exception e) {
return false;
}
}
// load config.json
public void loadConfig() {
try (FileReader file = new FileReader(this.configFile)) {
this.config = gson.fromJson(file, MeaMailConfig.class);
MeaMailPlusCore.getInstance().logger("Config Loaded!");
} catch (Exception e) {
this.config = new MeaMailConfig();
MeaMailPlusCore.getInstance().logger("Basic config creating...");
}
if (!saveConfig()) {
MeaMailPlusCore.getInstance().logger("Unable to save config file.","error");
}
}
// save config.json
public int createConfigFolder(String path) {
File dir = new File(path);
if (!dir.exists() || !dir.isDirectory()) {
if(new File(String.valueOf(dir)).mkdirs()) return 0;
else return -1;
}
return 1;
}
public boolean saveConfig() {
if (this.createConfigFolder(this.configPath) == -1) return false;
try (FileWriter file = new FileWriter(this.configFile)) {
file.write(gson.toJson(this.config));
} catch (Exception e) {
return false;
}
return true;
}
public MeaMailConfig getConfig() {
return this.config;
}
public long getTomorrowUpdateTime() {
// get tomorrow's update time
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE, 1);
cal.set(Calendar.HOUR_OF_DAY, this.config.updateTime[0]);
cal.set(Calendar.MINUTE, this.config.updateTime[1]);
cal.set(Calendar.SECOND, this.config.updateTime[2]);
return cal.getTimeInMillis() / 1000;
}
}

View File

@ -0,0 +1,118 @@
package io.github.gmw.module;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.command.Command;
import emu.grasscutter.command.CommandHandler;
import emu.grasscutter.game.player.Player;
import io.github.gmw.MeaMailPlusCore;
import io.github.gmw.config.MeaMailConfig;
import io.github.gmw.config.MeaMailTemplate;
import io.github.gmw.utils.MailCore;
import java.util.*;
@Command(label = "meamail", usage = "meamail help",
description = "MeaMailPlusCore command", aliases = {"mmail"}, permission = "meo.mail")
public class PluginCommand implements CommandHandler {
@Override
public void execute(Player sender, List<String> args) {
switch (args.size()) {
default -> // *No args*
showHelpList(sender);
case 1 -> {
switch (args.get(0)) {
case "reload" -> {
MeaMailPlusCore.getInstance().reloadConfig();
if (sender == null)
Grasscutter.getLogger().info("[MeaNoticeCore] Reloaded!");
else
CommandHandler.sendMessage(sender, "MeaNoticeCore config reloaded");
}
case "help" -> showHelpList(sender);
default -> CommandHandler.sendMessage(sender, "Invalid args.");
}
}
case 2 -> {
int templateId = Integer.parseInt(args.get(1));
MeaMailTemplate template = MeaMailPlusCore.getInstance().config.getTemplate(templateId);
switch (args.get(0)) {
case "sendall" -> {
if (template == null) {
CommandHandler.sendMessage(sender, "Invalid template id.");
return;
}
MailCore.sendMailToAllPlayers(template);
CommandHandler.sendMessage(sender, "Mail Sended!");
}
default -> CommandHandler.sendMessage(sender, "Invalid args.");
}
}
case 3 -> {
int templateId = Integer.parseInt(args.get(1));
MeaMailTemplate template = MeaMailPlusCore.getInstance().config.getTemplate(templateId);
switch (args.get(0)) {
case "send" -> {
if (template == null) {
CommandHandler.sendMessage(sender, "Invalid template id.");
return;
}
int uid = Integer.parseInt(args.get(2));
CommandHandler.sendMessage(sender, "Mail Sending...");
Grasscutter.getGameServer().getPlayers().forEach((index, player) -> {
if (player.getUid() == uid) {
MailCore.sendMailToPlayer(player, template);
}
});
}
case "sendall" -> {
if (template == null) {
CommandHandler.sendMessage(sender, "Invalid template id.");
return;
}
int minLevel = Integer.parseInt(args.get(2));
MailCore.sendMailToAllPlayers(template, minLevel);
CommandHandler.sendMessage(sender, "Mail Sended!");
}
case "sendallonline" -> {
if (template == null) {
CommandHandler.sendMessage(sender, "Invalid template id.");
return;
}
int minLevel = Integer.parseInt(args.get(2));
MailCore.sendMailToAllPlayers(template, minLevel, true);
CommandHandler.sendMessage(sender, "Mail Sended!");
}
default -> CommandHandler.sendMessage(sender, "Invalid args.");
}
}
}
}
public void showHelpList(Player sender) {
String[] helpMap = new String[]{
"Send Mail:",
" /meamail send <templateId> <uid>",
" /meamail sendall <templateId> <minLevel>",
" /meamail sendallonline <templateId> <minLevel>",
// " /meamail welcomemail <uid>",
// " /meamail dailymail <uid>",
// " /meamail initialmail <uid>",
"Other:",
" /meamail reload",
" /meamail help",
};
for (String text : helpMap) {
CommandHandler.sendMessage(sender, text);
}
}
}

View File

@ -0,0 +1,76 @@
package io.github.gmw.module;
import io.github.gmw.MeaMailPlusCore;
import io.github.gmw.config.MeaMailConfig;
import io.github.gmw.utils.MailCore;
import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import io.github.gmw.config.MeaMailConfig.DailyRepetitionTask;
public class TaskManager {
private Timer timer;
private static class dailyBeginTask extends TimerTask {
@Override
public void run() {
// new day
MailCore.dailyUpdate();
}
}
private static class dailyRepetitionTask extends TimerTask {
private DailyRepetitionTask task;
public dailyRepetitionTask(DailyRepetitionTask task) {
this.task = task;
}
@Override
public void run() {
MailCore.repetitionUpdate(task);
}
}
public Date getTaskStartTime(int hour, int minute, int second) {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, hour);
cal.set(Calendar.MINUTE, minute);
cal.set(Calendar.SECOND, second);
if (cal.getTime().before(new Date())) {
cal.add(Calendar.DATE, 1);
}
return cal.getTime();
}
public void enable() {
DailyRepetitionTask[] tasks = MeaMailPlusCore.getInstance().config.getConfig().dailyRepetitionMail;
int[] updateTime = MeaMailPlusCore.getInstance().config.getConfig().updateTime;
int cycleTime = 1000 * 60 * 60 * 24;
// create timer and task
this.timer = new Timer();
this.timer.schedule(
new dailyBeginTask(),
getTaskStartTime(updateTime[0], updateTime[1], updateTime[2]),
cycleTime
);
for(DailyRepetitionTask task : tasks) {
this.timer.schedule(
new dailyRepetitionTask(task),
getTaskStartTime(task.triggerTime[0], task.triggerTime[1], task.triggerTime[2]),
cycleTime
);
}
}
public void disable() {
this.timer.cancel();
}
}

View File

@ -0,0 +1,25 @@
package io.github.gmw.packetHandler;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.recv.HandlerSetPlayerBornDataReq;
import io.github.gmw.utils.MailCore;
import io.github.gmw.utils.PlayerUtils;
@Opcodes(PacketOpcodes.SetPlayerBornDataReq)
public class PlayerBornHook extends HandlerSetPlayerBornDataReq {
@Override
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
super.handle(session, header, payload);
int playerUid = session.getAccount().getPlayerUid();
// 第一次加入
if(playerUid != 0) {
MailCore.sendInitialMailToPlayer(playerUid);
MailCore.sendDailySignInMailToPlayer(playerUid);
}
}
}

View File

@ -0,0 +1,29 @@
package io.github.gmw.packetHandler;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.server.packet.recv.HandlerPlayerLoginReq;
import emu.grasscutter.server.game.GameSession;
import io.github.gmw.utils.MailCore;
import io.github.gmw.utils.PlayerUtils;
@Opcodes(PacketOpcodes.PlayerLoginReq)
public class PlayerJoinHook extends HandlerPlayerLoginReq {
@Override
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
super.handle(session, header, payload);
Player player = session.getPlayer();
if (player == null) return; // new player
if(PlayerUtils.isFirstLoginToday(player)) { // first login today
if (PlayerUtils.isPlayerBirthDay(player)) { // is player birthday
MailCore.sendBirthDayMailToPlayer(player);
}
// daily mail
MailCore.sendDailySignInMailToPlayer(player);
}
}
}

View File

@ -0,0 +1,177 @@
package io.github.gmw.utils;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.database.DatabaseHelper;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.mail.Mail;
import io.github.gmw.MeaMailPlusCore;
import io.github.gmw.config.MeaMailConfig;
import io.github.gmw.config.MeaMailTemplate;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public final class MailCore {
public static void sendMailToPlayer(Player player, MeaMailTemplate template) {
sendMailToPlayer(player, template, 0);
}
public static void sendMailToPlayer(Player player, int templateId) {
sendMailToPlayer(player, templateId, 0);
}
public static void sendMailToPlayer(Player player, int templateId, int minLevel) {
MeaMailTemplate template = getTemplateById(templateId);
if(template == null) {
MeaMailPlusCore.getInstance().logger("Template with id " + templateId + " not found");
return;
}
sendMailToPlayer(player, template, minLevel);
}
public static void sendMailToPlayer(Player player, MeaMailTemplate template, int minLevel) {
if (player.getLevel() >= minLevel) {
player.sendMail(templateToMail(template));
MeaMailPlusCore.getInstance().logger("Mail sent to " + player.getUid() + ": " + template.title);
} else {
MeaMailPlusCore.getInstance().logger("Player " + player.getUid() + " is not level " + minLevel + " and mail was not sent");
}
}
private static Mail templateToMail(MeaMailTemplate mailTemplate) {
Mail mail = new Mail();
mail.mailContent.content = mailTemplate.body.content;
mail.mailContent.title = mailTemplate.title;
mail.mailContent.sender = mailTemplate.sender;
mail.importance = mailTemplate.importance;
if (mailTemplate.remainTime == 0) {
mail.expireTime = mailTemplate.expireTime;
} else {
mail.expireTime = (int) Instant.now().getEpochSecond() + mailTemplate.remainTime;
}
mail.itemList = Arrays.stream(mailTemplate.body.items)
.map(item -> new Mail.MailItem(item.id, item.count, item.level))
.collect(Collectors.toList());
return mail;
}
private static MeaMailConfig getConfig() {
return MeaMailPlusCore.getInstance().config.getConfig();
}
private static MeaMailTemplate getTemplateById(int id) {
return MeaMailPlusCore.getInstance().config.getTemplate(id);
}
public static void sendMailToAllPlayers(int templateId) {
sendMailToAllPlayers(templateId, 0);
}
public static void sendMailToAllPlayers(MeaMailTemplate template) {
sendMailToAllPlayers(template, 0);
}
public static void sendMailToAllPlayers(int templateId, int minLevel) {
sendMailToAllPlayers(templateId, minLevel, false);
}
public static void sendMailToAllPlayers(MeaMailTemplate template, int minLevel) {
sendMailToAllPlayers(template, minLevel, false);
}
public static void sendMailToAllPlayers(int templateId, int minLevel, boolean onlineOnly) {
MeaMailTemplate template = getTemplateById(templateId);
if(template == null) {
MeaMailPlusCore.getInstance().logger("Template with id " + templateId + " not found");
return;
}
sendMailToAllPlayers(template, minLevel, onlineOnly);
}
public static void sendMailToAllPlayers(MeaMailTemplate template, int minLevel, boolean onlineOnly) {
if (template == null) return;
List<Player> onlinePlayers = new ArrayList<>();
List<Player> offlinePlayers = new ArrayList<>();
Grasscutter.getGameServer().getPlayers().forEach((index, player) -> onlinePlayers.add(player));
if (!onlineOnly) {
DatabaseHelper.getAllPlayers().forEach(player -> {
if (onlinePlayers.stream().noneMatch(onlinePlayer -> onlinePlayer.getUid() == player.getUid())) {
offlinePlayers.add(player);
}
});
}
// two methods to send mail
onlinePlayers.forEach(player -> sendMailToPlayer(player, template, minLevel));
offlinePlayers.forEach(player -> sendMailToPlayer(player, template, minLevel));
}
public static void sendDailySignInMailToPlayer(int uid) {
Grasscutter.getGameServer().getPlayers().forEach((index, player) -> {
if (player.getUid() == uid)
sendDailySignInMailToPlayer(player);
});
}
public static void sendDailySignInMailToPlayer(Player player) {
MeaMailConfig.DailySignInMailTask[] dailyTasks = getConfig().dailySignInMail;
for(MeaMailConfig.DailySignInMailTask task : dailyTasks) {
sendMailToPlayer(player, task.templateId, task.minLevel);
}
}
public static void sendBirthDayMailToPlayer(int uid) {
Grasscutter.getGameServer().getPlayers().forEach((index, player) -> {
if (player.getUid() == uid)
sendBirthDayMailToPlayer(player);
});
}
public static void sendBirthDayMailToPlayer(Player player) {
int[] BirthdayMailTemplateIds = getConfig().birthDayMail;
for(int templateId : BirthdayMailTemplateIds) {
sendMailToPlayer(player, templateId);
}
}
public static void sendInitialMailToPlayer(int uid) {
Grasscutter.getGameServer().getPlayers().forEach((index, player) -> {
if (player.getUid() == uid)
sendInitialMailToPlayer(player);
});
}
public static void sendInitialMailToPlayer(Player player) {
int[] InitialMailTemplateIds = getConfig().initialMail;
for(int templateId : InitialMailTemplateIds) {
sendMailToPlayer(player, templateId);
}
}
public static void dailyUpdate() {
// update daily
Grasscutter.getGameServer().getPlayers().forEach((index, player) -> {
// birthday mail
if (PlayerUtils.isPlayerBirthDay(player)) {
sendBirthDayMailToPlayer(player);
}
// daily sign in
sendDailySignInMailToPlayer(player);
});
}
public static void repetitionUpdate(MeaMailConfig.DailyRepetitionTask task) {
// update daily on time
sendMailToAllPlayers(task.templateId, task.minLevel, task.onlineOnly);
}
}

View File

@ -0,0 +1,42 @@
package io.github.gmw.utils;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.player.PlayerBirthday;
import io.github.gmw.MeaMailPlusCore;
import java.util.Calendar;
public final class PlayerUtils {
public static long getPlayerBirthDayTime(Player player) {
int[] updateTime = MeaMailPlusCore.getInstance().config.getConfig().updateTime;
PlayerBirthday date = player.getBirthday();
Calendar cal = Calendar.getInstance();
cal.set(Calendar.DAY_OF_MONTH, date.getDay());
cal.set(Calendar.MONTH, date.getMonth() - 1);
cal.set(Calendar.HOUR_OF_DAY, updateTime[0]);
cal.set(Calendar.MINUTE, updateTime[1]);
cal.set(Calendar.SECOND, updateTime[2]);
return cal.getTimeInMillis() / 1000;
}
public static boolean isPlayerBirthDay(Player player) {
if (player.hasBirthday()) {
long playerBirthDayTime = getPlayerBirthDayTime(player);
long playerEndBirthDayTime = playerBirthDayTime + 24 * 60 * 60;
long currentTime = System.currentTimeMillis() / 1000;
return currentTime >= playerBirthDayTime && currentTime < playerEndBirthDayTime;
}
return false;
}
public static boolean isFirstLoginToday(Player player) {
long startOfDayTime = MeaMailPlusCore.getInstance().config.getTomorrowUpdateTime() - 24 * 60 * 60;
long playerLastActiveTime = player.getProfile().getLastActiveTime();
long currentTime = System.currentTimeMillis() / 1000;
return playerLastActiveTime < startOfDayTime && currentTime >= startOfDayTime;
}
}

View File

@ -0,0 +1,10 @@
{
"name": "MeaMailPlus",
"description": "A plugin to send some notices to players",
"version": "1.0",
"mainClass": "io.github.gmw.MeaMailPlusCore",
"authors": [
"Hell",
"ButterCookies"
]
}