diff --git a/L2J_Mobius_C4_ScionsOfDestiny/dist/db_installer/sql/game/custom_mail.sql b/L2J_Mobius_C4_ScionsOfDestiny/dist/db_installer/sql/game/custom_mail.sql new file mode 100644 index 0000000000..59cb8b5cfa --- /dev/null +++ b/L2J_Mobius_C4_ScionsOfDestiny/dist/db_installer/sql/game/custom_mail.sql @@ -0,0 +1,7 @@ +CREATE TABLE IF NOT EXISTS `custom_mail` ( + `date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + `receiver` INT UNSIGNED NOT NULL DEFAULT 0, + `subject` TINYTEXT NOT NULL, + `message` TEXT NOT NULL, + `items` TEXT NOT NULL -- format: itemId1 count1;itemId2 count2;itemId3 count3... +) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; \ No newline at end of file diff --git a/L2J_Mobius_C4_ScionsOfDestiny/dist/game/config/custom/CustomMailManager.ini b/L2J_Mobius_C4_ScionsOfDestiny/dist/game/config/custom/CustomMailManager.ini new file mode 100644 index 0000000000..f8c3900ec4 --- /dev/null +++ b/L2J_Mobius_C4_ScionsOfDestiny/dist/game/config/custom/CustomMailManager.ini @@ -0,0 +1,11 @@ +# --------------------------------------------------------------------------- +# Custom Mail Manager +# --------------------------------------------------------------------------- + +# Enable/Disable sending mail through the custom_mail SQL table. +# Default: False +CustomMailManagerEnabled = False + +# Database query delay in seconds. +# Default: 30 +DatabaseQueryDelay = 30 diff --git a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/Config.java b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/Config.java index ae7e764a35..da05b926f4 100644 --- a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/Config.java +++ b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/Config.java @@ -89,6 +89,7 @@ public class Config private static final String BANK_CONFIG_FILE = "./config/custom/Bank.ini"; private static final String CANCEL_SKILL_RESTORE_BUFFS_CONFIG_FILE = "./config/custom/CancelSkillRestoreBuffs.ini"; private static final String CHAMPION_CONFIG_FILE = "./config/custom/Champion.ini"; + private static final String CUSTOM_CUSTOM_MAIL_MANAGER_CONFIG_FILE = "./config/custom/CustomMailManager.ini"; private static final String MERCHANT_ZERO_SELL_PRICE_CONFIG_FILE = "./config/custom/MerchantZeroSellPrice.ini"; private static final String OFFLINE_CONFIG_FILE = "./config/custom/Offline.ini"; private static final String OTHER_CONFIG_FILE = "./config/custom/Other.ini"; @@ -454,6 +455,9 @@ public class Config public static int CHAMPION_REWARD_QTY; public static String CHAMP_TITLE; + public static boolean CUSTOM_MAIL_MANAGER_ENABLED; + public static int CUSTOM_MAIL_MANAGER_DELAY; + public static boolean MERCHANT_ZERO_SELL_PRICE; public static boolean ALLOW_WEDDING; @@ -1623,6 +1627,13 @@ public class Config CHAMP_TITLE = championConfig.getString("ChampionTitle", "Champion"); } + public static void loadCustomMailManagerConfig() + { + final PropertiesParser customMailManagerConfig = new PropertiesParser(CUSTOM_CUSTOM_MAIL_MANAGER_CONFIG_FILE); + CUSTOM_MAIL_MANAGER_ENABLED = customMailManagerConfig.getBoolean("CustomMailManagerEnabled", false); + CUSTOM_MAIL_MANAGER_DELAY = customMailManagerConfig.getInt("DatabaseQueryDelay", 30) * 1000; + } + public static void loadMerchantZeroPriceConfig() { final PropertiesParser merchantZeroSellPriceConfig = new PropertiesParser(MERCHANT_ZERO_SELL_PRICE_CONFIG_FILE); @@ -3058,6 +3069,7 @@ public class Config // Custom loadCancelSkillRestoreBuffsConfig(); loadChampionConfig(); + loadCustomMailManagerConfig(); loadMerchantZeroPriceConfig(); loadWeddingConfig(); loadRebirthConfig(); diff --git a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/GameServer.java b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/GameServer.java index 357db12c44..30f6b6b266 100644 --- a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/GameServer.java +++ b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/GameServer.java @@ -87,6 +87,7 @@ import org.l2jmobius.gameserver.instancemanager.ClanHallManager; import org.l2jmobius.gameserver.instancemanager.ClassDamageManager; import org.l2jmobius.gameserver.instancemanager.CoupleManager; import org.l2jmobius.gameserver.instancemanager.CrownManager; +import org.l2jmobius.gameserver.instancemanager.CustomMailManager; import org.l2jmobius.gameserver.instancemanager.DayNightSpawnManager; import org.l2jmobius.gameserver.instancemanager.DimensionalRiftManager; import org.l2jmobius.gameserver.instancemanager.FortManager; @@ -361,6 +362,11 @@ public class GameServer // Schedule auto opening/closing doors. DoorData.getInstance().checkAutoOpen(); + if (Config.CUSTOM_MAIL_MANAGER_ENABLED) + { + CustomMailManager.getInstance(); + } + Util.printSection("Scripts"); if (!Config.ALT_DEV_NO_SCRIPT) { diff --git a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/instancemanager/CustomMailManager.java b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/instancemanager/CustomMailManager.java new file mode 100644 index 0000000000..13557aa5d4 --- /dev/null +++ b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/instancemanager/CustomMailManager.java @@ -0,0 +1,126 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.l2jmobius.gameserver.instancemanager; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.l2jmobius.Config; +import org.l2jmobius.commons.concurrent.ThreadPool; +import org.l2jmobius.commons.database.DatabaseFactory; +import org.l2jmobius.gameserver.enums.ChatType; +import org.l2jmobius.gameserver.model.World; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.ItemHolder; +import org.l2jmobius.gameserver.network.serverpackets.CreatureSay; +import org.l2jmobius.gameserver.util.Util; + +/** + * @author Mobius + */ +public class CustomMailManager +{ + private static final Logger LOGGER = Logger.getLogger(CustomMailManager.class.getName()); + + // SQL Statements + private static final String READ_SQL = "SELECT * FROM custom_mail"; + private static final String DELETE_SQL = "DELETE FROM custom_mail WHERE date=? AND receiver=?"; + + protected CustomMailManager() + { + ThreadPool.scheduleAtFixedRate(() -> + { + try (Connection con = DatabaseFactory.getConnection(); + Statement ps = con.createStatement(); + ResultSet rs = ps.executeQuery(READ_SQL)) + { + while (rs.next()) + { + final int playerId = rs.getInt("receiver"); + final PlayerInstance player = World.getInstance().getPlayer(playerId); + if ((player != null) && player.isOnline()) + { + // Create message. + final String items = rs.getString("items"); + player.sendPacket(new CreatureSay(0, ChatType.WHISPER, rs.getString("subject"), rs.getString("message"))); + final List itemHolders = new ArrayList<>(); + for (String str : items.split(";")) + { + if (str.contains(" ")) + { + final String itemId = str.split(" ")[0]; + final String itemCount = str.split(" ")[1]; + if (Util.isDigit(itemId) && Util.isDigit(itemCount)) + { + itemHolders.add(new ItemHolder(Integer.parseInt(itemId), Long.parseLong(itemCount))); + } + } + else if (Util.isDigit(str)) + { + itemHolders.add(new ItemHolder(Integer.parseInt(str), 1)); + } + } + if (!itemHolders.isEmpty()) + { + for (ItemHolder itemHolder : itemHolders) + { + player.addItem("Custom-Mail", itemHolder.getId(), (int) itemHolder.getCount(), null, true); + } + } + + // Delete entry from database. + try (PreparedStatement stmt = con.prepareStatement(DELETE_SQL)) + { + stmt.setString(1, rs.getString("date")); + stmt.setInt(2, playerId); + stmt.execute(); + } + catch (SQLException e) + { + LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Error deleting entry from database: ", e); + } + + LOGGER.info(getClass().getSimpleName() + ": Message sent to " + player.getName() + "."); + } + } + } + catch (SQLException e) + { + LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Error reading from database: ", e); + } + }, Config.CUSTOM_MAIL_MANAGER_DELAY, Config.CUSTOM_MAIL_MANAGER_DELAY); + + LOGGER.info(getClass().getSimpleName() + ": Enabled."); + } + + public static CustomMailManager getInstance() + { + return SingletonHolder.INSTANCE; + } + + private static class SingletonHolder + { + protected static final CustomMailManager INSTANCE = new CustomMailManager(); + } +} diff --git a/L2J_Mobius_C6_Interlude/dist/db_installer/sql/game/custom_mail.sql b/L2J_Mobius_C6_Interlude/dist/db_installer/sql/game/custom_mail.sql new file mode 100644 index 0000000000..59cb8b5cfa --- /dev/null +++ b/L2J_Mobius_C6_Interlude/dist/db_installer/sql/game/custom_mail.sql @@ -0,0 +1,7 @@ +CREATE TABLE IF NOT EXISTS `custom_mail` ( + `date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + `receiver` INT UNSIGNED NOT NULL DEFAULT 0, + `subject` TINYTEXT NOT NULL, + `message` TEXT NOT NULL, + `items` TEXT NOT NULL -- format: itemId1 count1;itemId2 count2;itemId3 count3... +) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; \ No newline at end of file diff --git a/L2J_Mobius_C6_Interlude/dist/game/config/custom/CustomMailManager.ini b/L2J_Mobius_C6_Interlude/dist/game/config/custom/CustomMailManager.ini new file mode 100644 index 0000000000..f8c3900ec4 --- /dev/null +++ b/L2J_Mobius_C6_Interlude/dist/game/config/custom/CustomMailManager.ini @@ -0,0 +1,11 @@ +# --------------------------------------------------------------------------- +# Custom Mail Manager +# --------------------------------------------------------------------------- + +# Enable/Disable sending mail through the custom_mail SQL table. +# Default: False +CustomMailManagerEnabled = False + +# Database query delay in seconds. +# Default: 30 +DatabaseQueryDelay = 30 diff --git a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/Config.java b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/Config.java index 89b5622ca3..0d3b65b882 100644 --- a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/Config.java +++ b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/Config.java @@ -90,6 +90,7 @@ public class Config private static final String BANK_CONFIG_FILE = "./config/custom/Bank.ini"; private static final String CANCEL_SKILL_RESTORE_BUFFS_CONFIG_FILE = "./config/custom/CancelSkillRestoreBuffs.ini"; private static final String CHAMPION_CONFIG_FILE = "./config/custom/Champion.ini"; + private static final String CUSTOM_CUSTOM_MAIL_MANAGER_CONFIG_FILE = "./config/custom/CustomMailManager.ini"; private static final String MERCHANT_ZERO_SELL_PRICE_CONFIG_FILE = "./config/custom/MerchantZeroSellPrice.ini"; private static final String OFFLINE_CONFIG_FILE = "./config/custom/Offline.ini"; private static final String OTHER_CONFIG_FILE = "./config/custom/Other.ini"; @@ -473,6 +474,9 @@ public class Config public static int CHAMPION_REWARD_QTY; public static String CHAMP_TITLE; + public static boolean CUSTOM_MAIL_MANAGER_ENABLED; + public static int CUSTOM_MAIL_MANAGER_DELAY; + public static boolean MERCHANT_ZERO_SELL_PRICE; public static boolean ALLOW_WEDDING; @@ -1673,6 +1677,13 @@ public class Config CHAMP_TITLE = championConfig.getString("ChampionTitle", "Champion"); } + public static void loadCustomMailManagerConfig() + { + final PropertiesParser customMailManagerConfig = new PropertiesParser(CUSTOM_CUSTOM_MAIL_MANAGER_CONFIG_FILE); + CUSTOM_MAIL_MANAGER_ENABLED = customMailManagerConfig.getBoolean("CustomMailManagerEnabled", false); + CUSTOM_MAIL_MANAGER_DELAY = customMailManagerConfig.getInt("DatabaseQueryDelay", 30) * 1000; + } + public static void loadMerchantZeroPriceConfig() { final PropertiesParser merchantZeroSellPriceConfig = new PropertiesParser(MERCHANT_ZERO_SELL_PRICE_CONFIG_FILE); @@ -3127,6 +3138,7 @@ public class Config // Custom loadCancelSkillRestoreBuffsConfig(); loadChampionConfig(); + loadCustomMailManagerConfig(); loadMerchantZeroPriceConfig(); loadWeddingConfig(); loadRebirthConfig(); diff --git a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/GameServer.java b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/GameServer.java index 7b620245f3..8baa117582 100644 --- a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/GameServer.java +++ b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/GameServer.java @@ -89,6 +89,7 @@ import org.l2jmobius.gameserver.instancemanager.ClassDamageManager; import org.l2jmobius.gameserver.instancemanager.CoupleManager; import org.l2jmobius.gameserver.instancemanager.CrownManager; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; +import org.l2jmobius.gameserver.instancemanager.CustomMailManager; import org.l2jmobius.gameserver.instancemanager.DayNightSpawnManager; import org.l2jmobius.gameserver.instancemanager.DimensionalRiftManager; import org.l2jmobius.gameserver.instancemanager.DuelManager; @@ -368,6 +369,11 @@ public class GameServer // Schedule auto opening/closing doors. DoorData.getInstance().checkAutoOpen(); + if (Config.CUSTOM_MAIL_MANAGER_ENABLED) + { + CustomMailManager.getInstance(); + } + Util.printSection("Scripts"); if (!Config.ALT_DEV_NO_SCRIPT) { diff --git a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/instancemanager/CustomMailManager.java b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/instancemanager/CustomMailManager.java new file mode 100644 index 0000000000..13557aa5d4 --- /dev/null +++ b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/instancemanager/CustomMailManager.java @@ -0,0 +1,126 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.l2jmobius.gameserver.instancemanager; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.l2jmobius.Config; +import org.l2jmobius.commons.concurrent.ThreadPool; +import org.l2jmobius.commons.database.DatabaseFactory; +import org.l2jmobius.gameserver.enums.ChatType; +import org.l2jmobius.gameserver.model.World; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.ItemHolder; +import org.l2jmobius.gameserver.network.serverpackets.CreatureSay; +import org.l2jmobius.gameserver.util.Util; + +/** + * @author Mobius + */ +public class CustomMailManager +{ + private static final Logger LOGGER = Logger.getLogger(CustomMailManager.class.getName()); + + // SQL Statements + private static final String READ_SQL = "SELECT * FROM custom_mail"; + private static final String DELETE_SQL = "DELETE FROM custom_mail WHERE date=? AND receiver=?"; + + protected CustomMailManager() + { + ThreadPool.scheduleAtFixedRate(() -> + { + try (Connection con = DatabaseFactory.getConnection(); + Statement ps = con.createStatement(); + ResultSet rs = ps.executeQuery(READ_SQL)) + { + while (rs.next()) + { + final int playerId = rs.getInt("receiver"); + final PlayerInstance player = World.getInstance().getPlayer(playerId); + if ((player != null) && player.isOnline()) + { + // Create message. + final String items = rs.getString("items"); + player.sendPacket(new CreatureSay(0, ChatType.WHISPER, rs.getString("subject"), rs.getString("message"))); + final List itemHolders = new ArrayList<>(); + for (String str : items.split(";")) + { + if (str.contains(" ")) + { + final String itemId = str.split(" ")[0]; + final String itemCount = str.split(" ")[1]; + if (Util.isDigit(itemId) && Util.isDigit(itemCount)) + { + itemHolders.add(new ItemHolder(Integer.parseInt(itemId), Long.parseLong(itemCount))); + } + } + else if (Util.isDigit(str)) + { + itemHolders.add(new ItemHolder(Integer.parseInt(str), 1)); + } + } + if (!itemHolders.isEmpty()) + { + for (ItemHolder itemHolder : itemHolders) + { + player.addItem("Custom-Mail", itemHolder.getId(), (int) itemHolder.getCount(), null, true); + } + } + + // Delete entry from database. + try (PreparedStatement stmt = con.prepareStatement(DELETE_SQL)) + { + stmt.setString(1, rs.getString("date")); + stmt.setInt(2, playerId); + stmt.execute(); + } + catch (SQLException e) + { + LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Error deleting entry from database: ", e); + } + + LOGGER.info(getClass().getSimpleName() + ": Message sent to " + player.getName() + "."); + } + } + } + catch (SQLException e) + { + LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Error reading from database: ", e); + } + }, Config.CUSTOM_MAIL_MANAGER_DELAY, Config.CUSTOM_MAIL_MANAGER_DELAY); + + LOGGER.info(getClass().getSimpleName() + ": Enabled."); + } + + public static CustomMailManager getInstance() + { + return SingletonHolder.INSTANCE; + } + + private static class SingletonHolder + { + protected static final CustomMailManager INSTANCE = new CustomMailManager(); + } +}