added enumeration for squad waypoints and changed field datatypes where appriopriate; added assertions to squad detail packet; removed old logic from squad request and squad response enumerations; WSA lfs -> lfsm

This commit is contained in:
FateJH 2019-10-20 15:34:01 -04:00
parent aa2e0089a4
commit 93f2264f61
12 changed files with 71 additions and 68 deletions

View file

@ -3,6 +3,7 @@ package net.psforever.objects.teamwork
import akka.actor.{Actor, ActorContext, ActorRef, Cancellable, Props}
import net.psforever.objects.DefaultCancellable
import net.psforever.types.SquadWaypoints
import services.teamwork.SquadService.WaypointData
import services.teamwork.SquadSwitchboard
@ -70,7 +71,7 @@ class SquadFeatures(val Squad : Squad) {
def Start(implicit context : ActorContext) : SquadFeatures = {
switchboard = context.actorOf(Props[SquadSwitchboard], s"squad${Squad.GUID.guid}")
waypoints = Array.fill[WaypointData](5)(new WaypointData())
waypoints = Array.fill[WaypointData](SquadWaypoints.values.size)(new WaypointData())
this
}

View file

@ -114,7 +114,10 @@ final case class SquadPositionDetail(is_closed : Option[Boolean],
* when 255, this indicated the end of enumerated squad position data and the data for that position is absent
* @param info the squad position field data
*/
final case class SquadPositionEntry(index : Int, info : Option[SquadPositionDetail])
final case class SquadPositionEntry(index : Int, info : Option[SquadPositionDetail]) {
assert((index > -1 && index < 10) || index == 255, "index value is out of range 0=>n<=9 or n=255")
assert(if(index == 255) { info.isEmpty } else { true }, "index=255 indicates end of stream exclusively and field data should be blank")
}
/**
* Information regarding a squad's position as a series of common fields.

View file

@ -1,8 +1,8 @@
// Copyright (c) 2017 PSForever
// Copyright (c) 2019 PSForever
package net.psforever.packet.game
import net.psforever.packet.{GamePacketOpcode, Marshallable, PlanetSideGamePacket}
import net.psforever.types.Vector3
import net.psforever.types.{SquadWaypoints, Vector3}
import scodec.{Attempt, Codec, Err}
import scodec.codecs._
import shapeless.{::, HNil}
@ -14,7 +14,7 @@ final case class WaypointEvent(zone_number : Int,
final case class SquadWaypointEvent(event_type : WaypointEventAction.Value,
unk : Int,
char_id : Long,
waypoint_type : Int,
waypoint_type : SquadWaypoints.Value,
unk5 : Option[Long],
waypoint_info : Option[WaypointEvent])
extends PlanetSideGamePacket {
@ -24,13 +24,13 @@ final case class SquadWaypointEvent(event_type : WaypointEventAction.Value,
}
object SquadWaypointEvent extends Marshallable[SquadWaypointEvent] {
def Add(unk : Int, char_id : Long, waypoint_type : Int, waypoint : WaypointEvent) : SquadWaypointEvent =
def Add(unk : Int, char_id : Long, waypoint_type : SquadWaypoints.Value, waypoint : WaypointEvent) : SquadWaypointEvent =
SquadWaypointEvent(WaypointEventAction.Add, unk, char_id, waypoint_type, None, Some(waypoint))
def Unknown1(unk : Int, char_id : Long, waypoint_type : Int, unk_a : Long) : SquadWaypointEvent =
def Unknown1(unk : Int, char_id : Long, waypoint_type : SquadWaypoints.Value, unk_a : Long) : SquadWaypointEvent =
SquadWaypointEvent(WaypointEventAction.Unknown1, unk, char_id, waypoint_type, Some(unk_a), None)
def Remove(unk : Int, char_id : Long, waypoint_type : Int) : SquadWaypointEvent =
def Remove(unk : Int, char_id : Long, waypoint_type : SquadWaypoints.Value) : SquadWaypointEvent =
SquadWaypointEvent(WaypointEventAction.Remove, unk, char_id, waypoint_type, None, None)
private val waypoint_codec : Codec[WaypointEvent] = (
@ -43,7 +43,7 @@ object SquadWaypointEvent extends Marshallable[SquadWaypointEvent] {
("event_type" | WaypointEventAction.codec) >>:~ { event_type =>
("unk" | uint16L) ::
("char_id" | uint32L) ::
("waypoint_type" | uint8L) ::
("waypoint_type" | SquadWaypoints.codec) ::
("unk5" | conditional(event_type == WaypointEventAction.Unknown1, uint32L)) ::
("waypoint_info" | conditional(event_type == WaypointEventAction.Add, waypoint_codec))
}

View file

@ -2,7 +2,7 @@
package net.psforever.packet.game
import net.psforever.packet.{GamePacketOpcode, Marshallable, PacketHelpers, PlanetSideGamePacket}
import net.psforever.types.Vector3
import net.psforever.types.{SquadWaypoints, Vector3}
import scodec.{Attempt, Codec, Err}
import scodec.codecs._
import shapeless.{::, HNil}
@ -46,7 +46,7 @@ final case class WaypointInfo(zone_number : Int,
*/
final case class SquadWaypointRequest(request_type : WaypointEventAction.Value,
char_id : Long,
waypoint_type : Int,
waypoint_type : SquadWaypoints.Value,
unk4 : Option[Long],
waypoint_info : Option[WaypointInfo])
extends PlanetSideGamePacket {
@ -56,13 +56,13 @@ final case class SquadWaypointRequest(request_type : WaypointEventAction.Value,
}
object SquadWaypointRequest extends Marshallable[SquadWaypointRequest] {
def Add(char_id : Long, waypoint_type : Int, waypoint : WaypointInfo) : SquadWaypointRequest =
def Add(char_id : Long, waypoint_type : SquadWaypoints.Value, waypoint : WaypointInfo) : SquadWaypointRequest =
SquadWaypointRequest(WaypointEventAction.Add, char_id, waypoint_type, None, Some(waypoint))
def Unknown1(char_id : Long, waypoint_type : Int, unk_a : Long) : SquadWaypointRequest =
def Unknown1(char_id : Long, waypoint_type : SquadWaypoints.Value, unk_a : Long) : SquadWaypointRequest =
SquadWaypointRequest(WaypointEventAction.Unknown1, char_id, waypoint_type, Some(unk_a), None)
def Remove(char_id : Long, waypoint_type : Int) : SquadWaypointRequest =
def Remove(char_id : Long, waypoint_type : SquadWaypoints.Value) : SquadWaypointRequest =
SquadWaypointRequest(WaypointEventAction.Remove, char_id, waypoint_type, None, None)
private val waypoint_codec : Codec[WaypointInfo] = (
@ -80,7 +80,7 @@ object SquadWaypointRequest extends Marshallable[SquadWaypointRequest] {
implicit val codec : Codec[SquadWaypointRequest] = (
("request_type" | WaypointEventAction.codec) >>:~ { request_type =>
("char_id" | uint32L) ::
("waypoint_type" | uint8L) ::
("waypoint_type" | SquadWaypoints.codec) ::
("unk4" | conditional(request_type == WaypointEventAction.Unknown1, uint32L)) ::
("waypoint" | conditional(request_type == WaypointEventAction.Add, waypoint_codec))
}

View file

@ -24,11 +24,4 @@ object SquadRequestType extends Enumeration {
= Value
implicit val codec = PacketHelpers.createEnumerationCodec(this, uint4L)
def toResponse(request : SquadRequestType.Value) : SquadResponseType.Value = {
val id = request.id
if(id < 6) SquadResponseType(id)
else if(id > 6) SquadResponseType(id - 1)
else throw new NoSuchElementException("request does not have an applicable response")
}
}

View file

@ -23,11 +23,4 @@ object SquadResponseType extends Enumeration {
= Value
implicit val codec = PacketHelpers.createEnumerationCodec(this, uint4L)
def fromRequest(response : SquadResponseType.Value) : SquadRequestType.Value = {
val id = response.id
if(id < 6) SquadRequestType(id)
else if(id > 5) SquadRequestType(id + 1)
else throw new NoSuchElementException("response does not stem from an applicable request")
}
}

View file

@ -0,0 +1,18 @@
// Copyright (c) 2019 PSForever
package net.psforever.types
import net.psforever.packet.PacketHelpers
import scodec.codecs._
object SquadWaypoints extends Enumeration {
type Type = Value
val
One,
Two,
Three,
Four,
ExperienceRally
= Value
implicit val codec = PacketHelpers.createEnumerationCodec(this, uint8L)
}

View file

@ -3,7 +3,7 @@ package services.teamwork
import net.psforever.objects.zones.Zone
import net.psforever.packet.game._
import net.psforever.types.{PlanetSideEmpire, SquadRequestType, Vector3}
import net.psforever.types.{PlanetSideEmpire, SquadRequestType, SquadWaypoints, Vector3}
object SquadAction {
trait Action
@ -13,6 +13,6 @@ object SquadAction {
final case class Definition(guid : PlanetSideGUID, line : Int, action : SquadAction) extends Action
final case class Membership(request_type : SquadRequestType.Value, unk2 : Long, unk3 : Option[Long], player_name : String, unk5 : Option[Option[String]]) extends Action
final case class Waypoint(event_type : WaypointEventAction.Value, waypoint_type : Int, unk : Option[Long], waypoint_info : Option[WaypointInfo]) extends Action
final case class Waypoint(event_type : WaypointEventAction.Value, waypoint_type : SquadWaypoints.Value, unk : Option[Long], waypoint_info : Option[WaypointInfo]) extends Action
final case class Update(char_id : Long, health : Int, max_health : Int, armor : Int, max_armor : Int, pos : Vector3, zone_number : Int) extends Action
}

View file

@ -3,7 +3,7 @@ package services.teamwork
import net.psforever.objects.teamwork.Squad
import net.psforever.packet.game._
import net.psforever.types.SquadResponseType
import net.psforever.types.{SquadResponseType, SquadWaypoints}
object SquadResponse {
trait Response
@ -27,8 +27,8 @@ object SquadResponse {
final case class Detail(guid : PlanetSideGUID, squad_detail : SquadDetail) extends Response
final case class InitWaypoints(char_id : Long, waypoints : Iterable[(Int, WaypointInfo, Int)]) extends Response
final case class WaypointEvent(event_type : WaypointEventAction.Value, char_id : Long, waypoint_type : Int, unk5 : Option[Long], waypoint_info : Option[WaypointInfo], unk : Int) extends Response
final case class InitWaypoints(char_id : Long, waypoints : Iterable[(SquadWaypoints.Value, WaypointInfo, Int)]) extends Response
final case class WaypointEvent(event_type : WaypointEventAction.Value, char_id : Long, waypoint_type : SquadWaypoints.Value, unk5 : Option[Long], waypoint_info : Option[WaypointInfo], unk : Int) extends Response
final case class SquadSearchResults() extends Response
}

View file

@ -2544,16 +2544,14 @@ class SquadService extends Actor {
* @see `SquadWaypointRequest`
* @see `WaypointInfo`
* @param guid the squad's unique identifier
* @param waypointType the type of the waypoint as an integer;
* 0-4 are squad waypoints;
* 5 is the squad leader's experience waypoint
* @param waypointType the type of the waypoint
* @param info information about the waypoint, as was reported by the client's packet
* @return the waypoint data, if the waypoint type is changed
*/
def AddWaypoint(guid : PlanetSideGUID, waypointType : Int, info : WaypointInfo) : Option[WaypointData] = {
def AddWaypoint(guid : PlanetSideGUID, waypointType : SquadWaypoints.Value, info : WaypointInfo) : Option[WaypointData] = {
squadFeatures.get(guid) match {
case Some(features) =>
features.Waypoints.lift(waypointType) match {
features.Waypoints.lift(waypointType.id) match {
case Some(point) =>
point.zone_number = info.zone_number
point.pos = info.pos
@ -2576,14 +2574,12 @@ class SquadService extends Actor {
* All of the waypoints constantly exist as long as the squad to which they are attached exists.
* They are merely "activated" and "deactivated."
* @param guid the squad's unique identifier
* @param waypointType the type of the waypoint as an integer;
* 0-4 are squad waypoints;
* 5 is the squad leader's experience waypoint
* @param waypointType the type of the waypoint
*/
def RemoveWaypoint(guid : PlanetSideGUID, waypointType : Int) : Unit = {
def RemoveWaypoint(guid : PlanetSideGUID, waypointType : SquadWaypoints.Value) : Unit = {
squadFeatures.get(guid) match {
case Some(features) =>
features.Waypoints.lift(waypointType) match {
features.Waypoints.lift(waypointType.id) match {
case Some(point) =>
point.pos = Vector3.z(1)
case _ =>
@ -2608,7 +2604,7 @@ class SquadService extends Actor {
Publish(
toCharId, SquadResponse.InitWaypoints(squad.Leader.CharId,
list.zipWithIndex.collect { case (point, index) if point.pos != vz1 =>
(index, WaypointInfo(point.zone_number, point.pos), 1)
(SquadWaypoints(index), WaypointInfo(point.zone_number, point.pos), 1)
}
)
)

View file

@ -3,8 +3,8 @@ package game
import org.specs2.mutable._
import net.psforever.packet._
import net.psforever.packet.game.{SquadWaypointEvent, WaypointEventAction, WaypointEvent}
import net.psforever.types.Vector3
import net.psforever.packet.game.{SquadWaypointEvent, WaypointEvent, WaypointEventAction}
import net.psforever.types.{SquadWaypoints, Vector3}
import scodec.bits._
class SquadWaypointEventTest extends Specification {
@ -19,7 +19,7 @@ class SquadWaypointEventTest extends Specification {
unk1 mustEqual WaypointEventAction.Remove
unk2 mustEqual 11
unk3 mustEqual 31155863L
unk4 mustEqual 0
unk4 mustEqual SquadWaypoints.One
unk5.isEmpty mustEqual true
unk6.isEmpty mustEqual true
case _ =>
@ -33,7 +33,7 @@ class SquadWaypointEventTest extends Specification {
unk1 mustEqual WaypointEventAction.Remove
unk2 mustEqual 10
unk3 mustEqual 0L
unk4 mustEqual 4
unk4 mustEqual SquadWaypoints.ExperienceRally
unk5.isEmpty mustEqual true
unk6.isEmpty mustEqual true
case _ =>
@ -47,7 +47,7 @@ class SquadWaypointEventTest extends Specification {
unk1 mustEqual WaypointEventAction.Add
unk2 mustEqual 3
unk3 mustEqual 41581052L
unk4 mustEqual 1
unk4 mustEqual SquadWaypoints.Two
unk5.isEmpty mustEqual true
unk6.contains( WaypointEvent(10, Vector3(3457.9688f, 5514.4688f, 0.0f), 1) ) mustEqual true
case _ =>
@ -61,7 +61,7 @@ class SquadWaypointEventTest extends Specification {
unk1 mustEqual WaypointEventAction.Unknown1
unk2 mustEqual 3
unk3 mustEqual 41581052L
unk4 mustEqual 1
unk4 mustEqual SquadWaypoints.Two
unk5.contains( 4L ) mustEqual true
unk6.isEmpty mustEqual true
case _ =>
@ -70,28 +70,28 @@ class SquadWaypointEventTest extends Specification {
}
"encode (1)" in {
val msg = SquadWaypointEvent.Remove(11, 31155863L, 0)
val msg = SquadWaypointEvent.Remove(11, 31155863L, SquadWaypoints.One)
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
pkt mustEqual string_1
}
"encode (2)" in {
val msg = SquadWaypointEvent.Remove(10, 0L, 4)
val msg = SquadWaypointEvent.Remove(10, 0L, SquadWaypoints.ExperienceRally)
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
pkt mustEqual string_2
}
"encode (3)" in {
val msg = SquadWaypointEvent.Add(3, 41581052L, 1, WaypointEvent(10, Vector3(3457.9688f, 5514.4688f, 0.0f), 1))
val msg = SquadWaypointEvent.Add(3, 41581052L, SquadWaypoints.Two, WaypointEvent(10, Vector3(3457.9688f, 5514.4688f, 0.0f), 1))
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
pkt mustEqual string_3
}
"encode (4)" in {
val msg = SquadWaypointEvent.Unknown1(3, 41581052L, 1, 4L)
val msg = SquadWaypointEvent.Unknown1(3, 41581052L, SquadWaypoints.Two, 4L)
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
pkt mustEqual string_4