From aa45ea8e8457d1b6c1af736888c9350e23b1108d Mon Sep 17 00:00:00 2001 From: tfarley Date: Sun, 17 Jul 2016 21:13:50 -0700 Subject: [PATCH 1/2] Add ChatMsg decoder and stubbed handler --- .../psforever/packet/GamePacketOpcode.scala | 2 +- .../scala/net/psforever/packet/PSPacket.scala | 4 + .../net/psforever/packet/game/ChatMsg.scala | 102 ++++++++++++++++++ .../src/main/scala/WorldSessionActor.scala | 7 ++ 4 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 common/src/main/scala/net/psforever/packet/game/ChatMsg.scala diff --git a/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala b/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala index 2bf05822..27e45f83 100644 --- a/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala +++ b/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala @@ -339,7 +339,7 @@ object GamePacketOpcode extends Enumeration { case DismountVehicleMsg => noDecoder(opcode) case UseItemMessage => noDecoder(opcode) case MoveItemMessage => noDecoder(opcode) - case ChatMsg => noDecoder(opcode) + case ChatMsg => game.ChatMsg.decode case CharacterNoRecordMessage => noDecoder(opcode) // OPCODE 20 diff --git a/common/src/main/scala/net/psforever/packet/PSPacket.scala b/common/src/main/scala/net/psforever/packet/PSPacket.scala index 95663dff..a5a5c229 100644 --- a/common/src/main/scala/net/psforever/packet/PSPacket.scala +++ b/common/src/main/scala/net/psforever/packet/PSPacket.scala @@ -159,4 +159,8 @@ object PacketHelpers { def encodedWideString : Codec[String] = variableSizeBytes(encodedStringSize.xmap( insize => insize*2, outSize => outSize/2), utf16) + + def encodedWideStringAligned(adjustment : Int) : Codec[String] = variableSizeBytes(encodedStringSizeWithPad(adjustment).xmap( + insize => insize*2, + outSize => outSize/2), utf16) } diff --git a/common/src/main/scala/net/psforever/packet/game/ChatMsg.scala b/common/src/main/scala/net/psforever/packet/game/ChatMsg.scala new file mode 100644 index 00000000..5bb4c977 --- /dev/null +++ b/common/src/main/scala/net/psforever/packet/game/ChatMsg.scala @@ -0,0 +1,102 @@ +// Copyright (c) 2016 PSForever.net to present +package net.psforever.packet.game + +import net.psforever.packet.{GamePacketOpcode, Marshallable, PacketHelpers, PlanetSideGamePacket} +import scodec.Codec +import scodec.codecs._ + +// ChatMessageTypes were reversed by: + // Checking the type in the packet upon receipt by server while using slash commands + // Replaying the ChatMsg packet back to the sender after modifying the messagetype value + +// Some other unchecked commands, if they actually exist as message types: +// Reply (/r), BattleGroup (/bg), ReplyCSR (/gmreply) + +object ChatMessageType extends Enumeration { + type Type = Value + val Unk0, // ??? Appears in top chat pane + Unk1, // ??? Appears in top chat pane + Unk2, // ??? Appears in top chat pane + Broadcast, // /b + Command, // /c + Global, // /comall + SituationReport, // /sitrep + SanctuaryAll, // /comsan + OrbitalStationAll, // No slash command??? + SupaiAll, // /comsu + HunhauAll, // /comhu + AdlivunAll, // /comad + ByblosAll, // /comby + AnnwnAll, // /coman + DrugaskanAll, // /comdr + SolsarAll, // /comso + HossinAll, // /comho + CyssorAll, // /comcy + IshundarAll, // /comis + ForseralAll, // /comfo + CeryshenAll, // /comce + EsamirAll, // /comes + OshurAll, // /comos + OshurPrimeAll, // /compr + SearhusAll, // /comse + AmerishAll, // /comam + Local, // /l + Outfit, // /o + Platoon, // /p + SquadLeaders, // /pl + Squad, // /s + SquadCommand, // /sl + Tell, // /t + BlackOps, // No slash command??? + CSRBroadcast, // /gmbroadcast + CSRBroadcastNC, // /ncbroadcast + CSRBroadcastTR, // /trbroadcast + CSRBroadcastVS, // /vsbroadcast + CSRWorldBroadcast, // /worldbroadcast || /wb + CSR, // /gmlocal + CSRTell, // /gmtell (actually causes normal /tell 0x20 when not a gm???) + Note, // /note + CSRWorldBroadcastPopup, // /gmpopup + CSRTellTo, // Recipient of /gmtell + TellTo, // Recipient of /t + Unk45, // ??? Looks like local? + Unk46, // ??? This actually causes the client to ping back to the server with some stringified numbers "80 120" (with the same 46 chatmsg causing infinite loop?) - may be incorrect decoding + PopupInstantAction, // Sent when Instant Action invoked + PopupRecallSanctuary, // Sent when Recall To Sanctuary invoked + Unk49, // ??? + Unk50, // ??? + Unk51, // ??? + Unk52, // ??? + Unk53, // ??? + Unk54, // ??? + Unk55, // ??? + Unk56, // ??? + Unk57, // ??? + Unk58, // ??? + Unk59, // ??? + Unk60, // ??? + PopupQuit // Sent when Quit invoked + // Could be more types + = Value + + implicit val codec = PacketHelpers.createEnumerationCodec(this, uint8L) +} + +final case class ChatMsg(channel : ChatMessageType.Value, + unk1 : Boolean, + recipient : String, + contents : String) + extends PlanetSideGamePacket { + type Packet = ChatMsg + def opcode = GamePacketOpcode.ChatMsg + def encode = ChatMsg.encode(this) +} + +object ChatMsg extends Marshallable[ChatMsg] { + implicit val codec : Codec[ChatMsg] = ( + ("messagetype" | ChatMessageType.codec) :: + ("unk1" | bool) :: + ("recipient" | PacketHelpers.encodedWideStringAligned(7)) :: + ("contents" | PacketHelpers.encodedWideString) + ).as[ChatMsg] +} diff --git a/pslogin/src/main/scala/WorldSessionActor.scala b/pslogin/src/main/scala/WorldSessionActor.scala index ad6dae39..1e113fe0 100644 --- a/pslogin/src/main/scala/WorldSessionActor.scala +++ b/pslogin/src/main/scala/WorldSessionActor.scala @@ -146,6 +146,13 @@ class WorldSessionActor extends Actor with MDCContextAware { sendResponse(PacketCoding.CreateGamePacket(0, KeepAliveMessage(0))) case PlayerStateMessageUpstream(_) => + + case msg @ ChatMsg(messagetype, unk1, recipient, contents) => + log.info("Handling " + msg) + + // TODO: Depending on messagetype, may need to prepend sender's name to contents with proper spacing + // TODO: Just replays the packet straight back to sender; actually needs to be routed to recipients! + sendResponse(PacketCoding.CreateGamePacket(0, ChatMsg(messagetype, unk1, recipient, contents))) case default => log.debug(s"Unhandled GamePacket ${pkt}") } From 8411af17d380ec31fd92ab337cbb6b5f6cd13a58 Mon Sep 17 00:00:00 2001 From: tfarley Date: Sun, 17 Jul 2016 23:35:17 -0700 Subject: [PATCH 2/2] fixup: Addressed comments --- .../net/psforever/packet/game/ChatMsg.scala | 78 +---------------- .../net/psforever/types/ChatMessageType.scala | 83 +++++++++++++++++++ .../src/main/scala/WorldSessionActor.scala | 2 +- 3 files changed, 85 insertions(+), 78 deletions(-) create mode 100644 common/src/main/scala/net/psforever/types/ChatMessageType.scala diff --git a/common/src/main/scala/net/psforever/packet/game/ChatMsg.scala b/common/src/main/scala/net/psforever/packet/game/ChatMsg.scala index 5bb4c977..62f9e9ba 100644 --- a/common/src/main/scala/net/psforever/packet/game/ChatMsg.scala +++ b/common/src/main/scala/net/psforever/packet/game/ChatMsg.scala @@ -2,86 +2,10 @@ package net.psforever.packet.game import net.psforever.packet.{GamePacketOpcode, Marshallable, PacketHelpers, PlanetSideGamePacket} +import net.psforever.types.ChatMessageType import scodec.Codec import scodec.codecs._ -// ChatMessageTypes were reversed by: - // Checking the type in the packet upon receipt by server while using slash commands - // Replaying the ChatMsg packet back to the sender after modifying the messagetype value - -// Some other unchecked commands, if they actually exist as message types: -// Reply (/r), BattleGroup (/bg), ReplyCSR (/gmreply) - -object ChatMessageType extends Enumeration { - type Type = Value - val Unk0, // ??? Appears in top chat pane - Unk1, // ??? Appears in top chat pane - Unk2, // ??? Appears in top chat pane - Broadcast, // /b - Command, // /c - Global, // /comall - SituationReport, // /sitrep - SanctuaryAll, // /comsan - OrbitalStationAll, // No slash command??? - SupaiAll, // /comsu - HunhauAll, // /comhu - AdlivunAll, // /comad - ByblosAll, // /comby - AnnwnAll, // /coman - DrugaskanAll, // /comdr - SolsarAll, // /comso - HossinAll, // /comho - CyssorAll, // /comcy - IshundarAll, // /comis - ForseralAll, // /comfo - CeryshenAll, // /comce - EsamirAll, // /comes - OshurAll, // /comos - OshurPrimeAll, // /compr - SearhusAll, // /comse - AmerishAll, // /comam - Local, // /l - Outfit, // /o - Platoon, // /p - SquadLeaders, // /pl - Squad, // /s - SquadCommand, // /sl - Tell, // /t - BlackOps, // No slash command??? - CSRBroadcast, // /gmbroadcast - CSRBroadcastNC, // /ncbroadcast - CSRBroadcastTR, // /trbroadcast - CSRBroadcastVS, // /vsbroadcast - CSRWorldBroadcast, // /worldbroadcast || /wb - CSR, // /gmlocal - CSRTell, // /gmtell (actually causes normal /tell 0x20 when not a gm???) - Note, // /note - CSRWorldBroadcastPopup, // /gmpopup - CSRTellTo, // Recipient of /gmtell - TellTo, // Recipient of /t - Unk45, // ??? Looks like local? - Unk46, // ??? This actually causes the client to ping back to the server with some stringified numbers "80 120" (with the same 46 chatmsg causing infinite loop?) - may be incorrect decoding - PopupInstantAction, // Sent when Instant Action invoked - PopupRecallSanctuary, // Sent when Recall To Sanctuary invoked - Unk49, // ??? - Unk50, // ??? - Unk51, // ??? - Unk52, // ??? - Unk53, // ??? - Unk54, // ??? - Unk55, // ??? - Unk56, // ??? - Unk57, // ??? - Unk58, // ??? - Unk59, // ??? - Unk60, // ??? - PopupQuit // Sent when Quit invoked - // Could be more types - = Value - - implicit val codec = PacketHelpers.createEnumerationCodec(this, uint8L) -} - final case class ChatMsg(channel : ChatMessageType.Value, unk1 : Boolean, recipient : String, diff --git a/common/src/main/scala/net/psforever/types/ChatMessageType.scala b/common/src/main/scala/net/psforever/types/ChatMessageType.scala new file mode 100644 index 00000000..24f5c174 --- /dev/null +++ b/common/src/main/scala/net/psforever/types/ChatMessageType.scala @@ -0,0 +1,83 @@ +// Copyright (c) 2016 PSForever.net to present +package net.psforever.types + +import net.psforever.packet.PacketHelpers +import scodec.codecs._ + +/** + * ChatMessageTypes were reversed by: + * Checking the type in the packet upon receipt by server while using slash commands + * Replaying the ChatMsg packet back to the sender after modifying the messagetype value + * + * Some other unchecked commands, if they actually exist as message types: + * Reply (/r), BattleGroup (/bg), CSRReply (/gmreply) + */ +object ChatMessageType extends Enumeration { + type Type = Value + val Unk0, // ??? Appears in top chat pane + Unk1, // ??? Appears in top chat pane + Unk2, // ??? Appears in top chat pane + Broadcast, // /b + Command, // /c + Global, // /comall + SituationReport, // /sitrep + SanctuaryAll, // /comsan + OrbitalStationAll, // No slash command??? + SupaiAll, // /comsu + HunhauAll, // /comhu + AdlivunAll, // /comad + ByblosAll, // /comby + AnnwnAll, // /coman + DrugaskanAll, // /comdr + SolsarAll, // /comso + HossinAll, // /comho + CyssorAll, // /comcy + IshundarAll, // /comis + ForseralAll, // /comfo + CeryshenAll, // /comce + EsamirAll, // /comes + OshurAll, // /comos + OshurPrimeAll, // /compr + SearhusAll, // /comse + AmerishAll, // /comam + Local, // /l + Outfit, // /o + Platoon, // /p + SquadLeaders, // /pl + Squad, // /s + SquadCommand, // /sl + Tell, // /t + BlackOps, // No slash command??? + CSRBroadcast, // /gmbroadcast + CSRBroadcastNC, // /ncbroadcast + CSRBroadcastTR, // /trbroadcast + CSRBroadcastVS, // /vsbroadcast + CSRWorldBroadcast, // /worldbroadcast || /wb + CSR, // /gmlocal + CSRTell, // /gmtell (actually causes normal /tell 0x20 when not a gm???) + Note, // /note + CSRWorldBroadcastPopup, // /gmpopup + CSRTellTo, // Recipient of /gmtell + TellTo, // Recipient of /t + Unk45, // ??? Looks like local? + Unk46, // ??? This actually causes the client to ping back to the server with some stringified numbers "80 120" (with the same 46 chatmsg causing infinite loop?) - may be incorrect decoding + PopupInstantAction, // Sent when Instant Action invoked + PopupRecallSanctuary, // Sent when Recall To Sanctuary invoked + Unk49, // ??? + Unk50, // ??? + Unk51, // ??? + Unk52, // ??? + Unk53, // ??? + Unk54, // ??? + Unk55, // ??? + Unk56, // ??? + Unk57, // ??? + Unk58, // ??? + Unk59, // ??? + Unk60, // ??? + PopupQuit // Sent when Quit invoked + // Could be more types + = Value + + implicit val codec = PacketHelpers.createEnumerationCodec(this, uint8L) +} diff --git a/pslogin/src/main/scala/WorldSessionActor.scala b/pslogin/src/main/scala/WorldSessionActor.scala index 1e113fe0..3f45b294 100644 --- a/pslogin/src/main/scala/WorldSessionActor.scala +++ b/pslogin/src/main/scala/WorldSessionActor.scala @@ -148,7 +148,7 @@ class WorldSessionActor extends Actor with MDCContextAware { case PlayerStateMessageUpstream(_) => case msg @ ChatMsg(messagetype, unk1, recipient, contents) => - log.info("Handling " + msg) + log.info("Chat: " + msg) // TODO: Depending on messagetype, may need to prepend sender's name to contents with proper spacing // TODO: Just replays the packet straight back to sender; actually needs to be routed to recipients!