diff --git a/src/main/java/client/BuddyList.java b/src/main/java/client/BuddyList.java index fdc98f3cff..f0504f65d1 100644 --- a/src/main/java/client/BuddyList.java +++ b/src/main/java/client/BuddyList.java @@ -21,6 +21,7 @@ */ package client; +import model.CharacterIdentity; import net.packet.Packet; import net.server.PlayerStorage; import tools.DatabaseConnection; @@ -43,7 +44,7 @@ public class BuddyList { private final Map buddies = new LinkedHashMap<>(); private int capacity; - private final Deque pendingRequests = new LinkedList<>(); + private final Deque pendingRequests = new LinkedList<>(); public BuddyList(int capacity) { this.capacity = capacity; @@ -145,7 +146,7 @@ public class BuddyList { try (ResultSet rs = ps.executeQuery()) { while (rs.next()) { if (rs.getInt("pending") == 1) { - pendingRequests.push(new CharacterNameAndId(rs.getInt("buddyid"), rs.getString("buddyname"))); + pendingRequests.push(new CharacterIdentity(rs.getString("buddyname"), rs.getInt("buddyid"))); } else { put(new BuddylistEntry(rs.getString("buddyname"), rs.getString("group"), rs.getInt("buddyid"), (byte) -1, true)); } @@ -162,7 +163,7 @@ public class BuddyList { } } - public CharacterNameAndId pollPendingRequest() { + public CharacterIdentity pollPendingRequest() { return pendingRequests.pollLast(); } @@ -171,7 +172,7 @@ public class BuddyList { if (pendingRequests.isEmpty()) { c.sendPacket(PacketCreator.requestBuddylistAdd(cidFrom, c.getPlayer().getId(), nameFrom)); } else { - pendingRequests.push(new CharacterNameAndId(cidFrom, nameFrom)); + pendingRequests.push(new CharacterIdentity(nameFrom, cidFrom)); } } } diff --git a/src/main/java/client/Character.java b/src/main/java/client/Character.java index 72be3814ae..2f3ede417e 100644 --- a/src/main/java/client/Character.java +++ b/src/main/java/client/Character.java @@ -41,6 +41,7 @@ import constants.id.MapId; import constants.id.MobId; import constants.inventory.ItemConstants; import constants.skills.*; +import model.CharacterIdentity; import net.packet.Packet; import net.server.PlayerBuffValueHolder; import net.server.PlayerCoolDownValueHolder; @@ -2115,9 +2116,9 @@ public class Character extends AbstractCharacterObject { } private void nextPendingRequest(Client c) { - CharacterNameAndId pendingBuddyRequest = c.getPlayer().getBuddylist().pollPendingRequest(); + CharacterIdentity pendingBuddyRequest = c.getPlayer().getBuddylist().pollPendingRequest(); if (pendingBuddyRequest != null) { - c.sendPacket(PacketCreator.requestBuddylistAdd(pendingBuddyRequest.getId(), c.getPlayer().getId(), pendingBuddyRequest.getName())); + c.sendPacket(PacketCreator.requestBuddylistAdd(pendingBuddyRequest.id(), c.getPlayer().getId(), pendingBuddyRequest.name())); } } diff --git a/src/main/java/client/CharacterNameAndId.java b/src/main/java/client/CharacterNameAndId.java deleted file mode 100644 index 1f7db9d4ac..0000000000 --- a/src/main/java/client/CharacterNameAndId.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - This file is part of the OdinMS Maple Story Server - Copyright (C) 2008 Patrick Huy - Matthias Butz - Jan Christian Meyer - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as - published by the Free Software Foundation version 3 as published by - the Free Software Foundation. You may not use, modify or distribute - this program under any other version of the GNU Affero General Public - License. - - 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 Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . -*/ -package client; - -public class CharacterNameAndId { - private final int id; - private final String name; - - public CharacterNameAndId(int id, String name) { - super(); - this.id = id; - this.name = name; - } - - public int getId() { - return id; - } - - public String getName() { - return name; - } -} diff --git a/src/main/java/client/Client.java b/src/main/java/client/Client.java index 9e1406d73f..c722d4f55e 100644 --- a/src/main/java/client/Client.java +++ b/src/main/java/client/Client.java @@ -27,6 +27,7 @@ import constants.id.MapId; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.handler.timeout.IdleStateEvent; +import model.CharacterIdentity; import net.PacketHandler; import net.PacketProcessor; import net.netty.DisconnectException; @@ -308,8 +309,8 @@ public class Client extends ChannelInboundHandlerAdapter { public List loadCharacters(int serverId) { List chars = new ArrayList<>(15); try { - for (CharNameAndId cni : loadCharactersInternal(serverId)) { - chars.add(Character.loadCharFromDB(cni.id, this, false)); + for (CharacterIdentity cni : loadCharactersInternal(serverId)) { + chars.add(Character.loadCharFromDB(cni.id(), this, false)); } } catch (Exception e) { e.printStackTrace(); @@ -317,8 +318,8 @@ public class Client extends ChannelInboundHandlerAdapter { return chars; } - private List loadCharactersInternal(int worldId) { - List chars = new ArrayList<>(15); + private List loadCharactersInternal(int worldId) { + List chars = new ArrayList<>(15); try (Connection con = DatabaseConnection.getConnection(); PreparedStatement ps = con.prepareStatement("SELECT id, name FROM characters WHERE accountid = ? AND world = ?")) { ps.setInt(1, this.getAccID()); @@ -326,7 +327,7 @@ public class Client extends ChannelInboundHandlerAdapter { try (ResultSet rs = ps.executeQuery()) { while (rs.next()) { - chars.add(new CharNameAndId(rs.getString("name"), rs.getInt("id"))); + chars.add(new CharacterIdentity(rs.getString("name"), rs.getInt("id"))); } } } catch (SQLException e) { @@ -1160,18 +1161,6 @@ public class Client extends ChannelInboundHandlerAdapter { actionsSemaphore.release(); } - private static class CharNameAndId { - - public String name; - public int id; - - public CharNameAndId(String name, int id) { - super(); - this.name = name; - this.id = id; - } - } - private static boolean checkHash(String hash, String type, String password) { try { MessageDigest digester = MessageDigest.getInstance(type); diff --git a/src/main/java/model/CharacterIdentity.java b/src/main/java/model/CharacterIdentity.java new file mode 100644 index 0000000000..21f5f370d6 --- /dev/null +++ b/src/main/java/model/CharacterIdentity.java @@ -0,0 +1,9 @@ +package model; + +public record CharacterIdentity(String name, int id) { + public CharacterIdentity { + if (name == null) { + throw new IllegalArgumentException("Character name must not be null"); + } + } +} diff --git a/src/main/java/net/server/channel/handlers/BuddylistModifyHandler.java b/src/main/java/net/server/channel/handlers/BuddylistModifyHandler.java index 88b4453a99..fbeb6ca898 100644 --- a/src/main/java/net/server/channel/handlers/BuddylistModifyHandler.java +++ b/src/main/java/net/server/channel/handlers/BuddylistModifyHandler.java @@ -21,10 +21,13 @@ */ package net.server.channel.handlers; -import client.*; +import client.BuddyList; import client.BuddyList.BuddyAddResult; -import client.Character; import client.BuddyList.BuddyOperation; +import client.BuddylistEntry; +import client.Character; +import client.Client; +import model.CharacterIdentity; import net.AbstractPacketHandler; import net.packet.InPacket; import net.server.world.World; @@ -39,28 +42,24 @@ import java.sql.SQLException; import static client.BuddyList.BuddyOperation.ADDED; public class BuddylistModifyHandler extends AbstractPacketHandler { - private static class CharacterIdNameBuddyCapacity extends CharacterNameAndId { - private final int buddyCapacity; - public CharacterIdNameBuddyCapacity(int id, String name, int buddyCapacity) { - super(id, name); - this.buddyCapacity = buddyCapacity; - } - - public int getBuddyCapacity() { - return buddyCapacity; + private record BuddyIdentity(String name, int id, int buddyCapacity) { + public BuddyIdentity { + if (name == null) { + throw new IllegalArgumentException("name must not be null"); + } } } private void nextPendingRequest(Client c) { - CharacterNameAndId pendingBuddyRequest = c.getPlayer().getBuddylist().pollPendingRequest(); + CharacterIdentity pendingBuddyRequest = c.getPlayer().getBuddylist().pollPendingRequest(); if (pendingBuddyRequest != null) { - c.sendPacket(PacketCreator.requestBuddylistAdd(pendingBuddyRequest.getId(), c.getPlayer().getId(), pendingBuddyRequest.getName())); + c.sendPacket(PacketCreator.requestBuddylistAdd(pendingBuddyRequest.id(), c.getPlayer().getId(), pendingBuddyRequest.name())); } } - private CharacterIdNameBuddyCapacity getCharacterIdAndNameFromDatabase(String name) throws SQLException { - CharacterIdNameBuddyCapacity ret = null; + private BuddyIdentity getBuddyIdentityFromDatabase(String name) throws SQLException { + BuddyIdentity buddyIdentity = null; try (Connection con = DatabaseConnection.getConnection(); PreparedStatement ps = con.prepareStatement("SELECT id, name, buddyCapacity FROM characters WHERE name LIKE ?")) { @@ -68,12 +67,15 @@ public class BuddylistModifyHandler extends AbstractPacketHandler { try (ResultSet rs = ps.executeQuery()) { if (rs.next()) { - ret = new CharacterIdNameBuddyCapacity(rs.getInt("id"), rs.getString("name"), rs.getInt("buddyCapacity")); + String actualName = rs.getString("name"); + int id = rs.getInt("id"); + int buddyCapacity = rs.getInt("buddyCapacity"); + buddyIdentity = new BuddyIdentity(actualName, id, buddyCapacity); } } } - return ret; + return buddyIdentity; } @Override @@ -95,68 +97,68 @@ public class BuddylistModifyHandler extends AbstractPacketHandler { } else if (ble == null) { try { World world = c.getWorldServer(); - CharacterIdNameBuddyCapacity charWithId; + final BuddyIdentity buddyIdentity; int channel; Character otherChar = c.getChannelServer().getPlayerStorage().getCharacterByName(addName); if (otherChar != null) { channel = c.getChannel(); - charWithId = new CharacterIdNameBuddyCapacity(otherChar.getId(), otherChar.getName(), otherChar.getBuddylist().getCapacity()); + buddyIdentity = new BuddyIdentity(otherChar.getName(), otherChar.getId(), otherChar.getBuddylist().getCapacity()); } else { channel = world.find(addName); - charWithId = getCharacterIdAndNameFromDatabase(addName); + buddyIdentity = getBuddyIdentityFromDatabase(addName); } - if (charWithId != null) { - BuddyAddResult buddyAddResult = null; - if (channel != -1) { - buddyAddResult = world.requestBuddyAdd(addName, c.getChannel(), player.getId(), player.getName()); - } else { - try (Connection con = DatabaseConnection.getConnection()) { - try (PreparedStatement ps = con.prepareStatement("SELECT COUNT(*) as buddyCount FROM buddies WHERE characterid = ? AND pending = 0")) { - ps.setInt(1, charWithId.getId()); - - try (ResultSet rs = ps.executeQuery()) { - if (!rs.next()) { - throw new RuntimeException("Result set expected"); - } else if (rs.getInt("buddyCount") >= charWithId.getBuddyCapacity()) { - buddyAddResult = BuddyAddResult.BUDDYLIST_FULL; - } - } - } - - try (PreparedStatement ps = con.prepareStatement("SELECT pending FROM buddies WHERE characterid = ? AND buddyid = ?")) { - ps.setInt(1, charWithId.getId()); - ps.setInt(2, player.getId()); - - try (ResultSet rs = ps.executeQuery()) { - if (rs.next()) { - buddyAddResult = BuddyAddResult.ALREADY_ON_LIST; - } - } - } - } - } - if (buddyAddResult == BuddyAddResult.BUDDYLIST_FULL) { - c.sendPacket(PacketCreator.serverNotice(1, "\"" + addName + "\"'s Buddylist is full")); - } else { - int displayChannel; - displayChannel = -1; - int otherCid = charWithId.getId(); - if (buddyAddResult == BuddyAddResult.ALREADY_ON_LIST && channel != -1) { - displayChannel = channel; - notifyRemoteChannel(c, channel, otherCid, ADDED); - } else if (buddyAddResult != BuddyAddResult.ALREADY_ON_LIST && channel == -1) { - try (Connection con = DatabaseConnection.getConnection(); - PreparedStatement ps = con.prepareStatement("INSERT INTO buddies (characterid, `buddyid`, `pending`) VALUES (?, ?, 1)")) { - ps.setInt(1, charWithId.getId()); - ps.setInt(2, player.getId()); - ps.executeUpdate(); - } - } - buddylist.put(new BuddylistEntry(charWithId.getName(), group, otherCid, displayChannel, true)); - c.sendPacket(PacketCreator.updateBuddylist(buddylist.getBuddies())); - } - } else { + if (buddyIdentity == null) { c.sendPacket(PacketCreator.serverNotice(1, "A character called \"" + addName + "\" does not exist")); + return; + } + BuddyAddResult buddyAddResult = null; + if (channel != -1) { + buddyAddResult = world.requestBuddyAdd(addName, c.getChannel(), player.getId(), player.getName()); + } else { + try (Connection con = DatabaseConnection.getConnection()) { + try (PreparedStatement ps = con.prepareStatement("SELECT COUNT(*) as buddyCount FROM buddies WHERE characterid = ? AND pending = 0")) { + ps.setInt(1, buddyIdentity.id()); + + try (ResultSet rs = ps.executeQuery()) { + if (!rs.next()) { + throw new RuntimeException("Result set expected"); + } else if (rs.getInt("buddyCount") >= buddyIdentity.buddyCapacity()) { + buddyAddResult = BuddyAddResult.BUDDYLIST_FULL; + } + } + } + + try (PreparedStatement ps = con.prepareStatement("SELECT pending FROM buddies WHERE characterid = ? AND buddyid = ?")) { + ps.setInt(1, buddyIdentity.id()); + ps.setInt(2, player.getId()); + + try (ResultSet rs = ps.executeQuery()) { + if (rs.next()) { + buddyAddResult = BuddyAddResult.ALREADY_ON_LIST; + } + } + } + } + } + if (buddyAddResult == BuddyAddResult.BUDDYLIST_FULL) { + c.sendPacket(PacketCreator.serverNotice(1, "\"" + addName + "\"'s Buddylist is full")); + } else { + int displayChannel; + displayChannel = -1; + int otherCid = buddyIdentity.id(); + if (buddyAddResult == BuddyAddResult.ALREADY_ON_LIST && channel != -1) { + displayChannel = channel; + notifyRemoteChannel(c, channel, otherCid, ADDED); + } else if (buddyAddResult != BuddyAddResult.ALREADY_ON_LIST && channel == -1) { + try (Connection con = DatabaseConnection.getConnection(); + PreparedStatement ps = con.prepareStatement("INSERT INTO buddies (characterid, `buddyid`, `pending`) VALUES (?, ?, 1)")) { + ps.setInt(1, buddyIdentity.id()); + ps.setInt(2, player.getId()); + ps.executeUpdate(); + } + } + buddylist.put(new BuddylistEntry(buddyIdentity.name(), group, otherCid, displayChannel, true)); + c.sendPacket(PacketCreator.updateBuddylist(buddylist.getBuddies())); } } catch (SQLException e) { e.printStackTrace(); diff --git a/src/main/java/net/server/channel/handlers/PlayerLoggedinHandler.java b/src/main/java/net/server/channel/handlers/PlayerLoggedinHandler.java index cb6616ba65..8061dd6ba3 100644 --- a/src/main/java/net/server/channel/handlers/PlayerLoggedinHandler.java +++ b/src/main/java/net/server/channel/handlers/PlayerLoggedinHandler.java @@ -28,6 +28,7 @@ import client.keybind.KeyBinding; import config.YamlConfig; import constants.game.GameConstants; import database.character.CharacterLoader; +import model.CharacterIdentity; import net.AbstractPacketHandler; import net.netty.GameViolationException; import net.packet.InPacket; @@ -332,9 +333,9 @@ public final class PlayerLoggedinHandler extends AbstractPacketHandler { c.sendPacket(PacketCreator.updateBuddylist(player.getBuddylist().getBuddies())); - CharacterNameAndId pendingBuddyRequest = c.getPlayer().getBuddylist().pollPendingRequest(); + CharacterIdentity pendingBuddyRequest = c.getPlayer().getBuddylist().pollPendingRequest(); if (pendingBuddyRequest != null) { - c.sendPacket(PacketCreator.requestBuddylistAdd(pendingBuddyRequest.getId(), c.getPlayer().getId(), pendingBuddyRequest.getName())); + c.sendPacket(PacketCreator.requestBuddylistAdd(pendingBuddyRequest.id(), c.getPlayer().getId(), pendingBuddyRequest.name())); } c.sendPacket(PacketCreator.updateGender(player));