Refactored the processing of incoming packets to do so synchronously on the start of the tick cycle (rather than being processed as soon as the packet is received)
Decoupled decoding of packets from processing of packets, so that both 530 and 578 packets can be decoded into the same data structures and processed the same way De-spaghettied many things, e.g. farming and the poster in stronghold of player safety
This commit is contained in:
@@ -8,9 +8,11 @@ import core.game.node.entity.player.link.request.RequestModule;
|
|||||||
import core.game.node.item.GroundItemManager;
|
import core.game.node.item.GroundItemManager;
|
||||||
import core.game.node.item.Item;
|
import core.game.node.item.Item;
|
||||||
import core.game.system.monitor.PlayerMonitor;
|
import core.game.system.monitor.PlayerMonitor;
|
||||||
|
import rs09.game.system.SystemLogger;
|
||||||
|
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -395,6 +397,8 @@ public final class TradeModule implements RequestModule {
|
|||||||
private void giveContainers(final TradeModule module) {
|
private void giveContainers(final TradeModule module) {
|
||||||
final Container pContainer = module.getContainer();
|
final Container pContainer = module.getContainer();
|
||||||
final Container oContainer = TradeModule.getExtension(module.getTarget()).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.getPlayer(), module.getTarget(), oContainer);
|
||||||
addContainer(module.getTarget(), module.getPlayer(), pContainer);
|
addContainer(module.getTarget(), module.getPlayer(), pContainer);
|
||||||
module.getTarget().getPacketDispatch().sendMessage("Accepted trade.");
|
module.getTarget().getPacketDispatch().sendMessage("Accepted trade.");
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package core.game.node.entity.skill.firemaking
|
package core.game.node.entity.skill.firemaking
|
||||||
|
|
||||||
|
import core.game.node.item.GroundItem
|
||||||
import org.rs09.consts.Items
|
import org.rs09.consts.Items
|
||||||
import rs09.game.interaction.InteractionListener
|
import rs09.game.interaction.InteractionListener
|
||||||
import rs09.game.interaction.IntType
|
import rs09.game.interaction.IntType
|
||||||
@@ -13,5 +14,9 @@ class FiremakingListener : InteractionListener
|
|||||||
player.pulseManager.run(FireMakingPulse(player, with.asItem(), null))
|
player.pulseManager.run(FireMakingPulse(player, with.asItem(), null))
|
||||||
return@onUseWith true
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7,6 +7,9 @@ import core.net.IoSession;
|
|||||||
import core.net.packet.IncomingPacket;
|
import core.net.packet.IncomingPacket;
|
||||||
import core.net.packet.IoBuffer;
|
import core.net.packet.IoBuffer;
|
||||||
import core.net.packet.PacketRepository;
|
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;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
@@ -94,21 +97,17 @@ public final class GameReadEvent extends IoReadEvent {
|
|||||||
buffer.get(data);
|
buffer.get(data);
|
||||||
IoBuffer buf = new IoBuffer(opcode, null, ByteBuffer.wrap(data));
|
IoBuffer buf = new IoBuffer(opcode, null, ByteBuffer.wrap(data));
|
||||||
//SystemLogger.log("Packet opcode " + opcode + "received.");
|
//SystemLogger.log("Packet opcode " + opcode + "received.");
|
||||||
IncomingPacket packet = PacketRepository.getIncoming(opcode);
|
//IncomingPacket packet = PacketRepository.getIncoming(opcode);
|
||||||
session.setLastPing(System.currentTimeMillis());
|
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;
|
last = opcode;
|
||||||
try {
|
|
||||||
packet.decode(session.getPlayer(), opcode, buf);
|
Packet processed = Decoders530.process(session.getPlayer(), opcode, buf);
|
||||||
//System.out.println("Handled packed " + opcode + "!");
|
if (processed instanceof Packet.UnhandledOp) {
|
||||||
} catch (Throwable t) {
|
SystemLogger.logWarn(this.getClass(), "Unhandled opcode: " + opcode);
|
||||||
t.printStackTrace();
|
} else if (processed instanceof Packet.DecodingError) {
|
||||||
|
SystemLogger.logErr(this.getClass(), ((Packet.DecodingError) processed).getMessage());
|
||||||
|
} else if (!(processed instanceof Packet.NoProcess)) {
|
||||||
|
PacketProcessor.enqueue(processed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,9 @@
|
|||||||
package core.net.packet;
|
package core.net.packet;
|
||||||
|
|
||||||
import core.net.packet.in.*;
|
|
||||||
import core.net.packet.out.GrandExchangePacket;
|
import core.net.packet.out.GrandExchangePacket;
|
||||||
import core.net.packet.out.*;
|
import core.net.packet.out.*;
|
||||||
import rs09.game.system.SystemLogger;
|
import rs09.game.system.SystemLogger;
|
||||||
import rs09.net.packet.PacketWriteQueue;
|
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.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -23,11 +19,6 @@ public final class PacketRepository {
|
|||||||
*/
|
*/
|
||||||
public final static Map<Class<?>, OutgoingPacket<? extends Context>> OUTGOING_PACKETS = new HashMap<>();
|
public final static Map<Class<?>, OutgoingPacket<? extends Context>> OUTGOING_PACKETS = new HashMap<>();
|
||||||
|
|
||||||
/**
|
|
||||||
* The incoming packets mapping.
|
|
||||||
*/
|
|
||||||
private final static Map<Integer, IncomingPacket> INCOMING_PACKETS = new HashMap<>();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Populate the mappings.
|
* Populate the mappings.
|
||||||
*/
|
*/
|
||||||
@@ -80,105 +71,6 @@ public final class PacketRepository {
|
|||||||
OUTGOING_PACKETS.put(CSConfigPacket.class, new CSConfigPacket()); //
|
OUTGOING_PACKETS.put(CSConfigPacket.class, new CSConfigPacket()); //
|
||||||
OUTGOING_PACKETS.put(Varbit.class, new Varbit());
|
OUTGOING_PACKETS.put(Varbit.class, new Varbit());
|
||||||
OUTGOING_PACKETS.put(VarcUpdate.class, new VarcUpdate());
|
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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<DialogueAction> 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -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.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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 <b>Incoming</b> 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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -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<AIPlayer> 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -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) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -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.
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -21,7 +21,6 @@ import core.game.world.map.path.Pathfinder;
|
|||||||
import core.game.world.map.zone.impl.WildernessZone;
|
import core.game.world.map.zone.impl.WildernessZone;
|
||||||
import rs09.game.world.repository.Repository;
|
import rs09.game.world.repository.Repository;
|
||||||
import core.net.packet.context.MessageContext;
|
import core.net.packet.context.MessageContext;
|
||||||
import core.net.packet.in.InteractionPacket;
|
|
||||||
import core.plugin.Plugin;
|
import core.plugin.Plugin;
|
||||||
import core.tools.RandomFunction;
|
import core.tools.RandomFunction;
|
||||||
import core.tools.StringUtils;
|
import core.tools.StringUtils;
|
||||||
@@ -578,6 +577,6 @@ public class AIPlayer extends Player {
|
|||||||
|
|
||||||
|
|
||||||
public void interact(Node n) {
|
public void interact(Node n) {
|
||||||
InteractionPacket.handleObjectInteraction(this, 0, n.getLocation(), n.getId());
|
// InteractionPacket.handleObjectInteraction(this, 0, n.getLocation(), n.getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10,6 +10,7 @@ import core.game.world.map.Location
|
|||||||
import core.game.world.map.zone.ZoneBorders
|
import core.game.world.map.zone.ZoneBorders
|
||||||
import core.game.world.update.flag.context.Animation
|
import core.game.world.update.flag.context.Animation
|
||||||
import org.rs09.consts.NPCs
|
import org.rs09.consts.NPCs
|
||||||
|
import rs09.game.ai.AIPlayer
|
||||||
import rs09.game.content.dialogue.DialogueFile
|
import rs09.game.content.dialogue.DialogueFile
|
||||||
import rs09.game.world.GameWorld
|
import rs09.game.world.GameWorld
|
||||||
|
|
||||||
@@ -19,7 +20,7 @@ class MorytaniaArea : MapArea {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun areaEnter(entity: Entity) {
|
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)
|
kickThemOut(entity)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -178,6 +178,7 @@ object InteractionListeners {
|
|||||||
val flag = when(type){
|
val flag = when(type){
|
||||||
IntType.NPC, IntType.PLAYER -> DestinationFlag.ENTITY
|
IntType.NPC, IntType.PLAYER -> DestinationFlag.ENTITY
|
||||||
IntType.SCENERY -> DestinationFlag.OBJECT
|
IntType.SCENERY -> DestinationFlag.OBJECT
|
||||||
|
IntType.GROUNDITEM -> DestinationFlag.ITEM
|
||||||
else -> DestinationFlag.OBJECT
|
else -> DestinationFlag.OBJECT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+18
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -131,7 +131,6 @@ class CompostBin(val player: Player, val bin: CompostBins) {
|
|||||||
}
|
}
|
||||||
if (isClosed) player.varpManager.get(bin.varpIndex).setVarbit(bin.varpOffest + 6, 1)
|
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)
|
player.varpManager.get(bin.varpIndex).send(player)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,85 @@
|
|||||||
package rs09.game.node.entity.skill.farming
|
package rs09.game.node.entity.skill.farming
|
||||||
|
|
||||||
|
import api.toIntArray
|
||||||
import core.game.interaction.NodeUsageEvent
|
import core.game.interaction.NodeUsageEvent
|
||||||
import core.game.node.item.Item
|
import core.game.node.item.Item
|
||||||
import core.game.system.task.Pulse
|
import core.game.system.task.Pulse
|
||||||
import core.game.world.update.flag.context.Animation
|
import core.game.world.update.flag.context.Animation
|
||||||
import org.rs09.consts.Items
|
import org.rs09.consts.Items
|
||||||
|
import rs09.game.interaction.IntType
|
||||||
|
import rs09.game.interaction.InteractionListener
|
||||||
|
|
||||||
object UseWithBinHandler {
|
class UseWithBinHandler : InteractionListener {
|
||||||
@JvmField
|
@JvmField
|
||||||
val allowedNodes = ArrayList<Int>(100)
|
val allowedNodes = ArrayList<Int>(100)
|
||||||
val fillAnim = Animation(832)
|
val fillAnim = Animation(832)
|
||||||
val compostPotionAnimation = Animation(2259)
|
val compostPotionAnimation = Animation(2259)
|
||||||
val scoopAnimation = Animation(8905)
|
val scoopAnimation = Animation(8905)
|
||||||
|
|
||||||
init {
|
val bins = 7836..7840
|
||||||
|
|
||||||
|
override fun defineListeners() {
|
||||||
loadNodes()
|
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() {
|
fun loadNodes() {
|
||||||
@@ -32,70 +97,6 @@ object UseWithBinHandler {
|
|||||||
allowedNodes.add(Items.BUCKET_1925)
|
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{
|
private fun Int.getNext(): Int{
|
||||||
if(this != 6476) return this + 2
|
if(this != 6476) return this + 2
|
||||||
else return Items.VIAL_229
|
else return Items.VIAL_229
|
||||||
|
|||||||
+219
-205
@@ -8,9 +8,12 @@ import core.game.node.item.Item
|
|||||||
import core.game.system.task.Pulse
|
import core.game.system.task.Pulse
|
||||||
import core.game.world.update.flag.context.Animation
|
import core.game.world.update.flag.context.Animation
|
||||||
import org.rs09.consts.Items
|
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
|
import rs09.game.node.entity.skill.farming.CropHarvester
|
||||||
|
|
||||||
object UseWithPatchHandler{
|
class UseWithPatchHandler : InteractionListener {
|
||||||
val RAKE = Items.RAKE_5341
|
val RAKE = Items.RAKE_5341
|
||||||
val SEED_DIBBER = Items.SEED_DIBBER_5343
|
val SEED_DIBBER = Items.SEED_DIBBER_5343
|
||||||
val SPADE = Items.SPADE_952
|
val SPADE = Items.SPADE_952
|
||||||
@@ -23,221 +26,232 @@ object UseWithPatchHandler{
|
|||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val allowedNodes = ArrayList<Int>()
|
val allowedNodes = ArrayList<Int>()
|
||||||
|
val patches = ArrayList<Int>()
|
||||||
|
|
||||||
init {
|
override fun defineListeners() {
|
||||||
loadNodes()
|
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(){
|
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()){
|
for(p in Plantable.values()){
|
||||||
allowedNodes.add(p.itemID)
|
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))
|
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 {
|
private fun Int.getNext(): Int {
|
||||||
if(this == Items.WATERING_CAN1_5333) return Items.WATERING_CAN_5331
|
if(this == Items.WATERING_CAN1_5333) return Items.WATERING_CAN_5331
|
||||||
else return this - 1
|
else return this - 1
|
||||||
|
|||||||
@@ -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<Packet>()
|
||||||
|
|
||||||
|
@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<Boolean>("logging_in") != null) {
|
||||||
|
GameWorld.Pulser.submit(object : Pulse() {
|
||||||
|
override fun pulse(): Boolean {
|
||||||
|
player.removeAttribute("logging_in")
|
||||||
|
LoginConfiguration.configureGameWorld(player)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (player.getAttribute<Any?>("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()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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<Int,Int> {
|
||||||
|
return Pair(ifHash shr 16, ifHash and 0xFFFF)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun decodeWalkInformation(buffer: IoBuffer, isMinimap: Boolean) : Triple<Boolean,Int,Int> {
|
||||||
|
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")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -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()
|
||||||
|
}
|
||||||
@@ -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?")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -10,6 +10,7 @@ import rs09.game.system.SystemLogger
|
|||||||
import rs09.game.world.GameWorld
|
import rs09.game.world.GameWorld
|
||||||
import rs09.game.world.repository.Repository
|
import rs09.game.world.repository.Repository
|
||||||
import rs09.game.world.update.UpdateSequence
|
import rs09.game.world.update.UpdateSequence
|
||||||
|
import rs09.net.packet.PacketProcessor
|
||||||
import rs09.tools.stringtools.colorize
|
import rs09.tools.stringtools.colorize
|
||||||
import java.lang.Long.max
|
import java.lang.Long.max
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
@@ -79,6 +80,8 @@ class MajorUpdateWorker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun handleTickActions(skipPulseUpdate: Boolean = false) {
|
fun handleTickActions(skipPulseUpdate: Boolean = false) {
|
||||||
|
PacketProcessor.processQueue()
|
||||||
|
|
||||||
if (!skipPulseUpdate) {
|
if (!skipPulseUpdate) {
|
||||||
GameWorld.Pulser.updateAll()
|
GameWorld.Pulser.updateAll()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user