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 0x09 => game.HitMessage.decode
case 0x0a => game.HitHint.decode case 0x0a => game.HitHint.decode
case 0x0b => noDecoder(DamageMessage) case 0x0b => noDecoder(DamageMessage)
case 0x0c => noDecoder(DestroyMessage) case 0x0c => game.DestroyMessage.decode
case 0x0d => game.ReloadMessage.decode case 0x0d => game.ReloadMessage.decode
case 0x0e => game.MountVehicleMsg.decode case 0x0e => game.MountVehicleMsg.decode
case 0x0f => game.DismountVehicleMsg.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._ 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> * Players/General:<br>
* Server to client : <br> * Server to client : <br>
* `0 - health`<br> * `0 - health`<br>
@ -91,7 +116,6 @@ import scodec.codecs._
* `106 - Custom Head`<br> * `106 - Custom Head`<br>
* <br> * <br>
* `Vehicles:`<br> * `Vehicles:`<br>
* `0 - Vehicle base health`<br>
* `10 - Driver seat permissions (0 = Locked, 1 = Group, 3 = Empire)`<br> * `10 - Driver seat permissions (0 = Locked, 1 = Group, 3 = Empire)`<br>
* `11 - Gunner seat(s) permissions (same)`<br> * `11 - Gunner seat(s) permissions (same)`<br>
* `12 - Passenger 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 val vehicle_guid = obj.GUID
if(state == DriveState.Deploying) { if(state == DriveState.Deploying) {
log.info(s"DeployRequest: $obj transitioning to deploy state") 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)) 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)) vehicleService ! VehicleServiceMessage(continent.Id, VehicleAction.DeployRequest(player.GUID, vehicle_guid, state, 0, false, obj.Position))
import scala.concurrent.duration._ import scala.concurrent.duration._
@ -1026,6 +1027,10 @@ class WorldSessionActor extends Actor with MDCContextAware {
sendResponse(CreateShortcutMessage(guid, 1, 0, true, Shortcut.MEDKIT)) sendResponse(CreateShortcutMessage(guid, 1, 0, true, Shortcut.MEDKIT))
sendResponse(ChatMsg(ChatMessageType.CMT_EXPANSIONS, true, "", "1 on", None)) //CC on 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) => case Zone.ItemFromGround(tplayer, item) =>
val obj_guid = item.GUID val obj_guid = item.GUID
val player_guid = tplayer.GUID val player_guid = tplayer.GUID
@ -1211,7 +1216,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.ExecutionContext.Implicits.global
clientKeepAlive.cancel clientKeepAlive.cancel
clientKeepAlive = context.system.scheduler.schedule(0 seconds, 500 milliseconds, self, PokeClient()) 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) => case msg @ CharacterCreateRequestMessage(name, head, voice, gender, empire) =>
log.info("Handling " + msg) log.info("Handling " + msg)
sendResponse(ActionResultMessage(true, None)) sendResponse(ActionResultMessage(true, None))
@ -1239,13 +1244,80 @@ class WorldSessionActor extends Actor with MDCContextAware {
log.info("Reticulating splines ...") log.info("Reticulating splines ...")
//map-specific initializations //map-specific initializations
//TODO continent.ClientConfiguration() //TODO continent.ClientConfiguration()
sendResponse(PacketCoding.CreateGamePacket(0, PlanetsideAttributeMessage(PlanetSideGUID(0), 112, 1)))
sendResponse(SetEmpireMessage(PlanetSideGUID(2), PlanetSideEmpire.VS)) //HART building C sendResponse(SetEmpireMessage(PlanetSideGUID(2), PlanetSideEmpire.VS)) //HART building C
sendResponse(SetEmpireMessage(PlanetSideGUID(29), PlanetSideEmpire.NC)) //South Villa Gun Tower sendResponse(SetEmpireMessage(PlanetSideGUID(29), PlanetSideEmpire.NC)) //South Villa Gun Tower
sendResponse(TimeOfDayMessage(1191182336)) sendResponse(TimeOfDayMessage(1191182336))
sendResponse(ReplicationStreamMessage(5, Some(6), Vector(SquadListing()))) //clear squad list 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 => { continent.EquipmentOnGround.foreach(item => {
val definition = item.Definition val definition = item.Definition
sendResponse( sendResponse(
@ -1399,8 +1471,8 @@ class WorldSessionActor extends Actor with MDCContextAware {
case msg @ ReleaseAvatarRequestMessage() => case msg @ ReleaseAvatarRequestMessage() =>
log.info(s"ReleaseAvatarRequest: ${player.GUID} on ${continent.Id} has released") 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, 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) => case msg @ SpawnRequestMessage(u1, u2, u3, u4, u5) =>
log.info(s"SpawnRequestMessage: $msg") log.info(s"SpawnRequestMessage: $msg")
@ -1412,10 +1484,12 @@ class WorldSessionActor extends Actor with MDCContextAware {
} }
if(messagetype == ChatMessageType.CMT_SUICIDE) { if(messagetype == ChatMessageType.CMT_SUICIDE) {
sendResponse(PacketCoding.CreateGamePacket(0, PlanetsideAttributeMessage(player.GUID, 0, 0))) val player_guid = player.GUID
sendResponse(PacketCoding.CreateGamePacket(0, PlanetsideAttributeMessage(player.GUID, 2, 0))) val pos = player.Position
sendResponse(PacketCoding.CreateGamePacket(0, PlanetsideAttributeMessage(player.GUID, 4, 0))) sendResponse(PacketCoding.CreateGamePacket(0, PlanetsideAttributeMessage(player_guid, 0, 0)))
sendResponse(PacketCoding.CreateGamePacket(0, AvatarDeadStateMessage(DeadState.Dead, 300000, 300000, player.Position, 2, true))) 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) { if (messagetype == ChatMessageType.CMT_VOICE) {