diff --git a/common/src/main/scala/net/psforever/packet/game/DestroyDisplayMessage.scala b/common/src/main/scala/net/psforever/packet/game/DestroyDisplayMessage.scala index 069cc210..db2fc6ed 100644 --- a/common/src/main/scala/net/psforever/packet/game/DestroyDisplayMessage.scala +++ b/common/src/main/scala/net/psforever/packet/game/DestroyDisplayMessage.scala @@ -36,24 +36,24 @@ import scodec.codecs._ * The exact range of unique and valid icon values for this parameter is currently unknown. * It is also unknown what the two bytes preceding `method` specify, as changing them does nothing to the displayed message. * @param killer the name of the player who did the killing - * @param killer_unk See above + * @param killer_charId Same as CharacterInfoMessage * @param killer_empire the empire affiliation of the killer * @param killer_inVehicle true, if the killer was in a vehicle at the time of the kill; false, otherwise * @param unk na; but does not like being set to 0 * @param method modifies the icon in the message, related to the way the victim was killed * @param victim the name of the player who was killed - * @param victim_unk See above + * @param victim_charId Same as CharacterInfoMessage * @param victim_empire the empire affiliation of the victim * @param victim_inVehicle true, if the victim was in a vehicle when he was killed; false, otherwise */ final case class DestroyDisplayMessage(killer : String, - killer_unk : Long, + killer_charId : Long, killer_empire : PlanetSideEmpire.Value, killer_inVehicle : Boolean, unk : Int, method : Int, victim : String, - victim_unk : Long, + victim_charId : Long, victim_empire : PlanetSideEmpire.Value, victim_inVehicle : Boolean ) @@ -66,13 +66,13 @@ final case class DestroyDisplayMessage(killer : String, object DestroyDisplayMessage extends Marshallable[DestroyDisplayMessage] { implicit val codec : Codec[DestroyDisplayMessage] = ( ("killer" | PacketHelpers.encodedWideString) :: - ("killer_unk" | ulongL(32)) :: + ("killer_charId" | ulongL(32)) :: ("killer_empire" | PlanetSideEmpire.codec) :: ("killer_inVehicle" | bool) :: ("unk" | uint16L) :: ("method" | uint16L) :: ("victim" | PacketHelpers.encodedWideStringAligned(5)) :: - ("victim_unk" | ulongL(32)) :: + ("victim_charId" | ulongL(32)) :: ("victim_empire" | PlanetSideEmpire.codec) :: ("victim_inVehicle" | bool) ).as[DestroyDisplayMessage] diff --git a/common/src/main/scala/net/psforever/packet/game/MoveItemMessage.scala b/common/src/main/scala/net/psforever/packet/game/MoveItemMessage.scala index 6b1a223c..635c0bf2 100644 --- a/common/src/main/scala/net/psforever/packet/game/MoveItemMessage.scala +++ b/common/src/main/scala/net/psforever/packet/game/MoveItemMessage.scala @@ -9,7 +9,7 @@ final case class MoveItemMessage(item_guid : PlanetSideGUID, avatar_guid_1 : PlanetSideGUID, avatar_guid_2 : PlanetSideGUID, dest : Int, - unk1 : Int) + unk1 : Int) // TODO ammo quantity ? extends PlanetSideGamePacket { type Packet = MoveItemMessage def opcode = GamePacketOpcode.MoveItemMessage diff --git a/common/src/main/scala/net/psforever/packet/game/PlayerStateMessageUpstream.scala b/common/src/main/scala/net/psforever/packet/game/PlayerStateMessageUpstream.scala index 85fbb637..96cd228a 100644 --- a/common/src/main/scala/net/psforever/packet/game/PlayerStateMessageUpstream.scala +++ b/common/src/main/scala/net/psforever/packet/game/PlayerStateMessageUpstream.scala @@ -15,32 +15,35 @@ import scodec.codecs._ * @param avatar_guid the player's GUID * @param pos where the player is in the world * @param vel how the player is moving - * @param unk1 na - * @param aim_pitch the vertical angle of viewing - * @param unk2 na + * @param facingYaw the angle with respect to the horizon towards which the avatar is looking; + * the model's whole body is facing this direction; + * measurements are counter-clockwise from East + * @param facingPitch the angle with respect to the sky and the ground towards which the avatar is looking + * @param facingYawUpper the angle of the avatar's upper body with respect to its forward-facing direction * @param seq_time na + * @param unk1 na + * @param is_crouching avatar is crouching + * @param is_jumping avatar is jumping; + * must remain flagged for jump to maintain animation + * @param jump_thrust provide a measure of vertical stability when really close to the avatar character + * @param is_cloaked avatar is cloaked by virtue of an Infiltration Suit + * @param unk2 na * @param unk3 na - * @param is_crouching whether the player is crouched - * @param is_jumping na - * @param unk4 na - * @param is_cloaking whether the player is cloaked by virtue of an Infiltration Suit - * @param unk5 na - * @param unk6 na */ final case class PlayerStateMessageUpstream(avatar_guid : PlanetSideGUID, pos : Vector3, vel : Option[Vector3], - unk1 : Int, - aim_pitch : Int, - unk2 : Int, + facingYaw : Int, + facingPitch : Int, + facingYawUpper : Int, seq_time : Int, - unk3 : Int, + unk1 : Int, is_crouching : Boolean, is_jumping : Boolean, - unk4 : Boolean, - is_cloaking : Boolean, - unk5 : Int, - unk6 : Int) + jump_thrust : Boolean, + is_cloaked : Boolean, + unk2 : Int, + unk3 : Int) extends PlanetSideGamePacket { type Packet = PlayerStateMessageUpstream def opcode = GamePacketOpcode.PlayerStateMessageUpstream @@ -49,19 +52,19 @@ final case class PlayerStateMessageUpstream(avatar_guid : PlanetSideGUID, object PlayerStateMessageUpstream extends Marshallable[PlayerStateMessageUpstream] { implicit val codec : Codec[PlayerStateMessageUpstream] = ( - ("avatar_guid" | PlanetSideGUID.codec) :: + ("avatar_guid" | PlanetSideGUID.codec) :: ("pos" | Vector3.codec_pos) :: ("vel" | optional(bool, Vector3.codec_vel)) :: - ("unk1" | uint8L) :: - ("aim_pitch" | uint8L) :: - ("unk2" | uint8L) :: + ("facingYaw" | uint8L) :: + ("facingPitch" | uint8L) :: + ("facingYawUpper" | uint8L) :: ("seq_time" | uintL(10)) :: - ("unk3" | uintL(3)) :: + ("unk1" | uintL(3)) :: ("is_crouching" | bool) :: ("is_jumping" | bool) :: - ("unk4" | bool) :: - ("is_cloaking" | bool) :: - ("unk5" | uint8L) :: - ("unk6" | uint16L) + ("jump_thrust" | bool) :: + ("is_cloaked" | bool) :: + ("unk2" | uint8L) :: + ("unk3" | uint16L) ).as[PlayerStateMessageUpstream] } diff --git a/common/src/main/scala/net/psforever/packet/game/UseItemMessage.scala b/common/src/main/scala/net/psforever/packet/game/UseItemMessage.scala index e3bfa7ea..89ca2e2e 100644 --- a/common/src/main/scala/net/psforever/packet/game/UseItemMessage.scala +++ b/common/src/main/scala/net/psforever/packet/game/UseItemMessage.scala @@ -6,6 +6,20 @@ import net.psforever.types.Vector3 import scodec.Codec import scodec.codecs._ +/** + * (Where the child object was before it was moved is not specified or important.)
+ * @param avatar_guid the player. + * @param unk1 dont know how call that. It's the "item" ID when use a rek to hack or a medkit to heal. + * @param object_guid can be : Door, Terminal, Avatar (medkit). + * @param unk2 ??? + * @param unk3 ??? true when use a rek (false when door, medkit or open equip term) + * @param unk4 ??? + * @param unk5 ??? + * @param unk6 ??? + * @param unk7 ??? 25 when door 223 when terminal + * @param unk8 ??? 0 when door 1 when use rek (252 then equipment term) + * @param itemType object ID from game_objects.adb (ex 612 is an equipment terminal, for medkit we have 121 (avatar)) + */ final case class UseItemMessage(avatar_guid : PlanetSideGUID, unk1 : Int, object_guid : PlanetSideGUID, @@ -16,7 +30,7 @@ final case class UseItemMessage(avatar_guid : PlanetSideGUID, unk6 : Int, unk7 : Int, unk8 : Int, - unk9 : Long) + itemType : Long) extends PlanetSideGamePacket { type Packet = UseItemMessage def opcode = GamePacketOpcode.UseItemMessage @@ -35,6 +49,6 @@ object UseItemMessage extends Marshallable[UseItemMessage] { ("unk6" | uint8L) :: ("unk7" | uint8L) :: ("unk8" | uint8L) :: - ("unk9" | uint32L) + ("itemType" | uint32L) ).as[UseItemMessage] } diff --git a/common/src/test/scala/game/DestroyDisplayMessageTest.scala b/common/src/test/scala/game/DestroyDisplayMessageTest.scala index 16da70e3..e486b9df 100644 --- a/common/src/test/scala/game/DestroyDisplayMessageTest.scala +++ b/common/src/test/scala/game/DestroyDisplayMessageTest.scala @@ -12,15 +12,15 @@ class DestroyDisplayMessageTest extends Specification { "decode" in { PacketCoding.DecodePacket(string).require match { - case DestroyDisplayMessage(killer, killer_unk, killer_empire, killer_inVehicle, unk, method, victim, victim_unk, victim_empire, victim_inVehicle) => + case DestroyDisplayMessage(killer, killer_charId, killer_empire, killer_inVehicle, unk, method, victim, victim_charId, victim_empire, victim_inVehicle) => killer mustEqual "Angello" - killer_unk mustEqual 30981173 + killer_charId mustEqual 30981173 killer_empire mustEqual PlanetSideEmpire.VS killer_inVehicle mustEqual false unk mustEqual 121 method mustEqual 969 victim mustEqual "HMFIC" - victim_unk mustEqual 31035057 + victim_charId mustEqual 31035057 victim_empire mustEqual PlanetSideEmpire.TR victim_inVehicle mustEqual false case _ => diff --git a/common/src/test/scala/game/PlayerStateMessageUpstreamTest.scala b/common/src/test/scala/game/PlayerStateMessageUpstreamTest.scala index 9b12086f..a95286da 100644 --- a/common/src/test/scala/game/PlayerStateMessageUpstreamTest.scala +++ b/common/src/test/scala/game/PlayerStateMessageUpstreamTest.scala @@ -12,21 +12,21 @@ class PlayerStateMessageUpstreamTest extends Specification { "decode" in { PacketCoding.DecodePacket(string).require match { - case PlayerStateMessageUpstream(avatar_guid, pos, vel, unk1, aim_pitch, unk2, seq_time, unk3, is_crouching, unk4, unk5, is_cloaking, unk6, unk7) => + case PlayerStateMessageUpstream(avatar_guid, pos, vel, facingYaw, facingPitch, facingYawUpper, seq_time, unk1, is_crouching, is_jumping, jump_thrust, is_cloaked, unk2, unk3) => avatar_guid mustEqual PlanetSideGUID(75) pos mustEqual Vector3(3694.1094f, 2735.4531f, 90.84375f) vel mustEqual Some(Vector3(4.375f, 2.59375f, 0.0f)) - unk1 mustEqual 10 - aim_pitch mustEqual 3 - unk2 mustEqual 0 + facingYaw mustEqual 10 + facingPitch mustEqual 3 + facingYawUpper mustEqual 0 seq_time mustEqual 136 - unk3 mustEqual 0 + unk1 mustEqual 0 is_crouching mustEqual false - unk4 mustEqual false - unk5 mustEqual false - is_cloaking mustEqual false - unk6 mustEqual 112 - unk7 mustEqual 0 + is_jumping mustEqual false + jump_thrust mustEqual false + is_cloaked mustEqual false + unk2 mustEqual 112 + unk3 mustEqual 0 case _ => ko } diff --git a/common/src/test/scala/game/UseItemMessageTest.scala b/common/src/test/scala/game/UseItemMessageTest.scala index b23e48c5..f6aca334 100644 --- a/common/src/test/scala/game/UseItemMessageTest.scala +++ b/common/src/test/scala/game/UseItemMessageTest.scala @@ -12,7 +12,7 @@ class UseItemMessageTest extends Specification { "decode" in { PacketCoding.DecodePacket(string).require match { - case UseItemMessage(avatar_guid, unk1, object_guid, unk2, unk3, unk4, unk5, unk6, unk7, unk8, unk9) => + case UseItemMessage(avatar_guid, unk1, object_guid, unk2, unk3, unk4, unk5, unk6, unk7, unk8, itemType) => avatar_guid mustEqual PlanetSideGUID(75) unk1 mustEqual 0 object_guid mustEqual PlanetSideGUID(372) @@ -23,7 +23,7 @@ class UseItemMessageTest extends Specification { unk6 mustEqual 11 unk7 mustEqual 25 unk8 mustEqual 0 - unk9 mustEqual 364 + itemType mustEqual 364 case _ => ko } diff --git a/pslogin/src/main/scala/WorldSessionActor.scala b/pslogin/src/main/scala/WorldSessionActor.scala index 7e87ab8b..d7cf6272 100644 --- a/pslogin/src/main/scala/WorldSessionActor.scala +++ b/pslogin/src/main/scala/WorldSessionActor.scala @@ -279,12 +279,14 @@ class WorldSessionActor extends Actor with MDCContextAware { sendResponse(PacketCoding.CreateGamePacket(0, EmoteMsg(avatar_guid, emote))) case msg @ DropItemMessage(item_guid) => + log.info("DropItem: " + msg) //item dropped where you spawn in VS Sanctuary sendResponse(PacketCoding.CreateGamePacket(0, ObjectDetachMessage(PlanetSideGUID(75), item_guid, app.pos, 0, 0, 0))) - log.info("DropItem: " + msg) case msg @ PickupItemMessage(item_guid, player_guid, unk1, unk2) => log.info("PickupItem: " + msg) + sendResponse(PacketCoding.CreateGamePacket(0, PickupItemMessage(item_guid, player_guid, unk1, unk2))) + sendResponse(PacketCoding.CreateGamePacket(0, ObjectAttachMessage(player_guid, item_guid, 250))) // item on mouse case msg @ ReloadMessage(item_guid, ammo_clip, unk1) => log.info("Reload: " + msg) @@ -298,15 +300,20 @@ class WorldSessionActor extends Actor with MDCContextAware { case msg @ ZipLineMessage(player_guid,origin_side,action,id,pos) => log.info("ZipLineMessage: " + msg) - if(action == 0) { - //doing this lets you use the zip line, but you can't get off - //sendResponse(PacketCoding.CreateGamePacket(0,ZipLineMessage(player_guid, origin_side, action, id, pos))) + if (!origin_side && action == 0) { + //doing this lets you use the zip line in one direction, cant come back + sendResponse(PacketCoding.CreateGamePacket(0, ZipLineMessage(player_guid, origin_side, action, id, pos))) } - else if(action == 1) { - //disembark from zipline at destination? + else if (!origin_side && action == 1) { + //disembark from zipline at destination ! + sendResponse(PacketCoding.CreateGamePacket(0, ZipLineMessage(player_guid, origin_side, action, 0, pos))) } - else if(action == 2) { + else if (!origin_side && action == 2) { //get off by force + sendResponse(PacketCoding.CreateGamePacket(0, ZipLineMessage(player_guid, origin_side, action, 0, pos))) + } + else if (origin_side && action == 0) { + // for teleporters & the other zipline direction } case msg @ RequestDestroyMessage(object_guid) => @@ -325,15 +332,17 @@ class WorldSessionActor extends Actor with MDCContextAware { case msg @ ChangeAmmoMessage(item_guid, unk1) => log.info("ChangeAmmo: " + msg) - case msg @ UseItemMessage(avatar_guid, unk1, object_guid, unk2, unk3, unk4, unk5, unk6, unk7, unk8, unk9) => + case msg @ UseItemMessage(avatar_guid, unk1, object_guid, unk2, unk3, unk4, unk5, unk6, unk7, unk8, itemType) => log.info("UseItem: " + msg) // TODO: Not all fields in the response are identical to source in real packet logs (but seems to be ok) // TODO: Not all incoming UseItemMessage's respond with another UseItemMessage (i.e. doors only send out GenericObjectStateMsg) - sendResponse(PacketCoding.CreateGamePacket(0, UseItemMessage(avatar_guid, unk1, object_guid, unk2, unk3, unk4, unk5, unk6, unk7, unk8, unk9))) - if(unk1 != 0){ // TODO : medkit use ?! - sendResponse(PacketCoding.CreateGamePacket(0, GenericObjectStateMsg(object_guid, 16))) + if (itemType != 121) sendResponse(PacketCoding.CreateGamePacket(0, UseItemMessage(avatar_guid, unk1, object_guid, unk2, unk3, unk4, unk5, unk6, unk7, unk8, itemType))) + if (itemType == 121 && !unk3){ // TODO : medkit use ?! + sendResponse(PacketCoding.CreateGamePacket(0, UseItemMessage(avatar_guid, unk1, object_guid, 0, unk3, unk4, unk5, unk6, unk7, unk8, itemType))) + sendResponse(PacketCoding.CreateGamePacket(0, PlanetsideAttributeMessage(avatar_guid, 0, 100))) // avatar with 100 hp sendResponse(PacketCoding.CreateGamePacket(0, ObjectDeleteMessage(PlanetSideGUID(unk1), 2))) - } else { + } + if (unk1 == 0 && !unk3 && unk7 == 25) { // TODO: This should only actually be sent to doors upon opening; may break non-door items upon use sendResponse(PacketCoding.CreateGamePacket(0, GenericObjectStateMsg(object_guid, 16))) }