diff --git a/Server/src/main/java/core/game/node/entity/player/link/request/trade/TradeModule.java b/Server/src/main/java/core/game/node/entity/player/link/request/trade/TradeModule.java index 741047d3f..250f5fccd 100644 --- a/Server/src/main/java/core/game/node/entity/player/link/request/trade/TradeModule.java +++ b/Server/src/main/java/core/game/node/entity/player/link/request/trade/TradeModule.java @@ -8,9 +8,11 @@ import core.game.node.entity.player.link.request.RequestModule; import core.game.node.item.GroundItemManager; import core.game.node.item.Item; import core.game.system.monitor.PlayerMonitor; +import rs09.game.system.SystemLogger; import java.text.DecimalFormat; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; /** @@ -395,6 +397,8 @@ public final class TradeModule implements RequestModule { private void giveContainers(final TradeModule module) { final Container pContainer = module.getContainer(); final Container oContainer = TradeModule.getExtension(module.getTarget()).getContainer(); + SystemLogger.logTrade(module.getPlayer().getUsername() + " -> " + module.getTarget().getUsername() + " " + Arrays.toString(pContainer.toArray())); + SystemLogger.logTrade(module.getTarget().getUsername() + " -> " + module.getPlayer().getUsername() + " " + Arrays.toString(oContainer.toArray())); addContainer(module.getPlayer(), module.getTarget(), oContainer); addContainer(module.getTarget(), module.getPlayer(), pContainer); module.getTarget().getPacketDispatch().sendMessage("Accepted trade."); diff --git a/Server/src/main/java/core/game/node/entity/skill/firemaking/FireMakingOptionPlugin.kt b/Server/src/main/java/core/game/node/entity/skill/firemaking/FireMakingOptionPlugin.kt index d2b56d38c..0c7f80c47 100644 --- a/Server/src/main/java/core/game/node/entity/skill/firemaking/FireMakingOptionPlugin.kt +++ b/Server/src/main/java/core/game/node/entity/skill/firemaking/FireMakingOptionPlugin.kt @@ -1,5 +1,6 @@ package core.game.node.entity.skill.firemaking +import core.game.node.item.GroundItem import org.rs09.consts.Items import rs09.game.interaction.InteractionListener import rs09.game.interaction.IntType @@ -13,5 +14,9 @@ class FiremakingListener : InteractionListener player.pulseManager.run(FireMakingPulse(player, with.asItem(), null)) return@onUseWith true } + onUseWith(IntType.GROUNDITEM, Items.TINDERBOX_590, *logs) { player, _, with -> + player.pulseManager.run(FireMakingPulse(player, with.asItem(), with as GroundItem)) + return@onUseWith true + } } } \ No newline at end of file diff --git a/Server/src/main/java/core/net/event/GameReadEvent.java b/Server/src/main/java/core/net/event/GameReadEvent.java index 753647d9a..a559402fc 100644 --- a/Server/src/main/java/core/net/event/GameReadEvent.java +++ b/Server/src/main/java/core/net/event/GameReadEvent.java @@ -7,6 +7,9 @@ import core.net.IoSession; import core.net.packet.IncomingPacket; import core.net.packet.IoBuffer; import core.net.packet.PacketRepository; +import rs09.net.packet.PacketProcessor; +import rs09.net.packet.in.Decoders530; +import rs09.net.packet.in.Packet; import java.nio.ByteBuffer; @@ -94,21 +97,17 @@ public final class GameReadEvent extends IoReadEvent { buffer.get(data); IoBuffer buf = new IoBuffer(opcode, null, ByteBuffer.wrap(data)); //SystemLogger.log("Packet opcode " + opcode + "received."); - IncomingPacket packet = PacketRepository.getIncoming(opcode); + //IncomingPacket packet = PacketRepository.getIncoming(opcode); session.setLastPing(System.currentTimeMillis()); - if (packet == null) { - SystemLogger.logErr(this.getClass(), "Unhandled packet [opcode=" + opcode + ", previous=" + last + ", size=" + size + ", header=" + header + "]"); - if (GameWorld.getSettings().isDevMode()) { - SystemLogger.logErr(this.getClass(), "Unhandled packet [opcode=" + opcode + ", previous=" + last + ", size=" + size + ", header=" + header + "]"); - } - continue; - } last = opcode; - try { - packet.decode(session.getPlayer(), opcode, buf); - //System.out.println("Handled packed " + opcode + "!"); - } catch (Throwable t) { - t.printStackTrace(); + + Packet processed = Decoders530.process(session.getPlayer(), opcode, buf); + if (processed instanceof Packet.UnhandledOp) { + SystemLogger.logWarn(this.getClass(), "Unhandled opcode: " + opcode); + } else if (processed instanceof Packet.DecodingError) { + SystemLogger.logErr(this.getClass(), ((Packet.DecodingError) processed).getMessage()); + } else if (!(processed instanceof Packet.NoProcess)) { + PacketProcessor.enqueue(processed); } } } diff --git a/Server/src/main/java/core/net/packet/PacketRepository.java b/Server/src/main/java/core/net/packet/PacketRepository.java index 09f89287e..d1f885684 100644 --- a/Server/src/main/java/core/net/packet/PacketRepository.java +++ b/Server/src/main/java/core/net/packet/PacketRepository.java @@ -1,13 +1,9 @@ package core.net.packet; -import core.net.packet.in.*; import core.net.packet.out.GrandExchangePacket; import core.net.packet.out.*; import rs09.game.system.SystemLogger; import rs09.net.packet.PacketWriteQueue; -import rs09.net.packet.in.ItemOnGroundItemPacket; -import rs09.net.packet.in.QuickChatPacketHandler; -import rs09.net.packet.in.RunScriptPacketHandler; import java.util.HashMap; import java.util.Map; @@ -23,11 +19,6 @@ public final class PacketRepository { */ public final static Map, OutgoingPacket> OUTGOING_PACKETS = new HashMap<>(); - /** - * The incoming packets mapping. - */ - private final static Map INCOMING_PACKETS = new HashMap<>(); - /** * Populate the mappings. */ @@ -80,105 +71,6 @@ public final class PacketRepository { OUTGOING_PACKETS.put(CSConfigPacket.class, new CSConfigPacket()); // OUTGOING_PACKETS.put(Varbit.class, new Varbit()); OUTGOING_PACKETS.put(VarcUpdate.class, new VarcUpdate()); - INCOMING_PACKETS.put(22, new ClientFocusPacket()); - INCOMING_PACKETS.put(93, new PingPacketHandler()); - INCOMING_PACKETS.put(44, new CommandPacket()); - INCOMING_PACKETS.put(237, new ChatPacket()); - INCOMING_PACKETS.put(21, new CameraMovementPacket()); - INCOMING_PACKETS.put(75, new MouseClickPacket()); - INCOMING_PACKETS.put(243, new DisplayUpdatePacket()); - INCOMING_PACKETS.put(177, new UpdateInterfaceCounter()); - INCOMING_PACKETS.put(4, new DummyPacket()); - INCOMING_PACKETS.put(245, new IdlePacketHandler()); - INCOMING_PACKETS.put(111, new core.net.packet.in.GrandExchangePacket()); - IncomingPacket packet = new WalkPacket(); - INCOMING_PACKETS.put(39, packet); - INCOMING_PACKETS.put(77, packet); - INCOMING_PACKETS.put(215, packet); - packet = new ItemActionPacket(); - INCOMING_PACKETS.put(134, packet);//item on object - INCOMING_PACKETS.put(115, packet);//on npc - INCOMING_PACKETS.put(27, packet);//item on item - INCOMING_PACKETS.put(248, packet);//on player - INCOMING_PACKETS.put(101,new ItemOnGroundItemPacket()); //Item on Ground Item - INCOMING_PACKETS.put(3, packet = new InteractionPacket()); - INCOMING_PACKETS.put(180, packet);//Player interact options v - INCOMING_PACKETS.put(68, packet); - INCOMING_PACKETS.put(71, packet); - INCOMING_PACKETS.put(114, packet); - INCOMING_PACKETS.put(175, packet);//Player interact options ^ - INCOMING_PACKETS.put(30, packet); - INCOMING_PACKETS.put(78, packet); - INCOMING_PACKETS.put(148, packet); - INCOMING_PACKETS.put(218, packet); - INCOMING_PACKETS.put(84, packet); - INCOMING_PACKETS.put(170, packet); - INCOMING_PACKETS.put(254, packet); - INCOMING_PACKETS.put(194, packet); - INCOMING_PACKETS.put(66, packet); - INCOMING_PACKETS.put(33, packet); - INCOMING_PACKETS.put(247, packet); - INCOMING_PACKETS.put(156, packet = new ActionButtonPacket()); //Item V - INCOMING_PACKETS.put(55, packet); - INCOMING_PACKETS.put(153, packet); - INCOMING_PACKETS.put(161, packet); - INCOMING_PACKETS.put(135, packet); //^ - INCOMING_PACKETS.put(81, packet); - INCOMING_PACKETS.put(184, packet);//close interface - INCOMING_PACKETS.put(155, packet); //Interface V - INCOMING_PACKETS.put(196, packet); - INCOMING_PACKETS.put(124, packet); - INCOMING_PACKETS.put(199, packet); - INCOMING_PACKETS.put(234, packet); - INCOMING_PACKETS.put(168, packet); - INCOMING_PACKETS.put(166, packet); - INCOMING_PACKETS.put(64, packet); - INCOMING_PACKETS.put(53, packet); - INCOMING_PACKETS.put(9, packet); //^ - INCOMING_PACKETS.put(132, packet); //Dialogue - INCOMING_PACKETS.put(10, packet); //logout - INCOMING_PACKETS.put(206, packet);//operate - INCOMING_PACKETS.put(72, packet = new ExaminePacket()); - INCOMING_PACKETS.put(92, packet); - INCOMING_PACKETS.put(94, packet); - /*INCOMING_PACKETS.put(57, packet); - INCOMING_PACKETS.put(34, packet); - INCOMING_PACKETS.put(213, packet);*/ - //INCOMING_PACKETS.put(69, packet); - //packet 98 - 530 settings interface - INCOMING_PACKETS.put(104, packet = new ClanPacketHandler()); - INCOMING_PACKETS.put(188, packet); - INCOMING_PACKETS.put(162, packet); - INCOMING_PACKETS.put(157, new ChatSettingsPacket()); - INCOMING_PACKETS.put(244, packet = new RunScriptPacketHandler()); - INCOMING_PACKETS.put(23, packet); - INCOMING_PACKETS.put(65, packet); - INCOMING_PACKETS.put(110, new RegionChangePacket()); - INCOMING_PACKETS.put(195, packet = new InterfaceUseOnPacket()); - INCOMING_PACKETS.put(239, packet); - INCOMING_PACKETS.put(73, packet); - INCOMING_PACKETS.put(253, packet); - INCOMING_PACKETS.put(233, packet); - INCOMING_PACKETS.put(231, packet = new SlotSwitchPacket()); - INCOMING_PACKETS.put(79, packet); - INCOMING_PACKETS.put(167, new QuickChatPacketHandler()); - INCOMING_PACKETS.put(201, packet = new CommunicationPacket()); - INCOMING_PACKETS.put(120, packet); - INCOMING_PACKETS.put(57, packet); - INCOMING_PACKETS.put(34, packet); - INCOMING_PACKETS.put(213, packet); - INCOMING_PACKETS.put(99, packet = new ReportAbusePacket()); - INCOMING_PACKETS.put(98, packet = new MapClosedPacket()); // this packet is sent when the world map is closed by the client - INCOMING_PACKETS.put(137,packet = new MusicPacketHandler()); //this packet is received when the client stops playing a song - // INCOMING_PACKETS.put(77, packet); - // INCOMING_PACKETS.put(191, packet); - // INCOMING_PACKETS.put(139, packet); - // INCOMING_PACKETS.put(251, packet); - // INCOMING_PACKETS.put(55, packet); - - //Packet 22 is sent on focus gain/loss - //packet 177 is sent when opening/closing interfaces - } /** @@ -199,12 +91,4 @@ public final class PacketRepository { } } - /** - * Gets an incoming packet. - * @param opcode The opcode. - * @return The incoming packet. - */ - public static IncomingPacket getIncoming(int opcode) { - return INCOMING_PACKETS.get(opcode); - } } diff --git a/Server/src/main/java/core/net/packet/in/ActionButtonPacket.java b/Server/src/main/java/core/net/packet/in/ActionButtonPacket.java deleted file mode 100644 index cebc8169d..000000000 --- a/Server/src/main/java/core/net/packet/in/ActionButtonPacket.java +++ /dev/null @@ -1,350 +0,0 @@ -package core.net.packet.in; - -import api.events.ButtonClickEvent; -import core.game.component.Component; -import core.game.component.ComponentPlugin; -import core.game.container.Container; -import core.game.content.dialogue.DialogueAction; -import core.game.interaction.Option; -import core.game.node.entity.player.Player; -import core.game.node.entity.player.info.login.LoginConfiguration; -import core.game.node.entity.player.link.request.assist.AssistSession; -import core.game.node.item.Item; -import core.game.system.task.Pulse; -import core.net.packet.IncomingPacket; -import core.net.packet.IoBuffer; -import rs09.game.interaction.InterfaceListeners; -import rs09.game.world.GameWorld; - -import java.util.List; - -/** - * The incoming reward button packet. - * @author Emperor - */ -public class ActionButtonPacket implements IncomingPacket { - - @Override - public void decode(final Player player, int opcode, IoBuffer buffer) { - if (player == null) { - return; - } - int[] args = getArguments(player, buffer); - if (args == null || (buffer.opcode() != 76 && args[0] != 106 && args[0] != 108 && args[0] != 110 && args[0] != 646 && player.getLocks().isComponentLocked() && player.getExtension(AssistSession.class) == null)) { - player.debug("Check this code in reward button packet, where args arent null && opcode !="); - return; - } - int componentId = args[0]; - int buttonId = args[1]; - int slot = args[2]; - int itemId = args[3]; - player.debug("Component=" + componentId + ", button=" + buttonId + ", slot=" + slot + ", item=" + itemId + ", opcode=" + buffer.opcode()); - if (player.getDialogueInterpreter().getDialogue() != null && buffer.opcode() != 132 && componentId != 64) { - player.getDialogueInterpreter().close(); - } - if (player.getLocks().isComponentLocked()) { - return; - } - if (itemId > -1 && slot > -1) { - Container container = getContainer(player, componentId); - if (container != null) { - handleItemInteraction(player, buffer.opcode(), itemId, slot, container); - return; - } - } - if (player.getZoneMonitor().clickButton(componentId, buttonId, slot, itemId, opcode)) { - return; - } - Component c = player.getInterfaceManager().getComponent(componentId); - if (c == null || c.isHidden()) { - player.debug("Component " + c + " wasn't opened in interface manager."); - return; - } - int cOpcode = buffer.opcode(); - ComponentPlugin plugin = c.getPlugin(); - player.dispatch(new ButtonClickEvent(c.getId(), buttonId)); - if (plugin != null) { - player.debug("Component plugin = " + plugin.getClass().getSimpleName()); - plugin.handle(player, c, cOpcode, buttonId, slot, itemId); - } else { - if(InterfaceListeners.run(player,c,cOpcode,buttonId,slot,itemId)){ - return; - } - } - } - - /** - * Gets the container for the component id. - * @param player The player. - * @param componentId The component id. - * @return The container. - */ - private Container getContainer(Player player, int componentId) { - switch (componentId) { - case 149: - return player.getInventory(); - } - return null; - } - - /** - * Gets the arguments for the reward button. - * @param player The player. - * @param buffer The buffer. - * @return The arguments [component, button, slot, item] - */ - private static int[] getArguments(final Player player, IoBuffer buffer) { - int data = -1; - int componentId = -1; - int buttonId = -1; - int itemId = -1; - int slot = -1; - switch (buffer.opcode()) { - case 81: - //System.out.println("Using action handler81"); - slot = buffer.getShortA(); - itemId = buffer.getShort(); - buttonId = buffer.getShort(); - componentId = buffer.getShort(); - break; - case 156: - //System.out.println("Using action handler156"); - slot = buffer.getLEShortA(); - itemId = buffer.getShortA(); - data = buffer.getLEInt(); - componentId = data >> 16; - buttonId = data & 0xffff; - break; - case 55: - //System.out.println("Using action handler55"); - itemId = buffer.getLEShort(); - slot = buffer.getShortA(); - data = buffer.getIntA(); - componentId = data >> 16; - buttonId = data & 0xffff; - break; - case 153: - //System.out.println("Using action handler153"); - data = buffer.getLEInt(); - slot = buffer.getLEShort(); - itemId = buffer.getLEShort(); - componentId = (data >> 16) & 0xFFFF; - buttonId = data & 0xFFFF; - break; - case 161: - //System.out.println("Using action handler161"); - data = buffer.getLEInt(); - itemId = buffer.getLEShortA(); - slot = buffer.getLEShortA(); - componentId = (data >> 16) & 0xFFFF; - buttonId = data & 0xFFFF; - break; - case 135: - //System.out.println("Using action handler135"); - itemId = buffer.getShortA(); - slot = buffer.getShortA(); - data = buffer.getIntB(); - componentId = (data >> 16) & 0xFFFF; - buttonId = data & 0xFFFF; - break; - case 155: //Interface options - case 196: - case 124: - case 199: - case 234: - case 168: - case 166: - case 64: - case 53: - case 9: - //System.out.println("Using action handler155-9"); - data = buffer.getInt(); - slot = buffer.getShort(); - componentId = (data >> 16) & 0xFFFF; - buttonId = data & 0xFFFF; - break; - case 132: //Dialogue options - //System.out.println("Using action handler132"); - data = buffer.getIntA(); - slot = buffer.getLEShort(); - componentId = data >> 16; - buttonId = data & 0xffff; - if (player.getDialogueInterpreter().getDialogue() == null) { - player.getInterfaceManager().closeChatbox(); - List actions = player.getDialogueInterpreter().getActions(); - if (actions.size() > 0) { - DialogueAction action = actions.get(0); - action.handle(player, buttonId); - actions.remove(action); - } - break; - } - player.getDialogueInterpreter().handle(componentId, buttonId); - break; - case 133: - //System.out.println("Using action handler133"); - data = buffer.getLEInt(); - componentId = (data >> 16) & 0xFFFF; - buttonId = data & 0xFFFF; - slot = buffer.getShort(); - itemId = buffer.getLEShortA(); - break; - case 206: - //System.out.println("Using action handler206"); - itemId = buffer.getShortA(); - slot = buffer.getLEShort(); - data = buffer.getLEInt(); - componentId = (data >> 16) & 0xFFFF; - buttonId = data & 0xFFFF; - //player.sendMessage("itemId=" + itemId + ", data=" + data + ", buttonId=" + buttonId + ", compId= " + componentId); - break; - case 230: // Short - case 180: - case 10: - //System.out.println("Using action handler230-10"); - data = buffer.getInt(); - componentId = data >> 16; - buttonId = data & 0xffff; - if (buffer.opcode() == 230) { - slot = buffer.getShort(); - } - if (componentId == 49) { - if (player.getDialogueInterpreter().getDialogue() == null) { - player.setAttribute("chatbox-buttonid",buttonId); - player.getInterfaceManager().closeChatbox(); - return null; - } - player.setAttribute("chatbox-buttonid",buttonId); - player.getDialogueInterpreter().getDialogue().handle(componentId, buttonId); - } - break; - case 157: - //System.out.println("Using action handler157"); - itemId = buffer.getLEShort(); - slot = buffer.getLEShort(); - data = buffer.getLEInt(); - componentId = data >> 16; - buttonId = data & 0xffff; - break; - case 39: - //System.out.println("Using action handler39"); - data = buffer.getInt(); - slot = buffer.getShort(); - componentId = (data >> 16) & 0xFFFF; - buttonId = data & 0xFFFF; - break; - case 128: - //System.out.println("Using action handler128"); - data = buffer.getInt(); - slot = buffer.getShort(); - componentId = (data >> 16) & 0xFFFF; - buttonId = data & 0xffff; - break; - case 235: - //System.out.println("Using action handler235"); - data = buffer.getInt(); - slot = buffer.getShort(); - componentId = (data >> 16) & 0xFFFF; - buttonId = data & 0xffff; - break; - case 243: - //System.out.println("Using action handler243"); - data = buffer.getInt(); - itemId = buffer.getShortA(); - slot = buffer.getLEShortA(); - componentId = data >> 16; - buttonId = data & 0xffff; - break; - case 170: - //System.out.println("Using action handler170"); - slot = buffer.getLEShort(); - itemId = buffer.getShortA(); - data = buffer.getLEInt(); - componentId = (data >> 16) & 0xFFFF; - buttonId = data & 0xFFFF; - break; - case 145: - //System.out.println("Using action handler145"); - data = buffer.getIntB(); - itemId = buffer.getShortA(); - slot = buffer.getLEShort(); - componentId = (data >> 16) & 0xFFFF; - buttonId = data & 0xffff; - // TODO dialogue with store X. - break; - case 127:// 3rd option on send item. - case 203:// 5th option on send item. - case 205:// 2 option - case 211:// 4rth option on send item. - case 187: // 6th - //System.out.println("Using action handler127-187"); - data = buffer.getInt(); - slot = buffer.getShort(); - componentId = data >> 16; - buttonId = data & 0xffff; - itemId = -1; - break; - case 184: - case 95: - //System.out.println("Using action handler184-95"); - if (player.getAttribute("logging_in") != null) { - player.getInterfaceManager().close(); - GameWorld.getPulser().submit(new Pulse(1, player) { - @Override - public boolean pulse() { - player.removeAttribute("logging_in"); - LoginConfiguration.configureGameWorld(player); - return true; - } - }); - } - player.getInterfaceManager().close(); - if (player.getAttribute("worldMap:viewing") != null) { - player.removeAttribute("worldMap:viewing"); - player.getPacketDispatch().sendWindowsPane(player.getInterfaceManager().isResizable() ? 746 : 548, 2); - player.unlock(); - } - break; - } - return new int[] { componentId, buttonId, slot, itemId }; - } - - /** - * Handles an item interaction. - * @param player The player. - * @param opcode The opcode. - * @param itemId The item. - */ - private static void handleItemInteraction(Player player, int opcode, int itemId, int slot, Container container) { - if (slot < 0 || slot >= container.capacity()) { - return; - } - Item item = container.get(slot); - if (item == null || item.getId() != itemId) { - return; - } - int index = 0; - switch (opcode) { - case 156: // First option - index = 0; - break; - case 55: // Second option (wield/wear) - index = 1; - break; - case 153: // Third option - index = 2; - break; - case 161: // Fourth option (summon) - index = 3; - break; - case 135: // Fifth option (drop/destroy) - index = 4; - break; - } - final Option option = item.getInteraction().get(index); - if (option == null || player.getLocks().isInteractionLocked()) { - return; - } - item.getInteraction().handleItemOption(player, option, container); - } -} \ No newline at end of file diff --git a/Server/src/main/java/core/net/packet/in/CameraMovementPacket.java b/Server/src/main/java/core/net/packet/in/CameraMovementPacket.java deleted file mode 100644 index 4f1f00e55..000000000 --- a/Server/src/main/java/core/net/packet/in/CameraMovementPacket.java +++ /dev/null @@ -1,19 +0,0 @@ -package core.net.packet.in; - -import core.game.node.entity.player.Player; -import core.net.packet.IncomingPacket; -import core.net.packet.IoBuffer; - -/** - * Handles an incoming camera movement changed packet. - * @author Emperor - */ -public final class CameraMovementPacket implements IncomingPacket { - - @Override - public void decode(Player player, int opcode, IoBuffer buffer) { - buffer.getShortA(); - buffer.getLEShort(); - } - -} \ No newline at end of file diff --git a/Server/src/main/java/core/net/packet/in/ChatPacket.java b/Server/src/main/java/core/net/packet/in/ChatPacket.java deleted file mode 100644 index 764d44404..000000000 --- a/Server/src/main/java/core/net/packet/in/ChatPacket.java +++ /dev/null @@ -1,56 +0,0 @@ -package core.net.packet.in; - -import core.game.node.entity.player.Player; -import core.game.system.monitor.PlayerMonitor; -import core.game.system.task.Pulse; -import proto.management.ClanMessage; -import rs09.game.world.GameWorld; -import core.game.world.update.flag.context.ChatMessage; -import core.game.world.update.flag.player.ChatFlag; -import core.net.amsc.MSPacketRepository; -import core.net.amsc.WorldCommunicator; -import core.net.packet.IncomingPacket; -import core.net.packet.IoBuffer; -import core.tools.StringUtils; -import rs09.worker.ManagementEvents; - -/** - * Represents the incoming chat packet. - * @author Emperor - */ -public class ChatPacket implements IncomingPacket { - - @Override - public void decode(final Player player, int opcode, IoBuffer buffer) { - try { - final int effects = buffer.getShort(); - final int numChars = buffer.getSmart(); - final String message = StringUtils.decryptPlayerChat(buffer, numChars); - if (player.getDetails().isMuted()) { - player.getPacketDispatch().sendMessage("You have been " + (player.getDetails().isPermMute() ? "permanently" : "temporarily") + " muted due to breaking a rule."); - return; - } - if (message.startsWith("/") && player.getCommunication().getClan() != null) { - ClanMessage.Builder builder = ClanMessage.newBuilder(); - builder.setSender(player.getName()); - builder.setClanName(player.getCommunication().getClan().getOwner().toLowerCase().replace(" ", "_")); - builder.setMessage(message.substring(1)); - builder.setRank(player.getDetails().getRights().ordinal()); - ManagementEvents.publish(builder.build()); - return; - } - player.getMonitor().log(message, PlayerMonitor.PUBLIC_CHAT_LOG); - ChatMessage ctx = new ChatMessage(player, message, effects, numChars); - GameWorld.getPulser().submit(new Pulse(0, player) { - @Override - public boolean pulse() { - player.getUpdateMasks().register(new ChatFlag(ctx)); - return true; - } - }); - } catch (Throwable t) { - t.printStackTrace(); - } - } - -} \ No newline at end of file diff --git a/Server/src/main/java/core/net/packet/in/ChatSettingsPacket.java b/Server/src/main/java/core/net/packet/in/ChatSettingsPacket.java deleted file mode 100644 index c0fa1b0f7..000000000 --- a/Server/src/main/java/core/net/packet/in/ChatSettingsPacket.java +++ /dev/null @@ -1,26 +0,0 @@ -package core.net.packet.in; - -import core.game.node.entity.player.Player; -import core.net.amsc.MSPacketRepository; -import core.net.amsc.WorldCommunicator; -import core.net.packet.IncomingPacket; -import core.net.packet.IoBuffer; - -/** - * Handles an incoming chat settings update packet. - * @author Emperor - */ -public final class ChatSettingsPacket implements IncomingPacket { - - @Override - public void decode(Player player, int opcode, IoBuffer buffer) { - int publicSetting = buffer.get(); - int privateSetting = buffer.get(); - int tradeSetting = buffer.get(); - if (WorldCommunicator.isEnabled()) { - MSPacketRepository.sendChatSetting(player, publicSetting, privateSetting, tradeSetting); - } - player.getSettings().updateChatSettings(publicSetting, privateSetting, tradeSetting); - } - -} \ No newline at end of file diff --git a/Server/src/main/java/core/net/packet/in/ClanPacketHandler.java b/Server/src/main/java/core/net/packet/in/ClanPacketHandler.java deleted file mode 100644 index d6f42e9ee..000000000 --- a/Server/src/main/java/core/net/packet/in/ClanPacketHandler.java +++ /dev/null @@ -1,66 +0,0 @@ -package core.net.packet.in; - -import core.game.node.entity.player.Player; -import core.game.system.communication.ClanRank; -import core.game.system.communication.ClanRepository; -import core.game.system.communication.CommunicationInfo; -import proto.management.JoinClanRequest; -import rs09.game.world.repository.Repository; -import core.net.amsc.MSPacketRepository; -import core.net.amsc.WorldCommunicator; -import core.net.packet.IncomingPacket; -import core.net.packet.IoBuffer; -import core.tools.StringUtils; -import rs09.worker.ManagementEvents; - -/** - * Handles incoming clan packets. - * @author Emperor - */ -public class ClanPacketHandler implements IncomingPacket { - - @Override - public void decode(Player player, int opcode, IoBuffer buffer) { - switch (buffer.opcode()) { - case 104: - if (player.getCommunication().getClan() != null) { - player.getCommunication().getClan().leave(player, true); - player.getCommunication().setClan(null); - return; - } - long nameLong = buffer.getLong(); - String name = StringUtils.longToString(nameLong); - if (nameLong != 0L) { - player.getPacketDispatch().sendMessage("Attempting to join channel...:clan:"); - } - JoinClanRequest.Builder builder = JoinClanRequest.newBuilder(); - builder.setClanName(name); - builder.setUsername(player.getName()); - ManagementEvents.publish(builder.build()); - break; - case 188: - int rank = buffer.getA(); - name = StringUtils.longToString(buffer.getLong()); - if (WorldCommunicator.isEnabled()) { - MSPacketRepository.sendContactUpdate(player.getName(), name, false, false, ClanRank.values()[rank + 1]); - break; - } - CommunicationInfo.updateClanRank(player, name, ClanRank.values()[rank + 1]); - break; - case 162: - name = StringUtils.longToString(buffer.getLong()); - if (WorldCommunicator.isEnabled()) { - MSPacketRepository.sendClanKick(player.getName(), name); - break; - } - ClanRepository clan = player.getCommunication().getClan(); - Player target = Repository.getPlayerByName(name); - if (clan == null || target == null) { - break; - } - clan.kick(player, target); - break; - } - } - -} \ No newline at end of file diff --git a/Server/src/main/java/core/net/packet/in/ClientFocusPacket.java b/Server/src/main/java/core/net/packet/in/ClientFocusPacket.java deleted file mode 100644 index 95b9b60c6..000000000 --- a/Server/src/main/java/core/net/packet/in/ClientFocusPacket.java +++ /dev/null @@ -1,20 +0,0 @@ -package core.net.packet.in; - -import core.game.node.entity.player.Player; -import core.net.packet.IncomingPacket; -import core.net.packet.IoBuffer; - -/** - * Handles an incoming client focus changed packet. - * @author Emperor - */ -public final class ClientFocusPacket implements IncomingPacket { - - @Override - public void decode(Player player, int opcode, IoBuffer buffer) { - if (player != null) { - player.getMonitor().setClientFocus(buffer.get() == 1); - } - } - -} \ No newline at end of file diff --git a/Server/src/main/java/core/net/packet/in/CommandPacket.java b/Server/src/main/java/core/net/packet/in/CommandPacket.java deleted file mode 100644 index 96cfed378..000000000 --- a/Server/src/main/java/core/net/packet/in/CommandPacket.java +++ /dev/null @@ -1,35 +0,0 @@ -package core.net.packet.in; - -import core.game.node.entity.player.Player; -import rs09.game.system.command.CommandSystem; -import core.game.system.monitor.PlayerMonitor; -import rs09.game.world.GameWorld; -import core.net.packet.IncomingPacket; -import core.net.packet.IoBuffer; - -/** - * Handles an incoming command packet. - * @author Emperor - * @author 'Vexia - */ -public final class CommandPacket implements IncomingPacket { - - @Override - public void decode(Player player, int opcode, IoBuffer buffer) { - final int data = buffer.get(); - if (buffer.toByteBuffer().hasRemaining()) { - final String message = ((char) data + buffer.getString()).toLowerCase(); - if (!GameWorld.getSettings().isDevMode()) { - int last = player.getAttribute("commandLast", 0); - if (last > GameWorld.getTicks()) { - return; - } - player.setAttribute("commandLast", GameWorld.getTicks() + 1); - } - if (CommandSystem.Companion.getCommandSystem().parse(player, message)) { - player.getMonitor().log(message, PlayerMonitor.COMMAND_LOG); - } - } - } - -} \ No newline at end of file diff --git a/Server/src/main/java/core/net/packet/in/CommunicationPacket.java b/Server/src/main/java/core/net/packet/in/CommunicationPacket.java deleted file mode 100644 index a4a26805b..000000000 --- a/Server/src/main/java/core/net/packet/in/CommunicationPacket.java +++ /dev/null @@ -1,43 +0,0 @@ -package core.net.packet.in; - -import core.game.node.entity.player.Player; -import core.game.system.communication.CommunicationInfo; -import core.net.packet.IncomingPacket; -import core.net.packet.IoBuffer; -import core.tools.StringUtils; - -/** - * Represents the packet used to handle all incoming packets related to - * communication. - * @author 'Vexia - */ -public final class CommunicationPacket implements IncomingPacket { - - @Override - public void decode(Player player, int opcode, IoBuffer buffer) { - switch (buffer.opcode()) { - case 120: - CommunicationInfo.add(player, StringUtils.longToString(buffer.getLong())); - break; - case 57: - CommunicationInfo.remove(player, StringUtils.longToString(buffer.getLong()), false); - break; - case 34: - CommunicationInfo.block(player, StringUtils.longToString(buffer.getLong())); - break; - case 213: - CommunicationInfo.remove(player, StringUtils.longToString(buffer.getLong()), true); - break; - case 201: - String name = StringUtils.longToString(buffer.getLong()); - String message = StringUtils.decryptPlayerChat(buffer, buffer.get() & 0xFF); - if (player.getDetails().isMuted()) { - player.getPacketDispatch().sendMessage("You have been " + (player.getDetails().isPermMute() ? "permanently" : "temporarily") + " muted due to breaking a rule."); - return; - } - CommunicationInfo.sendMessage(player, name, message); - break; - } - } - -} diff --git a/Server/src/main/java/core/net/packet/in/DisplayUpdatePacket.java b/Server/src/main/java/core/net/packet/in/DisplayUpdatePacket.java deleted file mode 100644 index 4b8ed425d..000000000 --- a/Server/src/main/java/core/net/packet/in/DisplayUpdatePacket.java +++ /dev/null @@ -1,26 +0,0 @@ -package core.net.packet.in; - -import core.game.node.entity.player.Player; -import core.net.packet.IncomingPacket; -import core.net.packet.IoBuffer; - -/** - * Handles the display update packet. - * @author Emperor - * - */ -public class DisplayUpdatePacket implements IncomingPacket { - - @Override - public void decode(Player player, int opcode, IoBuffer buffer) { - int windowMode = buffer.get(); //Window mode - int screenWidth = buffer.getShort(); - int screenHeight = buffer.getShort(); - int displayMode = buffer.get(); //Display mode - player.getSession().getClientInfo().setScreenWidth(screenWidth); - player.getSession().getClientInfo().setScreenHeight(screenHeight); - player.getSession().getClientInfo().setDisplayMode(displayMode); - player.getInterfaceManager().switchWindowMode(windowMode); - } - -} \ No newline at end of file diff --git a/Server/src/main/java/core/net/packet/in/DummyPacket.java b/Server/src/main/java/core/net/packet/in/DummyPacket.java deleted file mode 100644 index 9a22e0c26..000000000 --- a/Server/src/main/java/core/net/packet/in/DummyPacket.java +++ /dev/null @@ -1,13 +0,0 @@ -package core.net.packet.in; - -import core.game.node.entity.player.Player; -import rs09.game.system.SystemLogger; -import core.net.packet.IncomingPacket; -import core.net.packet.IoBuffer; - -public class DummyPacket implements IncomingPacket { - @Override - public void decode(Player player, int opcode, IoBuffer buffer) { - SystemLogger.logInfo(this.getClass(), "Received opcode " + opcode + " packet."); - } -} diff --git a/Server/src/main/java/core/net/packet/in/ExaminePacket.java b/Server/src/main/java/core/net/packet/in/ExaminePacket.java deleted file mode 100644 index c603c73d1..000000000 --- a/Server/src/main/java/core/net/packet/in/ExaminePacket.java +++ /dev/null @@ -1,63 +0,0 @@ -package core.net.packet.in; - -import core.cache.Cache; -import core.cache.def.impl.ItemDefinition; -import core.cache.def.impl.NPCDefinition; -import core.cache.def.impl.SceneryDefinition; -import core.cache.def.impl.VarbitDefinition; -import core.game.node.entity.player.Player; -import core.net.packet.IncomingPacket; -import core.net.packet.IoBuffer; -import org.rs09.consts.Items; - -import java.util.Arrays; - -/** - * Handles the incoming examine packets. - * @author Emperor - */ -public final class ExaminePacket implements IncomingPacket { - - @Override - public void decode(Player player, int opcode, IoBuffer buffer) { - String name; - switch (buffer.opcode()) { - case 94: // Object examine - int id = buffer.getLEShortA(); - if (id < 0 || id > Cache.getObjectDefinitionsSize()) { - break; - } - SceneryDefinition d = SceneryDefinition.forId(id); - name = d.getExamine(); - //String coords = id + ", " + player.getLocation().getX() + ", " + player.getLocation().getY() + ", " + player.getLocation().getZ(); - player.debug("Object id: " + id + ", models: " + (d.getModelIds() != null ? Arrays.toString(d.getModelIds()) : null) + ", anim: " + d.animationId + ", config: " + (d.getVarbitID() != -1 ? d.getVarbitID() + " (file)" : d.getConfigId()) + "."); - player.debug("Varp config index: " + VarbitDefinition.forObjectID(d.getVarbitID()).getVarpId()); - player.getPacketDispatch().sendMessage(""+name+""); - /*if { - Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection("LandscapeParser.removeGameObject(new GameObject("+coords+"));//"+ d.getName() ), null); - }*/ - break; - case 235: - case 92: // Item examine - id = buffer.getLEShortA(); - if (id < 0 || id > Cache.getItemDefinitionsSize()) { - break; - } - ItemDefinition itemDef = ItemDefinition.forId(id); - player.getPacketDispatch().sendMessage(itemDef.getExamine()); - break; - case 72: // NPC examine - id = buffer.getShort(); - if (id < 0 || id > Cache.getNPCDefinitionsSize()) { - break; - } - player.debug("NPC id: " + id + "."); - NPCDefinition def = NPCDefinition.forId(id); - if (def == null) { - break; - } - player.getPacketDispatch().sendMessage(def.getExamine()); - break; - } - } -} diff --git a/Server/src/main/java/core/net/packet/in/GrandExchangePacket.java b/Server/src/main/java/core/net/packet/in/GrandExchangePacket.java deleted file mode 100644 index efc7d67e7..000000000 --- a/Server/src/main/java/core/net/packet/in/GrandExchangePacket.java +++ /dev/null @@ -1,40 +0,0 @@ -package core.net.packet.in; - -import api.ContentAPIKt; -import core.game.node.entity.player.Player; -import core.net.packet.IncomingPacket; -import core.net.packet.IoBuffer; -import rs09.game.ge.GrandExchange; -import rs09.game.ge.GrandExchangeOffer; -import rs09.game.ge.PriceIndex; -import rs09.game.interaction.inter.ge.StockMarket; - -/** - * Represents the Incoming packet of the grand exchange. - * @author Emperor - */ -public class GrandExchangePacket implements IncomingPacket { - - @Override - public void decode(Player player, int opcode, IoBuffer buffer) { - int itemId = buffer.getShort(); - GrandExchangeOffer offer = player.getAttribute("ge-temp", new GrandExchangeOffer()); - int index = player.getAttribute("ge-index", -1); - offer.setItemID(itemId); - offer.setSell(false); - if(!PriceIndex.canTrade(offer.getItemID())) - { - ContentAPIKt.sendMessage(player, "That item is blacklisted from the grand exchange."); - return; - } - offer.setPlayer(player); - offer.setAmount(1); - offer.setOfferedValue(GrandExchange.getRecommendedPrice(itemId, false)); - offer.setIndex(index); - StockMarket.updateVarbits(player, offer, index, false); - player.setAttribute("ge-temp",offer); - player.getPacketDispatch().sendString(GrandExchange.getOfferStats(itemId, false), 105, 142); - player.getInterfaceManager().closeChatbox(); - } - -} diff --git a/Server/src/main/java/core/net/packet/in/IdlePacketHandler.java b/Server/src/main/java/core/net/packet/in/IdlePacketHandler.java deleted file mode 100644 index 0acb48c24..000000000 --- a/Server/src/main/java/core/net/packet/in/IdlePacketHandler.java +++ /dev/null @@ -1,26 +0,0 @@ -package core.net.packet.in; - -import core.game.node.entity.player.Player; -import core.game.node.entity.player.info.Rights; -import core.net.packet.IncomingPacket; -import core.net.packet.IoBuffer; -import rs09.game.ai.general.GeneralBotCreator; - -/** - * Handles the idle packet handler. - * @author Emperor - */ -public final class IdlePacketHandler implements IncomingPacket { - - @Override - public void decode(Player player, int opcode, IoBuffer buffer) { - if (player.getDetails().getRights() != Rights.ADMINISTRATOR) { - GeneralBotCreator.BotScriptPulse pulse = player.getAttribute("botting:script",null); - if(pulse != null && pulse.isRunning()){ - return; - } - player.getPacketDispatch().sendLogout(); - } - } - -} \ No newline at end of file diff --git a/Server/src/main/java/core/net/packet/in/InteractionPacket.java b/Server/src/main/java/core/net/packet/in/InteractionPacket.java deleted file mode 100644 index 083d955da..000000000 --- a/Server/src/main/java/core/net/packet/in/InteractionPacket.java +++ /dev/null @@ -1,413 +0,0 @@ -package core.net.packet.in; - -import core.cache.def.impl.SceneryDefinition; -import core.cache.def.impl.VarbitDefinition; -import core.game.content.quest.PluginInteractionManager; -import core.game.interaction.Interaction; -import core.game.interaction.MovementPulse; -import core.game.interaction.Option; -import core.game.interaction.SpecialGroundItems; -import core.game.node.Node; -import core.game.node.entity.impl.PulseType; -import core.game.node.entity.npc.NPC; -import core.game.node.entity.player.Player; -import core.game.node.item.GroundItem; -import core.game.node.item.GroundItemManager; -import core.game.node.scenery.Scenery; -import core.game.world.map.Location; -import core.game.world.map.RegionManager; -import core.net.packet.IncomingPacket; -import core.net.packet.IoBuffer; -import core.net.packet.PacketRepository; -import core.net.packet.context.PlayerContext; -import core.net.packet.out.ClearMinimapFlag; -import rs09.ServerConstants; -import rs09.game.ai.AIPlayer; -import rs09.game.interaction.IntType; -import rs09.game.interaction.InteractionListener; -import rs09.game.interaction.InteractionListeners; -import rs09.game.world.repository.Repository; - -import java.util.Arrays; -import java.util.List; - -/** - * Handles the incoming interaction packets. - * @author Emperor - */ -public final class InteractionPacket implements IncomingPacket { - - static int[] hweenNPCs = new int[] {307, 375, 743, 744, 755, 2634, 2690, 2691, 2692, 530, 531, 556, 557, 558, 559, 583, 585, 1860, 3299, 3671, 922, 970}; - - @Override - public void decode(Player player, int opcode, IoBuffer buffer) { - if (player == null) { - return; - } - if (buffer.opcode() != 105) { - player = getPlayer(player); - } - if (player.getLocks().isInteractionLocked() || !player.getInterfaceManager().close()) { - return; - } - player.getInterfaceManager().closeChatbox(); - player.debug("Received " + buffer.opcode()); - try { - switch (buffer.opcode()) { - case 78: // NPC reward 1 - int index = buffer.getLEShort(); - handleNPCInteraction(player, 0, index); - break; - case 3: // NPC reward 2 - index = buffer.getLEShortA(); - handleNPCInteraction(player, 1, index); - break; - case 148: // NPC reward 3 - index = buffer.getShortA(); - handleNPCInteraction(player, 2, index); - break; - case 30: // NPC reward 4 - index = buffer.getShort(); - handleNPCInteraction(player, 3, index); - break; - case 218: // NPC reward 5 - index = buffer.getLEShort(); - handleNPCInteraction(player, 4, index); - break; - case 254: // Object reward 1 - int x = buffer.getLEShort(); - int objectId = buffer.getShortA() & 0xFFFF; - int y = buffer.getShort(); - handleObjectInteraction(player, 0, x, y, objectId); - break; - case 194: // Object reward 2 - y = buffer.getLEShortA(); - x = buffer.getLEShort(); - objectId = buffer.getShort() & 0xFFFF; - handleObjectInteraction(player, 1, x, y, objectId); - break; - case 84: // Object reward 3 - objectId = buffer.getLEShortA() & 0xFFFF; - y = buffer.getLEShortA(); - x = buffer.getLEShort(); - handleObjectInteraction(player, 2, x, y, objectId); - break; - case 152: // Object reward 4 TODO - objectId = buffer.getLEShortA() & 0xFFFF; - x = buffer.getLEShort(); - y = buffer.getLEShortA(); - handleObjectInteraction(player, 3, x, y, objectId); - break; - case 247://Object reward 4 - y = buffer.getLEShort() & 0xFFFF; - x = buffer.getLEShortA(); - objectId = buffer.getShort() & 0xFFFF; - handleObjectInteraction(player, 3, x, y, objectId); - break; - case 170: // Object reward 5 - objectId = buffer.getLEShortA() & 0xFFFF; - x = buffer.getLEShortA(); - y = buffer.getLEShortA(); - handleObjectInteraction(player, 4, x, y, objectId); - break; - case 68: // Player reward 1 - Challenge - index = buffer.getLEShortA(); - handlePlayerInteraction(player, 0, index); - break; - /*case : // Player reward 2 TODO - index = buffer.getLEShort(); - handlePlayerInteraction(player, 1, index); - break;*/ - case 71: // Player reward 3 - follow - index = buffer.getLEShortA(); - handlePlayerInteraction(player, 2, index); - break; - case 180: // Player reward 4 - trade - index = buffer.getLEShortA(); - handlePlayerInteraction(player, 3, index); - break; - /*case : // Player reward 5 TODO - index = buffer.getLEShortA(); - handlePlayerInteraction(player, 4, index); - break;*/ - /*case : // Player reward 6 TODO - index = buffer.getShort(); - handlePlayerInteraction(player, 5, index); - break;*/ - case 114: // Player reward 7 - req assistance - index = buffer.getLEShortA(); - handlePlayerInteraction(player, 6, index); - break; - case 175: // Player reward 8 - "whack" (also "control" for AIPs) - index = buffer.getShortA(); - handlePlayerInteraction(player, 7, index); - break; - case 66: // Ground item reward 1 - x = buffer.getLEShort(); - int itemId = buffer.getShort(); - y = buffer.getLEShortA(); - handleGroundItemInteraction(player, 2, itemId, Location.create(x, y, player.getLocation().getZ())); - break; - case 33: // Ground item reward 2 - itemId = buffer.getShort(); - x = buffer.getShort(); - y = buffer.getLEShort(); - handleGroundItemInteraction(player, 3, itemId, Location.create(x, y, player.getLocation().getZ())); - break; - } - } catch (Exception e){ - e.printStackTrace(); - } - } - - /** - * Handles the NPC interaction. - * @param player the player. - * @param index the index. - */ - public static void handleNPCInteraction(Player player, int optionIndex, final int index) { - if (index < 1 || index > ServerConstants.MAX_NPCS) { - PacketRepository.send(ClearMinimapFlag.class, new PlayerContext(player)); - return; - } - final NPC npc = Repository.getNpcs().get(index); - if (npc == null) { - PacketRepository.send(ClearMinimapFlag.class, new PlayerContext(player)); - return; - } - if (player.getAttribute("removenpc", false)) { - npc.clear(); - player.getPacketDispatch().sendMessage("Removed npc=" + npc.toString()); - return; - } - NPC shown = npc.getShownNPC(player); - Option option = shown.getInteraction().get(optionIndex); - if (option == null) { - if (Arrays.stream(hweenNPCs).anyMatch(i -> i == shown.getId())) { - option = new Option("trick-or-treat", -1); - } - } - if(option == null) { - PacketRepository.send(ClearMinimapFlag.class, new PlayerContext(player)); - Interaction.handleInvalidInteraction(player, npc, Option.NULL); - return; - } - player.debug("NPC Interacting with \"" + shown.getUsername() + "\" [index=" + index + ", renderable=" + npc.isRenderable() + "]"); - player.debug("option=" + option.getName() + ", slot=" + option.getIndex() + ", id=" + shown.getId() + " original=" + npc.getId() + ", location=" + npc.getLocation() + ""); - player.debug("spawn=" + npc.getProperties().getSpawnLocation() + "."); - player.debug("Varp ID= " + npc.getDefinition().getConfigId() + " Offset=" + npc.getDefinition().getVarbitOffset() + " Size=" + npc.getDefinition().getVarbitSize()); - handleAIPLegion(player, 0, optionIndex, index); - if(InteractionListeners.run(shown.getId(),IntType.NPC, option.getName(),player,npc)){ - return; - } - if(PluginInteractionManager.handle(player,shown,option)){ - return; - } - npc.getInteraction().handle(player, option); - } - - /** - * Handles Node interaction with the first index - * @param player The interacting player. - * @param n The node to interact with. - */ - public static void handleObjectInteraction(final Player player, Node n) - { - handleObjectInteraction(player, 0, n.getLocation(), n.getId()); - } - - /** - * Handles object interaction - * @param player The interacting player. - * @param optionIndex The option index. - * @param l The (x,y) location of the object. - * @param objectId The object id. - */ - public static void handleObjectInteraction(final Player player, int optionIndex, Location l, int objectId) { - handleObjectInteraction(player, optionIndex, l.getX(), l.getY(), objectId); - } - - /** - * Handles object interaction - * @param player The interacting player. - * @param optionIndex The option index. - * @param x The x-coordinate of the object. - * @param y The y-coordinate of the object. - * @param objectId The object id. - */ - public static void handleObjectInteraction(final Player player, int optionIndex, int x, int y, int objectId) { - Scenery object = RegionManager.getObject(player.getLocation().getZ(), x, y, objectId); - if (objectId == 29735) {//player safety. - player.getPulseManager().run(new MovementPulse(player, Location.create(x, y, player .getLocation().getZ())) { - @Override - public boolean pulse() { - player.getDialogueInterpreter().sendDialogue("There appears to be a tunnel behind the poster."); - player.getDialogueInterpreter().addAction((player1, buttonId) -> player1.teleport(new Location(3140, 4230, 2))); - return true; - } - }, PulseType.STANDARD); - return; - } - if (objectId == 6898) { - object = new Scenery(6898, new Location(3219, 9618)); - } else if (objectId == 6899) { - object = new Scenery(6899, new Location(3221, 9618)); - } - - // Family crest levers don't have varps associated with them, so their state is validated with attributes - // instead, and they always appear as their down/odd variant in the server's map - if(2421 <= objectId && objectId <= 2426 && objectId % 2 == 0) { - object = new Scenery(objectId - 1, new Location(x, y, player.getLocation().getZ())); - objectId -= 1; - } - if (object == null || object.getId() != objectId) { - player.debug("Scenery(" + objectId + ") interaction was " + object + " at location " + x + ", " + y + "."); - PacketRepository.send(ClearMinimapFlag.class, new PlayerContext(player)); - Interaction.handleInvalidInteraction(player, object, Option.NULL); - return; - } - if (!object.isActive()) { - PacketRepository.send(ClearMinimapFlag.class, new PlayerContext(player)); - Interaction.handleInvalidInteraction(player, object, Option.NULL); - return; - } - object = object.getChild(player); - Option option = object.getInteraction().get(optionIndex); - if (option == null) { - player.debug("Invalid option" + object + ", original: " + objectId + "."); - PacketRepository.send(ClearMinimapFlag.class, new PlayerContext(player)); - Interaction.handleInvalidInteraction(player, object, Option.NULL); - return; - } - player.debug(object + ", original=" + objectId + ", option=" + option.getName() + ""); - player.debug("dir=" + object.getDirection()); - VarbitDefinition def = VarbitDefinition.forObjectID(SceneryDefinition.forId(objectId).getVarbitID()); - player.debug("Varp ID=" + def.getVarpId() + " Offset=" + def.getStartBit() + " Size=" + def.getEndBit()); - player.debug("Varbit: " + def.getId()); - if (option.getHandler() != null) { - player.debug("Object handler: " + option.getHandler().getClass().getSimpleName()); - } - handleAIPLegion(player, 1, optionIndex, x, y, objectId); - - if(InteractionListeners.run(object.getId(), IntType.SCENERY, option.getName(),player,object)){ - return; - } - if(PluginInteractionManager.handle(player,object)){ - return; - } - object.getInteraction().handle(player, option); - } - - /** - * Handles player interaction. - * @param player The player interacting. - * @param optionIndex The option index. - * @param index The target index. - */ - private static void handlePlayerInteraction(Player player, int optionIndex, int index) { - if (index < 1 || index > ServerConstants.MAX_PLAYERS) { - PacketRepository.send(ClearMinimapFlag.class, new PlayerContext(player)); - return; - } - final Player target = Repository.getPlayers().get(index); - if (target == null || !target.isActive()) { - PacketRepository.send(ClearMinimapFlag.class, new PlayerContext(player)); - return; - } - final Option option = player.getInteraction().get(optionIndex); - //Handling for "Pelt" option - if (option == null) { - PacketRepository.send(ClearMinimapFlag.class, new PlayerContext(player)); - return; - } - - if (!InteractionListeners.run(-1, IntType.PLAYER, option.getName().toLowerCase(), player, target)) { - handleAIPLegion(player, 2, optionIndex, index); - target.getInteraction().handle(player, option); - } - } - - /** - * Handles the ground item interaction. - * @param player The player. - * @param index The index of the reward. - * @param itemId The item id. - * @param location The location of the item. - */ - private static void handleGroundItemInteraction(final Player player, int index, int itemId, Location location) { - final GroundItem item = GroundItemManager.get(itemId, location, player); - SpecialGroundItems[] groundItems = SpecialGroundItems.values(); - for(SpecialGroundItems specialItem : groundItems){ - if(specialItem.getItemid() == itemId && specialItem.getLocation().getX() == location.getX() && specialItem.getLocation().getY() == location.getY()){ - player.debug("Using special ground item handler"); - specialItem.getInteraction().handle(player,item.getInteraction().get(index)); - return; - } - } - if (item == null) { - PacketRepository.send(ClearMinimapFlag.class, new PlayerContext(player)); - return; - } - final Option option = item.getInteraction().get(index); - if (option == null) { - PacketRepository.send(ClearMinimapFlag.class, new PlayerContext(player)); - Interaction.handleInvalidInteraction(player, item, Option.NULL); - return; - } - if(PluginInteractionManager.handle(player,item,option)){ - player.debug("Handled by quest interaction manager."); - return; - } - if(InteractionListeners.run(item.getId(), IntType.GROUNDITEM, option.getName(), player, item)) { - return; - } - if(InteractionListeners.run(item.getId(), IntType.ITEM, option.getName(), player, item)) { - return; - } - item.getInteraction().handle(player, option); - } - - /** - * Handles the AIPlayer legion. - * @param player The player. - * @param type The interaction type. - * @param args The arguments. - */ - private static void handleAIPLegion(Player player, int type, int... args) { - if (player.isArtificial()) { - List legion = player.getAttribute("aip_legion"); - if (legion != null) { - for (AIPlayer aip : legion) { - if (aip != player) { - switch (type) { - case 0: - handleNPCInteraction(aip, args[0], args[1]); - break; - case 1: - handleObjectInteraction(aip, args[0], args[1], args[2], args[3]); - break; - case 2: - handlePlayerInteraction(aip, args[0], args[1]); - break; - } - } - } - } - } - } - - /** - * Gets the player instance (used for AIP controlling). - * @param player The player. - * @return The player instance, or the AIP when the player is controlling an - * AIP. - */ - private static Player getPlayer(Player player) { - AIPlayer aip = player.getAttribute("aip_select"); - if (aip != null && aip.getLocation().withinDistance(player.getLocation())) { - return aip; - } - return player; - } - -} diff --git a/Server/src/main/java/core/net/packet/in/InterfaceUseOnPacket.java b/Server/src/main/java/core/net/packet/in/InterfaceUseOnPacket.java deleted file mode 100644 index 0f3d00fb3..000000000 --- a/Server/src/main/java/core/net/packet/in/InterfaceUseOnPacket.java +++ /dev/null @@ -1,270 +0,0 @@ -package core.net.packet.in; - -import core.game.node.entity.impl.PulseType; -import rs09.ServerConstants; -import core.game.node.entity.skill.magic.MagicSpell; -import core.game.node.entity.skill.summoning.familiar.FamiliarSpecial; -import core.game.interaction.MovementPulse; -import rs09.game.node.entity.combat.CombatSwingHandler; -import core.game.node.entity.npc.NPC; -import core.game.node.entity.player.Player; -import core.game.node.entity.player.link.SpellBookManager; -import core.game.node.item.GroundItemManager; -import core.game.node.item.Item; -import core.game.node.scenery.Scenery; -import rs09.game.node.entity.skill.magic.SpellListener; -import rs09.game.node.entity.skill.magic.SpellListeners; -import rs09.game.node.entity.skill.magic.SpellUtils; -import rs09.game.world.GameWorld; -import core.game.world.map.Location; -import core.game.world.map.RegionManager; -import rs09.game.world.repository.Repository; -import core.net.packet.IncomingPacket; -import core.net.packet.IoBuffer; -import core.net.packet.PacketRepository; -import core.net.packet.context.PlayerContext; -import core.net.packet.out.ClearMinimapFlag; - -/** - * Handles the Interface "Use" on packets. - * @author Stacx - */ -public class InterfaceUseOnPacket implements IncomingPacket { - - @SuppressWarnings("unused") - @Override - public void decode(final Player player, int opcode, IoBuffer buffer) { - int payload; - int interfaceId; - int componentId; - int itemId; - int x; - int y; - switch (buffer.opcode()) { - case 73: // Interface On GroundItem - componentId = buffer.getShort(); - interfaceId = buffer.getShort(); - y = buffer.getShort(); - itemId = buffer.getLEShortA(); - x = buffer.getLEShortA(); - final int spell = buffer.getLEShort(); - final Item groundItem = GroundItemManager.get(itemId, Location.create(x, y, player.getLocation().getZ()), player); - if (groundItem == null || !player.getLocation().withinDistance(groundItem.getLocation())) { - break; - } - if (player.getAttribute("magic:delay", -1) > GameWorld.getTicks()) { - break; - } - if (player.getZoneMonitor().clickButton(interfaceId, componentId, spell, itemId, opcode)) { - break; - } - if (CombatSwingHandler.isProjectileClipped(player, groundItem, false)) { - SpellListeners.run(spell, SpellListener.GROUND_ITEM, SpellUtils.getBookFromInterface(interfaceId),player,groundItem); - MagicSpell.castSpell(player, SpellBookManager.SpellBook.MODERN, spell, groundItem); - } else { - player.getPulseManager().run(new MovementPulse(player, groundItem) { - @Override - public boolean update() { - if (CombatSwingHandler.isProjectileClipped(player, groundItem, false)) { - super.destination = player.getLocation(); - } - boolean finished = super.update(); - if (finished) { - player.getWalkingQueue().reset(); - } - return finished; - - } - - @Override - public boolean pulse() { - SpellListeners.run(spell, SpellListener.GROUND_ITEM,SpellUtils.getBookFromInterface(interfaceId),player,groundItem); - MagicSpell.castSpell(player, SpellBookManager.SpellBook.MODERN, spell, groundItem); - return true; - } - }, PulseType.STANDARD); - } - break; - case 195: // Interface On Player - //payload = buffer.getShortA(); - buffer.getShortA(); - componentId = buffer.getLEShort(); - interfaceId = buffer.getLEShort(); - int targetIndex = buffer.getLEShortA(); - // Logger.log("Interface:" + interfaceId+ " Component:" + - // componentId + " Target Index:"+ targetIndex); - //System.out.println("magic on player component = "+componentId+"!"); - final Player target = Repository.getPlayers().get(targetIndex); - if (target == null || !player.getLocation().withinDistance(target.getLocation())) { - PacketRepository.send(ClearMinimapFlag.class, new PlayerContext(player)); - break; - } - if(!SpellUtils.getBookFromInterface(interfaceId).equals("none")){ - SpellListeners.run(componentId,SpellListener.PLAYER,SpellUtils.getBookFromInterface(interfaceId),player,target); - } - switch (interfaceId) { - case 192: - MagicSpell.castSpell(player, SpellBookManager.SpellBook.MODERN, componentId, target); - break; - case 193: - MagicSpell.castSpell(player, SpellBookManager.SpellBook.ANCIENT, componentId, target); - break; - case 430: - MagicSpell.castSpell(player, SpellBookManager.SpellBook.LUNAR, componentId, target); - break; - case 662: - switch (componentId) { - case 67: - case 69: - case 119: - case 121: - default: - if (!player.getFamiliarManager().hasFamiliar()) { - player.getPacketDispatch().sendMessage("You don't have a familiar."); - } else { - player.getFamiliarManager().getFamiliar().executeSpecialMove(new FamiliarSpecial(target)); - } - break; - } - break; - default: - player.debug("Option usage [inter=" + interfaceId + ", child=" + componentId + ", target=" + target + "]."); - } - break; - case 233: // Interface On Object - y = buffer.getLEShortA(); - x = buffer.getShortA(); - itemId = buffer.getLEShortA(); - if (itemId == 65535) { - itemId = -1; - } - payload = buffer.getIntA(); - interfaceId = payload >> 16; - componentId = payload & 0xFFFF; - int objectId = buffer.getShortA(); - player.debug("Option usage [inter=" + interfaceId + ", child=" + componentId + ", target=(" + objectId + "," + x + "," + y + "), item=" + itemId + "]."); - Scenery object = RegionManager.getObject(player.getLocation().getZ(), x, y); - if (object == null) { - object = RegionManager.getObject(Location.create(x, y, 0)); - } - if (object != null) { - object = object.getChild(player); - } - if (object == null || (object.getId() != objectId && object.getWrapper().getId() != objectId) || !player.getLocation().withinDistance(object.getLocation())) { - PacketRepository.send(ClearMinimapFlag.class, new PlayerContext(player)); - break; - } - if(!SpellUtils.getBookFromInterface(interfaceId).equals("none")){ - SpellListeners.run(componentId,SpellListener.OBJECT,SpellUtils.getBookFromInterface(interfaceId),player,object); - } - switch (interfaceId) { - case 430: - MagicSpell.castSpell(player, SpellBookManager.SpellBook.LUNAR, componentId, object); - break; - case 192: - MagicSpell.castSpell(player, SpellBookManager.SpellBook.MODERN, componentId, object); - break; - case 662: - switch (componentId) { - case 137: - default: - player.getFamiliarManager().getFamiliar().executeSpecialMove(new FamiliarSpecial(object)); - break; - } - break; - } - break; - case 239: // Interface On NPC - componentId = buffer.getLEShort(); - interfaceId = buffer.getLEShort(); - buffer.getShortA(); - int index = buffer.getLEShortA(); - if (index < 1 || index > ServerConstants.MAX_NPCS) { - PacketRepository.send(ClearMinimapFlag.class, new PlayerContext(player)); - break; - } - - NPC npc = Repository.getNpcs().get(index); - if (npc == null || !player.getLocation().withinDistance(npc.getLocation())) { - PacketRepository.send(ClearMinimapFlag.class, new PlayerContext(player)); - break; - } - if (player.getAttribute("magic:delay", -1) > GameWorld.getTicks()) { - break; - } - if(!SpellUtils.getBookFromInterface(interfaceId).equals("none")){ - SpellListeners.run(componentId,SpellListener.NPC, SpellUtils.getBookFromInterface(interfaceId),player,npc); - } - switch (interfaceId) { - case 430: - MagicSpell.castSpell(player, SpellBookManager.SpellBook.LUNAR, componentId, npc); - break; - case 192: - MagicSpell.castSpell(player, SpellBookManager.SpellBook.MODERN, componentId, npc); - break; - case 193: - MagicSpell.castSpell(player, SpellBookManager.SpellBook.ANCIENT, componentId, npc); - break; - case 662: - switch (componentId) { - case 67: - case 69: - case 177: - case 121: - case 119: - default: - if (!player.getFamiliarManager().hasFamiliar()) { - player.getPacketDispatch().sendMessage("You don't have a familiar."); - } else { - player.getFamiliarManager().getFamiliar().executeSpecialMove(new FamiliarSpecial(npc)); - } - break; - } - break; - default: - player.debug("Option usage [inter=" + interfaceId + ", child=" + componentId + ", target=" + npc + "]."); - } - break; - case 253: // Interface On Item - componentId = buffer.getLEShort(); - interfaceId = buffer.getLEShort(); - int itemSlot = buffer.getLEShortA(); - itemId = buffer.getShortA(); - buffer.getShortA(); - if (itemSlot < 0 || itemSlot > 27) { - break; - } - Item item = player.getInventory().get(itemSlot); - if (item == null) { - break; - } - if(!SpellUtils.getBookFromInterface(interfaceId).equals("none")){ - SpellListeners.run(componentId,SpellListener.ITEM,SpellUtils.getBookFromInterface(interfaceId),player,item); - } - switch (interfaceId) { - case 430: - if (player.getAttribute("magic:delay", -1) > GameWorld.getTicks()) { - break; - } - MagicSpell.castSpell(player, SpellBookManager.SpellBook.LUNAR, componentId, item); - break; - case 192: - if (player.getAttribute("magic:delay", -1) > GameWorld.getTicks()) { - break; - } - MagicSpell.castSpell(player, SpellBookManager.SpellBook.MODERN, componentId, item); - break; - case 662: - if (player.getFamiliarManager().hasFamiliar()) { - player.getFamiliarManager().getFamiliar().executeSpecialMove(new FamiliarSpecial(item, interfaceId, componentId, item)); - } else { - player.getPacketDispatch().sendMessage("You don't have a follower."); - } - break; - default: - player.debug("Option usage [inter=" + interfaceId + ", child=" + componentId + ", target=" + item + "]."); - } - break; - } - } -} \ No newline at end of file diff --git a/Server/src/main/java/core/net/packet/in/ItemActionPacket.java b/Server/src/main/java/core/net/packet/in/ItemActionPacket.java deleted file mode 100644 index cd61c4dba..000000000 --- a/Server/src/main/java/core/net/packet/in/ItemActionPacket.java +++ /dev/null @@ -1,247 +0,0 @@ -package core.net.packet.in; - -import core.game.content.quest.PluginInteractionManager; -import core.game.interaction.DestinationFlag; -import core.game.interaction.MovementPulse; -import core.game.interaction.NodeUsageEvent; -import core.game.interaction.UseWithHandler; -import core.game.node.entity.npc.NPC; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; -import core.game.node.scenery.Scenery; -import core.game.world.map.RegionManager; -import core.net.packet.IncomingPacket; -import core.net.packet.IoBuffer; -import core.net.packet.PacketRepository; -import core.net.packet.context.PlayerContext; -import core.net.packet.out.ClearMinimapFlag; -import org.rs09.consts.Items; -import rs09.game.interaction.IntType; -import rs09.game.interaction.InteractionListeners; -import rs09.game.node.entity.skill.farming.CompostBins; -import rs09.game.node.entity.skill.farming.FarmingPatch; -import rs09.game.node.entity.skill.farming.UseWithBinHandler; -import rs09.game.node.entity.skill.farming.UseWithPatchHandler; -import rs09.game.system.SystemLogger; -import rs09.game.system.command.rottenpotato.RottenPotatoUseWithHandler; -import rs09.game.world.repository.Repository; - -/** - * The incoming item reward packet. - * @author Emperor - */ -public class ItemActionPacket implements IncomingPacket { - - @SuppressWarnings("unused") - @Override - public void decode(Player player, int opcode, IoBuffer buffer) { - if (player.getLocks().isInteractionLocked()) { - return; - } - int usedWithItemId = -1; - int usedWithSlot = -1; - int interfaceHash1 = -1; - int interfaceId1 = -1; - int childId1 = -1; - int usedItemId = -1; - int usedSlot = -1; - int interfaceHash2 = -1; - int interfaceId2 = -1; - int childId2 = -1; - NodeUsageEvent event = null; - Item used = null; - player.debug(String.format("ItemActionPacket.decode(%d)", opcode)); - switch (buffer.opcode()) { - case 115: // Item on NPC - int interfaceId = buffer.getIntA() >> 16; - int slotId = buffer.getLEShort(); - int npcIndex = buffer.getLEShort(); - int itemId = buffer.getLEShortA(); - NPC npc = Repository.getNpcs().get(npcIndex); - Item item = player.getInventory().get(slotId); - if (item == null || item.getId() != itemId) { - return; - } - if(itemId == Items.ROTTEN_POTATO_5733){ - RottenPotatoUseWithHandler.handle(npc,player); - return; - } - event = new NodeUsageEvent(player, interfaceId, item, npc); - if(PluginInteractionManager.handle(player,event)){ - return; - } - if(InteractionListeners.run(item,npc,IntType.NPC,player)){ - return; - } - if(player.getZoneMonitor().useWith(used,npc)){ - return; - } - event = new NodeUsageEvent(player, interfaceId, item, npc); - try { - UseWithHandler.run(event); - } catch (Exception e){ - e.printStackTrace(); - } - return; - case 248: // Item on Player - int playerIndex = buffer.getLEShortA(); - itemId = buffer.getShort(); - slotId = buffer.getShort(); - interfaceId = buffer.getInt() >> 16; - Player target = Repository.getPlayers().get(playerIndex); - item = player.getInventory().get(slotId); - if (target == null || item == null || item.getId() != itemId) { - return; - } - if(itemId == Items.ROTTEN_POTATO_5733){ - RottenPotatoUseWithHandler.handle(target,player); - return; - } - event = new NodeUsageEvent(player, interfaceId, item, target); - if(PluginInteractionManager.handle(player,event)){ - return; - } - if(InteractionListeners.run(item, target, IntType.PLAYER, player)){ - return; - } - if(player.getZoneMonitor().useWith(used,player)){ - return; - } - event = new NodeUsageEvent(player, interfaceId, item, target); - try { - UseWithHandler.run(event); - } catch (Exception e){ - e.printStackTrace(); - } - return; - case 27://Item on Item - usedSlot = buffer.getShort(); - interfaceHash1 = buffer.getLEInt(); - usedWithSlot = buffer.getLEShort(); - interfaceHash2 = buffer.getLEInt(); - usedItemId = buffer.getLEShortA(); - usedWithItemId = buffer.getLEShortA(); - interfaceId1 = interfaceHash1 >> 16; - childId1 = interfaceHash1 & 0xFFFF; - interfaceId2 = interfaceHash2 >> 16; - childId2 = interfaceHash2 & 0xFFFF; - used = player.getInventory().get(usedSlot); - Item with = player.getInventory().get(usedWithSlot); - if (used == null || with == null || used.getId() != usedItemId || with.getId() != usedWithItemId) { - return; - } - if(used.getId() == Items.ROTTEN_POTATO_5733){ - RottenPotatoUseWithHandler.handle(with,player); - return; - } - if(with.getId() == Items.ROTTEN_POTATO_5733){ - RottenPotatoUseWithHandler.handle(used,player); - return; - } - if(InteractionListeners.run(used,with,IntType.ITEM,player)){ - return; - } - if(player.getZoneMonitor().useWith(used,with)){ - return; - } - if (usedItemId < usedWithItemId) { - item = used; - used = with; - with = item; - } - player.debug("USED: " + used + " WITH: " + with); - event = new NodeUsageEvent(player, interfaceId1, used, with); - if(PluginInteractionManager.handle(player,event)){ - return; - } - event = new NodeUsageEvent(player, interfaceId1, used, with); - try { - UseWithHandler.run(event); - } catch (Exception e){ - e.printStackTrace(); - } - break; - case 134://Item on Object - int x = buffer.getShortA(); - int id = buffer.getShort(); - int y = buffer.getLEShort(); - int slot = buffer.getShort(); - buffer.getLEShort(); - buffer.getShort(); - int objectId = buffer.getShortA(); - int z = player.getLocation().getZ(); - Scenery object = RegionManager.getObject(z, x, y); - //player.debug(String.format("opcode 134: oid %d iid %d", objectId, id)); - //player.debug(String.format("opcode 134: %d %d", object != null ? object.getId() : -1, object != null && object.getChild(player) != null ? object.getChild(player).getId() : -1)); - Scenery child = object != null ? object.getChild(player) : null; - if(object == null || (object.getId() != objectId && (child == null || child.getId() != objectId))) { - PacketRepository.send(ClearMinimapFlag.class, new PlayerContext(player)); - return; - } - used = player.getInventory().get(slot); - if (used == null || used.getId() != id) { - return; - } - if(used.getId() == Items.ROTTEN_POTATO_5733){ - RottenPotatoUseWithHandler.handle(object,player); - return; - } - if(InteractionListeners.run(used,child,IntType.SCENERY,player)){ - return; - } - if(InteractionListeners.run(used,object,IntType.SCENERY,player)){ - return; - } - if(player.getZoneMonitor().useWith(used,object)){ - return; - } - event = new NodeUsageEvent(player, 0, used, child != null ? child : object); - - /** - * Farming-specific handler for item -> patch - */ - if(FarmingPatch.forObject(object) != null && UseWithPatchHandler.allowedNodes.contains(used.getId())){ - NodeUsageEvent finalEvent = event; - player.getPulseManager().run(new MovementPulse(player,object, DestinationFlag.OBJECT) { - @Override - public boolean pulse() { - player.faceLocation(destination.getLocation()); - UseWithPatchHandler.handle(finalEvent); - return true; - } - }); - return; - } - - /** - * Farming-specific handler for item -> compost bin - */ - if(CompostBins.forObject(object) != null && UseWithBinHandler.allowedNodes.contains(used.getId())){ - NodeUsageEvent finalEvent = event; - player.getPulseManager().run(new MovementPulse(player,object,DestinationFlag.OBJECT){ - @Override - public boolean pulse() { - player.faceLocation(destination.getLocation()); - UseWithBinHandler.handle(finalEvent); - return true; - } - }); - return; - } - - if(PluginInteractionManager.handle(player,event)){ - return; - } - - try { - UseWithHandler.run(event); - } catch (Exception e){ - e.printStackTrace(); - } - return; - default: - SystemLogger.logErr(this.getClass(), "Error in Item Action Packet! Unhandled opcode = " + buffer.opcode()); - return; - } - } -} diff --git a/Server/src/main/java/core/net/packet/in/MapClosedPacket.java b/Server/src/main/java/core/net/packet/in/MapClosedPacket.java deleted file mode 100644 index e98f30148..000000000 --- a/Server/src/main/java/core/net/packet/in/MapClosedPacket.java +++ /dev/null @@ -1,12 +0,0 @@ -package core.net.packet.in; - -import core.game.node.entity.player.Player; -import core.net.packet.IncomingPacket; -import core.net.packet.IoBuffer; - -public class MapClosedPacket implements IncomingPacket { - @Override - public void decode(Player player, int opcode, IoBuffer buffer) { - //This buffer contains an int that is actually a bunch of booleans bitshifted into specific positions. No clue what the use might be. - } -} diff --git a/Server/src/main/java/core/net/packet/in/MouseClickPacket.java b/Server/src/main/java/core/net/packet/in/MouseClickPacket.java deleted file mode 100644 index 23cecfe4d..000000000 --- a/Server/src/main/java/core/net/packet/in/MouseClickPacket.java +++ /dev/null @@ -1,27 +0,0 @@ -package core.net.packet.in; - -import core.game.node.entity.player.Player; -import core.net.packet.IncomingPacket; -import core.net.packet.IoBuffer; - -/** - * Handles incoming mouse click packets. - * @author Emperor - */ -public final class MouseClickPacket implements IncomingPacket { - - @Override - public void decode(Player player, int opcode, IoBuffer buffer) { - int data = buffer.getLEShortA(); - int positioning = buffer.getIntB(); - boolean rightClick = ((data >> 15) & 0x1) == 1; - int delay = data & 0x7FF; - int x = positioning >> 16; - int y = positioning & 0xFFFF; - if (player == null) { - return; - } - player.getMonitor().handleMouseClick(x, y, delay, rightClick); - } - -} \ No newline at end of file diff --git a/Server/src/main/java/core/net/packet/in/MusicPacketHandler.java b/Server/src/main/java/core/net/packet/in/MusicPacketHandler.java deleted file mode 100644 index 8dbc4506f..000000000 --- a/Server/src/main/java/core/net/packet/in/MusicPacketHandler.java +++ /dev/null @@ -1,23 +0,0 @@ -package core.net.packet.in; - -import core.game.node.entity.player.Player; -import core.net.packet.IncomingPacket; -import core.net.packet.IoBuffer; - -/** - * Handles music-related incoming packets. - * @author Ceikry - */ -public final class MusicPacketHandler implements IncomingPacket { - - @Override - public void decode(Player player, int opcode, IoBuffer buffer) { - int musicId = buffer.getLEShortA(); - if (player.getMusicPlayer().isLooping()) { - player.getMusicPlayer().replay(); - return; - } - player.getMusicPlayer().setPlaying(false); - } - -} \ No newline at end of file diff --git a/Server/src/main/java/core/net/packet/in/PingPacketHandler.java b/Server/src/main/java/core/net/packet/in/PingPacketHandler.java deleted file mode 100644 index 38a4b6eaf..000000000 --- a/Server/src/main/java/core/net/packet/in/PingPacketHandler.java +++ /dev/null @@ -1,18 +0,0 @@ -package core.net.packet.in; - -import core.game.node.entity.player.Player; -import core.net.packet.IncomingPacket; -import core.net.packet.IoBuffer; - -/** - * Handles an incoming ping packet. - * @author Emperor - */ -public final class PingPacketHandler implements IncomingPacket { - - @Override - public void decode(Player player, int opcode, IoBuffer buffer) { - - } - -} \ No newline at end of file diff --git a/Server/src/main/java/core/net/packet/in/RegionChangePacket.java b/Server/src/main/java/core/net/packet/in/RegionChangePacket.java deleted file mode 100644 index 4db834ec7..000000000 --- a/Server/src/main/java/core/net/packet/in/RegionChangePacket.java +++ /dev/null @@ -1,19 +0,0 @@ -package core.net.packet.in; - -import core.game.node.entity.player.Player; -import core.net.packet.IncomingPacket; -import core.net.packet.IoBuffer; - -/** - * Packet received when a player's region has changed. - * @author Emperor - * @author 'Vexia - */ -public class RegionChangePacket implements IncomingPacket { - - @Override - public void decode(Player player, int opcode, IoBuffer buffer) { - //TODO: no data is sen't so not sure what to do. - } - -} diff --git a/Server/src/main/java/core/net/packet/in/ReportAbusePacket.java b/Server/src/main/java/core/net/packet/in/ReportAbusePacket.java deleted file mode 100644 index b13f9544b..000000000 --- a/Server/src/main/java/core/net/packet/in/ReportAbusePacket.java +++ /dev/null @@ -1,36 +0,0 @@ -package core.net.packet.in; - -import rs09.ServerConstants; -import core.game.content.global.report.AbuseReport; -import core.game.content.global.report.Rule; -import core.game.node.entity.player.Player; -import core.net.packet.IncomingPacket; -import core.net.packet.IoBuffer; -import core.tools.StringUtils; -import rs09.game.world.GameWorld; - -import java.io.File; - -/** - * Represents the incoming packet to handle a report against a player. - * @author Vexia - */ -public class ReportAbusePacket implements IncomingPacket { - - @Override - public void decode(Player player, int opcode, IoBuffer buffer) { - String target = StringUtils.longToString(buffer.getLong()); - Rule rule = Rule.forId(buffer.get()); - boolean mute = buffer.get() == 1; - if (!GameWorld.getAccountStorage().checkUsernameTaken(target.toLowerCase())) { - player.getPacketDispatch().sendMessage("Invalid player name."); - return; - } - if (target.equalsIgnoreCase(player.getUsername())) { - player.getPacketDispatch().sendMessage("You can't report yourself!"); - return; - } - AbuseReport abuse = new AbuseReport(player.getName(), target, rule); - abuse.construct(player, mute); - } -} diff --git a/Server/src/main/java/core/net/packet/in/SlotSwitchPacket.java b/Server/src/main/java/core/net/packet/in/SlotSwitchPacket.java deleted file mode 100644 index 11f69cf07..000000000 --- a/Server/src/main/java/core/net/packet/in/SlotSwitchPacket.java +++ /dev/null @@ -1,119 +0,0 @@ -package core.net.packet.in; - -import core.game.container.Container; -import core.game.container.impl.BankContainer; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; -import core.net.packet.IncomingPacket; -import core.net.packet.IoBuffer; - -import static api.ContentAPIKt.getAttribute; - -/** - * Represents the packet to handle an item slot switch. - * @author 'Vexia - */ -public class SlotSwitchPacket implements IncomingPacket { - - @Override - public void decode(Player player, int opcode, IoBuffer buffer) { - if (buffer.opcode() == 79) { - int interfaceHash = buffer.getIntB(); - int secondSlot = buffer.getLEShort(); - int interfaceHash2 = buffer.getInt(); - int slot = buffer.getLEShort(); - int interfaceId = interfaceHash >> 16; - int childId = interfaceHash & 0xFF; - int withInterfaceId = interfaceHash2 >> 16; - int withChildId = interfaceHash2 & 0xFF; - Container container = player.getInventory(); - switch (interfaceId) { - case 762: - if (withInterfaceId == 762) { - if (withChildId == 73) { - container = player.getBank(); - switchItem(slot, secondSlot, container, player.getBank().isInsertItems(), player); - player.debug("Switching item [" + slot + ", " + interfaceId + ", " + childId + "] with [" + secondSlot + ", " + withInterfaceId + ", " + withChildId + "]!"); - } - else { - int tabIndex = BankContainer.getArrayIndex(withChildId); - if (tabIndex > -1) { - secondSlot = tabIndex == 10 ? player.getBank().freeSlot() : player.getBank().getTabStartSlot()[tabIndex] + player.getBank().getItemsInTab(tabIndex); - - Item inSlot = player.getBank().get(slot); - - if (secondSlot == -1 && player.getBank().remove(inSlot)) { - player.getBank().add(inSlot); - return; - } - - childId = player.getBank().getTabByItemSlot(slot); - if (secondSlot > slot) { - player.getBank().insert(slot, secondSlot - 1); - } else if (slot > secondSlot) { - player.getBank().insert(slot, secondSlot); - } - player.getBank().increaseTabStartSlots(tabIndex); - player.getBank().decreaseTabStartSlots(childId); - player.getBank().setTabConfigurations(); - return; - } - } - break; - } - break; - default: - player.debug("Switching item slot [from=" + slot + ", to=" + secondSlot + ", child=" + childId + ", to child=" + withChildId + "]."); - switchItem(slot, secondSlot, container, false, player); - break; - } - return; - } - int slot = buffer.getShort(); - int interfaceHash = buffer.getLEInt(); - int secondSlot = buffer.getShortA(); - boolean insert = buffer.get() == 1; - int interfaceId = interfaceHash >> 16; - Container container = interfaceId == 762 ? player.getBank() : (interfaceId == 15 || interfaceId == 149 || interfaceId == 763) ? player.getInventory() : null; - switchItem(slot, secondSlot, container, insert, player); - } - - /** - * Switches an item. - * @param slot The slot. - * @param secondSlot The slot to switch slots with. - * @param container The container. - * @param insert If inserting should happen. - */ - public void switchItem(int slot, int secondSlot, Container container, boolean insert, Player player) { - if (container == null || slot < 0 || slot >= container.toArray().length || secondSlot < 0 || secondSlot >= container.toArray().length) { - return; - } - - final Item item = container.get(slot); - final Item second = container.get(secondSlot); - if (player.getInterfaceManager().hasChatbox() && !getAttribute(player, "close_c_", false)) { - player.getInterfaceManager().closeChatbox(); - switchItem(secondSlot,slot,container,insert,player); - container.refresh(); - return; - } - if (item == null) { - return; - } - if (!insert) { - container.replace(second, slot, false); - container.replace(item, secondSlot, false); - if (item != null) { - item.setIndex(secondSlot); - } - if (second != null) { - second.setIndex(slot); - } - } else { - container.insert(slot, secondSlot, false); - } - container.refresh(); - } - -} diff --git a/Server/src/main/java/core/net/packet/in/UpdateInterfaceCounter.java b/Server/src/main/java/core/net/packet/in/UpdateInterfaceCounter.java deleted file mode 100644 index 3e10fa8bd..000000000 --- a/Server/src/main/java/core/net/packet/in/UpdateInterfaceCounter.java +++ /dev/null @@ -1,20 +0,0 @@ -package core.net.packet.in; - -import core.game.node.entity.player.Player; -import core.net.packet.IncomingPacket; -import core.net.packet.IoBuffer; - -/** - * Handles the update interface packet counter packet. - * @author Emperor - * - */ -public final class UpdateInterfaceCounter implements IncomingPacket { - - @Override - public void decode(Player player, int opcode, IoBuffer buffer) { - int count = buffer.getShort() - player.getInterfaceManager().getPacketCount(0); - player.getInterfaceManager().getPacketCount(count); - } - -} \ No newline at end of file diff --git a/Server/src/main/java/core/net/packet/in/WalkPacket.java b/Server/src/main/java/core/net/packet/in/WalkPacket.java deleted file mode 100644 index 9adf6d834..000000000 --- a/Server/src/main/java/core/net/packet/in/WalkPacket.java +++ /dev/null @@ -1,102 +0,0 @@ -package core.net.packet.in; - -import core.game.interaction.MovementPulse; -import core.game.node.entity.Entity; -import core.game.node.entity.impl.PulseType; -import core.game.node.entity.player.Player; -import rs09.game.ai.AIPlayer; -import core.game.world.map.Location; -import core.net.packet.IncomingPacket; -import core.net.packet.IoBuffer; -import core.net.packet.PacketRepository; -import core.net.packet.context.PlayerContext; -import core.net.packet.out.ClearMinimapFlag; - -/** - * Handles an incoming walk packet. - * @author Emperor - */ -public final class WalkPacket implements IncomingPacket { - - @Override - public void decode(Player player, int opcode, IoBuffer buffer) { - player = getPlayer(player); - if (player == null) { - return; - } - if (player.getLocks().isMovementLocked() || !player.getInterfaceManager().close() || !player.getInterfaceManager().closeSingleTab() || !player.getDialogueInterpreter().close()) { - PacketRepository.send(ClearMinimapFlag.class, new PlayerContext(player)); - player.debug("[WalkPacket] did not handle - [locked=" + player.getLocks().isMovementLocked() + "]!"); - return; - } - player.getProperties().setSpell(null); - player.getInterfaceManager().close(); - player.getInterfaceManager().closeChatbox(); - player.getDialogueInterpreter().getActions().clear(); - boolean running = buffer.getA() == 1; - int x = buffer.getShort(); - int y = buffer.getShortA(); - int steps = (buffer.toByteBuffer().remaining() - (buffer.opcode() == 39 ? 14 : 0)) >> 1; - for (int i = 0; i < steps; i++) { - int offsetX = buffer.getA(); - int offsetY = buffer.getS(); - if (i == steps - 1) { - x += offsetX; - y += offsetY; - } - } - if (opcode == 77) { - player.getWalkingQueue().setRunning(running); - return; // Action walking. - } - player.face((Entity) null); - player.faceLocation((Location) null); - //player.getWalkingQueue().reset(running); - Player finalPlayer = player; - player.getPulseManager().run(new MovementPulse(finalPlayer, Location.create(x, y, player.getLocation().getZ()), running) { - @Override - public boolean pulse() { - if(running){ - finalPlayer.getWalkingQueue().setRunning(false); - } - return true; - } - }, PulseType.STANDARD); - if (opcode == 39) { - buffer.get(); // The x-coordinate of where we clicked on the - // minimap. - buffer.get(); // The y-coordinate of where we clicked on the - // minimap. - buffer.getShort(); // The rotation of the minimap. - buffer.get(); // Always 57. - buffer.get(); - buffer.get(); - buffer.get(); // Always 89 - buffer.getShort(); - buffer.getShort(); - buffer.get(); - buffer.get(); // Always 63 - } - } - - /** - * Gets the player instance (used for AIP controlling). - * @param player The player. - * @return The player instance, or the AIP when the player is controlling an - * AIP. - */ - private static Player getPlayer(Player player) { - if (player == null) { - return null; - } - AIPlayer aip = player.getAttribute("aip_select"); - if (aip != null && aip.getLocation().withinDistance(player.getLocation())) { - if (!player.getAttribute("aip_perm_select", true)) { - player.removeAttribute("aip_select"); - } - return aip; - } - return player; - } - -} \ No newline at end of file diff --git a/Server/src/main/java/rs09/game/ai/AIPlayer.java b/Server/src/main/java/rs09/game/ai/AIPlayer.java index 4ac644f8e..374c005bc 100644 --- a/Server/src/main/java/rs09/game/ai/AIPlayer.java +++ b/Server/src/main/java/rs09/game/ai/AIPlayer.java @@ -21,7 +21,6 @@ import core.game.world.map.path.Pathfinder; import core.game.world.map.zone.impl.WildernessZone; import rs09.game.world.repository.Repository; import core.net.packet.context.MessageContext; -import core.net.packet.in.InteractionPacket; import core.plugin.Plugin; import core.tools.RandomFunction; import core.tools.StringUtils; @@ -578,6 +577,6 @@ public class AIPlayer extends Player { public void interact(Node n) { - InteractionPacket.handleObjectInteraction(this, 0, n.getLocation(), n.getId()); + // InteractionPacket.handleObjectInteraction(this, 0, n.getLocation(), n.getId()); } } \ No newline at end of file diff --git a/Server/src/main/kotlin/rs09/game/content/zone/morytania/MorytaniaArea.kt b/Server/src/main/kotlin/rs09/game/content/zone/morytania/MorytaniaArea.kt index 98178f9e5..fc81dbc96 100644 --- a/Server/src/main/kotlin/rs09/game/content/zone/morytania/MorytaniaArea.kt +++ b/Server/src/main/kotlin/rs09/game/content/zone/morytania/MorytaniaArea.kt @@ -10,6 +10,7 @@ import core.game.world.map.Location import core.game.world.map.zone.ZoneBorders import core.game.world.update.flag.context.Animation import org.rs09.consts.NPCs +import rs09.game.ai.AIPlayer import rs09.game.content.dialogue.DialogueFile import rs09.game.world.GameWorld @@ -19,7 +20,7 @@ class MorytaniaArea : MapArea { } override fun areaEnter(entity: Entity) { - if (entity is Player && !isQuestComplete(entity, "Priest in Peril")) { + if (entity is Player && entity !is AIPlayer && !isQuestComplete(entity, "Priest in Peril")) { kickThemOut(entity) } } diff --git a/Server/src/main/kotlin/rs09/game/interaction/InteractionListeners.kt b/Server/src/main/kotlin/rs09/game/interaction/InteractionListeners.kt index b0b3d1d73..46497cbbf 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/InteractionListeners.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/InteractionListeners.kt @@ -178,6 +178,7 @@ object InteractionListeners { val flag = when(type){ IntType.NPC, IntType.PLAYER -> DestinationFlag.ENTITY IntType.SCENERY -> DestinationFlag.OBJECT + IntType.GROUNDITEM -> DestinationFlag.ITEM else -> DestinationFlag.OBJECT } diff --git a/Server/src/main/kotlin/rs09/game/interaction/region/dungeons/edgeville/PosterListener.kt b/Server/src/main/kotlin/rs09/game/interaction/region/dungeons/edgeville/PosterListener.kt new file mode 100644 index 000000000..8dcd4495d --- /dev/null +++ b/Server/src/main/kotlin/rs09/game/interaction/region/dungeons/edgeville/PosterListener.kt @@ -0,0 +1,18 @@ +package rs09.game.interaction.region.dungeons.edgeville + +import api.sendDialogue +import api.teleport +import core.game.world.map.Location +import org.rs09.consts.Scenery +import rs09.game.interaction.IntType +import rs09.game.interaction.InteractionListener + +class PosterListener : InteractionListener { + override fun defineListeners() { + on(Scenery.POSTER_29586, IntType.SCENERY, "pull-back") {player, _ -> + sendDialogue(player, "There appears to be a tunnel behind this poster.") + teleport(player, Location.create(3140, 4230, 2)) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/kotlin/rs09/game/node/entity/skill/farming/CompostBin.kt b/Server/src/main/kotlin/rs09/game/node/entity/skill/farming/CompostBin.kt index 4f7636ed3..1a416e0aa 100644 --- a/Server/src/main/kotlin/rs09/game/node/entity/skill/farming/CompostBin.kt +++ b/Server/src/main/kotlin/rs09/game/node/entity/skill/farming/CompostBin.kt @@ -131,7 +131,6 @@ class CompostBin(val player: Player, val bin: CompostBins) { } if (isClosed) player.varpManager.get(bin.varpIndex).setVarbit(bin.varpOffest + 6, 1) } - SystemLogger.logAlert(this::class.java, "Sending " + player.varpManager.get(bin.varpIndex).getValue()) player.varpManager.get(bin.varpIndex).send(player) } diff --git a/Server/src/main/kotlin/rs09/game/node/entity/skill/farming/UseWithBinHandler.kt b/Server/src/main/kotlin/rs09/game/node/entity/skill/farming/UseWithBinHandler.kt index c45cdc3b5..acdf67ba0 100644 --- a/Server/src/main/kotlin/rs09/game/node/entity/skill/farming/UseWithBinHandler.kt +++ b/Server/src/main/kotlin/rs09/game/node/entity/skill/farming/UseWithBinHandler.kt @@ -1,20 +1,85 @@ package rs09.game.node.entity.skill.farming +import api.toIntArray import core.game.interaction.NodeUsageEvent import core.game.node.item.Item import core.game.system.task.Pulse import core.game.world.update.flag.context.Animation import org.rs09.consts.Items +import rs09.game.interaction.IntType +import rs09.game.interaction.InteractionListener -object UseWithBinHandler { +class UseWithBinHandler : InteractionListener { @JvmField val allowedNodes = ArrayList(100) val fillAnim = Animation(832) val compostPotionAnimation = Animation(2259) val scoopAnimation = Animation(8905) - init { + val bins = 7836..7840 + + override fun defineListeners() { loadNodes() + onUseWith(IntType.SCENERY, allowedNodes.toIntArray(), *bins.toIntArray()) {player, usedNode, with -> + val cBin = CompostBins.forObject(with.asScenery()) ?: return@onUseWith true + val bin = cBin.getBinForPlayer(player) + val used = usedNode.id + + + when(used){ + Items.COMPOST_POTION1_6476,Items.COMPOST_POTION2_6474, Items.COMPOST_POTION3_6472,Items.COMPOST_POTION4_6470 -> { + if(!bin.isSuperCompost && bin.isFinished && !bin.isClosed){ + player.animator.animate(compostPotionAnimation) + player.pulseManager.run(object : Pulse(compostPotionAnimation.duration){ + override fun pulse(): Boolean { + if(player.inventory.remove(usedNode.asItem())) { + bin.convert() + player.inventory.add(Item(used.getNext())) + } + return true + } + }) + } else { + player.dialogueInterpreter.sendDialogue("You can only do this with an open bin of","finished regular compost.") + } + } + + Items.BUCKET_1925 -> { + if(bin.isFinished && !bin.isClosed){ + player.pulseManager.run(object : Pulse(scoopAnimation.duration){ + override fun pulse(): Boolean { + if(!player.inventory.containsItem(usedNode.asItem())) return true + player.animator.animate(scoopAnimation) + val item = bin.takeItem() + if(item != null && player.inventory.remove(usedNode.asItem())){ + player.inventory.add(item) + } + return item == null || !player.inventory.containsItem(usedNode.asItem()) + } + }) + } else { + player.dialogueInterpreter.sendDialogue("You can only scoop an opened bin of finished compost.") + } + } + + else -> + if(bin.isFull()){ + player.sendMessage("This compost bin is already full.") + return@onUseWith true + } else { + player.pulseManager.run(object : Pulse(fillAnim.duration){ + override fun pulse(): Boolean { + player.animator.animate(fillAnim) + if(player.inventory.remove(usedNode.asItem())){ + bin.addItem(usedNode.asItem()) + } + return bin.isFull() || player.inventory.getAmount(usedNode.asItem()) == 0 + } + }) + } + } + return@onUseWith true + } } fun loadNodes() { @@ -32,70 +97,6 @@ object UseWithBinHandler { allowedNodes.add(Items.BUCKET_1925) } - @JvmStatic - fun handle(event: NodeUsageEvent?): Boolean { - event ?: return false - val player = event.player - val used = event.used.id - val cBin = CompostBins.forObject(event.usedWith.asScenery()) ?: return false - val bin = cBin.getBinForPlayer(player) - - when(used){ - Items.COMPOST_POTION1_6476,Items.COMPOST_POTION2_6474, Items.COMPOST_POTION3_6472,Items.COMPOST_POTION4_6470 -> { - if(!bin.isSuperCompost && bin.isFinished && !bin.isClosed){ - player.animator.animate(compostPotionAnimation) - player.pulseManager.run(object : Pulse(compostPotionAnimation.duration){ - override fun pulse(): Boolean { - if(player.inventory.remove(event.usedItem)) { - bin.convert() - player.inventory.add(Item(used.getNext())) - } - return true - } - }) - } else { - player.dialogueInterpreter.sendDialogue("You can only do this with an open bin of","finished regular compost.") - } - } - - Items.BUCKET_1925 -> { - if(bin.isFinished && !bin.isClosed){ - player.pulseManager.run(object : Pulse(scoopAnimation.duration){ - override fun pulse(): Boolean { - if(!player.inventory.containsItem(event.usedItem)) return true - player.animator.animate(scoopAnimation) - val item = bin.takeItem() - if(item != null && player.inventory.remove(event.usedItem)){ - player.inventory.add(item) - } - return item == null || !player.inventory.containsItem(event.usedItem) - } - }) - } else { - player.dialogueInterpreter.sendDialogue("You can only scoop an opened bin of finished compost.") - } - } - - else -> - if(bin.isFull()){ - player.sendMessage("This compost bin is already full.") - return true - } else { - player.pulseManager.run(object : Pulse(fillAnim.duration){ - override fun pulse(): Boolean { - player.animator.animate(fillAnim) - if(player.inventory.remove(event.usedItem)){ - bin.addItem(event.usedItem) - } - return bin.isFull() || player.inventory.getAmount(event.usedItem) == 0 - } - }) - } - } - - return true - } - private fun Int.getNext(): Int{ if(this != 6476) return this + 2 else return Items.VIAL_229 diff --git a/Server/src/main/kotlin/rs09/game/node/entity/skill/farming/UseWithPatchHandler.kt b/Server/src/main/kotlin/rs09/game/node/entity/skill/farming/UseWithPatchHandler.kt index d1a7d5b8f..237bd39f4 100644 --- a/Server/src/main/kotlin/rs09/game/node/entity/skill/farming/UseWithPatchHandler.kt +++ b/Server/src/main/kotlin/rs09/game/node/entity/skill/farming/UseWithPatchHandler.kt @@ -8,9 +8,12 @@ import core.game.node.item.Item import core.game.system.task.Pulse import core.game.world.update.flag.context.Animation import org.rs09.consts.Items +import org.rs09.consts.Scenery +import rs09.game.interaction.IntType +import rs09.game.interaction.InteractionListener import rs09.game.node.entity.skill.farming.CropHarvester -object UseWithPatchHandler{ +class UseWithPatchHandler : InteractionListener { val RAKE = Items.RAKE_5341 val SEED_DIBBER = Items.SEED_DIBBER_5343 val SPADE = Items.SPADE_952 @@ -23,221 +26,232 @@ object UseWithPatchHandler{ @JvmField val allowedNodes = ArrayList() + val patches = ArrayList() - init { + override fun defineListeners() { loadNodes() + onUseWith(IntType.SCENERY, allowedNodes.toIntArray(), *patches.toIntArray()) {player, used, with -> + val patch = FarmingPatch.forObject(with.asScenery()) ?: return@onUseWith true + val usedItem = used.asItem() + + player.faceLocation(with.location) + when(usedItem.id){ + RAKE -> PatchRaker.rake(player,patch) + SEED_DIBBER -> player.sendMessage("I should plant a seed, not the seed dibber.") + SPADE -> player.dialogueInterpreter.open(67984003,patch.getPatchFor(player)) //DigUpPatchDialogue.kt + SECATEURS -> { + val p = patch.getPatchFor(player) + if(patch.type == PatchType.TREE) { + if(p.isDiseased && !p.isDead) { + player.pulseManager.run(object: Pulse(){ + override fun pulse(): Boolean { + player.animator.animate(secateursAnim) + p.cureDisease() + return true + } + }) + } else if(p.plantable == Plantable.WILLOW_SAPLING && p.harvestAmt > 0) { + val pulse = CropHarvester.harvestPulse(player, with, Items.WILLOW_BRANCH_5933) ?: return@onUseWith false + player.pulseManager.run(pulse) + } + } + } + TROWEL, Items.PLANT_POT_5350 -> { + if(!player.inventory.containsAtLeastOneItem(TROWEL)) { + player.sendMessage("You need a trowel to fill plant pots with dirt.") + return@onUseWith true + } + val p = patch.getPatchFor(player) + if(!p.isWeedy()){ + player.sendMessage("This patch has something growing in it.") + return@onUseWith true + } else if (p.currentGrowthStage != 3){ + player.sendMessage("I should clear this of weeds before trying to take some dirt.") + return@onUseWith true + } + + val potAmount = player.inventory.getAmount(Items.PLANT_POT_5350) + + if(potAmount == 0){ + player.sendMessage("You have no plant pots to fill.") + return@onUseWith true + } + + val anim = Animation(2272) + + player.pulseManager.run(object : Pulse(anim.duration){ + override fun pulse(): Boolean { + if(player.inventory.remove(Item(Items.PLANT_POT_5350))){ + player.animator.animate(anim) + player.inventory.add(Item(Items.PLANT_POT_5354)) + } else return true + return false + } + }) + } + + Items.PLANT_CURE_6036 -> { + val p = patch.getPatchFor(player) + if(p.isDiseased && !p.isDead){ + player.pulseManager.run(object: Pulse(){ + override fun pulse(): Boolean { + player.animator.animate(plantCureAnim) + player.audioManager.send(2438) + if(player.inventory.remove(usedItem)){ + player.inventory.add(Item(Items.VIAL_229)) + p.cureDisease() + } + return true + } + }) + } else { + player.sendMessage("I have no reason to do this right now.") + } + } + + Items.WATERING_CAN1_5333,Items.WATERING_CAN2_5334,Items.WATERING_CAN3_5335,Items.WATERING_CAN4_5336,Items.WATERING_CAN5_5337,Items.WATERING_CAN6_5338,Items.WATERING_CAN7_5339,Items.WATERING_CAN8_5340 -> { + val p = patch.getPatchFor(player) + val t = p.patch.type + if(!p.isWatered && (t == PatchType.ALLOTMENT || t == PatchType.FLOWER || t == PatchType.HOPS) && !p.isGrown()){ + player.pulseManager.run(object : Pulse(){ + override fun pulse(): Boolean { + if(p.isWeedy()){ + player.sendMessage("You should grow something first.") + return true + } + player.animator.animate(wateringCanAnim) + player.audioManager.send(2446) + if(player.inventory.remove(usedItem)){ + player.inventory.add(Item(usedItem.id.getNext())) + p.water() + } + return true + } + }) + } + } + + Items.SUPERCOMPOST_6034, Items.COMPOST_6032 -> { + val p = patch.getPatchFor(player) + if(p.compost == CompostType.NONE) { + player.animator.animate(pourBucketAnim) + player.audioManager.send(2427) + player.pulseManager.run(object : Pulse(){ + override fun pulse(): Boolean { + if(player.inventory.remove(usedItem,false)){ + p.compost = if(usedItem.id == Items.SUPERCOMPOST_6034) CompostType.SUPER else CompostType.NORMAL + if(p.compost == CompostType.SUPER) rewardXP(player, Skills.FARMING, 26.0) else rewardXP(player, Skills.FARMING, 18.5) + if(p.plantable != null && p.plantable?.applicablePatch != PatchType.FLOWER) { + p.harvestAmt += if(p.compost == CompostType.NORMAL) 1 else if(p.compost == CompostType.SUPER) 2 else 0 + } + p.cropLives += if(p.compost == CompostType.SUPER) 2 else 1 + player.inventory.add(Item(Items.BUCKET_1925)) + } + return true + } + }) + } else { + player.sendMessage("This patch has already been treated with compost.") + } + } + + else -> { + val plantable = Plantable.forItemID(usedItem.id) ?: return@onUseWith false + + if(plantable.applicablePatch != patch.type){ + player.sendMessage("You can't plant that seed in this patch.") + return@onUseWith true + } + + if(plantable.requiredLevel > player.skills.getLevel(Skills.FARMING)){ + player.sendMessage("You need a Farming level of ${plantable.requiredLevel} to plant this.") + return@onUseWith true + } + + val p = patch.getPatchFor(player) + if(p.getCurrentState() < 3 && p.isWeedy()){ + player.sendMessage("You must weed your patch before you can plant a seed in it.") + return@onUseWith true + } else if(p.getCurrentState() > 3){ + player.sendMessage("There is already something growing in this patch.") + return@onUseWith true + } + + val plantItem = + if(patch.type == PatchType.ALLOTMENT) Item(plantable.itemID,3) else if(patch.type == PatchType.HOPS){ + if(plantable == Plantable.JUTE_SEED) Item(plantable.itemID,3) else Item(plantable.itemID,4) + } else { + Item(plantable.itemID,1) + } + + if(patch.type == PatchType.ALLOTMENT){ + if(!player.inventory.containsItem(plantItem)){ + player.sendMessage("You need 3 seeds to plant an allotment patch.") + return@onUseWith true + } + } + if(patch.type != PatchType.FRUIT_TREE && patch.type != PatchType.TREE){ + if(!player.inventory.contains(Items.SEED_DIBBER_5343,1)){ + player.sendMessage("You need a seed dibber to plant that.") + return@onUseWith true + } + } else { + if(!player.inventory.contains(Items.SPADE_952,1)){ + player.sendMessage("You need a spade to plant that.") + return@onUseWith true + } + } + player.lock() + if(player.inventory.remove(plantItem)) { + player.animator.animate(Animation(2291)) + player.audioManager.send(2432) + player.pulseManager.run(object : Pulse(3) { + override fun pulse(): Boolean { + if(plantable == Plantable.JUTE_SEED && patch == FarmingPatch.MCGRUBOR_HOPS && !player.achievementDiaryManager.hasCompletedTask(DiaryType.SEERS_VILLAGE,0,7)){ + player.achievementDiaryManager.finishTask(player,DiaryType.SEERS_VILLAGE,0,7) + } + p.plant(plantable) + player.skills.addExperience(Skills.FARMING, plantable.plantingXP) + p.setNewHarvestAmount() + if(p.patch.type == PatchType.TREE || p.patch.type == PatchType.FRUIT_TREE){ + player.inventory.add(Item(Items.PLANT_POT_5350)) + } + player.unlock() + return true + } + }) + } + } + } + + return@onUseWith true + } } - @JvmStatic fun loadNodes(){ + patches.addAll(8550..8557) //allotment wrappers + patches.addAll(7847..7853) //flower patch wrappers + patches.addAll(8150..8156) //herb patch wrappers + patches.addAll(8388..8390) // Tree patches + patches.add(19147) //Tree patch + patches.addAll(7962..7965) //fruit trees + patches.addAll(8173..8176) //hops + patches.addAll(7577..7580) //bush + patches.add(23760) //evil turnip + patches.add(7572) //belladonna + patches.add(8337) //mushroom + patches.add(27197) //jade vine + patches.add(7771) //cactus + patches.add(7807) //calquat + patches.addAll(8382..8383)//spirit trees + patches.add(8338) //spirit tree + patches.add(18816) //death plateau wrapper for(p in Plantable.values()){ allowedNodes.add(p.itemID) } allowedNodes.addAll(arrayListOf(RAKE,SEED_DIBBER,SPADE,SECATEURS,TROWEL,Items.SUPERCOMPOST_6034,Items.COMPOST_6032,Items.PLANT_CURE_6036,Items.WATERING_CAN1_5333,Items.WATERING_CAN2_5334,Items.WATERING_CAN3_5335,Items.WATERING_CAN4_5336,Items.WATERING_CAN5_5337,Items.WATERING_CAN6_5338,Items.WATERING_CAN7_5339,Items.WATERING_CAN8_5340, Items.PLANT_POT_5350)) } - @JvmStatic - fun handle(event: NodeUsageEvent?): Boolean { - event ?: return false - val player = event.player - val usedItem = event.usedItem - val patch = FarmingPatch.forObject(event.usedWith.asScenery()) - patch ?: return false - - player.faceLocation(event.usedWith.location) - when(usedItem.id){ - RAKE -> PatchRaker.rake(player,patch) - SEED_DIBBER -> player.sendMessage("I should plant a seed, not the seed dibber.") - SPADE -> player.dialogueInterpreter.open(67984003,patch.getPatchFor(player)) //DigUpPatchDialogue.kt - SECATEURS -> { - val p = patch.getPatchFor(player) - if(patch.type == PatchType.TREE) { - if(p.isDiseased && !p.isDead) { - player.pulseManager.run(object: Pulse(){ - override fun pulse(): Boolean { - player.animator.animate(secateursAnim) - p.cureDisease() - return true - } - }) - } else if(p.plantable == Plantable.WILLOW_SAPLING && p.harvestAmt > 0) { - val pulse = CropHarvester.harvestPulse(player, event.usedWith, Items.WILLOW_BRANCH_5933) ?: return false - player.pulseManager.run(pulse) - } - } - } - TROWEL, Items.PLANT_POT_5350 -> { - if(!player.inventory.containsAtLeastOneItem(TROWEL)) { - player.sendMessage("You need a trowel to fill plant pots with dirt.") - return true - } - val p = patch.getPatchFor(player) - if(!p.isWeedy()){ - player.sendMessage("This patch has something growing in it.") - return true - } else if (p.currentGrowthStage != 3){ - player.sendMessage("I should clear this of weeds before trying to take some dirt.") - return true - } - - val potAmount = player.inventory.getAmount(Items.PLANT_POT_5350) - - if(potAmount == 0){ - player.sendMessage("You have no plant pots to fill.") - return true - } - - val anim = Animation(2272) - - player.pulseManager.run(object : Pulse(anim.duration){ - override fun pulse(): Boolean { - if(player.inventory.remove(Item(Items.PLANT_POT_5350))){ - player.animator.animate(anim) - player.inventory.add(Item(Items.PLANT_POT_5354)) - } else return true - return false - } - }) - } - - Items.PLANT_CURE_6036 -> { - val p = patch.getPatchFor(player) - if(p.isDiseased && !p.isDead){ - player.pulseManager.run(object: Pulse(){ - override fun pulse(): Boolean { - player.animator.animate(plantCureAnim) - player.audioManager.send(2438) - if(player.inventory.remove(event.usedItem)){ - player.inventory.add(Item(Items.VIAL_229)) - p.cureDisease() - } - return true - } - }) - } else { - player.sendMessage("I have no reason to do this right now.") - } - } - - Items.WATERING_CAN1_5333,Items.WATERING_CAN2_5334,Items.WATERING_CAN3_5335,Items.WATERING_CAN4_5336,Items.WATERING_CAN5_5337,Items.WATERING_CAN6_5338,Items.WATERING_CAN7_5339,Items.WATERING_CAN8_5340 -> { - val p = patch.getPatchFor(player) - val t = p.patch.type - if(!p.isWatered && (t == PatchType.ALLOTMENT || t == PatchType.FLOWER || t == PatchType.HOPS) && !p.isGrown()){ - player.pulseManager.run(object : Pulse(){ - override fun pulse(): Boolean { - if(p.isWeedy()){ - player.sendMessage("You should grow something first.") - return true - } - player.animator.animate(wateringCanAnim) - player.audioManager.send(2446) - if(player.inventory.remove(event.usedItem)){ - player.inventory.add(Item(usedItem.id.getNext())) - p.water() - } - return true - } - }) - } - } - - Items.SUPERCOMPOST_6034, Items.COMPOST_6032 -> { - val p = patch.getPatchFor(player) - if(p.compost == CompostType.NONE) { - player.animator.animate(pourBucketAnim) - player.audioManager.send(2427) - player.pulseManager.run(object : Pulse(){ - override fun pulse(): Boolean { - if(player.inventory.remove(event.usedItem,false)){ - p.compost = if(usedItem.id == Items.SUPERCOMPOST_6034) CompostType.SUPER else CompostType.NORMAL - if(p.compost == CompostType.SUPER) rewardXP(player, Skills.FARMING, 26.0) else rewardXP(player, Skills.FARMING, 18.5) - if(p.plantable != null && p.plantable?.applicablePatch != PatchType.FLOWER) { - p.harvestAmt += if(p.compost == CompostType.NORMAL) 1 else if(p.compost == CompostType.SUPER) 2 else 0 - } - p.cropLives += if(p.compost == CompostType.SUPER) 2 else 1 - player.inventory.add(Item(Items.BUCKET_1925)) - } - return true - } - }) - } else { - player.sendMessage("This patch has already been treated with compost.") - } - } - - else -> { - val plantable = Plantable.forItemID(usedItem.id) - if(plantable == null) return false - - if(plantable.applicablePatch != patch.type){ - player.sendMessage("You can't plant that seed in this patch.") - return true - } - - if(plantable.requiredLevel > player.skills.getLevel(Skills.FARMING)){ - player.sendMessage("You need a Farming level of ${plantable.requiredLevel} to plant this.") - return true - } - - val p = patch.getPatchFor(player) - if(p.getCurrentState() < 3 && p.isWeedy()){ - player.sendMessage("You must weed your patch before you can plant a seed in it.") - return true - } else if(p.getCurrentState() > 3){ - player.sendMessage("There is already something growing in this patch.") - return true - } - - val plantItem = - if(patch.type == PatchType.ALLOTMENT) Item(plantable.itemID,3) else if(patch.type == PatchType.HOPS){ - if(plantable == Plantable.JUTE_SEED) Item(plantable.itemID,3) else Item(plantable.itemID,4) - } else { - Item(plantable.itemID,1) - } - - if(patch.type == PatchType.ALLOTMENT){ - if(!player.inventory.containsItem(plantItem)){ - player.sendMessage("You need 3 seeds to plant an allotment patch.") - return true - } - } - if(patch.type != PatchType.FRUIT_TREE && patch.type != PatchType.TREE){ - if(!player.inventory.contains(Items.SEED_DIBBER_5343,1)){ - player.sendMessage("You need a seed dibber to plant that.") - return true - } - } else { - if(!player.inventory.contains(Items.SPADE_952,1)){ - player.sendMessage("You need a spade to plant that.") - return true - } - } - player.lock() - if(player.inventory.remove(plantItem)) { - player.animator.animate(Animation(2291)) - player.audioManager.send(2432) - player.pulseManager.run(object : Pulse(3) { - override fun pulse(): Boolean { - if(plantable == Plantable.JUTE_SEED && patch == FarmingPatch.MCGRUBOR_HOPS && !player.achievementDiaryManager.hasCompletedTask(DiaryType.SEERS_VILLAGE,0,7)){ - player.achievementDiaryManager.finishTask(player,DiaryType.SEERS_VILLAGE,0,7) - } - p.plant(plantable) - player.skills.addExperience(Skills.FARMING, plantable.plantingXP) - p.setNewHarvestAmount() - if(p.patch.type == PatchType.TREE || p.patch.type == PatchType.FRUIT_TREE){ - player.inventory.add(Item(Items.PLANT_POT_5350)) - } - player.unlock() - return true - } - }) - } - } - } - - return true - } - private fun Int.getNext(): Int { if(this == Items.WATERING_CAN1_5333) return Items.WATERING_CAN_5331 else return this - 1 diff --git a/Server/src/main/kotlin/rs09/net/packet/PacketProcessor.kt b/Server/src/main/kotlin/rs09/net/packet/PacketProcessor.kt new file mode 100644 index 000000000..e5658ea49 --- /dev/null +++ b/Server/src/main/kotlin/rs09/net/packet/PacketProcessor.kt @@ -0,0 +1,743 @@ +package rs09.net.packet + +import api.events.ButtonClickEvent +import api.getAttribute +import api.sendMessage +import core.cache.def.impl.ItemDefinition +import core.cache.def.impl.NPCDefinition +import core.cache.def.impl.SceneryDefinition +import core.game.container.Container +import core.game.container.impl.BankContainer +import core.game.content.global.report.AbuseReport +import core.game.content.global.report.Rule +import core.game.content.quest.PluginInteractionManager +import core.game.interaction.Interaction +import core.game.interaction.MovementPulse +import core.game.interaction.NodeUsageEvent +import core.game.interaction.Option +import core.game.interaction.UseWithHandler +import core.game.node.Node +import core.game.node.entity.impl.PulseType +import core.game.node.entity.player.Player +import core.game.node.entity.player.info.Rights +import core.game.node.entity.player.info.login.LoginConfiguration +import core.game.node.entity.player.link.SpellBookManager +import core.game.node.entity.skill.magic.MagicSpell +import core.game.node.entity.skill.summoning.familiar.FamiliarSpecial +import core.game.node.item.GroundItemManager +import core.game.node.item.Item +import core.game.node.scenery.Scenery +import core.game.system.communication.ClanRank +import core.game.system.communication.CommunicationInfo +import core.game.system.monitor.PlayerMonitor +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.game.world.map.RegionManager +import core.game.world.update.flag.context.ChatMessage +import core.game.world.update.flag.player.ChatFlag +import core.net.amsc.MSPacketRepository +import core.net.packet.PacketRepository +import core.net.packet.context.PlayerContext +import core.net.packet.out.ClearMinimapFlag +import discord.Discord +import org.rs09.consts.Components +import proto.management.ClanMessage +import proto.management.JoinClanRequest +import rs09.ServerConstants +import rs09.game.ge.GrandExchange +import rs09.game.ge.GrandExchange.Companion.getOfferStats +import rs09.game.ge.GrandExchange.Companion.getRecommendedPrice +import rs09.game.ge.GrandExchangeOffer +import rs09.game.ge.PriceIndex +import rs09.game.interaction.IntType +import rs09.game.interaction.InteractionListeners +import rs09.game.interaction.InterfaceListeners +import rs09.game.interaction.QCRepository +import rs09.game.interaction.inter.ge.StockMarket +import rs09.game.node.entity.skill.magic.SpellListener +import rs09.game.node.entity.skill.magic.SpellListeners +import rs09.game.node.entity.skill.magic.SpellUtils +import rs09.game.system.SystemLogger +import rs09.game.system.command.CommandSystem +import rs09.game.world.GameWorld +import rs09.game.world.repository.Repository +import rs09.net.packet.`in`.Packet +import rs09.net.packet.`in`.RunScript +import rs09.worker.ManagementEvents +import java.io.PrintWriter +import java.io.StringWriter +import java.util.* + +object PacketProcessor { + val queue = LinkedList() + + @JvmStatic fun enqueue(pkt: Packet) { + queue.addLast(pkt) + } + + @JvmStatic fun processQueue() { + var countThisCycle = queue.size + val sw = StringWriter() + val pw = PrintWriter(sw) + var pkt: Packet + while (countThisCycle-- > 0) { + pkt = queue.pop() + try { + process(pkt) + } catch (e: Exception) { + e.printStackTrace(pw) + SystemLogger.logErr(this::class.java, "Error Processing ${pkt::class.java.simpleName}: $sw") + } + } + } + + private fun process(pkt: Packet) { + when (pkt) { + is Packet.ItemAction -> processItemAction(pkt) + is Packet.NpcAction -> processNpcAction(pkt) + is Packet.SceneryAction -> processSceneryAction(pkt) + is Packet.PlayerAction -> processPlayerAction(pkt) + is Packet.GroundItemAction -> processGroundItemAction(pkt) + is Packet.UseWithNpc, + is Packet.UseWithItem, + is Packet.UseWithScenery, + is Packet.UseWithGroundItem, + is Packet.UseWithPlayer -> processUseWith(pkt) + is Packet.IfAction -> processIfAction(pkt) + is Packet.CloseIface -> processCloseIface(pkt) + is Packet.WorldspaceWalk, + is Packet.MinimapWalk, + is Packet.InteractWalk -> processWalkPacket(pkt) + is Packet.AddFriend -> CommunicationInfo.add(pkt.player, pkt.username) + is Packet.RemoveFriend -> CommunicationInfo.remove(pkt.player, pkt.username, false) + is Packet.AddIgnore -> CommunicationInfo.block(pkt.player, pkt.username) + is Packet.RemoveIgnore -> CommunicationInfo.remove(pkt.player, pkt.username, true) + is Packet.ComponentItemAction, + is Packet.ComponentPlayerAction, + is Packet.ComponentNpcAction, + is Packet.ComponentSceneryAction, + is Packet.ComponentGroundItemAction -> processComponentUseWith(pkt) + is Packet.SlotSwitchSingleComponent, + is Packet.SlotSwitchMultiComponent -> processSlotSwitch(pkt) + is Packet.TrackingMouseClick, + is Packet.TrackingAfkTimeout, + is Packet.TrackingFocus, + is Packet.TrackingCameraPos, + is Packet.TrackingDisplayUpdate -> processTrackingPacket(pkt) + is Packet.PlayerPrefsUpdate -> {/*TODO implement something that cares about this */} + is Packet.Ping -> pkt.player.session.lastPing = System.currentTimeMillis() + is Packet.JoinClan -> { + if (pkt.clanName.isNotEmpty()) + sendMessage(pkt.player, "Attempting to join channel....:clan:") + val builder = JoinClanRequest.newBuilder() + builder.clanName = pkt.clanName + builder.username = pkt.player.name + ManagementEvents.publish(builder.build()) + } + is Packet.SetClanRank -> { + CommunicationInfo.updateClanRank(pkt.player, pkt.username, ClanRank.values()[pkt.rank + 1]) + } + is Packet.KickFromClan -> { + val clan = pkt.player.communication.clan ?: return + val target = Repository.getPlayerByName(pkt.username) ?: return + clan.kick(pkt.player, target) + } + is Packet.QuickChat -> QCRepository.sendQC(pkt.player, pkt.multiplier, pkt.offset, pkt.type, pkt.indexA, pkt.indexB, pkt.forClan) + is Packet.InputPromptResponse -> { + val script: ((Any) -> Boolean) = pkt.player.getAttribute("runscript", null) ?: return + if (pkt.player.locks.isInteractionLocked) + return + try { + RunScript.processInput(pkt.player, pkt.response, script) + } finally { + pkt.player.removeAttribute("parseamount") + pkt.player.removeAttribute("runscript") + } + } + is Packet.ReportAbuse -> { + if (!GameWorld.accountStorage.checkUsernameTaken(pkt.target.lowercase())) { + sendMessage(pkt.player, "Invalid player name.") + return + } + if (pkt.target.equals(pkt.player.username, true)){ + pkt.player.sendMessage("You can't report yourself!") + } + AbuseReport ( + pkt.player.name, + pkt.target, + Rule.forId(pkt.rule) + ).construct(pkt.player, pkt.modMute) + } + is Packet.TrackFinished -> { + if (pkt.player.musicPlayer.isLooping) + pkt.player.musicPlayer.replay() + else + pkt.player.musicPlayer.isPlaying = false + } + is Packet.GESetOfferItem -> { + val offer = pkt.player.getAttribute("ge-temp", GrandExchangeOffer()) + val index = pkt.player.getAttribute("ge-index", -1) + offer.itemID = pkt.itemId + offer.sell = false + if (!PriceIndex.canTrade(pkt.itemId)) { + sendMessage(pkt.player, "That item is blacklisted from the grand exchange.") + return + } + offer.player = pkt.player + offer.amount = 1 + offer.offeredValue = getRecommendedPrice(pkt.itemId, false) + offer.index = index + StockMarket.updateVarbits(pkt.player, offer, index, false) + pkt.player.setAttribute("ge-temp", offer) + pkt.player.packetDispatch.sendString(getOfferStats(pkt.itemId, false), 105, 142) + pkt.player.interfaceManager.closeChatbox() + } + is Packet.Command -> { + if (CommandSystem.commandSystem.parse(pkt.player, pkt.commandLine)) + pkt.player.monitor.log(pkt.commandLine, PlayerMonitor.COMMAND_LOG) + } + is Packet.ChatMessage -> { + if (pkt.player.details.isMuted) + pkt.player.sendMessage("You have been muted due to breaking a rule.") + else { + if (pkt.message.startsWith("/") && pkt.player.communication.clan != null) { + val builder = ClanMessage.newBuilder() + builder.sender = pkt.player.name + builder.clanName = pkt.player.communication.clan.owner.lowercase().replace(" ", "_") + builder.message = pkt.message.substring(1) + builder.rank = pkt.player.rights.ordinal + ManagementEvents.publish(builder.build()) + return + } + pkt.player.monitor.log(pkt.message, PlayerMonitor.PUBLIC_CHAT_LOG) + val ctx = ChatMessage(pkt.player, pkt.message, pkt.effects, pkt.message.length) + pkt.player.updateMasks.register(ChatFlag(ctx)) + } + } + is Packet.ChatSetting -> { + MSPacketRepository.sendChatSetting(pkt.player, pkt.public, pkt.private, pkt.trade) + pkt.player.settings.updateChatSettings(pkt.public, pkt.private, pkt.trade) + } + is Packet.PrivateMessage -> { + if (pkt.player.details.isMuted) + pkt.player.sendMessage("You have been muted due to breaking a rule.") + else + CommunicationInfo.sendMessage(pkt.player, pkt.username, pkt.message) + } + is Packet.PacketCountUpdate -> { + val final = pkt.count - pkt.player.interfaceManager.getPacketCount(0) + pkt.player.interfaceManager.getPacketCount(final) + } + is Packet.DialogueOption -> { + val player = pkt.player + if (player.dialogueInterpreter.dialogue == null) { + player.interfaceManager.closeChatbox() + player.dialogueInterpreter.actions.removeFirstOrNull()?.handle(player, pkt.child) + return + } + player.dialogueInterpreter.handle(pkt.iface, pkt.child) + } + is Packet.ItemExamine -> { + val def = ItemDefinition.forId(pkt.id) ?: return + pkt.player.debug("[ITEM] ID: ${pkt.id} Value: ${def.value}") + pkt.player.sendMessage(def.examine) + } + is Packet.SceneryExamine -> { + val def = SceneryDefinition.forId(pkt.id) ?: return + pkt.player.debug("[SCENERY]---------------------") + pkt.player.debug("ID: ${pkt.id}") + if (def.configFile != null) + pkt.player.debug("Varbit: ${def.configFile.id}") + pkt.player.debug("------------------------------") + pkt.player.sendMessage(def.examine) + } + is Packet.NpcExamine -> { + val def = NPCDefinition.forId(pkt.id) + pkt.player.debug("[NPC]-------------------------") + pkt.player.debug("ID: ${pkt.id}") + if (def.configFileId != -1) + pkt.player.debug("Varbit: ${def.configFileId}") + pkt.player.debug("------------------------------") + pkt.player.sendMessage(def.examine) + } + + + else -> SystemLogger.logWarn(this::class.java, "Unprocessed Packet: ${pkt::class.java.simpleName}") + } + } + + private fun processTrackingPacket(pkt: Packet) { + when(pkt) { + is Packet.TrackingFocus -> pkt.player.monitor.isClientFocus = pkt.isFocused + is Packet.TrackingDisplayUpdate -> { + pkt.player.session.clientInfo.screenWidth = pkt.screenWidth + pkt.player.session.clientInfo.screenHeight = pkt.screenHeight + pkt.player.session.clientInfo.displayMode = pkt.displayMode + pkt.player.interfaceManager.switchWindowMode(pkt.windowMode) + } + is Packet.TrackingAfkTimeout -> { + if (pkt.player.details.rights != Rights.ADMINISTRATOR) + pkt.player.packetDispatch.sendLogout() + } + is Packet.TrackingCameraPos -> { + //TODO Refactor the player monitor to be actually useful and log this + } + is Packet.TrackingMouseClick -> { + //TODO see above todo + if (!pkt.player.monitor.isClientFocus) { + Discord.postPlayerAlert(pkt.player.username, "Mouseclick without window focus!") + } + } + } + } + + private fun processSlotSwitch(pkt: Packet) { + //TODO refactor this to function as callbacks to InterfaceListeners, e.g. onSlotSwitch + //TODO See above TODO, I hate Arios. This was hardcoded in the packet decoder. + if (pkt is Packet.SlotSwitchMultiComponent) { + if (pkt.destIface == 762) { + if (pkt.destChild == 73) { + val container = pkt.player.bank + switchItem(pkt.sourceSlot, pkt.destSlot, container, pkt.player.bank.isInsertItems, pkt.player) + } else { + val tabIndex = BankContainer.getArrayIndex(pkt.destChild) + if (tabIndex > -1) { + val secondSlot = + if (tabIndex == 10) pkt.player.bank.freeSlot() else pkt.player.bank.tabStartSlot[tabIndex] + pkt.player.bank.getItemsInTab(tabIndex) + val inSlot: Item = pkt.player.bank.get(pkt.sourceSlot) + if (secondSlot == -1 && pkt.player.bank.remove(inSlot)) { + pkt.player.bank.add(inSlot) + return + } + val childId = pkt.player.bank.getTabByItemSlot(pkt.sourceSlot) + if (secondSlot > pkt.sourceSlot) { + pkt.player.bank.insert(pkt.sourceSlot, secondSlot - 1) + } else if (pkt.sourceSlot > secondSlot) { + pkt.player.bank.insert(pkt.sourceSlot, secondSlot) + } + pkt.player.bank.increaseTabStartSlots(tabIndex) + pkt.player.bank.decreaseTabStartSlots(childId) + pkt.player.bank.setTabConfigurations() + return + } + } + return + } else { + switchItem(pkt.sourceSlot, pkt.destSlot, pkt.player.inventory, false, pkt.player) + } + } + else if (pkt is Packet.SlotSwitchSingleComponent) { + val container = if (pkt.iface == 762) pkt.player.bank else pkt.player.inventory + switchItem(pkt.sourceSlot, pkt.destSlot, container, pkt.isInsert, pkt.player) + } + } + + private fun processComponentUseWith(pkt: Packet) { + val iface: Int + val child: Int + val target: Node + val targetId: Int + val player: Player + val type: Int + if (pkt is Packet.ComponentGroundItemAction) { + player = pkt.player + child = pkt.child + iface = pkt.iface + target = GroundItemManager.get(pkt.itemId, Location.create(pkt.x, pkt.y, player.location.z), player) ?: return sendClearMinimap(player).also { sendMessage(player, "Too late!") } + targetId = pkt.itemId + type = SpellListener.GROUND_ITEM + } + else if (pkt is Packet.ComponentPlayerAction) { + player = pkt.player + child = pkt.child + iface = pkt.iface + target = Repository.players[pkt.otherIndex] ?: return sendClearMinimap(player) + targetId = target.id + type = SpellListener.PLAYER + } + else if (pkt is Packet.ComponentSceneryAction) { + player = pkt.player + child = pkt.child + iface = pkt.iface + target = RegionManager.getObject(player.location.z, pkt.x, pkt.y) ?: return sendClearMinimap(player) + targetId = pkt.sceneryId + type = SpellListener.OBJECT + } + else if (pkt is Packet.ComponentNpcAction) { + if (pkt.npcIndex !in 1 until ServerConstants.MAX_NPCS) + return sendClearMinimap(pkt.player) + player = pkt.player + child = pkt.child + iface = pkt.iface + target = Repository.npcs[pkt.npcIndex] ?: return sendClearMinimap(player) + targetId = target.id + type = SpellListener.NPC + } + else { + if (pkt !is Packet.ComponentItemAction) return + player = pkt.player + child = pkt.child + iface = pkt.iface + target = player.inventory[pkt.slot] ?: return + targetId = pkt.itemId + type = SpellListener.ITEM + } + + if (targetId != target.id) + return + if (player.getAttribute("magic:delay", -1) > GameWorld.ticks) + return + val book = SpellUtils.getBookFromInterface(iface) + if (book != "none") + SpellListeners.run(child, type, book, player, target) + when (iface) { + 430,192 -> MagicSpell.castSpell(player, SpellBookManager.SpellBook.forInterface(iface), child, target) + 662 -> { + if (player.familiarManager.hasFamiliar()) + player.familiarManager.familiar.executeSpecialMove(FamiliarSpecial(target, iface, child, target as? Item)) + else + player.sendMessage("You don't have a familiar.") + } + } + } + + private fun processWalkPacket(pkt: Packet) { + val player: Player + val x: Int + val y: Int + val isRunning: Boolean + if (pkt is Packet.WorldspaceWalk) { + player = pkt.player + x = pkt.destX + y = pkt.destY + isRunning = pkt.isRun + } + else if (pkt is Packet.InteractWalk) { + player = pkt.player + x = pkt.destX + y = pkt.destY + isRunning = pkt.isRun + } + else { + if (pkt !is Packet.MinimapWalk) return + player = pkt.player + x = pkt.destX + y = pkt.destY + isRunning = pkt.isRun + //there's more data in this packet, we're just not using it + } + + if (player.locks.isMovementLocked || !player.interfaceManager.close() || !player.interfaceManager.closeSingleTab() || !player.dialogueInterpreter.close()) { + player.debug("[WALK ACTION]-- NO HANDLE: PLAYER LOCKED OR INTERFACES SAY NO") + return sendClearMinimap(player) + } + + if (pkt is Packet.InteractWalk) { + //Arios did this, so we're replicating it for now. Probably wrong. + player.walkingQueue.isRunning = isRunning + return + } + + player.face(null) + player.faceLocation(null) + + player.pulseManager.run(object : MovementPulse(player, Location.create(x,y,player.location.z), isRunning) { + override fun pulse(): Boolean { + if (isRunning) + player.walkingQueue.isRunning = false + return true + } + }) + } + + private fun processCloseIface(pkt: Packet.CloseIface) { + val player = pkt.player + player.interfaceManager.close() + if (player.getAttribute("logging_in") != null) { + GameWorld.Pulser.submit(object : Pulse() { + override fun pulse(): Boolean { + player.removeAttribute("logging_in") + LoginConfiguration.configureGameWorld(player) + return true + } + }) + } + if (player.getAttribute("worldMap:viewing") != null) { + player.removeAttribute("worldMap:viewing") + player.packetDispatch.sendWindowsPane(if (player.interfaceManager.isResizable) 746 else 548, 2) + player.unlock() + } + } + + private fun processIfAction(pkt: Packet.IfAction) { + val player = pkt.player + player.debug("[IF ACTION]--------------------------") + player.debug("Iface: ${pkt.iface}, Button: ${pkt.child}") + player.debug("Slot: ${pkt.slot}, ItemID: ${pkt.itemId}") + player.debug("RCM Index: ${pkt.optIndex}, Op: ${pkt.opcode}") + player.debug("-------------------------------------") + if (player.dialogueInterpreter.dialogue != null && pkt.opcode != 132 && pkt.iface != 64) + player.dialogueInterpreter.close() + if (player.locks.isComponentLocked) + return + if (player.zoneMonitor.clickButton(pkt.iface, pkt.child, pkt.slot, pkt.itemId, pkt.opcode)) + return + val c = player.interfaceManager.getComponent(pkt.iface) ?: return + if (c.isHidden) + return + val plugin = c.plugin + player.dispatch(ButtonClickEvent(c.id, pkt.child)) + if (!InterfaceListeners.run(player, c, pkt.opcode, pkt.child, pkt.slot, pkt.itemId)) + plugin?.handle(player, c, pkt.opcode, pkt.child, pkt.slot, pkt.itemId) + } + + private fun processUseWith(pkt: Packet) { + val node: Node + var childNode: Node? = null + val item: Item + val itemId: Int + val nodeId: Int + val type: IntType + val player: Player + if (pkt is Packet.UseWithNpc) { + val container = getLikelyContainerForIface(pkt.player, pkt.iface) ?: return sendClearMinimap(pkt.player) + itemId = pkt.itemId + val itemSlot = pkt.slot + item = container[itemSlot] ?: return sendClearMinimap(pkt.player) + node = Repository.npcs[pkt.npcIndex] ?: return sendClearMinimap(pkt.player) + childNode = node.getShownNPC(pkt.player) + nodeId = node.id + type = IntType.NPC + player = pkt.player + } + else if (pkt is Packet.UseWithScenery) { + item = pkt.player.inventory[pkt.slot] ?: return sendClearMinimap(pkt.player) + node = RegionManager.getObject(pkt.player.location.z, pkt.x, pkt.y) ?: return sendClearMinimap(pkt.player) + childNode = node.asScenery().getChild(pkt.player) + itemId = pkt.itemId + nodeId = node.id + type = IntType.SCENERY + player = pkt.player + } + else if (pkt is Packet.UseWithItem) { + val containerUsed = getLikelyContainerForIface(pkt.player, pkt.usedIface) ?: return + val containerWith = getLikelyContainerForIface(pkt.player, pkt.usedWithIface) ?: return + item = containerUsed[pkt.usedSlot] ?: return + node = containerWith[pkt.usedWithSlot] ?: return + itemId = pkt.usedId + nodeId = pkt.usedWithId + type = IntType.ITEM + player = pkt.player + } else if (pkt is Packet.UseWithGroundItem) { + val container = getLikelyContainerForIface(pkt.player, pkt.iface) ?: return + item = container[pkt.slot] + itemId = pkt.usedId + node = GroundItemManager.get(pkt.withId, Location.create(pkt.x, pkt.y, pkt.player.location.z), pkt.player) + nodeId = pkt.withId + type = IntType.GROUNDITEM + player = pkt.player + } else { + if (pkt !is Packet.UseWithPlayer) return + val container = getLikelyContainerForIface(pkt.player, pkt.iface) ?: return sendClearMinimap(pkt.player) + item = container[pkt.slot] ?: return sendClearMinimap(pkt.player) + itemId = pkt.itemId + node = Repository.players[pkt.otherIndex] ?: return sendClearMinimap(pkt.player) + type = IntType.PLAYER + nodeId = node.id + player = pkt.player + } + + if (item.id != itemId) + return sendClearMinimap(player) + if (node.id != nodeId) + return sendClearMinimap(player) + + if (player.zoneMonitor.useWith(item, node)) + return + if (InteractionListeners.run(item, node, type, player)) + return + if (childNode != null && childNode.id != node.id) { + if (InteractionListeners.run(item, childNode, type, player)) + return + } + val flipped = type == IntType.ITEM && item.id < node.id + val event = if (flipped) + NodeUsageEvent(player, 0, node, item) + else + NodeUsageEvent(player, 0, item, childNode ?: node) + if (PluginInteractionManager.handle(player, event)) + return + UseWithHandler.run(event) + } + + private fun processGroundItemAction(pkt: Packet.GroundItemAction) { + val item = GroundItemManager.get(pkt.id, Location.create(pkt.x, pkt.y, pkt.player.location.z), pkt.player) + val player = pkt.player + + if (item == null) { + return sendClearMinimap(player) + } + val option = item.interaction[pkt.optIndex] + if (option == null) { + Interaction.handleInvalidInteraction(player, item, Option.NULL) + return sendClearMinimap(player) + } + if (PluginInteractionManager.handle(player, item, option)) + return + if (InteractionListeners.run(item.id, IntType.GROUNDITEM, option.name, player, item)) + return + if (InteractionListeners.run(item.id, IntType.ITEM, option.name, player, item)) + return + item.interaction.handle(player, option) + } + + private fun processPlayerAction(pkt: Packet.PlayerAction) { + val player = pkt.player + if (pkt.otherIndex !in 1 until ServerConstants.MAX_PLAYERS) { + return sendClearMinimap(player) + } + val other = Repository.players[pkt.otherIndex] + if (other == null || !other.isActive) + return sendClearMinimap(player) + val option = other.interaction[pkt.optIndex] ?: return sendClearMinimap(player) + if (!InteractionListeners.run(-1, IntType.PLAYER, option.name.lowercase(), player, other)) { + other.interaction.handle(player, option) + } + } + + private fun processSceneryAction(pkt: Packet.SceneryAction) { + val player = pkt.player + var scenery = RegionManager.getObject(player.location.z, pkt.x, pkt.y, pkt.id) + var objId = pkt.id + + //what follows is a series of hardcoded crimes against humanity + if (pkt.id == 6898) + scenery = Scenery(6898, Location(3219, 9618)) + if (pkt.id == 6899) + scenery = Scenery(6899, Location(3221, 9618)) + + // Family crest levers don't have varps associated with them, so their state is validated with attributes + // instead, and they always appear as their down/odd variant in the server's map + if (objId in 2421..2426 && objId % 2 == 0) { + scenery = Scenery(objId - 1, Location(pkt.x, pkt.y, player.location.z)) + objId -= 1 + } + + if (scenery == null || scenery.id != objId || !scenery.isActive) { + player.debug("[SCENERY INTERACT] NULL OR MISMATCH OR INACTIVE") + Interaction.handleInvalidInteraction(player, scenery, Option.NULL) + return sendClearMinimap(player) + } + + val wrapperChild = scenery.getChild(player) + val option = wrapperChild.interaction[pkt.optIndex] + + if (option == null) { + player.debug("[SCENERY INTERACT] NULL OPTION") + Interaction.handleInvalidInteraction(player, scenery, Option.NULL) + return sendClearMinimap(player) + } + + val hasWrapper = wrapperChild.id != scenery.id + + player.debug("[SCENERY INTERACT]------------------------------") + player.debug("ID: ${wrapperChild.id}, Option: ${option.name}[${option.index}]") + player.debug("Loc: ${scenery.location}, Dir: ${scenery.direction}") + if (hasWrapper) { + player.debug("WrapperID: ${scenery.id}, Varbit: ${scenery.definition.configFile.id}") + } + player.debug("------------------------------------------------") + + if (InteractionListeners.run(wrapperChild.id, IntType.SCENERY, option.name, player, wrapperChild)) + return + if (PluginInteractionManager.handle(player, wrapperChild)) + return + wrapperChild.interaction.handle(player, option) + } + + private fun processNpcAction(pkt: Packet.NpcAction) { + if (pkt.npcIndex !in 1 until ServerConstants.MAX_NPCS) + return sendClearMinimap(pkt.player) + val npc = Repository.npcs[pkt.npcIndex] ?: return sendClearMinimap(pkt.player) + + val wrapperChild = npc.getShownNPC(pkt.player) + val option = wrapperChild.interaction[pkt.optIndex] + + if (option == null) { + Interaction.handleInvalidInteraction(pkt.player, npc, Option.NULL) + return sendClearMinimap(pkt.player) + } + + val hasWrapper = wrapperChild.id != npc.id + + pkt.player.debug("[NPC INTERACT]-------------------") + pkt.player.debug("ID: ${wrapperChild.id}, Index: ${pkt.npcIndex}") + pkt.player.debug("Option: ${option.name}[${option.index}]") + pkt.player.debug("SpawnLoc: ${npc.properties.spawnLocation}") + if (hasWrapper) { + pkt.player.debug("WrapperID: ${npc.id}, Varbit: ${npc.definition.configFileId}") + } + pkt.player.debug("---------------------------------") + + if (InteractionListeners.run(wrapperChild.id, IntType.NPC,option.name,pkt.player,npc)) + return + if (PluginInteractionManager.handle(pkt.player, wrapperChild, option)) + return + npc.interaction.handle(pkt.player, option) + } + + private fun processItemAction(pkt: Packet.ItemAction) { + val container = getLikelyContainerForIface(pkt.player, pkt.iface) ?: return + if (pkt.slot !in 0 until container.capacity()) + return + val item = container.get(pkt.slot) ?: return + if (item.id != pkt.itemId) + return + val option = item.interaction[pkt.optIndex] ?: return + if (pkt.player.locks.isInteractionLocked) + return + item.interaction.handleItemOption(pkt.player, option, container) + pkt.player.debug("[ITEM INTERACT] ID: ${item.id}, Slot: ${pkt.slot}, Opt: ${option.name}") + } + + private fun getLikelyContainerForIface(player: Player, iface: Int) : Container? { + return when (iface) { + Components.INVENTORY_149 -> player.inventory + Components.BANK_V2_MAIN_762 -> player.bank + Components.EQUIP_SCREEN2_667 -> player.equipment + else -> null + } + } + + private fun sendClearMinimap(player: Player) { + PacketRepository.send(ClearMinimapFlag::class.java, PlayerContext(player)) + } + + fun switchItem(slot: Int, secondSlot: Int, container: Container?, insert: Boolean, player: Player) { + if (container == null || slot < 0 || slot >= container.toArray().size || secondSlot < 0 || secondSlot >= container.toArray().size) { + return + } + val item = container[slot] + val second = container[secondSlot] + if (player.interfaceManager.hasChatbox() && !getAttribute(player, "close_c_", false)) { + player.interfaceManager.closeChatbox() + switchItem(secondSlot, slot, container, insert, player) + container.refresh() + return + } + if (item == null) { + return + } + if (!insert) { + container.replace(second, slot, false) + container.replace(item, secondSlot, false) + item.index = secondSlot + if (second != null) { + second.index = slot + } + } else { + container.insert(slot, secondSlot, false) + } + container.refresh() + } +} \ No newline at end of file diff --git a/Server/src/main/kotlin/rs09/net/packet/in/Decoders530.kt b/Server/src/main/kotlin/rs09/net/packet/in/Decoders530.kt new file mode 100644 index 000000000..56563da42 --- /dev/null +++ b/Server/src/main/kotlin/rs09/net/packet/in/Decoders530.kt @@ -0,0 +1,771 @@ +package rs09.net.packet.`in` + +import core.game.node.entity.player.Player +import core.net.packet.IoBuffer +import core.tools.StringUtils +import rs09.game.system.SystemLogger +import java.io.PrintWriter +import java.io.StringWriter + +enum class Decoders530(val opcode: Int) { + /****************************************** + * ITEM INTERACTIONS + ******************************************/ + ITEM_ACTION_1(156) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val slot = buffer.leShortA + val itemId = buffer.shortA + val ifHash = buffer.leInt + val (iface, button) = deHash(ifHash) + return Packet.ItemAction(player, 0, itemId, slot, iface, button) + } + }, + ITEM_ACTION_2(55) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val itemId = buffer.leShort + val slot = buffer.shortA + val ifHash = buffer.intA + val (iface, button) = deHash(ifHash) + return Packet.ItemAction(player, 1, itemId, slot, iface, button) + } + }, + ITEM_ACTION_3(153) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val ifHash = buffer.leInt + val slot = buffer.leShort + val itemId = buffer.leShort + val (iface, button) = deHash(ifHash) + return Packet.ItemAction(player, 2, itemId, slot, iface, button) + } + }, + ITEM_ACTION_4(161) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val ifHash = buffer.leInt + val itemId = buffer.leShortA + val slot = buffer.leShortA + val (iface, button) = deHash(ifHash) + return Packet.ItemAction(player, 3, itemId, slot, iface, button) + } + }, + ITEM_ACTION_5(135) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val itemId = buffer.shortA + val slot = buffer.shortA + val ifHash = buffer.intB + val (iface, button) = deHash(ifHash) + return Packet.ItemAction(player, 4, itemId, slot, iface, button) + } + }, + + + + /****************************************** + * NPC INTERACTIONS + ******************************************/ + NPC_ACTION_1(78) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val npcIndex = buffer.leShort + return Packet.NpcAction(player, 0, npcIndex) + } + }, + NPC_ACTION_2(3) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val npcIndex = buffer.leShortA + return Packet.NpcAction(player, 1, npcIndex) + } + }, + NPC_ACTION_3(148) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val npcIndex = buffer.shortA + return Packet.NpcAction(player, 2, npcIndex) + } + }, + NPC_ACTION_4(30) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val npcIndex = buffer.short + return Packet.NpcAction(player, 3, npcIndex) + } + }, + NPC_ACTION_5(218) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val npcIndex = buffer.leShort + return Packet.NpcAction(player, 4, npcIndex) + } + }, + + /****************************************** + * SCENERY INTERACTIONS + ******************************************/ + SCENERY_ACTION_1(254) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val x = buffer.leShort + val objId = buffer.shortA and 0xFFFF + val y = buffer.short + return Packet.SceneryAction(player, 0, objId, x, y) + } + }, + SCENERY_ACTION_2(194) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val y = buffer.leShortA + val x = buffer.leShort + val objId = buffer.short and 0xFFFF + return Packet.SceneryAction(player, 1, objId, x, y) + } + }, + SCENERY_ACTION_3(84) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val objId = buffer.leShortA and 0xFFFF + val y = buffer.leShortA + val x = buffer.leShort + return Packet.SceneryAction(player, 2, objId, x, y) + } + }, + SCENERY_ACTION_4(247) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val y = buffer.leShort and 0xFFFF + val x = buffer.leShortA + val objId = buffer.short and 0xFFFF + return Packet.SceneryAction(player, 3, objId, x, y) + } + }, + SCENERY_ACTION_5(170) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val objId = buffer.leShortA and 0xFFFF + val x = buffer.leShortA + val y = buffer.leShortA + return Packet.SceneryAction(player, 4, objId, x, y) + } + }, + + /****************************************** + * PLAYER INTERACTIONS + ******************************************/ + PLAYER_ACTION_1(68) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val pIndex = buffer.leShortA + return Packet.PlayerAction(player, 0, pIndex) + } + }, + PLAYER_ACTION_3(71) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val pIndex = buffer.leShortA + return Packet.PlayerAction(player, 2, pIndex) + } + }, + PLAYER_ACTION_4(180) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val pIndex = buffer.leShortA + return Packet.PlayerAction(player, 3, pIndex) + } + }, + PLAYER_ACTION_7(114) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val index = buffer.leShortA + return Packet.PlayerAction(player, 6, index) + } + }, + PLAYER_ACTION_8(175) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val pIndex = buffer.shortA + return Packet.PlayerAction(player, 7, pIndex) + } + }, + + /****************************************** + * OBJSTACK (Ground Item) INTERACTIONS + ******************************************/ + OBJSTACK_ACTION_1(66) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val x = buffer.leShort + val itemId = buffer.short + val y = buffer.leShortA + return Packet.GroundItemAction(player, 2, itemId, x, y) + } + }, + OBJSTACK_ACTION_2(33) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val itemId = buffer.short + val x = buffer.short + val y = buffer.leShort + return Packet.GroundItemAction(player, 3, itemId, x, y) + } + }, + + /****************************************** + * USEWITH INTERACTIONS + ******************************************/ + USEWITH_NPC(115) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val ifHash = buffer.intB + val slot = buffer.leShort + val npcIndex = buffer.leShort + val itemId = buffer.leShortA + val (iface, _) = deHash(ifHash) + return Packet.UseWithNpc(player, itemId, npcIndex, iface, slot) + } + }, + USEWIH_PLAYER(248) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val otherIndex = buffer.leShortA + val itemId = buffer.short + val slot = buffer.short + val ifHash = buffer.intB + val (iface, _) = deHash(ifHash) + return Packet.UseWithPlayer(player, itemId, otherIndex, iface, slot) + } + }, + USEWITH_ITEM(27) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val usedSlot = buffer.short + val usedIfHash = buffer.leInt + val usedWithSlot = buffer.leShort + val usedWithIfHash = buffer.leInt + val usedId = buffer.leShortA + val usedWithId = buffer.leShortA + + val (usedIface, usedChild) = deHash(usedIfHash) + val (usedWithIface, usedWithChild) = deHash(usedWithIfHash) + return Packet.UseWithItem( + player, + usedId, usedWithId, + usedSlot, usedWithSlot, + usedIface, usedWithIface, + usedChild, usedWithChild + ) + } + }, + USEWITH_SCENERY(134) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val x = buffer.shortA + val id = buffer.short + val y = buffer.leShort + val slot = buffer.short + buffer.leShort //Suspicious noops? TODO: FIND OUT WHAT THESE ARE + buffer.short + val sceneryId = buffer.shortA + return Packet.UseWithScenery(player, id, slot, sceneryId, x, y) + } + }, + USEWITH_GROUNDITEM(101) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val x = buffer.leShortA + val slot = buffer.leShort + val usedId = buffer.leShort + val usedWithId = buffer.leShort + val y = buffer.leShortA + val ifHash = buffer.intB + val (iface,child) = deHash(ifHash) + return Packet.UseWithGroundItem(player, usedId, usedWithId, iface, child, slot, x, y) + } + }, + + /****************************************** + * INTERFACE INTERACTIONS + ******************************************/ + IF_ACTION_1(155) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val ifHash = buffer.int + val slot = buffer.short + val (iface, button) = deHash(ifHash) + return Packet.IfAction(player, opcode, 0, iface, button, slot) + } + }, + IF_ACTION_2(196) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val ifHash = buffer.int + val slot = buffer.short + val (iface, button) = deHash(ifHash) + return Packet.IfAction(player, opcode, 1, iface, button, slot) + } + }, + IF_ACTION_3(124) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val ifHash = buffer.int + val slot = buffer.short + val (iface, button) = deHash(ifHash) + return Packet.IfAction(player, opcode, 2, iface, button, slot) + } + }, + IF_ACTION_4(199) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val ifHash = buffer.int + val slot = buffer.short + val (iface, button) = deHash(ifHash) + return Packet.IfAction(player, opcode, 3, iface, button, slot) + } + }, + IF_ACTION_5(234) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val ifHash = buffer.int + val slot = buffer.short + val (iface, button) = deHash(ifHash) + return Packet.IfAction(player, opcode, 4, iface, button, slot) + } + }, + IF_ACTION_6(168) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val ifHash = buffer.int + val slot = buffer.short + val (iface, button) = deHash(ifHash) + return Packet.IfAction(player, opcode, 5, iface, button, slot) + } + }, + IF_ACTION_7(166) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val ifHash = buffer.int + val slot = buffer.short + val (iface, button) = deHash(ifHash) + return Packet.IfAction(player, opcode, 6, iface, button, slot) + } + }, + IF_ACTION_8(64) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val ifHash = buffer.int + val slot = buffer.short + val (iface, button) = deHash(ifHash) + return Packet.IfAction(player, opcode, 7, iface, button, slot) + } + }, + IF_ACTION_9(53) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val ifHash = buffer.int + val slot = buffer.short + val (iface, button) = deHash(ifHash) + return Packet.IfAction(player, opcode, 8, iface, button, slot) + } + }, + IF_ACTION_10(9) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val ifHash = buffer.int + val slot = buffer.short + val (iface, button) = deHash(ifHash) + return Packet.IfAction(player, opcode, 9, iface, button, slot) + } + }, + IF_ACTION_CS(10) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val ifHash = buffer.int + val (iface, button) = deHash(ifHash) + return Packet.IfAction(player, opcode, -1, iface, button, -1, -1) + } + }, + DIALOGUE_OPT(132) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val ifHash = buffer.intA + val slot = buffer.leShort + val (iface, button) = deHash(ifHash) + return Packet.DialogueOption(player, iface, button) + } + }, + CLOSE_IFACE(184) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + return Packet.CloseIface(player) + } + }, + IF_GROUNDITEM_ACTION(73) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val child = buffer.short + val iface = buffer.short + val y = buffer.short + val itemId = buffer.leShortA + val x = buffer.leShortA + val slot = buffer.leShort + return Packet.ComponentGroundItemAction(player, iface, child, slot, itemId, x, y) + } + }, + IF_PLAYER_ACTION(195) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + buffer.shortA //Arios ignoring more data... nice + val child = buffer.leShort + val iface = buffer.leShort + val otherIndex = buffer.leShortA + return Packet.ComponentPlayerAction(player, otherIndex, iface, child) + } + }, + IF_SCENERY_ACTION(233) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val y = buffer.leShortA + val x = buffer.shortA + val itemId = buffer.leShortA //probably misnamed/mislabeled by Arios. + val ifHash = buffer.intA + val (iface, child) = deHash(ifHash) + val objId = buffer.shortA + return Packet.ComponentSceneryAction(player, iface, child, objId, x, y) + } + }, + IF_NPC_ACTION(239) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val child = buffer.leShort + val iface = buffer.leShort + buffer.shortA //more ignored data.... + val index = buffer.leShortA + return Packet.ComponentNpcAction(player, iface, child, index) + } + }, + IF_ITEM_ACTION(253) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val child = buffer.leShort + val iface = buffer.leShort + val itemSlot = buffer.leShortA + val itemId = buffer.shortA + buffer.shortA //more ignored data.... + return Packet.ComponentItemAction(player, iface, child, itemId, itemSlot) + } + }, + SLOTSWITCH_MULTI(79) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val srcHash = buffer.intB + val destSlot = buffer.leShort + val destHash = buffer.int + val srcSlot = buffer.leShort + val (srcIface, srcChild) = deHash(srcHash) + val (destIface, destChild) = deHash(destHash) + return Packet.SlotSwitchMultiComponent(player, srcIface, srcChild, srcSlot, destIface, destChild, destSlot) + } + }, + SLOTSWITCH_SINGLE(231) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val srcSlot = buffer.short + val ifHash = buffer.leInt + val destSlot = buffer.shortA + val isInsert = buffer.get() == 1 + val (iface, child) = deHash(ifHash) + return Packet.SlotSwitchSingleComponent(player, iface, child, srcSlot, destSlot, isInsert) + } + }, + IF_ITEM_OPT_1(81) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val slot = buffer.shortA + val itemId = buffer.short + val child = buffer.short + val iface = buffer.short + return Packet.IfAction(player, opcode, 0, iface, child, slot, itemId) + } + }, + IF_ITEM_OPT_2(206) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val itemId = buffer.shortA + val slot = buffer.leShort + val ifHash = buffer.leInt + val (iface, button) = deHash(ifHash) + return Packet.IfAction(player, opcode, 1, iface, button, slot, itemId) + } + }, + + /****************************************** + * EXAMINE + ******************************************/ + EXAMINE_SCENERY(94) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + return Packet.SceneryExamine(player, buffer.leShortA) + } + }, + EXAMINE_ITEM(92) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + return Packet.ItemExamine(player, buffer.leShortA) + } + }, + EXAMINE_NPC(72) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + return Packet.NpcExamine(player, buffer.short) + } + }, + + /****************************************** + * CLANS + ******************************************/ + CLAN_JOIN(104) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val clanName = StringUtils.longToString(buffer.long) + return Packet.JoinClan(player, clanName) + } + }, + CLAN_SETRANK(188) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val rank = buffer.a + val name = StringUtils.longToString(buffer.long) + return Packet.SetClanRank(player, name, rank) + } + }, + CLAN_KICK(162) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val name = StringUtils.longToString(buffer.long) + return Packet.KickFromClan(player, name) + } + }, + + /****************************************** + * FRIENDS/IGNORES + ******************************************/ + ADD_FRIEND(120) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + return Packet.AddFriend(player, StringUtils.longToString(buffer.long)) + } + }, + REMOVE_FRIEND(57) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + return Packet.RemoveFriend(player, StringUtils.longToString(buffer.long)) + } + }, + ADD_IGNORE(34) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + return Packet.AddIgnore(player, StringUtils.longToString(buffer.long)) + } + }, + REMOVE_IGNORE(213) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + return Packet.RemoveIgnore(player, StringUtils.longToString(buffer.long)) + } + }, + PRIVATE_MESSAGE(201) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val name = StringUtils.longToString(buffer.long) + val message = StringUtils.decryptPlayerChat(buffer, buffer.get() and 0xFF) + return Packet.PrivateMessage(player, name, message) + } + }, + + /****************************************** + * INPUT TRACKING + ******************************************/ + FOCUS_CHANGE(22) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + return Packet.TrackingFocus(player, buffer.get() == 1) + } + }, + CAMERA_MOVEMENT(21) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val x = buffer.shortA + val y = buffer.leShort + return Packet.TrackingCameraPos(player, x, y) + } + }, + DISPLAY_UPDATE(243) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val windowMode = buffer.get() + val screenWidth = buffer.short + val screenHeight = buffer.short + val displayMode = buffer.get() + return Packet.TrackingDisplayUpdate(player, windowMode, screenWidth, screenHeight, displayMode) + } + }, + AFK_TIMEOUT(245) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + return Packet.TrackingAfkTimeout(player) + } + }, + MOUSE_CLICKED(75) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val data = buffer.leShortA + val pos = buffer.intB + val rightClick = ((data shr 15) and 0x1) == 1 + val delay = data and 0x7FF + val x = pos shr 16 + val y = pos and 0xFFFF + return Packet.TrackingMouseClick(player, x, y, rightClick, delay) + } + }, + + /****************************************** + * WALKING + ******************************************/ + WORLDSPACE_WALK(215) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val (running, x, y) = decodeWalkInformation(buffer, false) + return Packet.WorldspaceWalk(player, x, y, running) + } + }, + MINIMAP_WALK(39) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val (running, x, y) = decodeWalkInformation(buffer, true) + val clickedX = buffer.get() + val clickedY = buffer.get() + val rotation = buffer.short + //Unlabeled data ignored by arios + buffer.get() + buffer.get() + buffer.get() + buffer.get() + buffer.short + buffer.short + buffer.get() + buffer.get() + return Packet.MinimapWalk(player, x, y, clickedX, clickedY, rotation, running) + } + }, + INTERACT_WALK(77) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val (running, x, y) = decodeWalkInformation(buffer, false) + return Packet.InteractWalk(player, x, y, running) + } + }, + + /****************************************** + * INPUT PROMPT RESPONSE + ******************************************/ + INPUT_SHORT_STRING_RESPONSE(244) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + return Packet.InputPromptResponse(player, StringUtils.longToString(buffer.long)) + } + }, + INPUT_LONG_STRING_RESPONSE(65) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + return Packet.InputPromptResponse(player, buffer.string) + } + }, + INPUT_INT_RESPONSE(23) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + return Packet.InputPromptResponse(player, buffer.int) + } + }, + + /****************************************** + * ASSORTED + ******************************************/ + GE_SET_OFFER_ITEM(111) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val itemId = buffer.short + return Packet.GESetOfferItem(player, itemId) + } + }, + COMMAND(44) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + if (buffer.toByteBuffer().remaining() > 1) { + val message = buffer.string.lowercase() + return Packet.Command(player, message) + } + return Packet.NoProcess() + } + }, + CHAT_SETTINGS(157) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + return Packet.ChatSetting( + player, + buffer.get(), + buffer.get(), + buffer.get() + ) + } + }, + CHAT_MESSAGE(237) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val effects = buffer.short + val numChars = buffer.smart + val message = StringUtils.decryptPlayerChat(buffer, numChars) + return Packet.ChatMessage(player, effects, message) + } + }, + MUSIC_TRACK_FINISHED(137) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val trackId = buffer.leShortA + return Packet.TrackFinished(player, trackId) + } + }, + REPORT_ABUSE(99) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val target = StringUtils.longToString(buffer.long) + val ruleId = buffer.get() + val modMute = buffer.get() == 1 + return Packet.ReportAbuse(player, target, ruleId, modMute) + } + }, + UPDATE_PACKET_COUNT(177) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val count = buffer.short + return Packet.PacketCountUpdate(player, count) + } + }, + PING(93) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + return Packet.Ping(player) + } + }, + QUICKCHAT(167) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val x = buffer.toByteBuffer() + + val packetType = when(x.array().size){ + 3,4 -> QCPacketType.STANDARD + 5 -> QCPacketType.SINGLE + 7 -> QCPacketType.DOUBLE + else -> QCPacketType.UNHANDLED.also { SystemLogger.logWarn(this::class.java, "UNHANDLED QC PACKET TYPE Size ${x.array().size}") } + } + + val forClan = (buffer.get() and 0xFF) == 1 + val multiplier: Int = buffer.get() + val offset: Int = buffer.get() + var selection_a_index = -1 + var selection_b_index = -1 + + when(packetType){ + QCPacketType.SINGLE -> { + selection_a_index = buffer.short + } + QCPacketType.DOUBLE -> { + buffer.get() //discard + selection_a_index = buffer.get() + buffer.get() //discard + selection_b_index = buffer.get() + } + QCPacketType.UNHANDLED -> SystemLogger.logWarn(this::class.java, "Unhandled packet type, skipping remaining buffer contents.") + } + return Packet.QuickChat(player, selection_a_index, selection_b_index, forClan, multiplier, offset, packetType) + } + }, + MAP_REBUILD_STARTED(20) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + return Packet.NoProcess() + } + }, + MAP_REBUILD_FINISHED(110) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + return Packet.NoProcess() + } + }, + PLAYER_PREFS_UPDATE(98) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val prefs = buffer.int + return Packet.PlayerPrefsUpdate(player, prefs) + } + } + ; + abstract fun decode(player: Player, buffer: IoBuffer): Packet + + fun deHash(ifHash: Int) : Pair { + return Pair(ifHash shr 16, ifHash and 0xFFFF) + } + + fun decodeWalkInformation(buffer: IoBuffer, isMinimap: Boolean) : Triple { + val isRunning = buffer.a == 1 + var x = buffer.short + var y = buffer.shortA + val steps = (buffer.toByteBuffer().remaining() - if (isMinimap) 14 else 0) shr 1 + //derive the final destination by poking the last set of values in the packet (client does its own pathfinding and reports it) + for (i in 0 until steps) { + val offsetX = buffer.a + val offsetY = buffer.s + if (i == steps - 1){ + x += offsetX + y += offsetY + } + } + return Triple(isRunning, x, y) + } + + companion object { + private val opcodeMap = values().associateBy { it.opcode } + + @JvmStatic fun process(player: Player, opcode: Int, buffer: IoBuffer) : Packet { + val decoder = opcodeMap[opcode] ?: return Packet.UnhandledOp() + + return try { + decoder.decode(player, buffer) + } catch (e: Exception) { + val sw = StringWriter() + val pw = PrintWriter(sw) + e.printStackTrace(pw) + Packet.DecodingError("Error decoding opcode $opcode/${decoder.name}: $sw") + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/kotlin/rs09/net/packet/in/ItemOnGroundItemPacket.kt b/Server/src/main/kotlin/rs09/net/packet/in/ItemOnGroundItemPacket.kt deleted file mode 100644 index 32ba77aac..000000000 --- a/Server/src/main/kotlin/rs09/net/packet/in/ItemOnGroundItemPacket.kt +++ /dev/null @@ -1,62 +0,0 @@ -package rs09.net.packet.`in` - -import core.game.interaction.DestinationFlag -import core.game.interaction.MovementPulse -import core.game.node.entity.player.Player -import core.game.node.entity.skill.firemaking.FireMakingPulse -import core.game.node.item.GroundItemManager -import core.game.world.map.Location -import core.net.packet.IncomingPacket -import core.net.packet.IoBuffer -import org.rs09.consts.Items - -/** - * Handles the Item -> Ground Item packet - * Decided not to include it with the rest of ItemActionPacket because it functions a bit differently from the rest of that - * Will also require its own handlers instead of the normal UseWithHandler. Kind of annoying especially considering there's very few - * Interactions that actually make use of this packet. - * @author Ceikry - */ -class ItemOnGroundItemPacket : IncomingPacket { - override fun decode(player: Player?, opcode: Int, buffer: IoBuffer?) { - buffer ?: return - player ?: return - val x = buffer.leShortA - val slot = buffer.leShort - val usedItemId = buffer.leShort - val usedWithItemId = buffer.leShort - val y = buffer.leShortA - buffer.int //uncertain what the use for this int is. My suspicion was region ID but no variety of the int data type matches up with the region id - - val GILocation = Location.create(x,y,player.location.z) - - var usedWith = GroundItemManager.get(usedWithItemId, GILocation, null) ?: GroundItemManager.get(usedWithItemId, GILocation, player) - usedWith ?: return - - var used = player.inventory.get(slot) - if(used.id != usedItemId) return - - - /** - * I'm just gonna put the handler for tinderbox -> logs here. Yes I know it's lazy, etc, etc but frankly the number of interactions - * that are actually item -> ground item are so few it just doesn't make sense to make a whole system for it. - */ - player.pulseManager.run(object : MovementPulse(player,GILocation, DestinationFlag.ITEM){ - override fun pulse(): Boolean { - if(used.id == Items.TINDERBOX_590 || used.id == Items.GOLDEN_TINDERBOX_2946){ - when(usedWithItemId){ - Items.LOGS_1511,Items.ACHEY_TREE_LOGS_2862,Items.ARCTIC_PINE_LOGS_10810,Items.MAGIC_LOGS_1513,Items.MAHOGANY_LOGS_6332,Items.MAPLE_LOGS_1517,Items.YEW_LOGS_1515,Items.TEAK_LOGS_6333,Items.OAK_LOGS_1521, Items.WILLOW_LOGS_1519 - -> { - player.pulseManager.run(FireMakingPulse(player,usedWith.asItem(),usedWith)) - } - else -> player.sendMessage("Nothing interesting happens.") - } - } else { - player.sendMessage("Nothing interesting happens.") - } - return true - } - }) - } - -} \ No newline at end of file diff --git a/Server/src/main/kotlin/rs09/net/packet/in/Packet.kt b/Server/src/main/kotlin/rs09/net/packet/in/Packet.kt new file mode 100644 index 000000000..d06b4d69f --- /dev/null +++ b/Server/src/main/kotlin/rs09/net/packet/in/Packet.kt @@ -0,0 +1,60 @@ +package rs09.net.packet.`in` + +import core.game.node.entity.player.Player + +sealed class Packet { + data class ItemAction(val player: Player, val optIndex: Int, val itemId: Int, val slot: Int, val iface: Int, val child: Int) : Packet() + data class NpcAction(val player: Player, val optIndex: Int, val npcIndex: Int) : Packet() + data class SceneryAction(val player: Player, val optIndex: Int, val id: Int, val x: Int, val y: Int) : Packet() + data class PlayerAction(val player: Player, val optIndex: Int, val otherIndex: Int) : Packet() + data class GroundItemAction(val player: Player, val optIndex: Int, val id: Int, val x: Int, val y: Int) : Packet() + data class ItemExamine(val player: Player, val id: Int) : Packet() + data class SceneryExamine(val player: Player, val id: Int) : Packet() + data class NpcExamine(val player: Player, val id: Int) : Packet() + data class UseWithNpc(val player: Player, val itemId: Int, val npcIndex: Int, val iface: Int, val slot: Int) : Packet() + data class UseWithPlayer(val player: Player, val itemId: Int, val otherIndex: Int, val iface: Int, val slot: Int) : Packet() + data class UseWithItem(val player: Player, val usedId: Int, val usedWithId: Int, val usedSlot: Int, val usedWithSlot: Int, val usedIface: Int, val usedWithIface: Int, val usedChild: Int, val usedWithChild: Int) : Packet() + data class UseWithScenery(val player: Player, val itemId: Int, val slot: Int, val sceneryId: Int, val x: Int, val y: Int) : Packet() + data class UseWithGroundItem(val player: Player, val usedId: Int, val withId: Int, val iface: Int, val child: Int, val slot: Int, val x: Int, val y: Int) : Packet() + data class IfAction(val player: Player, val opcode: Int, val optIndex: Int, val iface: Int, val child: Int, val slot: Int, val itemId: Int = -1) : Packet() + data class DialogueOption(val player: Player, val iface: Int, val child: Int) : Packet() + data class CloseIface(val player: Player) : Packet() + data class JoinClan(val player: Player, val clanName: String) : Packet() + data class SetClanRank(val player: Player, val username: String, val rank: Int) : Packet() + data class KickFromClan(val player: Player, val username: String) : Packet() + data class AddFriend(val player: Player, val username: String) : Packet() + data class RemoveFriend(val player: Player, val username: String) : Packet() + data class AddIgnore(val player: Player, val username: String) : Packet() + data class RemoveIgnore(val player: Player, val username: String) : Packet() + data class TrackingFocus(val player: Player, val isFocused: Boolean) : Packet() + data class TrackingCameraPos(val player: Player, val x: Int, val y: Int) : Packet() + data class TrackingDisplayUpdate(val player: Player, val windowMode: Int, val screenWidth: Int, val screenHeight: Int, val displayMode: Int) : Packet() + data class TrackingAfkTimeout(val player: Player) : Packet() + data class TrackingMouseClick(val player: Player, val x: Int, val y: Int, val isRightClick: Boolean, val delay: Int) : Packet() + data class ComponentPlayerAction(val player: Player, val otherIndex: Int, val iface: Int, val child: Int) : Packet() + data class ComponentItemAction(val player: Player, val iface: Int, val child: Int, val itemId: Int, val slot: Int) : Packet() + data class ComponentNpcAction(val player: Player, val iface: Int, val child: Int, val npcIndex: Int) : Packet() + data class ComponentSceneryAction(val player: Player, val iface: Int, val child: Int, val sceneryId: Int, val x: Int, val y: Int) : Packet() + data class ComponentGroundItemAction(val player: Player, val iface: Int, val child: Int, val slot: Int, val itemId: Int, val x: Int, val y: Int) : Packet() + data class SlotSwitchMultiComponent(val player: Player, val sourceIface: Int, val sourceChild: Int, val sourceSlot: Int, val destIface: Int, val destChild: Int, val destSlot: Int) : Packet() + data class SlotSwitchSingleComponent(val player: Player, val iface: Int, val child: Int, val sourceSlot: Int, val destSlot: Int, val isInsert: Boolean) : Packet() + data class PacketCountUpdate(val player: Player, val count: Int) : Packet() + data class PrivateMessage(val player: Player, val username: String, val message: String) : Packet() + data class ChatMessage(val player: Player, val effects: Int, val message: String) : Packet() + data class ChatSetting(val player: Player, val public: Int, val private: Int, val trade: Int) : Packet() + data class Command(val player: Player, val commandLine: String) : Packet() + data class GESetOfferItem(val player: Player, val itemId: Int) : Packet() + data class TrackFinished(val player: Player, val trackId: Int) : Packet() + data class ReportAbuse(val player: Player, val target: String, val rule: Int, val modMute: Boolean) : Packet() + data class WorldspaceWalk(val player: Player, val destX: Int, val destY: Int, val isRun: Boolean) : Packet() + data class MinimapWalk(val player: Player, val destX: Int, val destY: Int, val clickedX: Int, val clickedY: Int, val rotation: Int, val isRun: Boolean) : Packet() + data class InteractWalk(val player: Player, val destX: Int, val destY: Int, val isRun: Boolean) : Packet() + data class Ping(val player: Player) : Packet() + data class QuickChat(val player: Player, val indexA: Int, val indexB: Int, val forClan: Boolean, val multiplier: Int, val offset: Int, val type: QCPacketType) : Packet() + data class InputPromptResponse(val player: Player, val response: Any) : Packet() + data class PlayerPrefsUpdate(val player: Player, val prefs: Int) : Packet() + + class NoProcess : Packet() + class UnhandledOp : Packet() + data class DecodingError(val message: String) : Packet() +} diff --git a/Server/src/main/kotlin/rs09/net/packet/in/RunScript.kt b/Server/src/main/kotlin/rs09/net/packet/in/RunScript.kt new file mode 100644 index 000000000..2ff6d56b7 --- /dev/null +++ b/Server/src/main/kotlin/rs09/net/packet/in/RunScript.kt @@ -0,0 +1,35 @@ +package rs09.net.packet.`in` + +import api.sendDialogue +import core.game.node.entity.player.Player + +/** + * Handles an incoming script execution request packet. + * + * @author vddCore + */ +object RunScript { + + fun processInput(player: Player, value: Any, script: ((Any) -> Boolean)) { + if (value is Int && value <= 0) return + + var input = value + + if (player.getAttribute("parseamount", false)) { + input = value.toString().lowercase() + + if (!input.matches(Regex("^(\\d+)(k+|m+)?$"))) { + sendDialogue(player, "That doesn't look right. Please try again.") + return + } + + input = input.replace("k", "000").replace("m", "000000") + } + + try { + script(input) + } catch (_: NumberFormatException) { + sendDialogue(player, "That number's a bit large, don't you think?") + } + } +} diff --git a/Server/src/main/kotlin/rs09/net/packet/in/RunScriptPacketHandler.kt b/Server/src/main/kotlin/rs09/net/packet/in/RunScriptPacketHandler.kt deleted file mode 100644 index b96b15a88..000000000 --- a/Server/src/main/kotlin/rs09/net/packet/in/RunScriptPacketHandler.kt +++ /dev/null @@ -1,56 +0,0 @@ -package rs09.net.packet.`in` - -import api.sendDialogue -import core.game.node.entity.player.Player -import core.net.packet.IncomingPacket -import core.net.packet.IoBuffer -import core.tools.StringUtils - -/** - * Handles an incoming script execution request packet. - * - * @author vddCore - */ -class RunScriptPacketHandler : IncomingPacket { - - private fun processInput(player: Player, value: Any, script: ((Any) -> Boolean)) { - if (value is Int && value <= 0) return - - var input = value - - if (player.getAttribute("parseamount", false)) { - input = value.toString().lowercase() - - if (!input.matches(Regex("^(\\d+)(k+|m+)?$"))) { - sendDialogue(player, "That doesn't look right. Please try again.") - return - } - - input = input.replace("k", "000").replace("m", "000000") - } - - try { - script(input) - } catch (_: NumberFormatException) { - sendDialogue(player, "That number's a bit large, don't you think?") - } - } - - override fun decode(player: Player, opcode: Int, buffer: IoBuffer) { - val script: ((Any) -> Boolean)? = player.getAttribute("runscript", null) - - if (script == null || player.locks.isInteractionLocked) - return - - val value: Any = when(opcode) { - 244 -> StringUtils.longToString(buffer.long) - 65 -> buffer.string - else -> buffer.int // Handles OpCode 23 and other cases. - } - - processInput(player, value, script) - - player.removeAttribute("parseamount") - player.removeAttribute("runscript") - } -} diff --git a/Server/src/main/kotlin/rs09/worker/MajorUpdateWorker.kt b/Server/src/main/kotlin/rs09/worker/MajorUpdateWorker.kt index 50d1cb460..1a2d26073 100644 --- a/Server/src/main/kotlin/rs09/worker/MajorUpdateWorker.kt +++ b/Server/src/main/kotlin/rs09/worker/MajorUpdateWorker.kt @@ -10,6 +10,7 @@ import rs09.game.system.SystemLogger import rs09.game.world.GameWorld import rs09.game.world.repository.Repository import rs09.game.world.update.UpdateSequence +import rs09.net.packet.PacketProcessor import rs09.tools.stringtools.colorize import java.lang.Long.max import java.text.SimpleDateFormat @@ -79,6 +80,8 @@ class MajorUpdateWorker { } fun handleTickActions(skipPulseUpdate: Boolean = false) { + PacketProcessor.processQueue() + if (!skipPulseUpdate) { GameWorld.Pulser.updateAll() }