Skip to content

Commit

Permalink
Merge pull request #1159 from Resaec/squad_voice_host_request_message
Browse files Browse the repository at this point in the history
Fully implement the VoiceHostRequest packet
  • Loading branch information
Fate-JH authored Jan 8, 2024
2 parents cc48e96 + 88ac2f3 commit da32c68
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 21 deletions.
34 changes: 23 additions & 11 deletions src/main/scala/net/psforever/packet/game/VoiceHostRequest.scala
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
// Copyright (c) 2017 PSForever
package net.psforever.packet.game

import net.psforever.packet.{GamePacketOpcode, Marshallable, PlanetSideGamePacket}
import net.psforever.types.PlanetSideGUID
import net.psforever.packet.{GamePacketOpcode, Marshallable, PacketHelpers, PlanetSideGamePacket}
import scodec.Codec
import scodec.bits.ByteVector
import scodec.codecs._
Expand All @@ -11,21 +10,34 @@ import scodec.codecs._
* Used by PlanetSide in conjunction with wiredred/pscs.exe to establish local platoon/squad voice chat.
* We are not focusing on implementation of this feature.
* At the most, we will merely record data about who requested it.
* @param unk na
* @param player_guid the player who sent this request
* @param data everything else
*
* @param remote_host true if the player provides info for a remote host (remote_ip)
* @param port the port to connect to
* @param bandwidth the bandwidth set by the player (valid values are 3, 201, 203)
* @param remote_ip the IP of the remote voice server, only set if remote_host == true
*/
final case class VoiceHostRequest(unk: Boolean, player_guid: PlanetSideGUID, data: ByteVector)
extends PlanetSideGamePacket {
type Packet = VoiceHostRequest
final case class VoiceHostRequest(
remote_host: Boolean,
port: Int,
bandwidth: Int,
remote_ip: String,
data: ByteVector
) extends PlanetSideGamePacket {
require(port > 0)
require(port <= 65535)
require(bandwidth == 3 || bandwidth == 201 || bandwidth == 203)
require(remote_host == (remote_ip != ""))

def opcode = GamePacketOpcode.VoiceHostRequest
def encode = VoiceHostRequest.encode(this)
}

object VoiceHostRequest extends Marshallable[VoiceHostRequest] {
implicit val codec: Codec[VoiceHostRequest] = (
("unk" | bool) ::
("player_guid" | PlanetSideGUID.codec) ::
("remote_host" | bool) ::
("port" | uint16L) ::
("bandwidth" | uint8L) ::
("remote_ip" | PacketHelpers.encodedStringAligned(7)) ::
("data" | bytes)
).as[VoiceHostRequest]
).as[VoiceHostRequest]
}
85 changes: 75 additions & 10 deletions src/test/scala/game/VoiceHostRequestTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,91 @@ package game
import org.specs2.mutable._
import net.psforever.packet._
import net.psforever.packet.game._
import net.psforever.types.PlanetSideGUID
import scodec.bits._

class VoiceHostRequestTest extends Specification {
val string_request = hex"b0 2580 00"
val string_request_local_75_high = hex"b0 2580 01 c0 00"
val string_request_local_1111_mid = hex"b0 2b82 64 c0 00"
val string_request_local_1112_mid = hex"b0 2c02 64 c0 00"
val string_request_remote_12345_high = hex"b0 9c98 01 c7 803131312e3232322e3132332e323334"

"decode" in {
PacketCoding.decodePacket(string_request).require match {
case VoiceHostRequest(unk, player, _) =>
unk mustEqual false
player mustEqual PlanetSideGUID(75)
"decode local 75 high" in {
PacketCoding.decodePacket(string_request_local_75_high).require match {
case VoiceHostRequest(remote_host, port, bandwidth, server_ip, data) =>
remote_host mustEqual false
port mustEqual 75
bandwidth mustEqual 3
server_ip mustEqual ""
data mustEqual ByteVector.empty
case _ =>
ko
}
}

"encode" in {
val msg = VoiceHostRequest(false, PlanetSideGUID(75), ByteVector.empty)
"encode local 75 high" in {
val msg = VoiceHostRequest(remote_host = false, 75, 3, "", ByteVector.empty)
val pkt = PacketCoding.encodePacket(msg).require.toByteVector

pkt mustEqual string_request
pkt mustEqual string_request_local_75_high
}

"decode local 1111 mid" in {
PacketCoding.decodePacket(string_request_local_1111_mid).require match {
case VoiceHostRequest(remote_host, port, bandwidth, server_ip, data) =>
remote_host mustEqual false
port mustEqual 1111
bandwidth mustEqual 201
server_ip mustEqual ""
data mustEqual ByteVector.empty
case _ =>
ko
}
}

"encode local 1111 mid" in {
val msg = VoiceHostRequest(remote_host = false, 1111, 201, "", ByteVector.empty)
val pkt = PacketCoding.encodePacket(msg).require.toByteVector

pkt mustEqual string_request_local_1111_mid
}

"decode local 1112 mid" in {
PacketCoding.decodePacket(string_request_local_1112_mid).require match {
case VoiceHostRequest(remote_host, port, bandwidth, server_ip, data) =>
remote_host mustEqual false
port mustEqual 1112
bandwidth mustEqual 201
server_ip mustEqual ""
data mustEqual ByteVector.empty
case _ =>
ko
}
}

"encode local 1112 mid" in {
val msg = VoiceHostRequest(remote_host = false, 1112, 201, "", ByteVector.empty)
val pkt = PacketCoding.encodePacket(msg).require.toByteVector

pkt mustEqual string_request_local_1112_mid
}

"decode remote 12345 high" in {
PacketCoding.decodePacket(string_request_remote_12345_high).require match {
case VoiceHostRequest(remote, port, codec, server_ip, data) =>
remote mustEqual true
port mustEqual 12345
codec mustEqual 3
server_ip mustEqual "111.222.123.234"
data mustEqual ByteVector.empty
case _ =>
ko
}
}

"encode remote 12345 high" in {
val msg = VoiceHostRequest(remote_host = true, port = 12345, bandwidth = 3, remote_ip = "111.222.123.234", ByteVector.empty)
val pkt = PacketCoding.encodePacket(msg).require.toByteVector

pkt mustEqual string_request_remote_12345_high
}
}

0 comments on commit da32c68

Please sign in to comment.