From 389b3ad2a45dcee3b218f45e196d01e30f3f02e2 Mon Sep 17 00:00:00 2001 From: P0nk Date: Tue, 27 Dec 2022 10:34:55 +0100 Subject: [PATCH] Add NoteService to handle note operations NoteService should be the only class with access to NoteDao; nowhere else should NoteDao be accessed directly. Channel dependencies are static in PacketProcessor, for now. Ideally they would be injected in the constructor, but since the constructor is private and I don't want to open up that can of worms, I'll leave it like this. At the very least, now we have a way of injecting services into the handlers. This will make further restructuring way easier. --- src/main/java/client/Character.java | 15 --- .../processor/npc/FredrickProcessor.java | 2 +- src/main/java/database/note/NoteDao.java | 9 +- .../database/{ => note}/NoteRowMapper.java | 2 +- src/main/java/net/ChannelDependencies.java | 12 +++ src/main/java/net/PacketProcessor.java | 21 ++++- src/main/java/net/server/Server.java | 16 ++++ .../handlers/CashOperationHandler.java | 43 +++------ .../channel/handlers/NoteActionHandler.java | 40 +++----- .../handlers/PlayerLoggedinHandler.java | 10 +- .../channel/handlers/RingActionHandler.java | 22 ++--- .../channel/handlers/UseCashItemHandler.java | 20 ++-- src/main/java/net/server/guild/Guild.java | 2 +- src/main/java/service/NoteService.java | 93 +++++++++++++++++++ src/main/java/tools/DatabaseConnection.java | 2 +- 15 files changed, 199 insertions(+), 110 deletions(-) rename src/main/java/database/{ => note}/NoteRowMapper.java (96%) create mode 100644 src/main/java/net/ChannelDependencies.java create mode 100644 src/main/java/service/NoteService.java diff --git a/src/main/java/client/Character.java b/src/main/java/client/Character.java index 11689acc4a..201160e582 100644 --- a/src/main/java/client/Character.java +++ b/src/main/java/client/Character.java @@ -41,9 +41,6 @@ import constants.id.MapId; import constants.id.MobId; import constants.inventory.ItemConstants; import constants.skills.*; -import database.DaoException; -import database.NoteDao; -import model.Note; import net.packet.Packet; import net.server.PlayerBuffValueHolder; import net.server.PlayerCoolDownValueHolder; @@ -9627,18 +9624,6 @@ public class Character extends AbstractCharacterObject { client.announceHint(msg, length); } - public void showNote() { - final List notes; - try { - notes = NoteDao.findAllByTo(name); - } catch (DaoException e) { - log.error("Failed to find notes for chr name {}", name, e); - return; - } - - sendPacket(PacketCreator.showNotes(notes)); - } - public void silentGiveBuffs(List> buffs) { for (Pair mbsv : buffs) { PlayerBuffValueHolder mbsvh = mbsv.getRight(); diff --git a/src/main/java/client/processor/npc/FredrickProcessor.java b/src/main/java/client/processor/npc/FredrickProcessor.java index e6beb8b649..4480ea4609 100644 --- a/src/main/java/client/processor/npc/FredrickProcessor.java +++ b/src/main/java/client/processor/npc/FredrickProcessor.java @@ -31,7 +31,7 @@ import client.inventory.Item; import client.inventory.ItemFactory; import client.inventory.manipulator.InventoryManipulator; import database.DaoException; -import database.NoteDao; +import database.note.NoteDao; import model.Note; import net.server.Server; import net.server.world.World; diff --git a/src/main/java/database/note/NoteDao.java b/src/main/java/database/note/NoteDao.java index c7dd61e337..34451e0963 100644 --- a/src/main/java/database/note/NoteDao.java +++ b/src/main/java/database/note/NoteDao.java @@ -1,5 +1,6 @@ -package database; +package database.note; +import database.DaoException; import model.Note; import org.jdbi.v3.core.Handle; import org.jdbi.v3.core.JdbiException; @@ -27,7 +28,7 @@ public class NoteDao { } } - public static List findAllByTo(String to) { + public List findAllByTo(String to) { try (Handle handle = DatabaseConnection.getHandle()) { return handle.createQuery(""" SELECT * @@ -38,11 +39,11 @@ public class NoteDao { .mapTo(Note.class) .list(); } catch (JdbiException e) { - throw new DaoException("Failed to find notes with \"to\": %s".formatted(to), e); + throw new DaoException("Failed to find notes sent to: %s".formatted(to), e); } } - public static Optional delete(int id) { + public Optional delete(int id) { try (Handle handle = DatabaseConnection.getHandle()) { Optional note = findById(handle, id); if (note.isEmpty()) { diff --git a/src/main/java/database/NoteRowMapper.java b/src/main/java/database/note/NoteRowMapper.java similarity index 96% rename from src/main/java/database/NoteRowMapper.java rename to src/main/java/database/note/NoteRowMapper.java index b035741859..fd239a5632 100644 --- a/src/main/java/database/NoteRowMapper.java +++ b/src/main/java/database/note/NoteRowMapper.java @@ -1,4 +1,4 @@ -package database; +package database.note; import model.Note; import org.jdbi.v3.core.mapper.RowMapper; diff --git a/src/main/java/net/ChannelDependencies.java b/src/main/java/net/ChannelDependencies.java new file mode 100644 index 0000000000..eb07b2bfba --- /dev/null +++ b/src/main/java/net/ChannelDependencies.java @@ -0,0 +1,12 @@ +package net; + +import service.NoteService; + +import java.util.Objects; + +public record ChannelDependencies(NoteService noteService) { + + public ChannelDependencies { + Objects.requireNonNull(noteService); + } +} diff --git a/src/main/java/net/PacketProcessor.java b/src/main/java/net/PacketProcessor.java index 4c5e2615cc..4f47b2c55d 100644 --- a/src/main/java/net/PacketProcessor.java +++ b/src/main/java/net/PacketProcessor.java @@ -37,6 +37,9 @@ import java.util.Map; public final class PacketProcessor { private static final Logger log = LoggerFactory.getLogger(PacketProcessor.class); private static final Map instances = new LinkedHashMap<>(); + + private static ChannelDependencies channelDependencies; + private PacketHandler[] handlers; private PacketProcessor() { @@ -49,11 +52,19 @@ public final class PacketProcessor { handlers = new PacketHandler[maxRecvOp + 1]; } + public static void registerGameHandlerDependencies(ChannelDependencies channelDependencies) { + PacketProcessor.channelDependencies = channelDependencies; + } + public static PacketProcessor getLoginServerProcessor() { return getProcessor(LoginServer.WORLD_ID, LoginServer.CHANNEL_ID); } public static PacketProcessor getChannelServerProcessor(int world, int channel) { + if (channelDependencies == null) { + throw new IllegalStateException("Unable to get channel server processor - dependencies are not registered"); + } + return getProcessor(world, channel); } @@ -141,7 +152,7 @@ public final class PacketProcessor { registerHandler(RecvOpcode.ITEM_SORT, new InventoryMergeHandler()); registerHandler(RecvOpcode.ITEM_MOVE, new ItemMoveHandler()); registerHandler(RecvOpcode.MESO_DROP, new MesoDropHandler()); - registerHandler(RecvOpcode.PLAYER_LOGGEDIN, new PlayerLoggedinHandler()); + registerHandler(RecvOpcode.PLAYER_LOGGEDIN, new PlayerLoggedinHandler(channelDependencies.noteService())); registerHandler(RecvOpcode.CHANGE_MAP, new ChangeMapHandler()); registerHandler(RecvOpcode.MOVE_LIFE, new MoveLifeHandler()); registerHandler(RecvOpcode.CLOSE_RANGE_ATTACK, new CloseRangeDamageHandler()); @@ -149,7 +160,7 @@ public final class PacketProcessor { registerHandler(RecvOpcode.MAGIC_ATTACK, new MagicDamageHandler()); registerHandler(RecvOpcode.TAKE_DAMAGE, new TakeDamageHandler()); registerHandler(RecvOpcode.MOVE_PLAYER, new MovePlayerHandler()); - registerHandler(RecvOpcode.USE_CASH_ITEM, new UseCashItemHandler()); + registerHandler(RecvOpcode.USE_CASH_ITEM, new UseCashItemHandler(channelDependencies.noteService())); registerHandler(RecvOpcode.USE_ITEM, new UseItemHandler()); registerHandler(RecvOpcode.USE_RETURN_SCROLL, new UseItemHandler()); registerHandler(RecvOpcode.USE_UPGRADE_SCROLL, new ScrollHandler()); @@ -191,7 +202,7 @@ public final class PacketProcessor { registerHandler(RecvOpcode.MESSENGER, new MessengerHandler()); registerHandler(RecvOpcode.NPC_ACTION, new NPCAnimationHandler()); registerHandler(RecvOpcode.CHECK_CASH, new TouchingCashShopHandler()); - registerHandler(RecvOpcode.CASHSHOP_OPERATION, new CashOperationHandler()); + registerHandler(RecvOpcode.CASHSHOP_OPERATION, new CashOperationHandler(channelDependencies.noteService())); registerHandler(RecvOpcode.COUPON_CODE, new CouponCodeHandler()); registerHandler(RecvOpcode.SPAWN_PET, new SpawnPetHandler()); registerHandler(RecvOpcode.MOVE_PET, new MovePetHandler()); @@ -204,11 +215,11 @@ public final class PacketProcessor { registerHandler(RecvOpcode.CANCEL_DEBUFF, new CancelDebuffHandler()); registerHandler(RecvOpcode.USE_SKILL_BOOK, new SkillBookHandler()); registerHandler(RecvOpcode.SKILL_MACRO, new SkillMacroHandler()); - registerHandler(RecvOpcode.NOTE_ACTION, new NoteActionHandler()); + registerHandler(RecvOpcode.NOTE_ACTION, new NoteActionHandler(channelDependencies.noteService())); registerHandler(RecvOpcode.CLOSE_CHALKBOARD, new CloseChalkboardHandler()); registerHandler(RecvOpcode.USE_MOUNT_FOOD, new UseMountFoodHandler()); registerHandler(RecvOpcode.MTS_OPERATION, new MTSHandler()); - registerHandler(RecvOpcode.RING_ACTION, new RingActionHandler()); + registerHandler(RecvOpcode.RING_ACTION, new RingActionHandler(channelDependencies.noteService())); registerHandler(RecvOpcode.SPOUSE_CHAT, new SpouseChatHandler()); registerHandler(RecvOpcode.PET_AUTO_POT, new PetAutoPotHandler()); registerHandler(RecvOpcode.PET_EXCLUDE_ITEMS, new PetExcludeItemsHandler()); diff --git a/src/main/java/net/server/Server.java b/src/main/java/net/server/Server.java index f47f4770af..f341b94eee 100644 --- a/src/main/java/net/server/Server.java +++ b/src/main/java/net/server/Server.java @@ -35,6 +35,9 @@ import constants.game.GameConstants; import constants.inventory.ItemConstants; import constants.net.OpcodeConstants; import constants.net.ServerConstants; +import database.note.NoteDao; +import net.ChannelDependencies; +import net.PacketProcessor; import net.netty.LoginServer; import net.packet.Packet; import net.server.channel.Channel; @@ -55,6 +58,7 @@ import server.TimerManager; import server.expeditions.ExpeditionBossLog; import server.life.PlayerNPCFactory; import server.quest.Quest; +import service.NoteService; import tools.DatabaseConnection; import tools.Pair; @@ -838,6 +842,8 @@ public class Server { throw new IllegalStateException("Failed to initiate a connection to the database"); } + registerChannelDependencies(); + final ExecutorService initExecutor = Executors.newFixedThreadPool(10); // Run slow operations asynchronously to make startup faster final List> futures = new ArrayList<>(); @@ -914,6 +920,16 @@ public class Server { } } + private void registerChannelDependencies() { + NoteDao noteDao = new NoteDao(); + + ChannelDependencies channelDependencies = new ChannelDependencies( + new NoteService(noteDao) + ); + + PacketProcessor.registerGameHandlerDependencies(channelDependencies); + } + private LoginServer initLoginServer(int port) { LoginServer loginServer = new LoginServer(port); loginServer.start(); diff --git a/src/main/java/net/server/channel/handlers/CashOperationHandler.java b/src/main/java/net/server/channel/handlers/CashOperationHandler.java index 36a8268104..077c654a5c 100644 --- a/src/main/java/net/server/channel/handlers/CashOperationHandler.java +++ b/src/main/java/net/server/channel/handlers/CashOperationHandler.java @@ -32,9 +32,6 @@ import client.inventory.manipulator.InventoryManipulator; import config.YamlConfig; import constants.id.ItemId; import constants.inventory.ItemConstants; -import database.DaoException; -import database.NoteDao; -import model.Note; import net.AbstractPacketHandler; import net.packet.InPacket; import net.server.Server; @@ -44,10 +41,10 @@ import server.CashShop; import server.CashShop.CashItem; import server.CashShop.CashItemFactory; import server.ItemInformationProvider; +import service.NoteService; import tools.PacketCreator; import tools.Pair; -import java.sql.SQLException; import java.util.Calendar; import java.util.List; import java.util.Map; @@ -57,6 +54,12 @@ import static java.util.concurrent.TimeUnit.DAYS; public final class CashOperationHandler extends AbstractPacketHandler { private static final Logger log = LoggerFactory.getLogger(CashOperationHandler.class); + private final NoteService noteService; + + public CashOperationHandler(NoteService noteService) { + this.noteService = noteService; + } + @Override public void handlePacket(InPacket p, Client c) { Character chr = c.getPlayer(); @@ -132,11 +135,12 @@ public final class CashOperationHandler extends AbstractPacketHandler { c.sendPacket(PacketCreator.showGiftSucceed(recipient.get("name"), cItem)); c.sendPacket(PacketCreator.showCash(chr)); - sendGiftNotificationNote(chr.getName(), recipient.get("name")); + String noteMessage = chr.getName() + " has sent you a gift! Go check out the Cash Shop."; + noteService.sendNormal(noteMessage, chr.getName(), recipient.get("name")); Character receiver = c.getChannelServer().getPlayerStorage().getCharacterByName(recipient.get("name")); if (receiver != null) { - receiver.showNote(); + noteService.show(receiver); } } else if (action == 0x05) { // Modify wish list cs.clearWishList(); @@ -331,8 +335,8 @@ public final class CashOperationHandler extends AbstractPacketHandler { cs.gainCash(toCharge, itemRing, chr.getWorld()); cs.gift(partner.getId(), chr.getName(), text, eqp.getSN(), rings.getRight()); chr.addCrushRing(Ring.loadFromDb(rings.getLeft())); - sendGiftNote(text, chr.getName(), partner.getName()); - partner.showNote(); + noteService.sendWithFame(text, chr.getName(), partner.getName()); + noteService.show(partner); } } } else { @@ -390,8 +394,8 @@ public final class CashOperationHandler extends AbstractPacketHandler { cs.gainCash(payment, -itemRing.getPrice()); cs.gift(partner.getId(), chr.getName(), text, eqp.getSN(), rings.getRight()); chr.addFriendshipRing(Ring.loadFromDb(rings.getLeft())); - sendGiftNote(text, chr.getName(), partner.getName()); - partner.showNote(); + noteService.sendWithFame(text, chr.getName(), partner.getName()); + noteService.show(partner); } } } else { @@ -487,23 +491,4 @@ public final class CashOperationHandler extends AbstractPacketHandler { return false; } } - - private void sendGiftNote(String message, String from, String to) { - Note giftNote = Note.createGift(message, from, to, Server.getInstance().getCurrentTime()); - sendGiftNote(giftNote); - } - - private void sendGiftNotificationNote(String from, String to) { - String message = from + " has sent you a gift! Go check out the Cash Shop."; - Note giftNotificationNote = Note.createNormal(message, from, to, Server.getInstance().getCurrentTime()); - sendGiftNote(giftNotificationNote); - } - - private void sendGiftNote(Note giftNote) { - try { - NoteDao.save(giftNote); - } catch (DaoException e) { - log.error("Failed to send gift note {}", giftNote, e); - } - } } diff --git a/src/main/java/net/server/channel/handlers/NoteActionHandler.java b/src/main/java/net/server/channel/handlers/NoteActionHandler.java index 7a99f23199..ed919b8c5b 100644 --- a/src/main/java/net/server/channel/handlers/NoteActionHandler.java +++ b/src/main/java/net/server/channel/handlers/NoteActionHandler.java @@ -22,22 +22,25 @@ package net.server.channel.handlers; import client.Client; -import database.DaoException; -import database.NoteDao; import model.Note; import net.AbstractPacketHandler; import net.packet.InPacket; -import net.server.Server; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import service.NoteService; import tools.PacketCreator; -import java.sql.SQLException; import java.util.Optional; public final class NoteActionHandler extends AbstractPacketHandler { private static final Logger log = LoggerFactory.getLogger(NoteActionHandler.class); + private final NoteService noteService; + + public NoteActionHandler(NoteService noteService) { + this.noteService = noteService; + } + @Override public void handlePacket(InPacket p, Client c) { int action = p.readByte(); @@ -48,7 +51,7 @@ public final class NoteActionHandler extends AbstractPacketHandler { c.sendPacket(PacketCreator.showCashInventory(c)); } - boolean sendNoteSuccess = sendGiftReplyNote(message, c.getPlayer().getName(), charname); + boolean sendNoteSuccess = noteService.sendWithFame(message, c.getPlayer().getName(), charname); if (sendNoteSuccess) { c.getPlayer().getCashShop().decreaseNotes(); } @@ -61,36 +64,17 @@ public final class NoteActionHandler extends AbstractPacketHandler { int id = p.readInt(); p.readByte(); //Fame, but we read it from the database :) - final Optional note; - try { - note = NoteDao.delete(id); - } catch (DaoException e) { - log.error("Failed to delete note {}", id, e); + Optional discardedNote = noteService.discard(id); + if (discardedNote.isEmpty()) { + log.warn("Note with id {} not able to be discarded. Already discarded?", id); continue; } - if (note.isEmpty()) { - log.warn("Note with id {} not able to be deleted. Already deleted?", id); - continue; - } - - fame += note.get().fame(); + fame += discardedNote.get().fame(); } if (fame > 0) { c.getPlayer().gainFame(fame); } } } - - private boolean sendGiftReplyNote(String message, String from, String to) { - Note giftReplyNote = Note.createGift(message, from, to, Server.getInstance().getCurrentTime()); - try { - NoteDao.save(giftReplyNote); - } catch (DaoException e) { - log.error("Failed to send gift reply note {}", giftReplyNote, e); - return false; - } - - return true; - } } diff --git a/src/main/java/net/server/channel/handlers/PlayerLoggedinHandler.java b/src/main/java/net/server/channel/handlers/PlayerLoggedinHandler.java index 61ccc18149..72a904006c 100644 --- a/src/main/java/net/server/channel/handlers/PlayerLoggedinHandler.java +++ b/src/main/java/net/server/channel/handlers/PlayerLoggedinHandler.java @@ -46,6 +46,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import scripting.event.EventInstanceManager; import server.life.MobSkill; +import service.NoteService; import tools.DatabaseConnection; import tools.PacketCreator; import tools.Pair; @@ -63,6 +64,12 @@ public final class PlayerLoggedinHandler extends AbstractPacketHandler { private static final Logger log = LoggerFactory.getLogger(PlayerLoggedinHandler.class); private static final Set attemptingLoginAccounts = new HashSet<>(); + private final NoteService noteService; + + public PlayerLoggedinHandler(NoteService noteService) { + this.noteService = noteService; + } + private boolean tryAcquireAccount(int accId) { synchronized (attemptingLoginAccounts) { if (attemptingLoginAccounts.contains(accId)) { @@ -302,7 +309,8 @@ public final class PlayerLoggedinHandler extends AbstractPacketHandler { } } - player.showNote(); + noteService.show(player); + if (player.getParty() != null) { PartyCharacter pchar = player.getMPC(); diff --git a/src/main/java/net/server/channel/handlers/RingActionHandler.java b/src/main/java/net/server/channel/handlers/RingActionHandler.java index 40de1106e6..d8da534cd0 100644 --- a/src/main/java/net/server/channel/handlers/RingActionHandler.java +++ b/src/main/java/net/server/channel/handlers/RingActionHandler.java @@ -30,18 +30,15 @@ import client.inventory.Item; import client.inventory.manipulator.InventoryManipulator; import client.processor.npc.DueyProcessor; import constants.id.ItemId; -import database.DaoException; -import database.NoteDao; -import model.Note; import net.AbstractPacketHandler; import net.packet.InPacket; -import net.server.Server; import net.server.channel.Channel; import net.server.world.World; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import scripting.event.EventInstanceManager; import server.ItemInformationProvider; +import service.NoteService; import tools.DatabaseConnection; import tools.PacketCreator; import tools.Pair; @@ -60,6 +57,12 @@ import java.sql.SQLException; public final class RingActionHandler extends AbstractPacketHandler { private static final Logger log = LoggerFactory.getLogger(RingActionHandler.class); + private final NoteService noteService; + + public RingActionHandler(NoteService noteService) { + this.noteService = noteService; + } + private static int getEngagementBoxId(int useItemId) { return switch (useItemId) { case ItemId.ENGAGEMENT_BOX_MOONSTONE -> ItemId.EMPTY_ENGAGEMENT_BOX_MOONSTONE; @@ -431,7 +434,7 @@ public final class RingActionHandler extends AbstractPacketHandler { if (guestChr != null && guestChr.isLoggedinWorld()) { guestChr.dropMessage(6, "[Wedding] %s".formatted(dueyMessage)); } else { - sendWeddingInvitationNote(dueyMessage, groom, name); + noteService.sendNormal(dueyMessage, groom, name); } Item weddingTicket = new Item(newItemId, (short) 0, (short) 1); @@ -525,13 +528,4 @@ public final class RingActionHandler extends AbstractPacketHandler { c.sendPacket(PacketCreator.enableActions()); } - - private void sendWeddingInvitationNote(String message, String from, String to) { - Note invitationNote = Note.createNormal(message, from, to, Server.getInstance().getCurrentTime()); - try { - NoteDao.save(invitationNote); - } catch (DaoException e) { - log.error("Failed to save wedding invitation note: {}", invitationNote, e); - } - } } diff --git a/src/main/java/net/server/channel/handlers/UseCashItemHandler.java b/src/main/java/net/server/channel/handlers/UseCashItemHandler.java index fc661e8cd0..18d09740bf 100644 --- a/src/main/java/net/server/channel/handlers/UseCashItemHandler.java +++ b/src/main/java/net/server/channel/handlers/UseCashItemHandler.java @@ -36,9 +36,6 @@ import constants.game.GameConstants; import constants.id.ItemId; import constants.id.MapId; import constants.inventory.ItemConstants; -import database.DaoException; -import database.NoteDao; -import model.Note; import net.AbstractPacketHandler; import net.packet.InPacket; import net.server.Server; @@ -49,10 +46,10 @@ import server.Shop; import server.ShopFactory; import server.TimerManager; import server.maps.*; +import service.NoteService; import tools.PacketCreator; import tools.Pair; -import java.sql.SQLException; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; @@ -63,6 +60,12 @@ import static java.util.concurrent.TimeUnit.SECONDS; public final class UseCashItemHandler extends AbstractPacketHandler { private static final Logger log = LoggerFactory.getLogger(UseCashItemHandler.class); + private final NoteService noteService; + + public UseCashItemHandler(NoteService noteService) { + this.noteService = noteService; + } + @Override public void handlePacket(InPacket p, Client c) { final Character player = c.getPlayer(); @@ -361,13 +364,10 @@ public final class UseCashItemHandler extends AbstractPacketHandler { } else if (itemType == 509) { String sendTo = p.readString(); String msg = p.readString(); - Note note = Note.createNormal(msg, player.getName(), sendTo, Server.getInstance().getCurrentTime()); - try { - NoteDao.save(note); - } catch (DaoException e) { - log.error("Failed to save note {}", note, e); + boolean sendSuccess = noteService.sendNormal(msg, player.getName(), sendTo); + if (sendSuccess) { + remove(c, position, itemId); } - remove(c, position, itemId); } else if (itemType == 510) { player.getMap().broadcastMessage(PacketCreator.musicChange("Jukebox/Congratulation")); remove(c, position, itemId); diff --git a/src/main/java/net/server/guild/Guild.java b/src/main/java/net/server/guild/Guild.java index daf145e00e..b9ea426923 100644 --- a/src/main/java/net/server/guild/Guild.java +++ b/src/main/java/net/server/guild/Guild.java @@ -25,7 +25,7 @@ import client.Character; import client.Client; import config.YamlConfig; import database.DaoException; -import database.NoteDao; +import database.note.NoteDao; import model.Note; import net.packet.Packet; import net.server.PlayerStorage; diff --git a/src/main/java/service/NoteService.java b/src/main/java/service/NoteService.java new file mode 100644 index 0000000000..20d2e1e4db --- /dev/null +++ b/src/main/java/service/NoteService.java @@ -0,0 +1,93 @@ +package service; + +import client.Character; +import database.DaoException; +import database.note.NoteDao; +import model.Note; +import net.packet.Packet; +import net.server.Server; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import tools.PacketCreator; + +import java.util.List; +import java.util.Optional; + +public class NoteService { + private static final Logger log = LoggerFactory.getLogger(NoteService.class); + + private final NoteDao noteDao; + + public NoteService(NoteDao noteDao) { + this.noteDao = noteDao; + } + + /** + * Send normal note from one character to another + * + * @return Send success + */ + public boolean sendNormal(String message, String senderName, String receiverName) { + Note normalNote = Note.createNormal(message, senderName, receiverName, Server.getInstance().getCurrentTime()); + return send(normalNote); + } + + /** + * Send note which will increase the receiver's fame by one. + * + * @return Send success + */ + public boolean sendWithFame(String message, String senderName, String receiverName) { + Note noteWithFame = Note.createGift(message, senderName, receiverName, Server.getInstance().getCurrentTime()); + return send(noteWithFame); + } + + private boolean send(Note note) { + try { + NoteDao.save(note); + return true; + } catch (DaoException e) { + log.error("Failed to send note {}", note, e); + return false; + } + } + + /** + * Show unread notes + * + * @param chr Note recipient + */ + public void show(Character chr) { + if (chr == null) { + throw new IllegalArgumentException("Unable to show notes - chr is null"); + } + + final List notes; + try { + notes = noteDao.findAllByTo(chr.getName()); + } catch (DaoException e) { + log.error("Failed to find notes sent to chr name {}", chr.getName(), e); + return; + } + + Packet showNotesPacket = PacketCreator.showNotes(notes); + chr.sendPacket(showNotesPacket); + } + + /** + * Discard a read note + * + * @param id Id of note to discard + * @return Discarded note. Empty optional if failed to discard. + */ + public Optional discard(int id) { + try { + return noteDao.delete(id); + } catch (DaoException e) { + log.error("Failed to discard note with id {}", id, e); + return Optional.empty(); + } + } + + +} diff --git a/src/main/java/tools/DatabaseConnection.java b/src/main/java/tools/DatabaseConnection.java index 433f90ae19..d7b51f0366 100644 --- a/src/main/java/tools/DatabaseConnection.java +++ b/src/main/java/tools/DatabaseConnection.java @@ -3,7 +3,7 @@ package tools; import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; import config.YamlConfig; -import database.NoteRowMapper; +import database.note.NoteRowMapper; import org.jdbi.v3.core.Handle; import org.jdbi.v3.core.Jdbi; import org.slf4j.Logger;