initial coding for packet and its tests; includes commented-out extended functionality

This commit is contained in:
FateJH 2016-09-11 00:57:04 -04:00
parent daa22c572e
commit 38a4e128b6
3 changed files with 84 additions and 1 deletions

View file

@ -368,7 +368,7 @@ object GamePacketOpcode extends Enumeration {
// 0x28
case 0x28 => noDecoder(CreateShortcutMessage)
case 0x29 => noDecoder(ChangeShortcutBankMessage)
case 0x2a => noDecoder(ObjectAttachMessage)
case 0x2a => game.ObjectAttachMessage.decode
case 0x2b => noDecoder(UnknownMessage43)
case 0x2c => noDecoder(PlanetsideAttributeMessage)
case 0x2d => game.RequestDestroyMessage.decode

View file

@ -0,0 +1,60 @@
// Copyright (c) 2016 PSForever.net to present
package net.psforever.packet.game
import net.psforever.packet.{GamePacketOpcode, Marshallable, PlanetSideGamePacket}
import scodec.Codec
import scodec.codecs._
/**
* Change the location of an item within the game's inventory system.<br>
* <br>
* The data portion of this packet defines a player, an item, and a destination.
* After the packet is received by the client, the item will be guaranteed to be within the player's inventory in the codified location.
* The "inventory" in this case includes both the player's literal grid inventory and their available equipment slots.
* Where the item was before it was moved is not specified.<br>
* <br>
* This packet is a complementary packet that simulates a lazy TCP-like approach to coordinating item manipulation.
* In some cases, the client will (appear to) proceed with what it intended to do without waiting for the server to confirm.
* For example, grabbing an item from an inventory position will generate a `MoveItemMessage` that defines "the player's cursor" as a destination.
* The client will "attach to the player's cursor" without waiting for the `ObjectAttachMessage` from the server which echoes the destination.
* The change is observable.
* Inversely, the client is blocked from detaching the item from "the player's cursor" and putting it back into the inventory on its own.
* It waits until it receives an `ObjectAttachMessage` in confirmation.<br>
* <br>
* Destination codes:<br>
* `80` is the first pistol slot<br>
* `81` is the second pistol slot<br>
* `82` is the first rifle slot<br>
* `83` is the second rifle slot<br>
* `86` is the first entry in the player's inventory<br>
* `00 FA` is a special dest/extra code that "attaches the object to the player's cursor"
* @param player_guid the player GUID
* @param item_guid the item GUID
* @param dest a codified location within the player's inventory see above
* //@param extra optional; a special kind of item manipulation; the common one is `FA`
*/
final case class ObjectAttachMessage(player_guid : PlanetSideGUID,
item_guid : PlanetSideGUID,
dest : Int)
extends PlanetSideGamePacket {
type Packet = ObjectAttachMessage
def opcode = GamePacketOpcode.ObjectAttachMessage
def encode = ObjectAttachMessage.encode(this)
}
object ObjectAttachMessage extends Marshallable[ObjectAttachMessage] {
// implicit val codec : Codec[ObjectAttachMessage] = (
// ("player_guid" | PlanetSideGUID.codec) ::
// ("item_guid" | PlanetSideGUID.codec) >>:~ { _ =>
// ("dest" | uint8L) >>:~ ( loc =>
// conditional(loc == 0, "extra" | uint8L)
// )
// }
// ).as[ObjectAttachMessage]
implicit val codec : Codec[ObjectAttachMessage] = (
("player_guid" | PlanetSideGUID.codec) ::
("item_guid" | PlanetSideGUID.codec) ::
("dest" | uint8L)
).as[ObjectAttachMessage]
}

View file

@ -299,6 +299,29 @@ class GamePacketTest extends Specification {
}
}
"ObjectAttachMessage" should {
val stringToInventory = hex"2A 9F05 D405 86"
val stringToCursor = hex"2A 9F05 D405 00FA"
"encode" in {
PacketCoding.DecodePacket(stringToInventory).require match {
case ObjectAttachMessage(player_guid, item_guid, index) =>
player_guid mustEqual PlanetSideGUID(1439)
item_guid mustEqual PlanetSideGUID(1492)
index mustEqual 134
case default =>
ko
}
}
"decode" in {
val msg = ObjectAttachMessage(PlanetSideGUID(1439), PlanetSideGUID(1492), 134)
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
pkt mustEqual stringToInventory
}
}
"DropItemMessage" should {
val string = hex"37 4C00"