diff --git a/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala b/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala index 20fbcf6ed..a62be6265 100644 --- a/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala +++ b/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala @@ -578,7 +578,7 @@ object GamePacketOpcode extends Enumeration { case WarpgateLinkOverrideMessage => noDecoder(opcode) case EmpireBenefitsMessage => noDecoder(opcode) case ForceEmpireMessage => noDecoder(opcode) - case BroadcastWarpgateUpdateMessage => noDecoder(opcode) + case BroadcastWarpgateUpdateMessage => game.BroadcastWarpgateUpdateMessage.decode case UnknownMessage218 => noDecoder(opcode) case SquadMainTerminalMessage => noDecoder(opcode) diff --git a/common/src/main/scala/net/psforever/packet/game/BroadcastWarpgateUpdateMessage.scala b/common/src/main/scala/net/psforever/packet/game/BroadcastWarpgateUpdateMessage.scala new file mode 100644 index 000000000..71975c42c --- /dev/null +++ b/common/src/main/scala/net/psforever/packet/game/BroadcastWarpgateUpdateMessage.scala @@ -0,0 +1,40 @@ +// 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._ + +/** + * Promotes a Broadcast Warpgate. + * + * Change the map name of a warpgate into "Broadcast Warpgate." + * If a proper warpgate is not designated, nothing happens. + * The input state is a byte starting at 00 where the first valid "on" state is 20. + * Subsequent "on" states are 40 values apart - 20, 60, A0, and E0. + * All other numbers (seem to) default to the normal map designation for the warpgate. + * + * Exploration: is this packet merely cosmetic or does it change the functionality of a warpgate too? + * Exploration: are there any differences between the states besides "on" and "off"? + * + * @param continent_guid identifies the zone (continent) + * @param building_guid identifies the warpgate (see BuildingInfoUpdateMessage) + * @param state whether or not a warpgate is considered "broadcast;" + * 00, 20, 80, and A0 are common values; C0 is an uncommon value + */ +final case class BroadcastWarpgateUpdateMessage(continent_guid : PlanetSideGUID, + building_guid : PlanetSideGUID, + state : Int) + extends PlanetSideGamePacket { + type Packet = BroadcastWarpgateUpdateMessage + def opcode = GamePacketOpcode.BroadcastWarpgateUpdateMessage + def encode = BroadcastWarpgateUpdateMessage.encode(this) +} + +object BroadcastWarpgateUpdateMessage extends Marshallable[BroadcastWarpgateUpdateMessage] { + implicit val codec : Codec[BroadcastWarpgateUpdateMessage] = ( + ("continent_guid" | PlanetSideGUID.codec) :: + ("building_guid" | PlanetSideGUID.codec) :: + ("state" | uint8L) + ).as[BroadcastWarpgateUpdateMessage] +} diff --git a/common/src/test/scala/GamePacketTest.scala b/common/src/test/scala/GamePacketTest.scala index 006e8302f..5d4f30a5b 100644 --- a/common/src/test/scala/GamePacketTest.scala +++ b/common/src/test/scala/GamePacketTest.scala @@ -637,6 +637,28 @@ class GamePacketTest extends Specification { } } + "BroadcastWarpgateUpdateMessage" should { + val string = hex"D9 0D 00 01 00 20" + + "decode" in { + PacketCoding.DecodePacket(string).require match { + case BroadcastWarpgateUpdateMessage(continent_guid, building_guid, state) => + continent_guid mustEqual PlanetSideGUID(13) + building_guid mustEqual PlanetSideGUID(1) + state mustEqual 32 + case default => + ko + } + } + + "encode" in { + val msg = BroadcastWarpgateUpdateMessage(PlanetSideGUID(13), PlanetSideGUID(1), 32) + val pkt = PacketCoding.EncodePacket(msg).require.toByteVector + + pkt mustEqual string + } + } + "encode" in { val msg = ContinentalLockUpdateMessage(PlanetSideGUID(22), PlanetSideEmpire.NC) val pkt = PacketCoding.EncodePacket(msg).require.toByteVector diff --git a/pslogin/src/main/scala/WorldSessionActor.scala b/pslogin/src/main/scala/WorldSessionActor.scala index 464354487..b7d33f970 100644 --- a/pslogin/src/main/scala/WorldSessionActor.scala +++ b/pslogin/src/main/scala/WorldSessionActor.scala @@ -128,6 +128,7 @@ class WorldSessionActor extends Actor with MDCContextAware { sendRawResponse(objectHex) sendResponse(PacketCoding.CreateGamePacket(0, ContinentalLockUpdateMessage(PlanetSideGUID(13), PlanetSideEmpire.VS))) // "The VS have captured the VS Sanctuary." + sendResponse(PacketCoding.CreateGamePacket(0, BroadcastWarpgateUpdateMessage(PlanetSideGUID(13), PlanetSideGUID(1), 32))) // VS Sanctuary: Inactive Warpgate -> Broadcast Warpgate sendResponse(PacketCoding.CreateGamePacket(0, SetCurrentAvatarMessage(PlanetSideGUID(guid),0,0)))