added initial DestroyMessage packet and tests

This commit is contained in:
FateJH 2018-02-27 20:19:14 -05:00
parent 4b2e3763f1
commit e93c510d22
5 changed files with 166 additions and 9 deletions

View file

@ -332,7 +332,7 @@ object GamePacketOpcode extends Enumeration {
case 0x09 => game.HitMessage.decode
case 0x0a => game.HitHint.decode
case 0x0b => noDecoder(DamageMessage)
case 0x0c => noDecoder(DestroyMessage)
case 0x0c => game.DestroyMessage.decode
case 0x0d => game.ReloadMessage.decode
case 0x0e => game.MountVehicleMsg.decode
case 0x0f => game.DismountVehicleMsg.decode

View file

@ -0,0 +1,26 @@
// Copyright (c) 2017 PSForever
package net.psforever.packet.game
import net.psforever.packet.{GamePacketOpcode, Marshallable, PlanetSideGamePacket}
import net.psforever.types.Vector3
import scodec.Codec
import scodec.codecs._
final case class DestroyMessage(unk1 : PlanetSideGUID,
unk2 : PlanetSideGUID,
unk3 : PlanetSideGUID,
pos : Vector3)
extends PlanetSideGamePacket {
type Packet = DestroyMessage
def opcode = GamePacketOpcode.DestroyMessage
def encode = DestroyMessage.encode(this)
}
object DestroyMessage extends Marshallable[DestroyMessage] {
implicit val codec : Codec[DestroyMessage] = (
("unk1" | PlanetSideGUID.codec) ::
("unk2" | PlanetSideGUID.codec) ::
("unk3" | PlanetSideGUID.codec) ::
("pos" | Vector3.codec_pos)
).as[DestroyMessage]
}

View file

@ -6,6 +6,31 @@ import scodec.Codec
import scodec.codecs._
/**
* na<br>
* Global (GUID=0)<br>
* `83 - max boomers`<br>
* `84 - max he mines`<br>
* `85 - max disruptor mines`<br>
* `86 - max spitfire turrets`<br>
* `87 - max motion sensors`<br>
* `88 - max shadow turrets`<br>
* `89 - max cerebus turrets`<br>
* `90 - max Aegis shield generators`<br>
* `91 - max TRAPs`<br>
* `92 - max OMFTs`<br>
* `93 - max sensor disruptors`<br>
* `94 - boomers`<br>
* `95 - he mines`<br>
* `96 - disruptor mines`<br>
* `97 - spitfire turrets`<br>
* `98 - motion sensors`<br>
* `99 - shadow turrets`<br>
* `100 - cerebus turrets`<br>
* `101 - Aegis shield generators`<br>
* `102 - TRAPSs`<br>
* `103 - OMFTs`<br>
* `104 - sensor disruptors`<br>
* <br>
* Players/General:<br>
* Server to client : <br>
* `0 - health`<br>
@ -91,7 +116,6 @@ import scodec.codecs._
* `106 - Custom Head`<br>
* <br>
* `Vehicles:`<br>
* `0 - Vehicle base health`<br>
* `10 - Driver seat permissions (0 = Locked, 1 = Group, 3 = Empire)`<br>
* `11 - Gunner seat(s) permissions (same)`<br>
* `12 - Passenger seat(s) permissions (same)`<br>

View file

@ -0,0 +1,33 @@
// Copyright (c) 2017 PSForever
package game
import org.specs2.mutable._
import net.psforever.packet._
import net.psforever.packet.game._
import net.psforever.types.Vector3
import scodec.bits._
class DestroyMessageTest extends Specification {
val string = hex"0C 74 09 74 09 00 00 06 35 3C FF D7 26 08"
"DestroyMessage" should {
"decode" in {
PacketCoding.DecodePacket(string).require match {
case DestroyMessage(unk1, unk2, unk3, pos) =>
unk1 mustEqual PlanetSideGUID(2420)
unk2 mustEqual PlanetSideGUID(2420)
unk3 mustEqual PlanetSideGUID(0)
pos mustEqual Vector3(1642.0469f, 4091.6172f, 32.59375f)
case _ =>
ko
}
}
"encode" in {
val msg = DestroyMessage(PlanetSideGUID(2420), PlanetSideGUID(2420), PlanetSideGUID(0), Vector3(1642.0469f, 4091.6172f, 32.59375f))
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
pkt mustEqual string
}
}
}

View file

@ -403,6 +403,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
val vehicle_guid = obj.GUID
if(state == DriveState.Deploying) {
log.info(s"DeployRequest: $obj transitioning to deploy state")
obj.Velocity = Some(Vector3.Zero) //no velocity
sendResponse(DeployRequestMessage(player.GUID, vehicle_guid, state, 0, false, obj.Position))
vehicleService ! VehicleServiceMessage(continent.Id, VehicleAction.DeployRequest(player.GUID, vehicle_guid, state, 0, false, obj.Position))
import scala.concurrent.duration._
@ -1026,6 +1027,10 @@ class WorldSessionActor extends Actor with MDCContextAware {
sendResponse(CreateShortcutMessage(guid, 1, 0, true, Shortcut.MEDKIT))
sendResponse(ChatMsg(ChatMessageType.CMT_EXPANSIONS, true, "", "1 on", None)) //CC on
(1 to 73).foreach( i => {
sendResponse(PacketCoding.CreateGamePacket(0, PlanetsideAttributeMessage(PlanetSideGUID(i), 43, 0)))
})
case Zone.ItemFromGround(tplayer, item) =>
val obj_guid = item.GUID
val player_guid = tplayer.GUID
@ -1211,7 +1216,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
import scala.concurrent.ExecutionContext.Implicits.global
clientKeepAlive.cancel
clientKeepAlive = context.system.scheduler.schedule(0 seconds, 500 milliseconds, self, PokeClient())
//log.warn(PacketCoding.DecodePacket(hex"17 6C 00 00 00 03 01 4C 93 70 48 18 00 00 00").toString)
case msg @ CharacterCreateRequestMessage(name, head, voice, gender, empire) =>
log.info("Handling " + msg)
sendResponse(ActionResultMessage(true, None))
@ -1239,13 +1244,80 @@ class WorldSessionActor extends Actor with MDCContextAware {
log.info("Reticulating splines ...")
//map-specific initializations
//TODO continent.ClientConfiguration()
sendResponse(PacketCoding.CreateGamePacket(0, PlanetsideAttributeMessage(PlanetSideGUID(0), 112, 1)))
sendResponse(SetEmpireMessage(PlanetSideGUID(2), PlanetSideEmpire.VS)) //HART building C
sendResponse(SetEmpireMessage(PlanetSideGUID(29), PlanetSideEmpire.NC)) //South Villa Gun Tower
sendResponse(TimeOfDayMessage(1191182336))
sendResponse(ReplicationStreamMessage(5, Some(6), Vector(SquadListing()))) //clear squad list
//render Equipment that was dropped into zone before the player arrived
sendResponse(PacketCoding.CreateGamePacket(0,
BuildingInfoUpdateMessage(
PlanetSideGUID(6),PlanetSideGUID(10),
0,false,PlanetSideEmpire.NEUTRAL,0,PlanetSideEmpire.NEUTRAL,0,None,PlanetSideGeneratorState.Normal,true,false,0,0,Nil,0,false,8,None,false,false
)
))
sendResponse(PacketCoding.CreateGamePacket(0,
BroadcastWarpgateUpdateMessage(PlanetSideGUID(6), PlanetSideGUID(10), true, false, false)
))
sendResponse(PacketCoding.CreateGamePacket(0,
BuildingInfoUpdateMessage(
PlanetSideGUID(6),PlanetSideGUID(11),
0,false,PlanetSideEmpire.NEUTRAL,0,PlanetSideEmpire.NEUTRAL,0,None,PlanetSideGeneratorState.Normal,true,false,0,0,Nil,0,false,8,None,false,false
)
))
sendResponse(PacketCoding.CreateGamePacket(0,
BroadcastWarpgateUpdateMessage(PlanetSideGUID(6), PlanetSideGUID(11), true, false, false)
))
sendResponse(PacketCoding.CreateGamePacket(0,
BuildingInfoUpdateMessage(
PlanetSideGUID(6),PlanetSideGUID(12),
0,false,PlanetSideEmpire.NEUTRAL,0,PlanetSideEmpire.NEUTRAL,0,None,PlanetSideGeneratorState.Normal,true,false,0,0,Nil,0,false,8,None,false,false
)
))
sendResponse(PacketCoding.CreateGamePacket(0,
BroadcastWarpgateUpdateMessage(PlanetSideGUID(6), PlanetSideGUID(12), true, false, false)
))
sendResponse(PacketCoding.CreateGamePacket(0,
BuildingInfoUpdateMessage(
PlanetSideGUID(6),PlanetSideGUID(13),
0,false,PlanetSideEmpire.NEUTRAL,0,PlanetSideEmpire.NEUTRAL,0,None,PlanetSideGeneratorState.Normal,true,false,0,0,Nil,0,false,8,None,false,false
)
))
sendResponse(PacketCoding.CreateGamePacket(0,
BroadcastWarpgateUpdateMessage(PlanetSideGUID(6), PlanetSideGUID(13), true, false, false)
))
sendResponse(PacketCoding.CreateGamePacket(0,
BuildingInfoUpdateMessage(
PlanetSideGUID(6),PlanetSideGUID(18657),
0,false,PlanetSideEmpire.NEUTRAL,0,PlanetSideEmpire.NEUTRAL,0,None,PlanetSideGeneratorState.Normal,true,false,0,0,Nil,0,false,8,None,false,false
)
))
sendResponse(PacketCoding.CreateGamePacket(0,
BroadcastWarpgateUpdateMessage(PlanetSideGUID(6), PlanetSideGUID(18657), true, false, false)
))
sendResponse(PacketCoding.CreateGamePacket(0,
BuildingInfoUpdateMessage(
PlanetSideGUID(6),PlanetSideGUID(18658),
0,false,PlanetSideEmpire.NEUTRAL,0,PlanetSideEmpire.NEUTRAL,0,None,PlanetSideGeneratorState.Normal,true,false,0,0,Nil,0,false,8,None,false,false
)
))
sendResponse(PacketCoding.CreateGamePacket(0,
BroadcastWarpgateUpdateMessage(PlanetSideGUID(6), PlanetSideGUID(18658), true, false, false)
))
sendRawResponse(hex"C0060000") //basic CaptureFlagUpdateMessage
sendResponse(PacketCoding.CreateGamePacket(0, ZoneInfoMessage(6, true, 0)))
sendResponse(PacketCoding.CreateGamePacket(0, ZoneLockInfoMessage(PlanetSideGUID(6), false, true)))
sendResponse(PacketCoding.CreateGamePacket(0, ZonePopulationUpdateMessage(PlanetSideGUID(6), 414, 138, 1, 138, 1, 138, 1, 138, 0)))
sendResponse(PacketCoding.CreateGamePacket(0, PlanetsideAttributeMessage(PlanetSideGUID(2145), 50, 0)))
sendResponse(PacketCoding.CreateGamePacket(0, PlanetsideAttributeMessage(PlanetSideGUID(2145), 51, 0)))
sendResponse(PacketCoding.CreateGamePacket(0, PlanetsideAttributeMessage(PlanetSideGUID(2146), 50, 0)))
sendResponse(PacketCoding.CreateGamePacket(0, PlanetsideAttributeMessage(PlanetSideGUID(2146), 51, 0)))
sendResponse(PacketCoding.CreateGamePacket(0, PlanetsideAttributeMessage(PlanetSideGUID(2147), 50, 0)))
sendResponse(PacketCoding.CreateGamePacket(0, PlanetsideAttributeMessage(PlanetSideGUID(2147), 51, 0)))
//render Equipment that was dropped into zone before the player arrived
continent.EquipmentOnGround.foreach(item => {
val definition = item.Definition
sendResponse(
@ -1399,8 +1471,8 @@ class WorldSessionActor extends Actor with MDCContextAware {
case msg @ ReleaseAvatarRequestMessage() =>
log.info(s"ReleaseAvatarRequest: ${player.GUID} on ${continent.Id} has released")
sendResponse(PacketCoding.CreateGamePacket(0, PlanetsideAttributeMessage(player.GUID, 6, 1)))
sendResponse(PacketCoding.CreateGamePacket(0, AvatarDeadStateMessage(DeadState.Release, 0, 0, player.Position, 2, true)))
//sendResponse(PacketCoding.CreateGamePacket(0, PlanetsideAttributeMessage(player.GUID, 6, 1)))
case msg @ SpawnRequestMessage(u1, u2, u3, u4, u5) =>
log.info(s"SpawnRequestMessage: $msg")
@ -1412,10 +1484,12 @@ class WorldSessionActor extends Actor with MDCContextAware {
}
if(messagetype == ChatMessageType.CMT_SUICIDE) {
sendResponse(PacketCoding.CreateGamePacket(0, PlanetsideAttributeMessage(player.GUID, 0, 0)))
sendResponse(PacketCoding.CreateGamePacket(0, PlanetsideAttributeMessage(player.GUID, 2, 0)))
sendResponse(PacketCoding.CreateGamePacket(0, PlanetsideAttributeMessage(player.GUID, 4, 0)))
sendResponse(PacketCoding.CreateGamePacket(0, AvatarDeadStateMessage(DeadState.Dead, 300000, 300000, player.Position, 2, true)))
val player_guid = player.GUID
val pos = player.Position
sendResponse(PacketCoding.CreateGamePacket(0, PlanetsideAttributeMessage(player_guid, 0, 0)))
sendResponse(PacketCoding.CreateGamePacket(0, PlanetsideAttributeMessage(player_guid, 2, 0)))
sendResponse(PacketCoding.CreateGamePacket(0, DestroyMessage(player_guid, player_guid, PlanetSideGUID(0), pos)))
sendResponse(PacketCoding.CreateGamePacket(0, AvatarDeadStateMessage(DeadState.Dead, 300000, 300000, pos, 2, true)))
}
if (messagetype == ChatMessageType.CMT_VOICE) {