From 53b7aca0cead64a3d242652e487edfa6675edf84 Mon Sep 17 00:00:00 2001
From: MagicBot <MagicBot@magicbane.com>
Date: Sun, 24 Mar 2024 10:34:41 -0400
Subject: [PATCH] Handlers created for vendor buy/sell windows

---
 src/engine/net/client/ClientMessagePump.java  | 73 -----------------
 src/engine/net/client/Protocol.java           |  4 +-
 .../handlers/VendorBuyWindowMsgHandler.java   | 58 ++++++++++++++
 .../handlers/VendorSellWindowMsgHandler.java  | 80 +++++++++++++++++++
 ...WindowMsg.java => VendorBuyWindowMsg.java} | 12 +--
 ...indowMsg.java => VendorSellWindowMsg.java} | 14 ++--
 6 files changed, 153 insertions(+), 88 deletions(-)
 create mode 100644 src/engine/net/client/handlers/VendorBuyWindowMsgHandler.java
 create mode 100644 src/engine/net/client/handlers/VendorSellWindowMsgHandler.java
 rename src/engine/net/client/msg/{BuyFromNPCWindowMsg.java => VendorBuyWindowMsg.java} (94%)
 rename src/engine/net/client/msg/{SellToNPCWindowMsg.java => VendorSellWindowMsg.java} (93%)

diff --git a/src/engine/net/client/ClientMessagePump.java b/src/engine/net/client/ClientMessagePump.java
index f1a16f77..b3d15c6a 100644
--- a/src/engine/net/client/ClientMessagePump.java
+++ b/src/engine/net/client/ClientMessagePump.java
@@ -774,73 +774,6 @@ public class ClientMessagePump implements NetMsgHandler {
         DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
     }
 
-    private static void openSellToNPCWindow(SellToNPCWindowMsg msg, ClientConnection origin) {
-
-        PlayerCharacter sourcePlayer = SessionManager.getPlayerCharacter(origin);
-        Dispatch dispatch;
-
-        if (sourcePlayer == null)
-            return;
-
-        NPC npc = NPC.getFromCache(msg.getNPCID());
-
-        if (npc == null)
-            return;
-
-        // test within talking range
-
-        if (sourcePlayer.getLoc().distanceSquared2D(npc.getLoc()) > MBServerStatics.NPC_TALK_RANGE * MBServerStatics.NPC_TALK_RANGE) {
-            ErrorPopupMsg.sendErrorPopup(sourcePlayer, 14);
-            return;
-        }
-
-        Contract con = npc.getContract();
-
-        if (con == null)
-            return;
-        float bargain = sourcePlayer.getBargain();
-
-        float profit = npc.getBuyPercent(sourcePlayer) + bargain;
-
-        if (profit > 1)
-            profit = 1;
-
-        msg.setupOutput();
-
-        msg.setUnknown05(profit);
-        msg.setUnknown06(500000); //TODO set goldItem on npc later
-        msg.setItemType(con.getBuyItemType());
-        msg.setSkillTokens(con.getBuySkillToken());
-        msg.setUnknownArray(con.getBuyUnknownToken());
-
-        dispatch = Dispatch.borrow(sourcePlayer, msg);
-        DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
-    }
-
-    private static void openBuyFromNPCWindow(BuyFromNPCWindowMsg msg, ClientConnection origin) {
-
-        PlayerCharacter sourcePlayer = SessionManager.getPlayerCharacter(origin);
-        Dispatch dispatch;
-
-        if (sourcePlayer == null)
-            return;
-
-        NPC npc = NPC.getFromCache(msg.getNpcID());
-
-        if (npc == null)
-            return;
-
-        // test within talking range
-
-        if (sourcePlayer.getLoc().distanceSquared2D(npc.getLoc()) > MBServerStatics.NPC_TALK_RANGE * MBServerStatics.NPC_TALK_RANGE) {
-            ErrorPopupMsg.sendErrorPopup(sourcePlayer, 14);
-            return;
-        }
-
-        dispatch = Dispatch.borrow(sourcePlayer, msg);
-        DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
-    }
-
     protected static void petAttack(PetAttackMsg msg, ClientConnection conn) throws MsgSendException {
 
         PlayerCharacter pc = SessionManager.getPlayerCharacter(conn);
@@ -1141,12 +1074,6 @@ public class ClientMessagePump implements NetMsgHandler {
                 case VENDORDIALOG:
                     VendorDialogMsg.replyDialog((VendorDialogMsg) msg, origin);
                     break;
-                case SHOPLIST:
-                    openBuyFromNPCWindow((BuyFromNPCWindowMsg) msg, origin);
-                    break;
-                case SHOPINFO:
-                    openSellToNPCWindow((SellToNPCWindowMsg) msg, origin);
-                    break;
                 case TRAINERLIST:
                     WorldServer.trainerInfo((TrainerInfoMsg) msg, origin);
                     break;
diff --git a/src/engine/net/client/Protocol.java b/src/engine/net/client/Protocol.java
index 35307b5c..9eb1efc5 100644
--- a/src/engine/net/client/Protocol.java
+++ b/src/engine/net/client/Protocol.java
@@ -196,8 +196,6 @@ public enum Protocol {
     SETOBJVAL(0x08A50FD1, null, null),
     SETRUNE(0x888E7C64, ApplyRuneMsg.class, null),  //Apply Promotion, Stat Rune (maybe disc also)
     SETSELECTEDOBECT(0x64E10938, TargetObjectMsg.class, null), // Target an object
-    SHOPINFO(0x267DAB90, SellToNPCWindowMsg.class, null), //open Sell to NPC Window
-    SHOPLIST(0x682DAB4D, BuyFromNPCWindowMsg.class, null), // Open Buy From NPC Window
     SHOWCOMBATINFO(0x9BF1E5EA, ShowMsg.class, null), // Request/Response /show
     SHOWVAULTINVENTORY(0xD1FB4842, null, null), // Show Vault Inventory
     SOCIALCHANNEL(0x2BF58FA6, SocialMsg.class, null), // Socials
@@ -240,6 +238,8 @@ public enum Protocol {
     UPDATETRADEWINDOW(0x406EBDE6, UpdateTradeWindowMsg.class, null), // Trade Complete
     UPGRADEASSET(0x2B85A865, UpgradeAssetMessage.class, UpgradeAssetMsgHandler.class),
     VENDORDIALOG(0x98ACD594, VendorDialogMsg.class, null), // Send/Recv Vendor Dialog
+    VENDORSELLWINDOW(0x267DAB90, VendorSellWindowMsg.class, VendorSellWindowMsgHandler.class), //open Sell to NPC Window
+    VENDORBUYWINDOW(0x682DAB4D, VendorBuyWindowMsg.class, VendorBuyWindowMsgHandler.class), // Open Buy From NPC Window
     VERSIONINFO(0x4B7EE463, VersionInfoMsg.class, null), // Version Information
     VIEWRESOURCES(0xCEFD0346, ViewResourcesMessage.class, null),
     VISUALUPDATE(0x33402fd2, null, null),
diff --git a/src/engine/net/client/handlers/VendorBuyWindowMsgHandler.java b/src/engine/net/client/handlers/VendorBuyWindowMsgHandler.java
new file mode 100644
index 00000000..02f98625
--- /dev/null
+++ b/src/engine/net/client/handlers/VendorBuyWindowMsgHandler.java
@@ -0,0 +1,58 @@
+// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
+// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
+// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
+// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
+// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
+//      Magicbane Emulator Project © 2013 - 2022
+//                www.magicbane.com
+
+package engine.net.client.handlers;
+
+import engine.Enum.DispatchChannel;
+import engine.exception.MsgSendException;
+import engine.gameManager.SessionManager;
+import engine.net.Dispatch;
+import engine.net.DispatchMessage;
+import engine.net.client.ClientConnection;
+import engine.net.client.msg.ClientNetMsg;
+import engine.net.client.msg.ErrorPopupMsg;
+import engine.net.client.msg.VendorBuyWindowMsg;
+import engine.objects.NPC;
+import engine.objects.PlayerCharacter;
+import engine.server.MBServerStatics;
+
+public class VendorBuyWindowMsgHandler extends AbstractClientMsgHandler {
+
+    public VendorBuyWindowMsgHandler() {
+        super(VendorBuyWindowMsg.class);
+    }
+
+    @Override
+    protected boolean _handleNetMsg(ClientNetMsg baseMsg, ClientConnection origin) throws MsgSendException {
+
+        PlayerCharacter sourcePlayer = SessionManager.getPlayerCharacter(origin);
+        Dispatch dispatch;
+
+        VendorBuyWindowMsg msg = (VendorBuyWindowMsg) baseMsg;
+
+        if (sourcePlayer == null)
+            return true;
+
+        NPC npc = NPC.getFromCache(msg.getNpcID());
+
+        if (npc == null)
+            return true;
+
+        // test within talking range
+
+        if (sourcePlayer.getLoc().distanceSquared2D(npc.getLoc()) > MBServerStatics.NPC_TALK_RANGE * MBServerStatics.NPC_TALK_RANGE) {
+            ErrorPopupMsg.sendErrorPopup(sourcePlayer, 14);
+            return true;
+        }
+
+        dispatch = Dispatch.borrow(sourcePlayer, msg);
+        DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
+        return true;
+    }
+
+}
\ No newline at end of file
diff --git a/src/engine/net/client/handlers/VendorSellWindowMsgHandler.java b/src/engine/net/client/handlers/VendorSellWindowMsgHandler.java
new file mode 100644
index 00000000..87cf382e
--- /dev/null
+++ b/src/engine/net/client/handlers/VendorSellWindowMsgHandler.java
@@ -0,0 +1,80 @@
+// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
+// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
+// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
+// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
+// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
+//      Magicbane Emulator Project © 2013 - 2022
+//                www.magicbane.com
+
+package engine.net.client.handlers;
+
+import engine.Enum.DispatchChannel;
+import engine.exception.MsgSendException;
+import engine.gameManager.SessionManager;
+import engine.net.Dispatch;
+import engine.net.DispatchMessage;
+import engine.net.client.ClientConnection;
+import engine.net.client.msg.ClientNetMsg;
+import engine.net.client.msg.ErrorPopupMsg;
+import engine.net.client.msg.VendorSellWindowMsg;
+import engine.objects.Contract;
+import engine.objects.NPC;
+import engine.objects.PlayerCharacter;
+import engine.server.MBServerStatics;
+
+public class VendorSellWindowMsgHandler extends AbstractClientMsgHandler {
+
+    public VendorSellWindowMsgHandler() {
+        super(VendorSellWindowMsg.class);
+    }
+
+    @Override
+    protected boolean _handleNetMsg(ClientNetMsg baseMsg, ClientConnection origin) throws MsgSendException {
+
+        PlayerCharacter playerCharacter = SessionManager.getPlayerCharacter(origin);
+        Dispatch dispatch;
+
+        VendorSellWindowMsg msg = (VendorSellWindowMsg) baseMsg;
+
+        if (playerCharacter == null)
+            return true;
+
+        NPC npc = NPC.getFromCache(msg.getNPCID());
+
+        if (npc == null)
+            return true;
+
+        // test within talking range
+
+        if (playerCharacter.getLoc().distanceSquared2D(npc.getLoc()) > MBServerStatics.NPC_TALK_RANGE * MBServerStatics.NPC_TALK_RANGE) {
+            ErrorPopupMsg.sendErrorPopup(playerCharacter, 14);
+            return true;
+        }
+
+        Contract contract = npc.getContract();
+
+        if (contract == null)
+            return true;
+
+        float bargain = playerCharacter.getBargain();
+
+        float profit = npc.getBuyPercent(playerCharacter) + bargain;
+
+        if (profit > 1)
+            profit = 1;
+
+        msg.setupOutput();
+
+        msg.setUnknown05(profit);
+        msg.setUnknown06(500000); //TODO set goldItem on npc later
+        msg.setItemType(contract.getBuyItemType());
+        msg.setSkillTokens(contract.getBuySkillToken());
+        msg.setUnknownArray(contract.getBuyUnknownToken());
+
+        dispatch = Dispatch.borrow(playerCharacter, msg);
+        DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
+
+        return true;
+    }
+
+}
\ No newline at end of file
diff --git a/src/engine/net/client/msg/BuyFromNPCWindowMsg.java b/src/engine/net/client/msg/VendorBuyWindowMsg.java
similarity index 94%
rename from src/engine/net/client/msg/BuyFromNPCWindowMsg.java
rename to src/engine/net/client/msg/VendorBuyWindowMsg.java
index 79e8ce38..133588b7 100644
--- a/src/engine/net/client/msg/BuyFromNPCWindowMsg.java
+++ b/src/engine/net/client/msg/VendorBuyWindowMsg.java
@@ -21,7 +21,7 @@ import engine.objects.*;
 
 import java.util.ArrayList;
 
-public class BuyFromNPCWindowMsg extends ClientNetMsg {
+public class VendorBuyWindowMsg extends ClientNetMsg {
 
     private int unknown01;
     private int npcType;
@@ -33,9 +33,9 @@ public class BuyFromNPCWindowMsg extends ClientNetMsg {
     /**
      * This is the general purpose constructor
      */
-    public BuyFromNPCWindowMsg(int unknown01, int npcType, int npcID,
-                               float unknown02, byte unknown03, int unknown04) {
-        super(Protocol.SHOPLIST);
+    public VendorBuyWindowMsg(int unknown01, int npcType, int npcID,
+                              float unknown02, byte unknown03, int unknown04) {
+        super(Protocol.VENDORBUYWINDOW);
         this.unknown01 = unknown01;
         this.npcType = npcType;
         this.npcID = npcID;
@@ -50,8 +50,8 @@ public class BuyFromNPCWindowMsg extends ClientNetMsg {
      * past the limit) then this constructor Throws that Exception to the
      * caller.
      */
-    public BuyFromNPCWindowMsg(AbstractConnection origin, ByteBufferReader reader) {
-        super(Protocol.SHOPLIST, origin, reader);
+    public VendorBuyWindowMsg(AbstractConnection origin, ByteBufferReader reader) {
+        super(Protocol.VENDORBUYWINDOW, origin, reader);
     }
 
     /**
diff --git a/src/engine/net/client/msg/SellToNPCWindowMsg.java b/src/engine/net/client/msg/VendorSellWindowMsg.java
similarity index 93%
rename from src/engine/net/client/msg/SellToNPCWindowMsg.java
rename to src/engine/net/client/msg/VendorSellWindowMsg.java
index 17e37139..5a81f731 100644
--- a/src/engine/net/client/msg/SellToNPCWindowMsg.java
+++ b/src/engine/net/client/msg/VendorSellWindowMsg.java
@@ -24,7 +24,7 @@ import java.util.ArrayList;
  *
  * @author Eighty
  */
-public class SellToNPCWindowMsg extends ClientNetMsg {
+public class VendorSellWindowMsg extends ClientNetMsg {
 
 //Item Types:
 //1: weapon
@@ -53,10 +53,10 @@ public class SellToNPCWindowMsg extends ClientNetMsg {
     /**
      * This is the general purpose constructor
      */
-    public SellToNPCWindowMsg(int npcType, int npcID, byte unknownByte02,
-                              ArrayList<Integer> itemTypes, ArrayList<Integer> skillTokens,
-                              ArrayList<Integer> unknownArray02, float unknown05, int unknown06) {
-        super(Protocol.SHOPINFO);
+    public VendorSellWindowMsg(int npcType, int npcID, byte unknownByte02,
+                               ArrayList<Integer> itemTypes, ArrayList<Integer> skillTokens,
+                               ArrayList<Integer> unknownArray02, float unknown05, int unknown06) {
+        super(Protocol.VENDORSELLWINDOW);
         this.npcType = npcType;
         this.npcID = npcID;
         this.unknownByte01 = (byte) 0;
@@ -75,8 +75,8 @@ public class SellToNPCWindowMsg extends ClientNetMsg {
     /**
      * This constructor is used by NetMsgFactory. It attempts to deserialize the ByteBuffer into a message. If a BufferUnderflow occurs (based on reading past the limit) then this constructor Throws that Exception to the caller.
      */
-    public SellToNPCWindowMsg(AbstractConnection origin, ByteBufferReader reader) {
-        super(Protocol.SHOPINFO, origin, reader);
+    public VendorSellWindowMsg(AbstractConnection origin, ByteBufferReader reader) {
+        super(Protocol.VENDORSELLWINDOW, origin, reader);
     }
 
     /**