From 7c1df1cb16f90e6895d9667a3465629840e2830e Mon Sep 17 00:00:00 2001 From: FateJH Date: Sat, 24 Sep 2016 00:17:08 -0400 Subject: [PATCH 1/2] added BattleExperienceMessage packet and tests --- .../psforever/packet/GamePacketOpcode.scala | 2 +- .../packet/game/BattleExperienceMessage.scala | 39 +++++++++++++++++++ common/src/test/scala/GamePacketTest.scala | 22 +++++++++++ 3 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 common/src/main/scala/net/psforever/packet/game/BattleExperienceMessage.scala diff --git a/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala b/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala index 6e9984e5d..01cc94374 100644 --- a/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala +++ b/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala @@ -532,7 +532,7 @@ object GamePacketOpcode extends Enumeration { case 0xb1 => noDecoder(VoiceHostKill) case 0xb2 => noDecoder(VoiceHostInfo) case 0xb3 => noDecoder(BattleplanMessage) - case 0xb4 => noDecoder(BattleExperienceMessage) + case 0xb4 => game.BattleExperienceMessage.decode case 0xb5 => noDecoder(TargetingImplantRequest) case 0xb6 => game.ZonePopulationUpdateMessage.decode case 0xb7 => noDecoder(DisconnectMessage) diff --git a/common/src/main/scala/net/psforever/packet/game/BattleExperienceMessage.scala b/common/src/main/scala/net/psforever/packet/game/BattleExperienceMessage.scala new file mode 100644 index 000000000..542f76daf --- /dev/null +++ b/common/src/main/scala/net/psforever/packet/game/BattleExperienceMessage.scala @@ -0,0 +1,39 @@ +// 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._ + +/** + * Inform the client how many battle experience points (BEP) the player currently has earned.
+ *
+ * The amount of `experience` earned is an accumulating value. + * Whenever the server sends this packet, the value of this field is equal to the player's current total BEP. + * Each packet updates to a higher BEP score and the client occasionally reports of the difference as an event message. + * "You have been awarded `x` battle experience points." + * Milestone notifications that occur due to BEP gain, e.g., rank progression, will trigger naturally as the client is updated.
+ *
+ * It is possible to award more battle experience than is necessary to progress one's character to the highest battle rank. + * (This must be accomplished in a single event packet.) + * Only the most significant notification will be displayed. + * @param player_guid the player + * @param experience the current total experience + * @param unk na; always zero? + */ +final case class BattleExperienceMessage(player_guid : PlanetSideGUID, + experience : Long, + unk : Int) + extends PlanetSideGamePacket { + type Packet = BattleExperienceMessage + def opcode = GamePacketOpcode.BattleExperienceMessage + def encode = BattleExperienceMessage.encode(this) +} + +object BattleExperienceMessage extends Marshallable[BattleExperienceMessage] { + implicit val codec : Codec[BattleExperienceMessage] = ( + ("player_guid" | PlanetSideGUID.codec) :: + ("experience" | ulongL(32)) :: + ("unk" | uint8L) + ).as[BattleExperienceMessage] +} diff --git a/common/src/test/scala/GamePacketTest.scala b/common/src/test/scala/GamePacketTest.scala index 2f7e8a11d..a1b6a9c7c 100644 --- a/common/src/test/scala/GamePacketTest.scala +++ b/common/src/test/scala/GamePacketTest.scala @@ -703,6 +703,28 @@ class GamePacketTest extends Specification { } } + "BattleExperienceMessage" should { + val string = hex"B4 8A0A E7030000 00" + + "decode" in { + PacketCoding.DecodePacket(string).require match { + case BattleExperienceMessage(player_guid, experience, unk) => + player_guid mustEqual PlanetSideGUID(2698) + experience mustEqual 999 + unk mustEqual 0 + case default => + ko + } + } + + "encode" in { + val msg = BattleExperienceMessage(PlanetSideGUID(2698), 999, 0) + val pkt = PacketCoding.EncodePacket(msg).require.toByteVector + + pkt mustEqual string + } + } + "ZonePopulationUpdateMessage" should { val string = hex"B6 0400 9E010000 8A000000 25000000 8A000000 25000000 8A000000 25000000 8A000000 25000000" From 318771ec824e7702044cf67a1f88fe2a350e734c Mon Sep 17 00:00:00 2001 From: FateJH Date: Tue, 10 Jan 2017 23:36:57 -0500 Subject: [PATCH 2/2] clarifying parameter (partially) --- .../packet/game/BattleExperienceMessage.scala | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/common/src/main/scala/net/psforever/packet/game/BattleExperienceMessage.scala b/common/src/main/scala/net/psforever/packet/game/BattleExperienceMessage.scala index 542f76daf..163db697d 100644 --- a/common/src/main/scala/net/psforever/packet/game/BattleExperienceMessage.scala +++ b/common/src/main/scala/net/psforever/packet/game/BattleExperienceMessage.scala @@ -16,14 +16,25 @@ import scodec.codecs._ *
* It is possible to award more battle experience than is necessary to progress one's character to the highest battle rank. * (This must be accomplished in a single event packet.) - * Only the most significant notification will be displayed. + * Only the most significant notifications will be displayed in that case. + * If the BEP has been modified, there will be an extra three bits to indicate which message to display.
+ *
+ * Messages:
+ * 0 - Normal
+ * 1 - Normal (repeat?)
+ * 2 - Support bonus ("due to support activity")
+ * 4 - Rabbit bonus ("+25% rabbit Bonus")
+ * (Support message has priority over Rabbit message.)
+ *
+ * Exploration:
+ * `msg = 1` probably does not do the same thing as `mod = 0`. * @param player_guid the player * @param experience the current total experience - * @param unk na; always zero? + * @param msg modifies the awarded experience message */ final case class BattleExperienceMessage(player_guid : PlanetSideGUID, experience : Long, - unk : Int) + msg : Int) extends PlanetSideGamePacket { type Packet = BattleExperienceMessage def opcode = GamePacketOpcode.BattleExperienceMessage @@ -33,7 +44,7 @@ final case class BattleExperienceMessage(player_guid : PlanetSideGUID, object BattleExperienceMessage extends Marshallable[BattleExperienceMessage] { implicit val codec : Codec[BattleExperienceMessage] = ( ("player_guid" | PlanetSideGUID.codec) :: - ("experience" | ulongL(32)) :: - ("unk" | uint8L) + ("experience" | uint32L) :: + ("msg" | uintL(3)) ).as[BattleExperienceMessage] }