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.
This commit is contained in:
P0nk
2022-12-27 10:34:55 +01:00
parent 5f1f5b7dcd
commit 389b3ad2a4
15 changed files with 199 additions and 110 deletions

View File

@@ -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<Future<?>> 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();

View File

@@ -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);
}
}
}

View File

@@ -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> note;
try {
note = NoteDao.delete(id);
} catch (DaoException e) {
log.error("Failed to delete note {}", id, e);
Optional<Note> 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;
}
}

View File

@@ -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<Integer> 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();

View File

@@ -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);
}
}
}

View File

@@ -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);

View File

@@ -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;