mirror of
https://github.com/psforever/PSF-LoginServer.git
synced 2026-07-16 08:55:18 +00:00
modified ChatActor to be replaced by a function-data logic pair, and modified ChatService to be able to accommodate the new chat channel; chat packet handling moved from general operations to the new chat operations
This commit is contained in:
parent
b5b72e5b7b
commit
8e7be33a15
21 changed files with 1791 additions and 114 deletions
|
|
@ -10,6 +10,7 @@ import net.psforever.actors.session.spectator.{SpectatorMode => SessionSpectator
|
|||
import net.psforever.actors.zone.ZoneActor
|
||||
import net.psforever.objects.sourcing.PlayerSource
|
||||
import net.psforever.objects.zones.ZoneInfo
|
||||
import net.psforever.services.chat.{DefaultChannel, SquadChannel}
|
||||
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||
import net.psforever.types.ChatMessageType.CMT_QUIT
|
||||
import org.log4s.Logger
|
||||
|
|
@ -33,7 +34,7 @@ import net.psforever.packet.game.objectcreate.DrawnSlot
|
|||
import net.psforever.packet.game.{ChatMsg, CreateShortcutMessage, DeadState, RequestDestroyMessage, Shortcut}
|
||||
import net.psforever.services.{CavernRotationService, InterstellarClusterService}
|
||||
import net.psforever.services.chat.ChatService
|
||||
import net.psforever.services.chat.ChatService.ChatChannel
|
||||
import net.psforever.services.chat.ChatChannel
|
||||
import net.psforever.types.ChatMessageType.{CMT_GMOPEN, UNK_227, UNK_229}
|
||||
import net.psforever.types.{ChatMessageType, Cosmetic, ExperienceType, ImplantType, PlanetSideEmpire, PlanetSideGUID, Vector3}
|
||||
import net.psforever.util.{Config, PointOfInterest}
|
||||
|
|
@ -385,7 +386,7 @@ object ChatActor {
|
|||
sendTo ! ChatService.Message(
|
||||
session,
|
||||
ChatMsg(UNK_227, wideContents=true, "", content.mkString(" "), None),
|
||||
ChatChannel.Default()
|
||||
DefaultChannel
|
||||
)
|
||||
true
|
||||
}
|
||||
|
|
@ -688,7 +689,7 @@ class ChatActor(
|
|||
|
||||
case ListingResponse(ChatService.ChatServiceKey.Listing(listings)) =>
|
||||
chatService = Some(listings.head)
|
||||
channels ++= List(ChatChannel.Default())
|
||||
channels ++= List(DefaultChannel)
|
||||
postStartBehaviour()
|
||||
|
||||
case SetSession(newSession) =>
|
||||
|
|
@ -704,7 +705,7 @@ class ChatActor(
|
|||
def postStartBehaviour(): Behavior[Command] = {
|
||||
(session, chatService, cluster) match {
|
||||
case (Some(_session), Some(_chatService), Some(_cluster)) if _session.player != null =>
|
||||
_chatService ! ChatService.JoinChannel(chatServiceAdapter, _session, ChatChannel.Default())
|
||||
_chatService ! ChatService.JoinChannel(chatServiceAdapter, null, DefaultChannel)
|
||||
logic = NormalMode.init(_chatService, _cluster)
|
||||
buffer.unstashAll(active(_session, _chatService, _cluster))
|
||||
case _ =>
|
||||
|
|
@ -724,7 +725,7 @@ class ChatActor(
|
|||
active(newSession, chatService, cluster)
|
||||
|
||||
case JoinChannel(channel) =>
|
||||
chatService ! ChatService.JoinChannel(chatServiceAdapter, session, channel)
|
||||
chatService ! ChatService.JoinChannel(chatServiceAdapter, null, channel)
|
||||
channels ++= List(channel)
|
||||
Behaviors.same
|
||||
|
||||
|
|
@ -1057,7 +1058,7 @@ class ChatActor(
|
|||
// SH prefix are tactical voice macros only sent to squad
|
||||
if (contents.startsWith("SH")) {
|
||||
channels.foreach {
|
||||
case _/*channel*/: ChatChannel.Squad =>
|
||||
case _/*channel*/: SquadChannel =>
|
||||
commandSendToRecipient(session, message, chatService)
|
||||
case _ => ()
|
||||
}
|
||||
|
|
@ -1082,7 +1083,7 @@ class ChatActor(
|
|||
|
||||
def commandSquad(session: Session, message: ChatMsg, chatService: ActorRef[ChatService.Command]): Unit = {
|
||||
channels.foreach {
|
||||
case _/*channel*/: ChatChannel.Squad =>
|
||||
case _/*channel*/: SquadChannel =>
|
||||
commandSendToRecipient(session, message, chatService)
|
||||
case _ => ()
|
||||
}
|
||||
|
|
@ -1415,7 +1416,7 @@ class ChatActor(
|
|||
chatService ! ChatService.Message(
|
||||
session,
|
||||
message,
|
||||
ChatChannel.Default()
|
||||
DefaultChannel
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -1423,7 +1424,7 @@ class ChatActor(
|
|||
chatService ! ChatService.Message(
|
||||
session,
|
||||
message.copy(recipient = session.player.Name),
|
||||
ChatChannel.Default()
|
||||
DefaultChannel
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -113,7 +113,9 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
|
|||
middlewareActor ! MiddlewareActor.Send(KeepAliveMessage())
|
||||
|
||||
case SessionActor.SetMode(newMode) =>
|
||||
logic.switchFrom(data.session)
|
||||
if (mode != newMode) {
|
||||
logic.switchFrom(data.session)
|
||||
}
|
||||
mode = newMode
|
||||
logic = mode.setup(data)
|
||||
logic.switchTo(data.session)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,234 @@
|
|||
// Copyright (c) 2024 PSForever
|
||||
package net.psforever.actors.session.normal
|
||||
|
||||
import akka.actor.ActorContext
|
||||
import net.psforever.actors.session.support.{ChatFunctions, ChatOperations, SessionData}
|
||||
import net.psforever.objects.Session
|
||||
import net.psforever.packet.game.{ChatMsg, SetChatFilterMessage}
|
||||
import net.psforever.services.chat.DefaultChannel
|
||||
import net.psforever.types.ChatMessageType
|
||||
import net.psforever.util.Config
|
||||
|
||||
object ChatLogic {
|
||||
def apply(ops: ChatOperations): ChatLogic = {
|
||||
new ChatLogic(ops, ops.context)
|
||||
}
|
||||
}
|
||||
|
||||
class ChatLogic(val ops: ChatOperations, implicit val context: ActorContext) extends ChatFunctions {
|
||||
def sessionLogic: SessionData = ops.sessionLogic
|
||||
|
||||
def handleChatMsg(session: Session, message: ChatMsg): Unit = {
|
||||
import net.psforever.types.ChatMessageType._
|
||||
val gmCommandAllowed =
|
||||
session.account.gm || Config.app.development.unprivilegedGmCommands.contains(message.messageType)
|
||||
(message.messageType, message.recipient.trim, message.contents.trim) match {
|
||||
/** Messages starting with ! are custom chat commands */
|
||||
case (_, _, contents) if contents.startsWith("!") &&
|
||||
customCommandMessages(message, session) => ()
|
||||
|
||||
case (CMT_FLY, recipient, contents) if gmCommandAllowed =>
|
||||
ops.commandFly(contents, recipient)
|
||||
|
||||
case (CMT_ANONYMOUS, _, _) =>
|
||||
// ?
|
||||
|
||||
case (CMT_TOGGLE_GM, _, _) =>
|
||||
// ?
|
||||
|
||||
case (CMT_CULLWATERMARK, _, contents) =>
|
||||
ops.commandWatermark(contents)
|
||||
|
||||
case (CMT_SPEED, _, contents) if gmCommandAllowed =>
|
||||
ops.commandSpeed(message, contents)
|
||||
|
||||
case (CMT_TOGGLESPECTATORMODE, _, contents) if gmCommandAllowed =>
|
||||
ops.commandToggleSpectatorMode(session, contents)
|
||||
|
||||
case (CMT_RECALL, _, _) =>
|
||||
ops.commandRecall(session)
|
||||
|
||||
case (CMT_INSTANTACTION, _, _) =>
|
||||
ops.commandInstantAction(session)
|
||||
|
||||
case (CMT_QUIT, _, _) =>
|
||||
ops.commandQuit(session)
|
||||
|
||||
case (CMT_SUICIDE, _, _) =>
|
||||
ops.commandSuicide(session)
|
||||
|
||||
case (CMT_DESTROY, _, contents) if contents.matches("\\d+") =>
|
||||
ops.commandDestroy(session, message, contents)
|
||||
|
||||
case (CMT_SETBASERESOURCES, _, contents) if gmCommandAllowed =>
|
||||
ops.commandSetBaseResources(session, contents)
|
||||
|
||||
case (CMT_ZONELOCK, _, contents) if gmCommandAllowed =>
|
||||
ops.commandZoneLock(contents)
|
||||
|
||||
case (U_CMT_ZONEROTATE, _, _) if gmCommandAllowed =>
|
||||
ops.commandZoneRotate()
|
||||
|
||||
case (CMT_CAPTUREBASE, _, contents) if gmCommandAllowed =>
|
||||
ops.commandCaptureBase(session, message, contents)
|
||||
|
||||
case (CMT_GMBROADCAST | CMT_GMBROADCAST_NC | CMT_GMBROADCAST_VS | CMT_GMBROADCAST_TR, _, _)
|
||||
if gmCommandAllowed =>
|
||||
ops.commandSendToRecipient(session, message, DefaultChannel)
|
||||
|
||||
case (CMT_GMTELL, _, _) if gmCommandAllowed =>
|
||||
ops.commandSend(session, message, DefaultChannel)
|
||||
|
||||
case (CMT_GMBROADCASTPOPUP, _, _) if gmCommandAllowed =>
|
||||
ops.commandSendToRecipient(session, message, DefaultChannel)
|
||||
|
||||
case (CMT_OPEN, _, _) if !session.player.silenced =>
|
||||
ops.commandSendToRecipient(session, message, DefaultChannel)
|
||||
|
||||
case (CMT_VOICE, _, contents) =>
|
||||
ops.commandVoice(session, message, contents, DefaultChannel)
|
||||
|
||||
case (CMT_TELL, _, _) if !session.player.silenced =>
|
||||
ops.commandTellOrIgnore(session, message, DefaultChannel)
|
||||
|
||||
case (CMT_BROADCAST, _, _) if !session.player.silenced =>
|
||||
ops.commandSendToRecipient(session, message, DefaultChannel)
|
||||
|
||||
case (CMT_PLATOON, _, _) if !session.player.silenced =>
|
||||
ops.commandSendToRecipient(session, message, DefaultChannel)
|
||||
|
||||
case (CMT_COMMAND, _, _) if gmCommandAllowed =>
|
||||
ops.commandSendToRecipient(session, message, DefaultChannel)
|
||||
|
||||
case (CMT_NOTE, _, _) =>
|
||||
ops.commandSend(session, message, DefaultChannel)
|
||||
|
||||
case (CMT_SILENCE, _, _) if gmCommandAllowed =>
|
||||
ops.commandSend(session, message, DefaultChannel)
|
||||
|
||||
case (CMT_SQUAD, _, _) =>
|
||||
ops.commandSquad(session, message, DefaultChannel) //todo SquadChannel, but what is the guid
|
||||
|
||||
case (CMT_WHO | CMT_WHO_CSR | CMT_WHO_CR | CMT_WHO_PLATOONLEADERS | CMT_WHO_SQUADLEADERS | CMT_WHO_TEAMS, _, _) =>
|
||||
ops.commandWho(session)
|
||||
|
||||
case (CMT_ZONE, _, contents) if gmCommandAllowed =>
|
||||
ops.commandZone(message, contents)
|
||||
|
||||
case (CMT_WARP, _, contents) if gmCommandAllowed =>
|
||||
ops.commandWarp(session, message, contents)
|
||||
|
||||
case (CMT_SETBATTLERANK, _, contents) if gmCommandAllowed =>
|
||||
ops.commandSetBattleRank(session, message, contents)
|
||||
|
||||
case (CMT_SETCOMMANDRANK, _, contents) if gmCommandAllowed =>
|
||||
ops.commandSetCommandRank(session, message, contents)
|
||||
|
||||
case (CMT_ADDBATTLEEXPERIENCE, _, contents) if gmCommandAllowed =>
|
||||
ops.commandAddBattleExperience(message, contents)
|
||||
|
||||
case (CMT_ADDCOMMANDEXPERIENCE, _, contents) if gmCommandAllowed =>
|
||||
ops.commandAddCommandExperience(message, contents)
|
||||
|
||||
case (CMT_TOGGLE_HAT, _, contents) =>
|
||||
ops.commandToggleHat(session, message, contents)
|
||||
|
||||
case (CMT_HIDE_HELMET | CMT_TOGGLE_SHADES | CMT_TOGGLE_EARPIECE, _, contents) =>
|
||||
ops.commandToggleCosmetics(session, message, contents)
|
||||
|
||||
case (CMT_ADDCERTIFICATION, _, contents) if gmCommandAllowed =>
|
||||
ops.commandAddCertification(session, message, contents)
|
||||
|
||||
case (CMT_KICK, _, contents) if gmCommandAllowed =>
|
||||
ops.commandKick(session, message, contents)
|
||||
|
||||
case _ =>
|
||||
log.warn(s"Unhandled chat message $message")
|
||||
}
|
||||
}
|
||||
|
||||
def handleChatFilter(pkt: SetChatFilterMessage): Unit = {
|
||||
val SetChatFilterMessage(_, _, _) = pkt
|
||||
}
|
||||
|
||||
def handleIncomingMessage(session: Session, message: ChatMsg, fromSession: Session): Unit = {
|
||||
import ChatMessageType._
|
||||
message.messageType match {
|
||||
case CMT_BROADCAST | CMT_SQUAD | CMT_PLATOON | CMT_COMMAND | CMT_NOTE =>
|
||||
ops.commandIncomingSendAllIfOnline(session, message)
|
||||
|
||||
case CMT_OPEN =>
|
||||
ops.commandIncomingSendToLocalIfOnline(session, fromSession, message)
|
||||
|
||||
case CMT_TELL | U_CMT_TELLFROM |
|
||||
CMT_GMOPEN | CMT_GMBROADCAST | CMT_GMBROADCAST_NC | CMT_GMBROADCAST_TR | CMT_GMBROADCAST_VS |
|
||||
CMT_GMBROADCASTPOPUP | CMT_GMTELL | U_CMT_GMTELLFROM | UNK_45 | UNK_71 | UNK_227 | UNK_229 =>
|
||||
ops.commandIncomingSend(message)
|
||||
|
||||
case CMT_VOICE =>
|
||||
ops.commandIncomingVoice(session, fromSession, message)
|
||||
|
||||
case CMT_SILENCE =>
|
||||
ops.commandIncomingSilence(session, message)
|
||||
|
||||
case _ =>
|
||||
log.warn(s"Unexpected messageType $message")
|
||||
}
|
||||
}
|
||||
|
||||
private def customCommandMessages(
|
||||
message: ChatMsg,
|
||||
session: Session
|
||||
): Boolean = {
|
||||
val contents = message.contents
|
||||
if (contents.startsWith("!")) {
|
||||
val (command, params) = ops.cliTokenization(contents.drop(1)) match {
|
||||
case a :: b => (a, b)
|
||||
case _ => ("", Seq(""))
|
||||
}
|
||||
val gmBangCommandAllowed = session.account.gm || Config.app.development.unprivilegedGmBangCommands.contains(command)
|
||||
//try gm commands
|
||||
val tryGmCommandResult = if (gmBangCommandAllowed) {
|
||||
command match {
|
||||
case "whitetext" => Some(ops.customCommandWhitetext(session, params))
|
||||
case "list" => Some(ops.customCommandList(session, params, message))
|
||||
case "ntu" => Some(ops.customCommandNtu(session, params))
|
||||
case "zonerotate" => Some(ops.customCommandZonerotate(params))
|
||||
case "nearby" => Some(ops.customCommandNearby(session))
|
||||
case _ => None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
//try commands for all players if not caught as a gm command
|
||||
val result = tryGmCommandResult match {
|
||||
case None =>
|
||||
command match {
|
||||
case "loc" => ops.customCommandLoc(session, message)
|
||||
case "suicide" => ops.customCommandSuicide(session)
|
||||
case "grenade" => ops.customCommandGrenade(session, log)
|
||||
case "macro" => ops.customCommandMacro(session, params)
|
||||
case "progress" => ops.customCommandProgress(session, params)
|
||||
case _ => false
|
||||
}
|
||||
case Some(out) =>
|
||||
out
|
||||
}
|
||||
if (!result) {
|
||||
// command was not handled
|
||||
sendResponse(
|
||||
ChatMsg(
|
||||
ChatMessageType.CMT_GMOPEN, // CMT_GMTELL
|
||||
message.wideContents,
|
||||
"Server",
|
||||
s"Unknown command !$command",
|
||||
message.note
|
||||
)
|
||||
)
|
||||
}
|
||||
result
|
||||
} else {
|
||||
false // not a handled command
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,11 +2,11 @@
|
|||
package net.psforever.actors.session.normal
|
||||
|
||||
import akka.actor.typed.scaladsl.adapter._
|
||||
import akka.actor.{ActorContext, Cancellable, typed}
|
||||
import net.psforever.actors.session.{AvatarActor, ChatActor, SessionActor}
|
||||
import akka.actor.{ActorContext, typed}
|
||||
import net.psforever.actors.session.{AvatarActor, SessionActor}
|
||||
import net.psforever.actors.session.support.{GeneralFunctions, GeneralOperations, SessionData}
|
||||
import net.psforever.login.WorldSession.{CallBackForTask, ContainableMoveItem, DropEquipmentFromInventory, PickUpEquipmentFromGround, RemoveOldEquipmentFromInventory}
|
||||
import net.psforever.objects.{Account, BoomerDeployable, BoomerTrigger, ConstructionItem, Default, Deployables, GlobalDefinitions, Kit, LivePlayerList, PlanetSideGameObject, Player, SensorDeployable, ShieldGeneratorDeployable, SpecialEmp, TelepadDeployable, Tool, TrapDeployable, TurretDeployable, Vehicle}
|
||||
import net.psforever.objects.{Account, BoomerDeployable, BoomerTrigger, ConstructionItem, Deployables, GlobalDefinitions, Kit, LivePlayerList, PlanetSideGameObject, Player, SensorDeployable, ShieldGeneratorDeployable, SpecialEmp, TelepadDeployable, Tool, TrapDeployable, TurretDeployable, Vehicle}
|
||||
import net.psforever.objects.avatar.{Avatar, PlayerControl, SpecialCarry}
|
||||
import net.psforever.objects.ballistics.Projectile
|
||||
import net.psforever.objects.ce.{Deployable, DeployedItem, TelepadLike}
|
||||
|
|
@ -39,13 +39,12 @@ import net.psforever.objects.vital.interaction.DamageInteraction
|
|||
import net.psforever.objects.zones.{Zone, ZoneProjectile, Zoning}
|
||||
import net.psforever.packet.PlanetSideGamePacket
|
||||
import net.psforever.packet.game.objectcreate.ObjectClass
|
||||
import net.psforever.packet.game.{ActionCancelMessage, ActionResultMessage, AvatarFirstTimeEventMessage, AvatarImplantMessage, AvatarJumpMessage, BattleplanMessage, BindPlayerMessage, BindStatus, BugReportMessage, ChangeFireModeMessage, ChangeShortcutBankMessage, CharacterCreateRequestMessage, CharacterRequestAction, CharacterRequestMessage, ChatMsg, CollisionIs, ConnectToWorldRequestMessage, CreateShortcutMessage, DeadState, DeployObjectMessage, DisplayedAwardMessage, DropItemMessage, EmoteMsg, FacilityBenefitShieldChargeRequestMessage, FriendsRequest, GenericAction, GenericActionMessage, GenericCollisionMsg, GenericObjectActionAtPositionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HitHint, ImplantAction, InvalidTerrainMessage, ItemTransactionMessage, LootItemMessage, MoveItemMessage, ObjectDeleteMessage, ObjectDetectedMessage, ObjectHeldMessage, PickupItemMessage, PlanetsideAttributeMessage, PlayerStateMessageUpstream, PlayerStateShiftMessage, RequestDestroyMessage, SetChatFilterMessage, ShiftState, TargetInfo, TargetingImplantRequest, TargetingInfoMessage, TerrainCondition, TradeMessage, UnuseItemMessage, UseItemMessage, VoiceHostInfo, VoiceHostKill, VoiceHostRequest, ZipLineMessage}
|
||||
import net.psforever.packet.game.{ActionCancelMessage, ActionResultMessage, AvatarFirstTimeEventMessage, AvatarImplantMessage, AvatarJumpMessage, BattleplanMessage, BindPlayerMessage, BindStatus, BugReportMessage, ChangeFireModeMessage, ChangeShortcutBankMessage, CharacterCreateRequestMessage, CharacterRequestAction, CharacterRequestMessage, ChatMsg, CollisionIs, ConnectToWorldRequestMessage, CreateShortcutMessage, DeadState, DeployObjectMessage, DisplayedAwardMessage, DropItemMessage, EmoteMsg, FacilityBenefitShieldChargeRequestMessage, FriendsRequest, GenericAction, GenericActionMessage, GenericCollisionMsg, GenericObjectActionAtPositionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HitHint, ImplantAction, InvalidTerrainMessage, ItemTransactionMessage, LootItemMessage, MoveItemMessage, ObjectDeleteMessage, ObjectDetectedMessage, ObjectHeldMessage, PickupItemMessage, PlanetsideAttributeMessage, PlayerStateMessageUpstream, PlayerStateShiftMessage, RequestDestroyMessage, ShiftState, TargetInfo, TargetingImplantRequest, TargetingInfoMessage, TerrainCondition, TradeMessage, UnuseItemMessage, UseItemMessage, VoiceHostInfo, VoiceHostKill, VoiceHostRequest, ZipLineMessage}
|
||||
import net.psforever.services.RemoverActor
|
||||
import net.psforever.services.account.{AccountPersistenceService, RetrieveAccountData}
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||
import net.psforever.services.local.support.CaptureFlagManager
|
||||
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||
import net.psforever.types.{CapacitorStateType, ChatMessageType, Cosmetic, DriveState, ExoSuitType, ImplantType, PlanetSideEmpire, PlanetSideGUID, SpawnGroup, TransactionType, Vector3}
|
||||
import net.psforever.util.Config
|
||||
|
||||
|
|
@ -62,8 +61,6 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex
|
|||
|
||||
private val avatarActor: typed.ActorRef[AvatarActor.Command] = ops.avatarActor
|
||||
|
||||
private val chatActor: typed.ActorRef[ChatActor.Command] = ops.chatActor
|
||||
|
||||
def handleConnectToWorldRequest(pkt: ConnectToWorldRequestMessage): Unit = {
|
||||
val ConnectToWorldRequestMessage(_, token, majorVersion, minorVersion, revision, buildDate, _, _) = pkt
|
||||
log.trace(
|
||||
|
|
@ -192,14 +189,6 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex
|
|||
player.zoneInteractions()
|
||||
}
|
||||
|
||||
def handleChat(pkt: ChatMsg): Unit = {
|
||||
chatActor ! ChatActor.Message(pkt)
|
||||
}
|
||||
|
||||
def handleChatFilter(pkt: SetChatFilterMessage): Unit = {
|
||||
val SetChatFilterMessage(_, _, _) = pkt
|
||||
}
|
||||
|
||||
def handleVoiceHostRequest(pkt: VoiceHostRequest): Unit = {
|
||||
log.debug(s"$pkt")
|
||||
sendResponse(VoiceHostKill())
|
||||
|
|
|
|||
|
|
@ -3,10 +3,9 @@ package net.psforever.actors.session.normal
|
|||
|
||||
import akka.actor.Actor.Receive
|
||||
import akka.actor.ActorRef
|
||||
import net.psforever.actors.session.ChatActor
|
||||
import net.psforever.actors.session.support.{GeneralFunctions, LocalHandlerFunctions, MountHandlerFunctions, SquadHandlerFunctions, TerminalHandlerFunctions, VehicleFunctions, VehicleHandlerFunctions, WeaponAndProjectileFunctions}
|
||||
import net.psforever.objects.Session
|
||||
import net.psforever.actors.session.support.{ChatFunctions, GeneralFunctions, LocalHandlerFunctions, MountHandlerFunctions, SquadHandlerFunctions, TerminalHandlerFunctions, VehicleFunctions, VehicleHandlerFunctions, WeaponAndProjectileFunctions}
|
||||
import net.psforever.packet.game.UplinkRequest
|
||||
import net.psforever.services.chat.ChatService
|
||||
//
|
||||
import net.psforever.actors.session.{AvatarActor, SessionActor}
|
||||
import net.psforever.actors.session.support.{ModeLogic, PlayerMode, SessionData, ZoningOperations}
|
||||
|
|
@ -34,6 +33,7 @@ import net.psforever.util.Config
|
|||
|
||||
class NormalModeLogic(data: SessionData) extends ModeLogic {
|
||||
val avatarResponse: AvatarHandlerLogic = AvatarHandlerLogic(data.avatarResponse)
|
||||
val chat: ChatFunctions = ChatLogic(data.chat)
|
||||
val galaxy: GalaxyHandlerLogic = GalaxyHandlerLogic(data.galaxyResponseHandlers)
|
||||
val general: GeneralFunctions = GeneralLogic(data.general)
|
||||
val local: LocalHandlerFunctions = LocalHandlerLogic(data.localResponse)
|
||||
|
|
@ -44,11 +44,6 @@ class NormalModeLogic(data: SessionData) extends ModeLogic {
|
|||
val vehicles: VehicleFunctions = VehicleLogic(data.vehicles)
|
||||
val vehicleResponse: VehicleHandlerFunctions = VehicleHandlerLogic(data.vehicleResponseOperations)
|
||||
|
||||
override def switchTo(session: Session): Unit = {
|
||||
data.general.chatActor ! ChatActor.SetMode("normal")
|
||||
super.switchTo(session)
|
||||
}
|
||||
|
||||
def parse(sender: ActorRef): Receive = {
|
||||
/* really common messages (very frequently, every life) */
|
||||
case packet: PlanetSideGamePacket =>
|
||||
|
|
@ -75,6 +70,9 @@ class NormalModeLogic(data: SessionData) extends ModeLogic {
|
|||
case VehicleServiceResponse(toChannel, guid, reply) =>
|
||||
vehicleResponse.handle(toChannel, guid, reply)
|
||||
|
||||
case ChatService.MessageResponse(fromSession, message, _) =>
|
||||
chat.handleIncomingMessage(data.session, message, fromSession)
|
||||
|
||||
case SessionActor.SendResponse(packet) =>
|
||||
data.sendResponse(packet)
|
||||
|
||||
|
|
@ -315,10 +313,10 @@ class NormalModeLogic(data: SessionData) extends ModeLogic {
|
|||
data.zoning.spawn.handleSpawnRequest(packet)
|
||||
|
||||
case packet: ChatMsg =>
|
||||
general.handleChat(packet)
|
||||
chat.handleChatMsg(data.session, packet)
|
||||
|
||||
case packet: SetChatFilterMessage =>
|
||||
general.handleChatFilter(packet)
|
||||
chat.handleChatFilter(packet)
|
||||
|
||||
case packet: VoiceHostRequest =>
|
||||
general.handleVoiceHostRequest(packet)
|
||||
|
|
|
|||
|
|
@ -3,12 +3,12 @@ package net.psforever.actors.session.normal
|
|||
|
||||
import akka.actor.{ActorContext, ActorRef, typed}
|
||||
import net.psforever.actors.session.support.SessionSquadHandlers.SquadUIElement
|
||||
import net.psforever.actors.session.{AvatarActor, ChatActor}
|
||||
import net.psforever.actors.session.AvatarActor
|
||||
import net.psforever.actors.session.support.{SessionData, SessionSquadHandlers, SquadHandlerFunctions}
|
||||
import net.psforever.objects.{Default, LivePlayerList}
|
||||
import net.psforever.objects.avatar.Avatar
|
||||
import net.psforever.packet.game.{CharacterKnowledgeInfo, CharacterKnowledgeMessage, ChatMsg, MemberEvent, PlanetsideAttributeMessage, ReplicationStreamMessage, SquadAction, SquadDefinitionActionMessage, SquadDetailDefinitionUpdateMessage, SquadListing, SquadMemberEvent, SquadMembershipRequest, SquadMembershipResponse, SquadState, SquadStateInfo, SquadWaypointEvent, SquadWaypointRequest, WaypointEvent, WaypointEventAction}
|
||||
import net.psforever.services.chat.ChatService
|
||||
import net.psforever.services.chat.SquadChannel
|
||||
import net.psforever.services.teamwork.{SquadResponse, SquadServiceMessage, SquadAction => SquadServiceAction}
|
||||
import net.psforever.types.{ChatMessageType, PlanetSideGUID, SquadListDecoration, SquadResponseType, WaypointSubtype}
|
||||
|
||||
|
|
@ -23,8 +23,6 @@ class SquadHandlerLogic(val ops: SessionSquadHandlers, implicit val context: Act
|
|||
|
||||
private val avatarActor: typed.ActorRef[AvatarActor.Command] = ops.avatarActor
|
||||
|
||||
private val chatActor: typed.ActorRef[ChatActor.Command] = ops.chatActor
|
||||
|
||||
private val squadService: ActorRef = ops.squadService
|
||||
|
||||
private var waypointCooldown: Long = 0L
|
||||
|
|
@ -194,8 +192,8 @@ class SquadHandlerLogic(val ops: SessionSquadHandlers, implicit val context: Act
|
|||
sendResponse(SquadDefinitionActionMessage(squad.GUID, 0, SquadAction.Unknown(18)))
|
||||
squadService ! SquadServiceMessage(player, continent, SquadServiceAction.ReloadDecoration())
|
||||
ops.updateSquadRef = ref
|
||||
ops. updateSquad = ops.PeriodicUpdatesWhenEnrolledInSquad
|
||||
chatActor ! ChatActor.JoinChannel(ChatService.ChatChannel.Squad(squad.GUID))
|
||||
ops.updateSquad = ops.PeriodicUpdatesWhenEnrolledInSquad
|
||||
sessionLogic.chat.JoinChannel(SquadChannel(squad.GUID))
|
||||
case _ =>
|
||||
//other player is joining our squad
|
||||
//load each member's entry
|
||||
|
|
@ -245,7 +243,7 @@ class SquadHandlerLogic(val ops: SessionSquadHandlers, implicit val context: Act
|
|||
ops.squad_supplement_id = 0
|
||||
ops.squadUpdateCounter = 0
|
||||
ops.updateSquad = ops.NoSquadUpdates
|
||||
chatActor ! ChatActor.LeaveChannel(ChatService.ChatChannel.Squad(squad.GUID))
|
||||
sessionLogic.chat.LeaveChannel(SquadChannel(squad.GUID))
|
||||
case _ =>
|
||||
//remove each member's entry
|
||||
ops.GiveSquadColorsToMembers(
|
||||
|
|
|
|||
|
|
@ -0,0 +1,143 @@
|
|||
// Copyright (c) 2024 PSForever
|
||||
package net.psforever.actors.session.spectator
|
||||
|
||||
import akka.actor.ActorContext
|
||||
import net.psforever.actors.session.SessionActor
|
||||
import net.psforever.actors.session.normal.NormalMode
|
||||
import net.psforever.actors.session.support.{ChatFunctions, ChatOperations, SessionData}
|
||||
import net.psforever.objects.Session
|
||||
import net.psforever.packet.game.{ChatMsg, SetChatFilterMessage}
|
||||
import net.psforever.services.chat.SpectatorChannel
|
||||
import net.psforever.types.ChatMessageType
|
||||
|
||||
import scala.collection.Seq
|
||||
|
||||
object ChatLogic {
|
||||
def apply(ops: ChatOperations): ChatLogic = {
|
||||
new ChatLogic(ops, ops.context)
|
||||
}
|
||||
}
|
||||
|
||||
class ChatLogic(val ops: ChatOperations, implicit val context: ActorContext) extends ChatFunctions {
|
||||
def sessionLogic: SessionData = ops.sessionLogic
|
||||
|
||||
def handleChatMsg(session: Session, message: ChatMsg): Unit = {
|
||||
import ChatMessageType._
|
||||
(message.messageType, message.recipient.trim, message.contents.trim) match {
|
||||
/** Messages starting with ! are custom chat commands */
|
||||
case (_, _, contents) if contents.startsWith("!") &&
|
||||
customCommandMessages(message, session) => ()
|
||||
|
||||
case (CMT_FLY, recipient, contents) =>
|
||||
ops.commandFly(contents, recipient)
|
||||
|
||||
case (CMT_ANONYMOUS, _, _) =>
|
||||
// ?
|
||||
|
||||
case (CMT_TOGGLE_GM, _, _) =>
|
||||
// ?
|
||||
|
||||
case (CMT_CULLWATERMARK, _, contents) =>
|
||||
ops.commandWatermark(contents)
|
||||
|
||||
case (CMT_SPEED, _, contents) =>
|
||||
ops.commandSpeed(message, contents)
|
||||
|
||||
case (CMT_TOGGLESPECTATORMODE, _, contents) =>
|
||||
commandToggleSpectatorMode(contents)
|
||||
|
||||
case (CMT_RECALL, _, _) =>
|
||||
commandToggleSpectatorMode(contents = "off")
|
||||
|
||||
case (CMT_QUIT, _, _) =>
|
||||
ops.commandQuit(session)
|
||||
|
||||
case (CMT_SUICIDE, _, _) =>
|
||||
commandToggleSpectatorMode(contents = "off")
|
||||
|
||||
case (CMT_OPEN, _, _) =>
|
||||
ops.commandSendToRecipient(session, message, SpectatorChannel)
|
||||
|
||||
case (CMT_VOICE, _, contents) =>
|
||||
ops.commandVoice(session, message, contents, SpectatorChannel)
|
||||
|
||||
case (CMT_TELL, _, _) =>
|
||||
ops.commandTellOrIgnore(session, message, SpectatorChannel)
|
||||
|
||||
case (CMT_BROADCAST, _, _) =>
|
||||
ops.commandSendToRecipient(session, message, SpectatorChannel)
|
||||
|
||||
case (CMT_PLATOON, _, _) =>
|
||||
ops.commandSendToRecipient(session, message, SpectatorChannel)
|
||||
|
||||
case (CMT_GMTELL, _, _) =>
|
||||
ops.commandSend(session, message, SpectatorChannel)
|
||||
|
||||
case (CMT_NOTE, _, _) =>
|
||||
ops.commandSend(session, message, SpectatorChannel)
|
||||
|
||||
case (CMT_WHO | CMT_WHO_CSR | CMT_WHO_CR | CMT_WHO_PLATOONLEADERS | CMT_WHO_SQUADLEADERS | CMT_WHO_TEAMS, _, _) =>
|
||||
ops.commandWho(session)
|
||||
|
||||
case (CMT_ZONE, _, contents) =>
|
||||
ops.commandZone(message, contents)
|
||||
|
||||
case (CMT_WARP, _, contents) =>
|
||||
ops.commandWarp(session, message, contents)
|
||||
|
||||
case _ => ()
|
||||
}
|
||||
}
|
||||
|
||||
def handleChatFilter(pkt: SetChatFilterMessage): Unit = {
|
||||
val SetChatFilterMessage(_, _, _) = pkt
|
||||
}
|
||||
|
||||
def handleIncomingMessage(session: Session, message: ChatMsg, fromSession: Session): Unit = {
|
||||
import ChatMessageType._
|
||||
message.messageType match {
|
||||
case CMT_BROADCAST | CMT_SQUAD | CMT_PLATOON | CMT_COMMAND | CMT_NOTE =>
|
||||
ops.commandIncomingSendAllIfOnline(session, message)
|
||||
|
||||
case CMT_OPEN =>
|
||||
ops.commandIncomingSendToLocalIfOnline(session, fromSession, message)
|
||||
|
||||
case CMT_TELL | U_CMT_TELLFROM |
|
||||
CMT_GMOPEN | CMT_GMBROADCAST | CMT_GMBROADCAST_NC | CMT_GMBROADCAST_TR | CMT_GMBROADCAST_VS |
|
||||
CMT_GMBROADCASTPOPUP | CMT_GMTELL | U_CMT_GMTELLFROM | UNK_45 | UNK_71 | UNK_227 | UNK_229 =>
|
||||
ops.commandIncomingSend(message)
|
||||
|
||||
case _ => ()
|
||||
}
|
||||
}
|
||||
|
||||
private def customCommandMessages(
|
||||
message: ChatMsg,
|
||||
session: Session
|
||||
): Boolean = {
|
||||
val contents = message.contents
|
||||
if (contents.startsWith("!")) {
|
||||
val (command, params) = ops.cliTokenization(contents.drop(1)) match {
|
||||
case a :: b => (a, b)
|
||||
case _ => ("", Seq(""))
|
||||
}
|
||||
command match {
|
||||
case "list" => ops.customCommandList(session, params, message)
|
||||
case "nearby" => ops.customCommandNearby(session)
|
||||
case "loc" => ops.customCommandLoc(session, message)
|
||||
case "macro" => ops.customCommandMacro(session, params)
|
||||
case _ => false
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
private def commandToggleSpectatorMode(contents: String): Unit = {
|
||||
contents.toLowerCase() match {
|
||||
case "off" | "of" =>
|
||||
context.self ! SessionActor.SetMode(NormalMode)
|
||||
case _ => ()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
package net.psforever.actors.session.spectator
|
||||
|
||||
import akka.actor.{ActorContext, typed}
|
||||
import net.psforever.actors.session.{AvatarActor, ChatActor}
|
||||
import net.psforever.actors.session.AvatarActor
|
||||
import net.psforever.actors.session.support.{GeneralFunctions, GeneralOperations, SessionData}
|
||||
import net.psforever.login.WorldSession.RemoveOldEquipmentFromInventory
|
||||
import net.psforever.objects.{Account, BoomerDeployable, BoomerTrigger, GlobalDefinitions, LivePlayerList, PlanetSideGameObject, Player, TelepadDeployable, Tool, Vehicle}
|
||||
|
|
@ -21,7 +21,7 @@ import net.psforever.objects.vehicles.Utility.InternalTelepad
|
|||
import net.psforever.objects.vital.{VehicleDismountActivity, VehicleMountActivity}
|
||||
import net.psforever.objects.zones.{Zone, ZoneProjectile}
|
||||
import net.psforever.packet.PlanetSideGamePacket
|
||||
import net.psforever.packet.game.{ActionCancelMessage, AvatarFirstTimeEventMessage, AvatarImplantMessage, AvatarJumpMessage, BattleplanMessage, BindPlayerMessage, BugReportMessage, ChangeFireModeMessage, ChangeShortcutBankMessage, CharacterCreateRequestMessage, CharacterRequestMessage, ChatMsg, ConnectToWorldRequestMessage, CreateShortcutMessage, DeployObjectMessage, DisplayedAwardMessage, DropItemMessage, EmoteMsg, FacilityBenefitShieldChargeRequestMessage, FriendsRequest, GenericAction, GenericActionMessage, GenericCollisionMsg, GenericObjectActionAtPositionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HitHint, ImplantAction, InvalidTerrainMessage, LootItemMessage, MoveItemMessage, ObjectDeleteMessage, ObjectDetectedMessage, ObjectHeldMessage, PickupItemMessage, PlanetsideAttributeMessage, PlayerStateMessageUpstream, PlayerStateShiftMessage, RequestDestroyMessage, SetChatFilterMessage, ShiftState, TargetInfo, TargetingImplantRequest, TargetingInfoMessage, TradeMessage, UnuseItemMessage, UseItemMessage, VoiceHostInfo, VoiceHostKill, VoiceHostRequest, ZipLineMessage}
|
||||
import net.psforever.packet.game.{ActionCancelMessage, AvatarFirstTimeEventMessage, AvatarImplantMessage, AvatarJumpMessage, BattleplanMessage, BindPlayerMessage, BugReportMessage, ChangeFireModeMessage, ChangeShortcutBankMessage, CharacterCreateRequestMessage, CharacterRequestMessage, ChatMsg, ConnectToWorldRequestMessage, CreateShortcutMessage, DeployObjectMessage, DisplayedAwardMessage, DropItemMessage, EmoteMsg, FacilityBenefitShieldChargeRequestMessage, FriendsRequest, GenericAction, GenericActionMessage, GenericCollisionMsg, GenericObjectActionAtPositionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HitHint, ImplantAction, InvalidTerrainMessage, LootItemMessage, MoveItemMessage, ObjectDeleteMessage, ObjectDetectedMessage, ObjectHeldMessage, PickupItemMessage, PlanetsideAttributeMessage, PlayerStateMessageUpstream, PlayerStateShiftMessage, RequestDestroyMessage, ShiftState, TargetInfo, TargetingImplantRequest, TargetingInfoMessage, TradeMessage, UnuseItemMessage, UseItemMessage, VoiceHostInfo, VoiceHostKill, VoiceHostRequest, ZipLineMessage}
|
||||
import net.psforever.services.RemoverActor
|
||||
import net.psforever.services.account.AccountPersistenceService
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
|
|
@ -40,8 +40,6 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex
|
|||
|
||||
private val avatarActor: typed.ActorRef[AvatarActor.Command] = ops.avatarActor
|
||||
|
||||
private val chatActor: typed.ActorRef[ChatActor.Command] = ops.chatActor
|
||||
|
||||
private var customImplants = SpectatorModeLogic.SpectatorImplants.map(_.get)
|
||||
|
||||
def handleConnectToWorldRequest(pkt: ConnectToWorldRequestMessage): Unit = { /* intentionally blank */ }
|
||||
|
|
@ -85,12 +83,6 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex
|
|||
}
|
||||
}
|
||||
|
||||
def handleChat(pkt: ChatMsg): Unit = {
|
||||
chatActor ! ChatActor.Message(pkt)
|
||||
}
|
||||
|
||||
def handleChatFilter(pkt: SetChatFilterMessage): Unit = { /* intentionally blank */ }
|
||||
|
||||
def handleVoiceHostRequest(pkt: VoiceHostRequest): Unit = {
|
||||
log.debug(s"$pkt")
|
||||
sendResponse(VoiceHostKill())
|
||||
|
|
|
|||
|
|
@ -3,8 +3,7 @@ package net.psforever.actors.session.spectator
|
|||
|
||||
import akka.actor.Actor.Receive
|
||||
import akka.actor.ActorRef
|
||||
import net.psforever.actors.session.ChatActor
|
||||
import net.psforever.actors.session.support.{AvatarHandlerFunctions, GalaxyHandlerFunctions, GeneralFunctions, LocalHandlerFunctions, MountHandlerFunctions, SquadHandlerFunctions, TerminalHandlerFunctions, VehicleFunctions, VehicleHandlerFunctions, WeaponAndProjectileFunctions}
|
||||
import net.psforever.actors.session.support.{AvatarHandlerFunctions, ChatFunctions, GalaxyHandlerFunctions, GeneralFunctions, LocalHandlerFunctions, MountHandlerFunctions, SquadHandlerFunctions, TerminalHandlerFunctions, VehicleFunctions, VehicleHandlerFunctions, WeaponAndProjectileFunctions}
|
||||
import net.psforever.actors.zone.ZoneActor
|
||||
import net.psforever.objects.avatar.{BattleRank, CommandRank, DeployableToolbox, FirstTimeEvents, Implant, ProgressDecoration, Shortcut => AvatarShortcut}
|
||||
import net.psforever.objects.serverobject.ServerObject
|
||||
|
|
@ -13,6 +12,7 @@ import net.psforever.packet.PlanetSidePacket
|
|||
import net.psforever.packet.game.{ObjectCreateDetailedMessage, ObjectDeleteMessage}
|
||||
import net.psforever.packet.game.objectcreate.{ObjectClass, ObjectCreateMessageParent, RibbonBars}
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import net.psforever.services.chat.{ChatService, SpectatorChannel}
|
||||
import net.psforever.services.teamwork.{SquadAction, SquadServiceMessage}
|
||||
import net.psforever.types.{CapacitorStateType, ChatMessageType, ExoSuitType, MeritCommendation, SquadRequestType}
|
||||
//
|
||||
|
|
@ -41,6 +41,7 @@ import net.psforever.services.vehicle.VehicleServiceResponse
|
|||
|
||||
class SpectatorModeLogic(data: SessionData) extends ModeLogic {
|
||||
val avatarResponse: AvatarHandlerFunctions = AvatarHandlerLogic(data.avatarResponse)
|
||||
val chat: ChatFunctions = ChatLogic(data.chat)
|
||||
val galaxy: GalaxyHandlerFunctions = GalaxyHandlerLogic(data.galaxyResponseHandlers)
|
||||
val general: GeneralFunctions = GeneralLogic(data.general)
|
||||
val local: LocalHandlerFunctions = LocalHandlerLogic(data.localResponse)
|
||||
|
|
@ -115,9 +116,12 @@ class SpectatorModeLogic(data: SessionData) extends ModeLogic {
|
|||
val originalEvent = player.History.headOption
|
||||
player.ClearHistory()
|
||||
player.LogActivity(originalEvent)
|
||||
player.spectator = true
|
||||
//
|
||||
data.general.chatActor ! ChatActor.SetMode("spectator")
|
||||
player.spectator = true
|
||||
if (player.silenced) {
|
||||
data.chat.commandIncomingSilence(session, ChatMsg(ChatMessageType.CMT_SILENCE, "player 0"))
|
||||
}
|
||||
data.chat.JoinChannel(SpectatorChannel)
|
||||
val newPlayer = SpectatorModeLogic.spectatorCharacter(player)
|
||||
val cud = new SimpleItem(GlobalDefinitions.command_detonater)
|
||||
cud.GUID = player.avatar.locker.GUID
|
||||
|
|
@ -145,6 +149,7 @@ class SpectatorModeLogic(data: SessionData) extends ModeLogic {
|
|||
val zoning = data.zoning
|
||||
val sendResponse: PlanetSidePacket => Unit = data.sendResponse
|
||||
//
|
||||
data.chat.LeaveChannel(SpectatorChannel)
|
||||
player.spectator = false
|
||||
sendResponse(ObjectDeleteMessage(player.avatar.locker.GUID, 0)) //free up the slot (from cud)
|
||||
sendResponse(ChatMsg(ChatMessageType.CMT_TOGGLESPECTATORMODE, "off"))
|
||||
|
|
@ -178,6 +183,9 @@ class SpectatorModeLogic(data: SessionData) extends ModeLogic {
|
|||
case VehicleServiceResponse(toChannel, guid, reply) =>
|
||||
vehicleResponse.handle(toChannel, guid, reply)
|
||||
|
||||
case ChatService.MessageResponse(fromSession, message, _) =>
|
||||
chat.handleIncomingMessage(data.session, message, fromSession)
|
||||
|
||||
case SessionActor.SendResponse(packet) =>
|
||||
data.sendResponse(packet)
|
||||
|
||||
|
|
@ -409,10 +417,10 @@ class SpectatorModeLogic(data: SessionData) extends ModeLogic {
|
|||
data.zoning.spawn.handleSpawnRequest(packet)
|
||||
|
||||
case packet: ChatMsg =>
|
||||
general.handleChat(packet)
|
||||
chat.handleChatMsg(data.session, packet)
|
||||
|
||||
case packet: SetChatFilterMessage =>
|
||||
general.handleChatFilter(packet)
|
||||
chat.handleChatFilter(packet)
|
||||
|
||||
case packet: VoiceHostRequest =>
|
||||
general.handleVoiceHostRequest(packet)
|
||||
|
|
|
|||
|
|
@ -3,12 +3,12 @@ package net.psforever.actors.session.spectator
|
|||
|
||||
import akka.actor.{ActorContext, typed}
|
||||
import net.psforever.actors.session.support.SessionSquadHandlers.SquadUIElement
|
||||
import net.psforever.actors.session.{AvatarActor, ChatActor}
|
||||
import net.psforever.actors.session.AvatarActor
|
||||
import net.psforever.actors.session.support.{SessionData, SessionSquadHandlers, SquadHandlerFunctions}
|
||||
import net.psforever.objects.{Default, LivePlayerList}
|
||||
import net.psforever.objects.avatar.Avatar
|
||||
import net.psforever.packet.game.{CharacterKnowledgeInfo, CharacterKnowledgeMessage, PlanetsideAttributeMessage, ReplicationStreamMessage, SquadAction, SquadDefinitionActionMessage, SquadDetailDefinitionUpdateMessage, SquadListing, SquadMemberEvent, SquadMembershipRequest, SquadMembershipResponse, SquadState, SquadStateInfo, SquadWaypointEvent, SquadWaypointRequest, WaypointEventAction}
|
||||
import net.psforever.services.chat.ChatService
|
||||
import net.psforever.services.chat.SquadChannel
|
||||
import net.psforever.services.teamwork.SquadResponse
|
||||
import net.psforever.types.{PlanetSideGUID, SquadListDecoration, SquadResponseType}
|
||||
|
||||
|
|
@ -23,10 +23,6 @@ class SquadHandlerLogic(val ops: SessionSquadHandlers, implicit val context: Act
|
|||
|
||||
private val avatarActor: typed.ActorRef[AvatarActor.Command] = ops.avatarActor
|
||||
|
||||
private val chatActor: typed.ActorRef[ChatActor.Command] = ops.chatActor
|
||||
|
||||
//private val squadService: ActorRef = ops.squadService
|
||||
|
||||
/* packet */
|
||||
|
||||
def handleSquadDefinitionAction(pkt: SquadDefinitionActionMessage): Unit = { /* intentionally blank */ }
|
||||
|
|
@ -122,7 +118,7 @@ class SquadHandlerLogic(val ops: SessionSquadHandlers, implicit val context: Act
|
|||
ops.squad_supplement_id = 0
|
||||
ops.squadUpdateCounter = 0
|
||||
ops.updateSquad = ops.NoSquadUpdates
|
||||
chatActor ! ChatActor.LeaveChannel(ChatService.ChatChannel.Squad(squad.GUID))
|
||||
sessionLogic.chat.LeaveChannel(SquadChannel(squad.GUID))
|
||||
case _ =>
|
||||
//remove each member's entry
|
||||
ops.GiveSquadColorsToMembers(
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -8,7 +8,7 @@ import scala.collection.mutable
|
|||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.duration._
|
||||
//
|
||||
import net.psforever.actors.session.{AvatarActor, ChatActor, SessionActor}
|
||||
import net.psforever.actors.session.{AvatarActor, SessionActor}
|
||||
import net.psforever.login.WorldSession._
|
||||
import net.psforever.objects._
|
||||
import net.psforever.objects.avatar._
|
||||
|
|
@ -25,7 +25,7 @@ import net.psforever.objects.vehicles._
|
|||
import net.psforever.objects.vital._
|
||||
import net.psforever.objects.zones._
|
||||
import net.psforever.packet._
|
||||
import net.psforever.packet.game.{ActionCancelMessage, AvatarFirstTimeEventMessage, AvatarImplantMessage, AvatarJumpMessage, BattleplanMessage, BindPlayerMessage, ChangeShortcutBankMessage, CharacterRequestMessage, ConnectToWorldRequestMessage, CreateShortcutMessage, DeployObjectMessage, DisplayedAwardMessage, EmoteMsg, FacilityBenefitShieldChargeRequestMessage, FriendsRequest, GenericActionMessage, GenericCollisionMsg, GenericObjectActionAtPositionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HitHint, InvalidTerrainMessage, LootItemMessage, MoveItemMessage, ObjectDetectedMessage, ObjectHeldMessage, PickupItemMessage, PlanetsideAttributeMessage, PlayerStateMessageUpstream, RequestDestroyMessage, SetChatFilterMessage, TargetingImplantRequest, TradeMessage, UnuseItemMessage, UseItemMessage, ZipLineMessage}
|
||||
import net.psforever.packet.game.{ActionCancelMessage, AvatarFirstTimeEventMessage, AvatarImplantMessage, AvatarJumpMessage, BattleplanMessage, BindPlayerMessage, ChangeShortcutBankMessage, CharacterRequestMessage, ConnectToWorldRequestMessage, CreateShortcutMessage, DeployObjectMessage, DisplayedAwardMessage, EmoteMsg, FacilityBenefitShieldChargeRequestMessage, FriendsRequest, GenericActionMessage, GenericCollisionMsg, GenericObjectActionAtPositionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HitHint, InvalidTerrainMessage, LootItemMessage, MoveItemMessage, ObjectDetectedMessage, ObjectHeldMessage, PickupItemMessage, PlanetsideAttributeMessage, PlayerStateMessageUpstream, RequestDestroyMessage, TargetingImplantRequest, TradeMessage, UnuseItemMessage, UseItemMessage, ZipLineMessage}
|
||||
import net.psforever.packet.game.PlanetsideAttributeEnum.PlanetsideAttributeEnum
|
||||
import net.psforever.packet.game.objectcreate._
|
||||
import net.psforever.packet.game._
|
||||
|
|
@ -48,10 +48,6 @@ trait GeneralFunctions extends CommonSessionInterfacingFunctionality {
|
|||
|
||||
def handlePlayerStateUpstream(pkt: PlayerStateMessageUpstream): Unit
|
||||
|
||||
def handleChat(pkt: ChatMsg): Unit
|
||||
|
||||
def handleChatFilter(pkt: SetChatFilterMessage): Unit
|
||||
|
||||
def handleVoiceHostRequest(pkt: VoiceHostRequest): Unit
|
||||
|
||||
def handleVoiceHostInfo(pkt: VoiceHostInfo): Unit
|
||||
|
|
@ -148,7 +144,6 @@ trait GeneralFunctions extends CommonSessionInterfacingFunctionality {
|
|||
class GeneralOperations(
|
||||
val sessionLogic: SessionData,
|
||||
val avatarActor: typed.ActorRef[AvatarActor.Command],
|
||||
val chatActor: typed.ActorRef[ChatActor.Command],
|
||||
implicit val context: ActorContext
|
||||
) extends CommonSessionInterfacingFunctionality {
|
||||
private[session] var progressBarValue: Option[Float] = None
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import net.psforever.objects.Session
|
|||
|
||||
trait ModeLogic {
|
||||
def avatarResponse: AvatarHandlerFunctions
|
||||
def chat: ChatFunctions
|
||||
def galaxy: GalaxyHandlerFunctions
|
||||
def general: GeneralFunctions
|
||||
def local: LocalHandlerFunctions
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import net.psforever.objects.zones.exp
|
|||
|
||||
import scala.collection.mutable
|
||||
//
|
||||
import net.psforever.actors.session.{AvatarActor, ChatActor}
|
||||
import net.psforever.actors.session.AvatarActor
|
||||
import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent
|
||||
import net.psforever.packet.game._
|
||||
import net.psforever.services.avatar.AvatarResponse
|
||||
|
|
@ -24,7 +24,6 @@ trait AvatarHandlerFunctions extends CommonSessionInterfacingFunctionality {
|
|||
class SessionAvatarHandlers(
|
||||
val sessionLogic: SessionData,
|
||||
val avatarActor: typed.ActorRef[AvatarActor.Command],
|
||||
chatActor: typed.ActorRef[ChatActor.Command],
|
||||
implicit val context: ActorContext
|
||||
) extends CommonSessionInterfacingFunctionality {
|
||||
//TODO player characters only exist within a certain range of GUIDs for a given zone; this is overkill
|
||||
|
|
|
|||
|
|
@ -4,12 +4,14 @@ package net.psforever.actors.session.support
|
|||
import akka.actor.typed.receptionist.Receptionist
|
||||
import akka.actor.typed.scaladsl.adapter._
|
||||
import akka.actor.{ActorContext, ActorRef, typed}
|
||||
import net.psforever.services.chat.ChatService
|
||||
|
||||
import scala.collection.mutable
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.duration._
|
||||
//
|
||||
import net.psforever.actors.net.MiddlewareActor
|
||||
import net.psforever.actors.session.{AvatarActor, ChatActor}
|
||||
import net.psforever.actors.session.AvatarActor
|
||||
import net.psforever.actors.zone.ZoneActor
|
||||
import net.psforever.objects._
|
||||
import net.psforever.objects.avatar._
|
||||
|
|
@ -60,7 +62,7 @@ object SessionData {
|
|||
class SessionData(
|
||||
val middlewareActor: typed.ActorRef[MiddlewareActor.Command],
|
||||
implicit val context: ActorContext
|
||||
) {
|
||||
) extends SessionSource {
|
||||
/**
|
||||
* Hardwire an implicit `sender` to be the same as `context.self` of the `SessionActor` actor class
|
||||
* for which this support class was initialized.
|
||||
|
|
@ -74,7 +76,6 @@ class SessionData(
|
|||
private[this] implicit val sender: ActorRef = context.self
|
||||
|
||||
private val avatarActor: typed.ActorRef[AvatarActor.Command] = context.spawnAnonymous(AvatarActor(context.self))
|
||||
private val chatActor: typed.ActorRef[ChatActor.Command] = context.spawnAnonymous(ChatActor(context.self, avatarActor))
|
||||
|
||||
private[session] val log = org.log4s.getLogger
|
||||
private[session] var theSession: Session = Session()
|
||||
|
|
@ -83,6 +84,7 @@ class SessionData(
|
|||
private[session] var galaxyService: ActorRef = Default.Actor
|
||||
private[session] var squadService: ActorRef = Default.Actor
|
||||
private[session] var cluster: typed.ActorRef[ICS.Command] = Default.typed.Actor
|
||||
private[session] var chatService: typed.ActorRef[ChatService.Command] = Default.typed.Actor
|
||||
private[session] var connectionState: Int = 25
|
||||
private[session] var persistFunc: () => Unit = noPersistence
|
||||
private[session] var persist: () => Unit = updatePersistenceOnly
|
||||
|
|
@ -92,13 +94,13 @@ class SessionData(
|
|||
private var contextSafeEntity: PlanetSideGUID = PlanetSideGUID(0)
|
||||
|
||||
val general: GeneralOperations =
|
||||
new GeneralOperations(sessionLogic=this, avatarActor, chatActor, context)
|
||||
new GeneralOperations(sessionLogic=this, avatarActor, context)
|
||||
val shooting: WeaponAndProjectileOperations =
|
||||
new WeaponAndProjectileOperations(sessionLogic=this, avatarActor, chatActor, context)
|
||||
new WeaponAndProjectileOperations(sessionLogic=this, avatarActor, context)
|
||||
val vehicles: VehicleOperations =
|
||||
new VehicleOperations(sessionLogic=this, avatarActor, context)
|
||||
val avatarResponse: SessionAvatarHandlers =
|
||||
new SessionAvatarHandlers(sessionLogic=this, avatarActor, chatActor, context)
|
||||
new SessionAvatarHandlers(sessionLogic=this, avatarActor, context)
|
||||
val localResponse: SessionLocalHandlers =
|
||||
new SessionLocalHandlers(sessionLogic=this, context)
|
||||
val mountResponse: SessionMountHandlers =
|
||||
|
|
@ -109,16 +111,19 @@ class SessionData(
|
|||
private var galaxyResponseOpt: Option[SessionGalaxyHandlers] = None
|
||||
private var squadResponseOpt: Option[SessionSquadHandlers] = None
|
||||
private var zoningOpt: Option[ZoningOperations] = None
|
||||
private var chatOpt: Option[ChatOperations] = None
|
||||
def vehicleResponseOperations: SessionVehicleHandlers = vehicleResponseOpt.orNull
|
||||
def galaxyResponseHandlers: SessionGalaxyHandlers = galaxyResponseOpt.orNull
|
||||
def squad: SessionSquadHandlers = squadResponseOpt.orNull
|
||||
def zoning: ZoningOperations = zoningOpt.orNull
|
||||
def chat: ChatOperations = chatOpt.orNull
|
||||
|
||||
ServiceManager.serviceManager ! Lookup("accountIntermediary")
|
||||
ServiceManager.serviceManager ! Lookup("accountPersistence")
|
||||
ServiceManager.serviceManager ! Lookup("galaxy")
|
||||
ServiceManager.serviceManager ! Lookup("squad")
|
||||
ServiceManager.receptionist ! Receptionist.Find(ICS.InterstellarClusterServiceKey, context.self)
|
||||
ServiceManager.receptionist ! Receptionist.Find(ChatService.ChatServiceKey, context.self)
|
||||
|
||||
/**
|
||||
* updated when an upstream packet arrives;
|
||||
|
|
@ -129,7 +134,6 @@ class SessionData(
|
|||
def session: Session = theSession
|
||||
|
||||
def session_=(session: Session): Unit = {
|
||||
chatActor ! ChatActor.SetSession(session)
|
||||
avatarActor ! AvatarActor.SetSession(session)
|
||||
theSession = session
|
||||
}
|
||||
|
|
@ -164,6 +168,11 @@ class SessionData(
|
|||
case ICS.InterstellarClusterServiceKey.Listing(listings) =>
|
||||
cluster = listings.head
|
||||
buildDependentOperationsForZoning(galaxyService, cluster)
|
||||
buildDependentOperationsForChat(chatService, cluster)
|
||||
true
|
||||
case ChatService.ChatServiceKey.Listing(listings) =>
|
||||
chatService = listings.head
|
||||
buildDependentOperationsForChat(chatService, cluster)
|
||||
true
|
||||
|
||||
case _ =>
|
||||
|
|
@ -186,7 +195,13 @@ class SessionData(
|
|||
|
||||
def buildDependentOperationsForSquad(squadActor: ActorRef): Unit = {
|
||||
if (squadResponseOpt.isEmpty && squadActor != Default.Actor) {
|
||||
squadResponseOpt = Some(new SessionSquadHandlers(sessionLogic=this, avatarActor, chatActor, squadActor, context))
|
||||
squadResponseOpt = Some(new SessionSquadHandlers(sessionLogic=this, avatarActor, squadActor, context))
|
||||
}
|
||||
}
|
||||
|
||||
def buildDependentOperationsForChat(chatService: typed.ActorRef[ChatService.Command], clusterActor: typed.ActorRef[ICS.Command]): Unit = {
|
||||
if (chatOpt.isEmpty && chatService != Default.typed.Actor && clusterActor != Default.typed.Actor) {
|
||||
chatOpt = Some(new ChatOperations(sessionLogic=this, avatarActor, chatService, clusterActor, context))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -196,7 +211,8 @@ class SessionData(
|
|||
vehicleResponseOpt.nonEmpty &&
|
||||
galaxyResponseOpt.nonEmpty &&
|
||||
squadResponseOpt.nonEmpty &&
|
||||
zoningOpt.nonEmpty
|
||||
zoningOpt.nonEmpty &&
|
||||
chatOpt.nonEmpty
|
||||
}
|
||||
|
||||
/* support functions */
|
||||
|
|
@ -363,11 +379,11 @@ class SessionData(
|
|||
terminals.actionsToCancel()
|
||||
if (session.flying) {
|
||||
session = session.copy(flying = false)
|
||||
chatActor ! ChatActor.Message(ChatMsg(ChatMessageType.CMT_FLY, wideContents=false, "", "off", None))
|
||||
chat.commandFly(contents = "off", recipient = "")
|
||||
}
|
||||
if (session.speed > 1) {
|
||||
session = session.copy(speed = 1)
|
||||
chatActor ! ChatActor.Message(ChatMsg(ChatMessageType.CMT_SPEED, wideContents=false, "", "1.000", None))
|
||||
chat.commandSpeed(ChatMsg(ChatMessageType.CMT_SPEED, "1.000"), contents = "1.000")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -542,7 +558,6 @@ class SessionData(
|
|||
|
||||
def stop(): Unit = {
|
||||
context.stop(avatarActor)
|
||||
context.stop(chatActor)
|
||||
general.stop()
|
||||
shooting.stop()
|
||||
vehicles.stop()
|
||||
|
|
@ -554,6 +569,7 @@ class SessionData(
|
|||
galaxyResponseOpt.foreach(_.stop())
|
||||
squadResponseOpt.foreach(_.stop())
|
||||
zoningOpt.foreach(_.stop())
|
||||
chatOpt.foreach(_.stop())
|
||||
continent.AvatarEvents ! Service.Leave()
|
||||
continent.LocalEvents ! Service.Leave()
|
||||
continent.VehicleEvents ! Service.Leave()
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ package net.psforever.actors.session.support
|
|||
import akka.actor.{ActorContext, ActorRef, typed}
|
||||
import scala.collection.mutable
|
||||
//
|
||||
import net.psforever.actors.session.{AvatarActor, ChatActor}
|
||||
import net.psforever.actors.session.AvatarActor
|
||||
import net.psforever.objects.teamwork.Squad
|
||||
import net.psforever.objects.{Default, Player}
|
||||
import net.psforever.packet.game._
|
||||
|
|
@ -39,7 +39,6 @@ object SessionSquadHandlers {
|
|||
class SessionSquadHandlers(
|
||||
val sessionLogic: SessionData,
|
||||
val avatarActor: typed.ActorRef[AvatarActor.Command],
|
||||
val chatActor: typed.ActorRef[ChatActor.Command],
|
||||
val squadService: ActorRef,
|
||||
implicit val context: ActorContext
|
||||
) extends CommonSessionInterfacingFunctionality {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import net.psforever.objects.zones.exp.ToDatabase
|
|||
import scala.collection.mutable
|
||||
import scala.concurrent.duration._
|
||||
//
|
||||
import net.psforever.actors.session.{AvatarActor, ChatActor}
|
||||
import net.psforever.actors.session.AvatarActor
|
||||
import net.psforever.objects.avatar.scoring.EquipmentStat
|
||||
import net.psforever.objects.ballistics.Projectile
|
||||
import net.psforever.objects.equipment.EquipmentSize
|
||||
|
|
@ -63,7 +63,6 @@ trait WeaponAndProjectileFunctions extends CommonSessionInterfacingFunctionality
|
|||
class WeaponAndProjectileOperations(
|
||||
val sessionLogic: SessionData,
|
||||
val avatarActor: typed.ActorRef[AvatarActor.Command],
|
||||
val chatActor: typed.ActorRef[ChatActor.Command],
|
||||
implicit val context: ActorContext
|
||||
) extends CommonSessionInterfacingFunctionality {
|
||||
var shooting: mutable.Set[PlanetSideGUID] = mutable.Set.empty //ChangeFireStateMessage_Start
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import akka.actor.typed.scaladsl.adapter._
|
|||
import akka.actor.{ActorContext, ActorRef, Cancellable, typed}
|
||||
import akka.pattern.ask
|
||||
import akka.util.Timeout
|
||||
import net.psforever.actors.session.spectator.SpectatorMode
|
||||
import net.psforever.login.WorldSession
|
||||
import net.psforever.objects.avatar.BattleRank
|
||||
import net.psforever.objects.avatar.scoring.{CampaignStatistics, ScoreCard, SessionStatistics}
|
||||
|
|
@ -17,6 +18,7 @@ import net.psforever.objects.serverobject.turret.auto.AutomatedTurret
|
|||
import net.psforever.objects.sourcing.{PlayerSource, SourceEntry, VehicleSource}
|
||||
import net.psforever.objects.vital.{InGameHistory, IncarnationActivity, ReconstructionActivity, SpawningActivity}
|
||||
import net.psforever.packet.game.{CampaignStatistic, ChangeFireStateMessage_Start, MailMessage, ObjectDetectedMessage, SessionStatistic}
|
||||
import net.psforever.services.chat.DefaultChannel
|
||||
|
||||
import scala.collection.mutable
|
||||
import scala.concurrent.duration._
|
||||
|
|
@ -2164,6 +2166,7 @@ class ZoningOperations(
|
|||
*/
|
||||
def avatarLoginResponse(avatar: Avatar): Unit = {
|
||||
session = session.copy(avatar = avatar)
|
||||
sessionLogic.chat.JoinChannel(DefaultChannel)
|
||||
Deployables.InitializeDeployableQuantities(avatar)
|
||||
cluster ! ICS.FilterZones(_ => true, context.self)
|
||||
}
|
||||
|
|
@ -3070,6 +3073,9 @@ class ZoningOperations(
|
|||
}
|
||||
})
|
||||
}
|
||||
if (!setAvatar && tplayer.spectator) {
|
||||
context.self ! SessionActor.SetMode(SpectatorMode) //should reload spectator status
|
||||
}
|
||||
}
|
||||
upstreamMessageCount = 0
|
||||
setAvatar = true
|
||||
|
|
|
|||
|
|
@ -15,3 +15,7 @@ case class Session(
|
|||
speed: Float = 1.0f,
|
||||
flying: Boolean = false
|
||||
)
|
||||
|
||||
trait SessionSource {
|
||||
def session: Session
|
||||
}
|
||||
|
|
|
|||
12
src/main/scala/net/psforever/services/chat/ChatChannel.scala
Normal file
12
src/main/scala/net/psforever/services/chat/ChatChannel.scala
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright (c) 2024 PSForever
|
||||
package net.psforever.services.chat
|
||||
|
||||
import net.psforever.types.PlanetSideGUID
|
||||
|
||||
trait ChatChannel
|
||||
|
||||
case object DefaultChannel extends ChatChannel
|
||||
|
||||
final case class SquadChannel(guid: PlanetSideGUID) extends ChatChannel
|
||||
|
||||
case object SpectatorChannel extends ChatChannel
|
||||
|
|
@ -4,9 +4,9 @@ package net.psforever.services.chat
|
|||
import akka.actor.typed.receptionist.{Receptionist, ServiceKey}
|
||||
import akka.actor.typed.{ActorRef, Behavior}
|
||||
import akka.actor.typed.scaladsl.{AbstractBehavior, ActorContext, Behaviors}
|
||||
import net.psforever.objects.Session
|
||||
import net.psforever.objects.{Session, SessionSource}
|
||||
import net.psforever.packet.game.ChatMsg
|
||||
import net.psforever.types.{ChatMessageType, PlanetSideEmpire, PlanetSideGUID}
|
||||
import net.psforever.types.{ChatMessageType, PlanetSideEmpire}
|
||||
|
||||
object ChatService {
|
||||
val ChatServiceKey: ServiceKey[Command] = ServiceKey[ChatService.Command]("chatService")
|
||||
|
|
@ -19,20 +19,12 @@ object ChatService {
|
|||
|
||||
sealed trait Command
|
||||
|
||||
final case class JoinChannel(actor: ActorRef[MessageResponse], session: Session, channel: ChatChannel) extends Command
|
||||
final case class JoinChannel(actor: ActorRef[MessageResponse], sessionSource: SessionSource, channel: ChatChannel) extends Command
|
||||
final case class LeaveChannel(actor: ActorRef[MessageResponse], channel: ChatChannel) extends Command
|
||||
final case class LeaveAllChannels(actor: ActorRef[MessageResponse]) extends Command
|
||||
|
||||
final case class Message(session: Session, message: ChatMsg, channel: ChatChannel) extends Command
|
||||
final case class MessageResponse(session: Session, message: ChatMsg, channel: ChatChannel)
|
||||
|
||||
trait ChatChannel
|
||||
object ChatChannel {
|
||||
// one of the default channels that the player is always subscribed to (local, broadcast, command...)
|
||||
final case class Default() extends ChatChannel
|
||||
final case class Squad(guid: PlanetSideGUID) extends ChatChannel
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ChatService(context: ActorContext[ChatService.Command]) extends AbstractBehavior[ChatService.Command](context) {
|
||||
|
|
@ -63,9 +55,10 @@ class ChatService(context: ActorContext[ChatService.Command]) extends AbstractBe
|
|||
|
||||
case Message(session, message, channel) =>
|
||||
(channel, message.messageType) match {
|
||||
case (ChatChannel.Squad(_), CMT_SQUAD) => ()
|
||||
case (ChatChannel.Squad(_), CMT_VOICE) if message.contents.startsWith("SH") => ()
|
||||
case (ChatChannel.Default(), messageType) if messageType != CMT_SQUAD => ()
|
||||
case (SquadChannel(_), CMT_SQUAD) => ()
|
||||
case (SquadChannel(_), CMT_VOICE) if message.contents.startsWith("SH") => ()
|
||||
case (DefaultChannel, messageType) if messageType != CMT_SQUAD => ()
|
||||
case (SpectatorChannel, messageType) if messageType != CMT_SQUAD => ()
|
||||
case _ =>
|
||||
log.error(s"invalid chat channel $channel for messageType ${message.messageType}")
|
||||
return this
|
||||
|
|
@ -78,8 +71,8 @@ class ChatService(context: ActorContext[ChatService.Command]) extends AbstractBe
|
|||
val recipientName = message.recipient
|
||||
val recipientNameLower = recipientName.toLowerCase()
|
||||
(
|
||||
subs.find(_.session.player.Name.toLowerCase().equals(playerNameLower)),
|
||||
subs.find(_.session.player.Name.toLowerCase().equals(recipientNameLower))
|
||||
subs.find(_.sessionSource.session.player.Name.toLowerCase().equals(playerNameLower)),
|
||||
subs.find(_.sessionSource.session.player.Name.toLowerCase().equals(recipientNameLower))
|
||||
) match {
|
||||
case (Some(JoinChannel(sender, _, _)), Some(JoinChannel(receiver, _, _))) =>
|
||||
val replyType = if (mtype == CMT_TELL) { U_CMT_TELLFROM } else { U_CMT_GMTELLFROM }
|
||||
|
|
@ -122,14 +115,14 @@ class ChatService(context: ActorContext[ChatService.Command]) extends AbstractBe
|
|||
case _ => (None, None, None)
|
||||
}
|
||||
|
||||
val sender = subs.find(_.session.player.Name == session.player.Name)
|
||||
val sender = subs.find(_.sessionSource.session.player.Name == session.player.Name)
|
||||
|
||||
(sender, name, time, error) match {
|
||||
case (Some(sender), Some(name), Some(_), None) =>
|
||||
val recipient = subs.find(_.session.player.Name == name)
|
||||
val recipient = subs.find(_.sessionSource.session.player.Name == name)
|
||||
recipient match {
|
||||
case Some(recipient) =>
|
||||
if (recipient.session.player.silenced) {
|
||||
if (recipient.sessionSource.session.player.silenced) {
|
||||
sender.actor ! MessageResponse(
|
||||
session,
|
||||
ChatMsg(UNK_229, wideContents = true, "", "@silence_disabled_ack", None),
|
||||
|
|
@ -167,7 +160,7 @@ class ChatService(context: ActorContext[ChatService.Command]) extends AbstractBe
|
|||
|
||||
case CMT_NOTE =>
|
||||
subs
|
||||
.filter(_.session.player.Name == message.recipient)
|
||||
.filter(_.sessionSource.session.player.Name == message.recipient)
|
||||
.foreach(
|
||||
_.actor ! MessageResponse(session, message.copy(recipient = session.player.Name), channel)
|
||||
)
|
||||
|
|
@ -175,23 +168,23 @@ class ChatService(context: ActorContext[ChatService.Command]) extends AbstractBe
|
|||
// faction commands
|
||||
case CMT_OPEN | CMT_PLATOON | CMT_COMMAND =>
|
||||
subs
|
||||
.filter(_.session.player.Faction == session.player.Faction)
|
||||
.filter(_.sessionSource.session.player.Faction == session.player.Faction)
|
||||
.foreach(
|
||||
_.actor ! MessageResponse(session, message, channel)
|
||||
)
|
||||
|
||||
case CMT_GMBROADCAST_NC =>
|
||||
subs.filter(_.session.player.Faction == PlanetSideEmpire.NC).foreach {
|
||||
subs.filter(_.sessionSource.session.player.Faction == PlanetSideEmpire.NC).foreach {
|
||||
case JoinChannel(actor, _, _) => actor ! MessageResponse(session, message, channel)
|
||||
}
|
||||
|
||||
case CMT_GMBROADCAST_TR =>
|
||||
subs.filter(_.session.player.Faction == PlanetSideEmpire.TR).foreach {
|
||||
subs.filter(_.sessionSource.session.player.Faction == PlanetSideEmpire.TR).foreach {
|
||||
case JoinChannel(actor, _, _) => actor ! MessageResponse(session, message, channel)
|
||||
}
|
||||
|
||||
case CMT_GMBROADCAST_VS =>
|
||||
subs.filter(_.session.player.Faction == PlanetSideEmpire.VS).foreach {
|
||||
subs.filter(_.sessionSource.session.player.Faction == PlanetSideEmpire.VS).foreach {
|
||||
case JoinChannel(actor, _, _) => actor ! MessageResponse(session, message, channel)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue