mirror of
https://github.com/psforever/PSF-LoginServer.git
synced 2026-07-15 00:14:43 +00:00
introducing generic event message services; implementing GalaxyService using the generic framework
This commit is contained in:
parent
83482a7207
commit
406e89ea50
33 changed files with 309 additions and 178 deletions
|
|
@ -3,9 +3,10 @@ package net.psforever.actors.session.normal
|
||||||
|
|
||||||
import akka.actor.{ActorContext, ActorRef, typed}
|
import akka.actor.{ActorContext, ActorRef, typed}
|
||||||
import net.psforever.actors.session.AvatarActor
|
import net.psforever.actors.session.AvatarActor
|
||||||
import net.psforever.actors.session.support.{GalaxyHandlerFunctions, SessionGalaxyHandlers, SessionData}
|
import net.psforever.actors.session.support.{GalaxyHandlerFunctions, SessionData, SessionGalaxyHandlers}
|
||||||
import net.psforever.packet.game.{BroadcastWarpgateUpdateMessage, FriendsResponse, HotSpotUpdateMessage, ZoneInfoMessage, ZonePopulationUpdateMessage, HotSpotInfo => PacketHotSpotInfo}
|
import net.psforever.packet.game.{BroadcastWarpgateUpdateMessage, FriendsResponse, HotSpotUpdateMessage, ZoneInfoMessage, ZonePopulationUpdateMessage, HotSpotInfo => PacketHotSpotInfo}
|
||||||
import net.psforever.services.galaxy.{GalaxyAction, GalaxyResponse, GalaxyServiceMessage}
|
import net.psforever.services.base.EventResponse
|
||||||
|
import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage}
|
||||||
import net.psforever.types.{MemberAction, PlanetSideEmpire}
|
import net.psforever.types.{MemberAction, PlanetSideEmpire}
|
||||||
|
|
||||||
object GalaxyHandlerLogic {
|
object GalaxyHandlerLogic {
|
||||||
|
|
@ -32,9 +33,9 @@ class GalaxyHandlerLogic(val ops: SessionGalaxyHandlers, implicit val context: A
|
||||||
|
|
||||||
/* response handlers */
|
/* response handlers */
|
||||||
|
|
||||||
def handle(reply: GalaxyResponse.Response): Unit = {
|
def handle(reply: EventResponse): Unit = {
|
||||||
reply match {
|
reply match {
|
||||||
case GalaxyResponse.HotSpotUpdate(zone_index, priority, hot_spot_info) =>
|
case GalaxyAction.HotSpotUpdate(zone_index, priority, hot_spot_info) =>
|
||||||
sendResponse(
|
sendResponse(
|
||||||
HotSpotUpdateMessage(
|
HotSpotUpdateMessage(
|
||||||
zone_index,
|
zone_index,
|
||||||
|
|
@ -43,7 +44,7 @@ class GalaxyHandlerLogic(val ops: SessionGalaxyHandlers, implicit val context: A
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
case GalaxyResponse.MapUpdate(msg) =>
|
case GalaxyAction.MapUpdate(msg) =>
|
||||||
sendResponse(msg)
|
sendResponse(msg)
|
||||||
import net.psforever.actors.zone.ZoneActor
|
import net.psforever.actors.zone.ZoneActor
|
||||||
import net.psforever.zones.Zones
|
import net.psforever.zones.Zones
|
||||||
|
|
@ -53,7 +54,7 @@ class GalaxyHandlerLogic(val ops: SessionGalaxyHandlers, implicit val context: A
|
||||||
case None =>
|
case None =>
|
||||||
}
|
}
|
||||||
|
|
||||||
case GalaxyResponse.UpdateBroadcastPrivileges(zoneId, gateMapId, fromFactions, toFactions) =>
|
case GalaxyAction.UpdateBroadcastPrivileges(zoneId, gateMapId, fromFactions, toFactions) =>
|
||||||
val faction = player.Faction
|
val faction = player.Faction
|
||||||
val from = fromFactions.contains(faction)
|
val from = fromFactions.contains(faction)
|
||||||
val to = toFactions.contains(faction)
|
val to = toFactions.contains(faction)
|
||||||
|
|
@ -63,16 +64,16 @@ class GalaxyHandlerLogic(val ops: SessionGalaxyHandlers, implicit val context: A
|
||||||
sendResponse(BroadcastWarpgateUpdateMessage(zoneId, gateMapId, faction))
|
sendResponse(BroadcastWarpgateUpdateMessage(zoneId, gateMapId, faction))
|
||||||
}
|
}
|
||||||
|
|
||||||
case GalaxyResponse.FlagMapUpdate(msg) =>
|
case GalaxyAction.FlagMapUpdate(msg) =>
|
||||||
sendResponse(msg)
|
sendResponse(msg)
|
||||||
|
|
||||||
case GalaxyResponse.TransferPassenger(temp_channel, vehicle, _, manifest) =>
|
case GalaxyAction.TransferPassenger(_, temp_channel, vehicle, _, manifest) =>
|
||||||
sessionLogic.zoning.handleTransferPassenger(temp_channel, vehicle, manifest)
|
sessionLogic.zoning.handleTransferPassenger(temp_channel, vehicle, manifest)
|
||||||
|
|
||||||
case GalaxyResponse.LockedZoneUpdate(zone, time) =>
|
case GalaxyAction.LockedZoneUpdate(zone, time) =>
|
||||||
sendResponse(ZoneInfoMessage(zone.Number, empire_status=false, lock_time=time))
|
sendResponse(ZoneInfoMessage(zone.Number, empire_status=false, lock_time=time))
|
||||||
|
|
||||||
case GalaxyResponse.UnlockedZoneUpdate(zone) =>
|
case GalaxyAction.UnlockedZoneUpdate(zone) =>
|
||||||
sendResponse(ZoneInfoMessage(zone.Number, empire_status=true, lock_time=0L))
|
sendResponse(ZoneInfoMessage(zone.Number, empire_status=true, lock_time=0L))
|
||||||
val popBO = 0
|
val popBO = 0
|
||||||
val pop = zone.LivePlayers.distinctBy(_.CharId)
|
val pop = zone.LivePlayers.distinctBy(_.CharId)
|
||||||
|
|
@ -81,10 +82,10 @@ class GalaxyHandlerLogic(val ops: SessionGalaxyHandlers, implicit val context: A
|
||||||
val popVS = pop.count(_.Faction == PlanetSideEmpire.VS)
|
val popVS = pop.count(_.Faction == PlanetSideEmpire.VS)
|
||||||
sendResponse(ZonePopulationUpdateMessage(zone.Number, 414, 138, popTR, 138, popNC, 138, popVS, 138, popBO))
|
sendResponse(ZonePopulationUpdateMessage(zone.Number, 414, 138, popTR, 138, popNC, 138, popVS, 138, popBO))
|
||||||
|
|
||||||
case GalaxyResponse.LogStatusChange(name) if avatar.people.friend.exists(_.name.equals(name)) =>
|
case GalaxyAction.LogStatusChange(name) if avatar.people.friend.exists(_.name.equals(name)) =>
|
||||||
avatarActor ! AvatarActor.MemberListRequest(MemberAction.UpdateFriend, name)
|
avatarActor ! AvatarActor.MemberListRequest(MemberAction.UpdateFriend, name)
|
||||||
|
|
||||||
case GalaxyResponse.SendResponse(msg) =>
|
case GalaxyAction.SendResponse(msg) =>
|
||||||
sendResponse(msg)
|
sendResponse(msg)
|
||||||
|
|
||||||
case _ => ()
|
case _ => ()
|
||||||
|
|
|
||||||
|
|
@ -3,16 +3,18 @@ package net.psforever.actors.session.support
|
||||||
|
|
||||||
import akka.actor.{ActorContext, ActorRef, typed}
|
import akka.actor.{ActorContext, ActorRef, typed}
|
||||||
import net.psforever.packet.game.FriendsResponse
|
import net.psforever.packet.game.FriendsResponse
|
||||||
|
import net.psforever.services.base.EventResponse
|
||||||
|
|
||||||
|
import scala.annotation.unused
|
||||||
//
|
//
|
||||||
import net.psforever.actors.session.AvatarActor
|
import net.psforever.actors.session.AvatarActor
|
||||||
import net.psforever.services.galaxy.GalaxyResponse
|
|
||||||
|
|
||||||
trait GalaxyHandlerFunctions extends CommonSessionInterfacingFunctionality {
|
trait GalaxyHandlerFunctions extends CommonSessionInterfacingFunctionality {
|
||||||
def ops: SessionGalaxyHandlers
|
def ops: SessionGalaxyHandlers
|
||||||
|
|
||||||
def handleUpdateIgnoredPlayers(pkt: FriendsResponse): Unit
|
def handleUpdateIgnoredPlayers(pkt: FriendsResponse): Unit
|
||||||
|
|
||||||
def handle(reply: GalaxyResponse.Response): Unit
|
def handle(@unused reply: EventResponse): Unit
|
||||||
}
|
}
|
||||||
|
|
||||||
class SessionGalaxyHandlers(
|
class SessionGalaxyHandlers(
|
||||||
|
|
|
||||||
|
|
@ -602,7 +602,7 @@ class ZoningOperations(
|
||||||
sendResponse(ReplicationStreamMessage(5, Some(6), Vector.empty)) //clear squad list
|
sendResponse(ReplicationStreamMessage(5, Some(6), Vector.empty)) //clear squad list
|
||||||
spawn.initializeFriendsAndIgnoredLists()
|
spawn.initializeFriendsAndIgnoredLists()
|
||||||
//the following subscriptions last until character switch/logout
|
//the following subscriptions last until character switch/logout
|
||||||
galaxyService ! Service.Join("galaxy") //for galaxy-wide messages
|
galaxyService ! Service.Join("") //for galaxy-wide messages
|
||||||
galaxyService ! Service.Join(s"${avatar.faction}") //for hotspots, etc.
|
galaxyService ! Service.Join(s"${avatar.faction}") //for hotspots, etc.
|
||||||
sessionLogic.squadService ! Service.Join(s"${avatar.faction}") //channel will be player.Faction
|
sessionLogic.squadService ! Service.Join(s"${avatar.faction}") //channel will be player.Faction
|
||||||
sessionLogic.squadService ! Service.Join(s"${avatar.id}") //channel will be player.CharId (in order to work with packets)
|
sessionLogic.squadService ! Service.Join(s"${avatar.id}") //channel will be player.CharId (in order to work with packets)
|
||||||
|
|
@ -1470,10 +1470,7 @@ class ZoningOperations(
|
||||||
case Some(manifest) =>
|
case Some(manifest) =>
|
||||||
val toChannel = manifest.file
|
val toChannel = manifest.file
|
||||||
val topLevel = interstellarFerryTopLevelGUID.getOrElse(vehicle.GUID)
|
val topLevel = interstellarFerryTopLevelGUID.getOrElse(vehicle.GUID)
|
||||||
galaxyService ! GalaxyServiceMessage(
|
galaxyService ! GalaxyServiceMessage(toChannel, GalaxyAction.TransferPassenger(player_guid, toChannel, vehicle, topLevel, manifest))
|
||||||
toChannel,
|
|
||||||
GalaxyAction.TransferPassenger(player_guid, toChannel, vehicle, topLevel, manifest)
|
|
||||||
)
|
|
||||||
vehicle.CargoHolds.values
|
vehicle.CargoHolds.values
|
||||||
.collect {
|
.collect {
|
||||||
case hold if hold.isOccupied =>
|
case hold if hold.isOccupied =>
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@ import akka.actor.{Actor, ActorRef, Cancellable, Props}
|
||||||
import net.psforever.objects.Default
|
import net.psforever.objects.Default
|
||||||
import net.psforever.types.{PlanetSideEmpire, Vector3}
|
import net.psforever.types.{PlanetSideEmpire, Vector3}
|
||||||
import net.psforever.services.ServiceManager
|
import net.psforever.services.ServiceManager
|
||||||
|
import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage}
|
||||||
|
|
||||||
import scala.collection.mutable.ListBuffer
|
import scala.collection.mutable.ListBuffer
|
||||||
import scala.concurrent.duration._
|
import scala.concurrent.duration._
|
||||||
|
|
||||||
|
|
@ -303,12 +305,11 @@ class ZoneHotSpotProjector(zone: Zone, hotspots: ListBuffer[HotSpotInfo], blanki
|
||||||
val zoneNumber = zone.Number
|
val zoneNumber = zone.Number
|
||||||
val hotSpotInfoList = hotSpotInfos.toList
|
val hotSpotInfoList = hotSpotInfos.toList
|
||||||
affectedFactions.foreach(faction =>
|
affectedFactions.foreach(faction =>
|
||||||
galaxy ! Zone.HotSpot.Update(
|
galaxy ! GalaxyServiceMessage(faction.toString, GalaxyAction.HotSpotUpdate(
|
||||||
faction,
|
zoneNumber,
|
||||||
zoneNumber,
|
1,
|
||||||
1,
|
ZoneHotSpotProjector.SpecificHotSpotInfo(faction, hotSpotInfoList)
|
||||||
ZoneHotSpotProjector.SpecificHotSpotInfo(faction, hotSpotInfoList)
|
))
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import net.psforever.objects.Default
|
||||||
import net.psforever.objects.serverobject.structures.{Building, WarpGate}
|
import net.psforever.objects.serverobject.structures.{Building, WarpGate}
|
||||||
import net.psforever.objects.zones.Zone
|
import net.psforever.objects.zones.Zone
|
||||||
import net.psforever.packet.game.ChatMsg
|
import net.psforever.packet.game.ChatMsg
|
||||||
import net.psforever.services.galaxy.{GalaxyAction, GalaxyResponse, GalaxyServiceMessage, GalaxyServiceResponse}
|
import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage, GalaxyServiceResponse}
|
||||||
import net.psforever.types.ChatMessageType
|
import net.psforever.types.ChatMessageType
|
||||||
import net.psforever.util.Config
|
import net.psforever.util.Config
|
||||||
import net.psforever.zones.Zones
|
import net.psforever.zones.Zones
|
||||||
|
|
@ -557,20 +557,14 @@ class CavernRotationService(
|
||||||
val (lockedZones, unlockedZones) = managedZones.partition(_.locked)
|
val (lockedZones, unlockedZones) = managedZones.partition(_.locked)
|
||||||
//borrow GalaxyService response structure, but send to the specific endpoint math.max(0, monitor.start + monitor.duration - curr)
|
//borrow GalaxyService response structure, but send to the specific endpoint math.max(0, monitor.start + monitor.duration - curr)
|
||||||
unlockedZones.foreach { monitor =>
|
unlockedZones.foreach { monitor =>
|
||||||
sendToSession ! GalaxyServiceResponse("", GalaxyResponse.UnlockedZoneUpdate(monitor.zone))
|
sendToSession ! GalaxyServiceResponse("", GalaxyAction.UnlockedZoneUpdate(monitor.zone))
|
||||||
}
|
}
|
||||||
val sortedLocked = lockedZones.sortBy(z => z.start)
|
val sortedLocked = lockedZones.sortBy(z => z.start)
|
||||||
sortedLocked.take(2).foreach { monitor =>
|
sortedLocked.take(2).foreach { monitor =>
|
||||||
sendToSession ! GalaxyServiceResponse(
|
sendToSession ! GalaxyServiceResponse("", GalaxyAction.LockedZoneUpdate(monitor.zone, math.max(0, monitor.start + monitor.duration - curr)))
|
||||||
"",
|
|
||||||
GalaxyResponse.LockedZoneUpdate(monitor.zone, math.max(0, monitor.start + monitor.duration - curr))
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
sortedLocked.takeRight(2).foreach { monitor =>
|
sortedLocked.takeRight(2).foreach { monitor =>
|
||||||
sendToSession ! GalaxyServiceResponse(
|
sendToSession ! GalaxyServiceResponse("", GalaxyAction.LockedZoneUpdate(monitor.zone, 0L))
|
||||||
"",
|
|
||||||
GalaxyResponse.LockedZoneUpdate(monitor.zone, 0L)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -654,8 +648,8 @@ class CavernRotationService(
|
||||||
val unlocking = managedZones(nextToUnlock)
|
val unlocking = managedZones(nextToUnlock)
|
||||||
val lockingZone = locking.zone
|
val lockingZone = locking.zone
|
||||||
val unlockingZone = unlocking.zone
|
val unlockingZone = unlocking.zone
|
||||||
val fullHoursBetweenRotationsAsHours = timeToCompleteAllRotationsHours.hours
|
//val fullHoursBetweenRotationsAsHours = timeToCompleteAllRotationsHours.hours
|
||||||
val fullHoursBetweenRotationsAsMillis = fullHoursBetweenRotationsAsHours.toMillis
|
//val fullHoursBetweenRotationsAsMillis = fullHoursBetweenRotationsAsHours.toMillis
|
||||||
val hoursBetweenRotationsAsHours = timeBetweenRotationsHours.hours
|
val hoursBetweenRotationsAsHours = timeBetweenRotationsHours.hours
|
||||||
val prevToLock = nextToLock
|
val prevToLock = nextToLock
|
||||||
nextToLock = (nextToLock + 1) % managedZones.size
|
nextToLock = (nextToLock + 1) % managedZones.size
|
||||||
|
|
@ -729,7 +723,7 @@ class CavernRotationService(
|
||||||
advanceTimeBy: FiniteDuration,
|
advanceTimeBy: FiniteDuration,
|
||||||
galaxyService: ActorRef
|
galaxyService: ActorRef
|
||||||
) : Unit = {
|
) : Unit = {
|
||||||
val curr = System.currentTimeMillis()
|
//val curr = System.currentTimeMillis()
|
||||||
val advanceByTimeAsMillis = advanceTimeBy.toMillis
|
val advanceByTimeAsMillis = advanceTimeBy.toMillis
|
||||||
managedZones.foreach { zone =>
|
managedZones.foreach { zone =>
|
||||||
zone.start = zone.start - advanceByTimeAsMillis
|
zone.start = zone.start - advanceByTimeAsMillis
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@ import akka.actor.Cancellable
|
||||||
import net.psforever.objects.guid.{StraightforwardTask, TaskBundle, TaskWorkflow}
|
import net.psforever.objects.guid.{StraightforwardTask, TaskBundle, TaskWorkflow}
|
||||||
import net.psforever.objects.zones.Zone
|
import net.psforever.objects.zones.Zone
|
||||||
import net.psforever.objects.{Default, PlanetSideGameObject}
|
import net.psforever.objects.{Default, PlanetSideGameObject}
|
||||||
|
import net.psforever.services.base.support.{SimilarityComparator, SupportActor, SupportActorCaseConversions}
|
||||||
import net.psforever.types.Vector3
|
import net.psforever.types.Vector3
|
||||||
import net.psforever.services.support.{SimilarityComparator, SupportActor, SupportActorCaseConversions}
|
|
||||||
|
|
||||||
import scala.concurrent.Future
|
import scala.concurrent.Future
|
||||||
import scala.concurrent.duration._
|
import scala.concurrent.duration._
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
// Copyright (c) 2017 PSForever
|
// Copyright (c) 2017 PSForever
|
||||||
package net.psforever.services
|
package net.psforever.services
|
||||||
|
|
||||||
import akka.event.{ActorEventBus, SubchannelClassification}
|
|
||||||
import akka.util.Subclassification
|
|
||||||
import net.psforever.types.PlanetSideGUID
|
import net.psforever.types.PlanetSideGUID
|
||||||
|
|
||||||
object Service {
|
object Service {
|
||||||
|
|
@ -14,24 +12,3 @@ object Service {
|
||||||
final case class Leave(channel: Option[String] = None)
|
final case class Leave(channel: Option[String] = None)
|
||||||
final case class LeaveAll()
|
final case class LeaveAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
trait GenericEventBusMsg {
|
|
||||||
def channel: String
|
|
||||||
}
|
|
||||||
|
|
||||||
class GenericEventBus[A <: GenericEventBusMsg] extends ActorEventBus with SubchannelClassification {
|
|
||||||
type Event = A
|
|
||||||
type Classifier = String
|
|
||||||
|
|
||||||
protected def classify(event: Event): Classifier = event.channel
|
|
||||||
|
|
||||||
protected def subclassification =
|
|
||||||
new Subclassification[Classifier] {
|
|
||||||
def isEqual(x: Classifier, y: Classifier) = x == y
|
|
||||||
def isSubclass(x: Classifier, y: Classifier) = x.startsWith(y)
|
|
||||||
}
|
|
||||||
|
|
||||||
protected def publish(event: Event, subscriber: Subscriber): Unit = {
|
|
||||||
subscriber ! event
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,8 @@ import net.psforever.packet.game.ObjectCreateMessage
|
||||||
import net.psforever.packet.game.objectcreate.{DroppedItemData, ObjectCreateMessageParent, PlacementData}
|
import net.psforever.packet.game.objectcreate.{DroppedItemData, ObjectCreateMessageParent, PlacementData}
|
||||||
import net.psforever.types.PlanetSideGUID
|
import net.psforever.types.PlanetSideGUID
|
||||||
import net.psforever.services.avatar.support.{CorpseRemovalActor, DroppedItemRemover}
|
import net.psforever.services.avatar.support.{CorpseRemovalActor, DroppedItemRemover}
|
||||||
import net.psforever.services.{GenericEventBus, RemoverActor, Service}
|
import net.psforever.services.base.GenericEventBus
|
||||||
|
import net.psforever.services.{RemoverActor, Service}
|
||||||
|
|
||||||
class AvatarService(zone: Zone) extends Actor {
|
class AvatarService(zone: Zone) extends Actor {
|
||||||
private val undertaker: ActorRef = context.actorOf(Props[CorpseRemovalActor](), s"${zone.id}-corpse-removal-agent")
|
private val undertaker: ActorRef = context.actorOf(Props[CorpseRemovalActor](), s"${zone.id}-corpse-removal-agent")
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import net.psforever.objects.zones.Zone
|
||||||
import net.psforever.packet.PlanetSideGamePacket
|
import net.psforever.packet.PlanetSideGamePacket
|
||||||
import net.psforever.packet.game.ImplantAction
|
import net.psforever.packet.game.ImplantAction
|
||||||
import net.psforever.packet.game.objectcreate.{ConstructorData, ObjectCreateMessageParent}
|
import net.psforever.packet.game.objectcreate.{ConstructorData, ObjectCreateMessageParent}
|
||||||
|
import net.psforever.services.base.{EventMessage, EventResponse}
|
||||||
import net.psforever.types.{ExoSuitType, ExperienceType, PlanetSideEmpire, PlanetSideGUID, TransactionType, Vector3}
|
import net.psforever.types.{ExoSuitType, ExperienceType, PlanetSideEmpire, PlanetSideGUID, TransactionType, Vector3}
|
||||||
|
|
||||||
import scala.concurrent.duration.FiniteDuration
|
import scala.concurrent.duration.FiniteDuration
|
||||||
|
|
@ -25,7 +26,9 @@ object AvatarServiceMessage {
|
||||||
}
|
}
|
||||||
|
|
||||||
object AvatarAction {
|
object AvatarAction {
|
||||||
sealed trait Action
|
sealed trait Action extends EventMessage {
|
||||||
|
def response(): EventResponse = null
|
||||||
|
}
|
||||||
|
|
||||||
final case class ArmorChanged(player_guid: PlanetSideGUID, suit: ExoSuitType.Value, subtype: Int) extends Action
|
final case class ArmorChanged(player_guid: PlanetSideGUID, suit: ExoSuitType.Value, subtype: Int) extends Action
|
||||||
final case class AvatarImplant(player_guid: PlanetSideGUID, action: ImplantAction.Value, implantSlot: Int, status: Int) extends Action
|
final case class AvatarImplant(player_guid: PlanetSideGUID, action: ImplantAction.Value, implantSlot: Int, status: Int) extends Action
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import net.psforever.packet.PlanetSideGamePacket
|
||||||
import net.psforever.packet.game.objectcreate.ConstructorData
|
import net.psforever.packet.game.objectcreate.ConstructorData
|
||||||
import net.psforever.packet.game.{ImplantAction, ObjectCreateMessage}
|
import net.psforever.packet.game.{ImplantAction, ObjectCreateMessage}
|
||||||
import net.psforever.types.{ExoSuitType, ExperienceType, PlanetSideEmpire, PlanetSideGUID, TransactionType, Vector3}
|
import net.psforever.types.{ExoSuitType, ExperienceType, PlanetSideEmpire, PlanetSideGUID, TransactionType, Vector3}
|
||||||
import net.psforever.services.GenericEventBusMsg
|
import net.psforever.services.base.{EventResponse, GenericEventBusMsg}
|
||||||
|
|
||||||
final case class AvatarServiceResponse(
|
final case class AvatarServiceResponse(
|
||||||
channel: String,
|
channel: String,
|
||||||
|
|
@ -22,7 +22,7 @@ final case class AvatarServiceResponse(
|
||||||
) extends GenericEventBusMsg
|
) extends GenericEventBusMsg
|
||||||
|
|
||||||
object AvatarResponse {
|
object AvatarResponse {
|
||||||
sealed trait Response
|
sealed trait Response extends EventResponse
|
||||||
|
|
||||||
final case class ArmorChanged(suit: ExoSuitType.Value, subtype: Int) extends Response
|
final case class ArmorChanged(suit: ExoSuitType.Value, subtype: Int) extends Response
|
||||||
final case class AvatarImplant(action: ImplantAction.Value, implantSlot: Int, status: Int) extends Response
|
final case class AvatarImplant(action: ImplantAction.Value, implantSlot: Int, status: Int) extends Response
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
// Copyright (c) 2026 PSForever
|
||||||
|
package net.psforever.services.base
|
||||||
|
|
||||||
|
trait EventExchange
|
||||||
|
|
||||||
|
trait EventResponse extends EventExchange
|
||||||
|
|
||||||
|
trait EventMessage extends EventExchange {
|
||||||
|
def response(): EventResponse
|
||||||
|
}
|
||||||
|
|
||||||
|
trait SelfResponseMessage
|
||||||
|
extends EventMessage
|
||||||
|
with EventResponse {
|
||||||
|
def response(): EventResponse = this
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
// Copyright (c) 2017 PSForever
|
||||||
|
package net.psforever.services.base
|
||||||
|
|
||||||
|
import akka.event.{ActorEventBus, SubchannelClassification}
|
||||||
|
import akka.util.Subclassification
|
||||||
|
|
||||||
|
trait GenericEventBusMsg {
|
||||||
|
def channel: String
|
||||||
|
}
|
||||||
|
|
||||||
|
class GenericEventBus[A <: GenericEventBusMsg] extends ActorEventBus with SubchannelClassification {
|
||||||
|
type Event = A
|
||||||
|
type Classifier = String
|
||||||
|
|
||||||
|
protected def classify(event: Event): Classifier = event.channel
|
||||||
|
|
||||||
|
protected def subclassification: Subclassification[String] =
|
||||||
|
new Subclassification[Classifier] {
|
||||||
|
def isEqual(x: Classifier, y: Classifier): Boolean = x == y
|
||||||
|
|
||||||
|
def isSubclass(x: Classifier, y: Classifier): Boolean = x.startsWith(y)
|
||||||
|
}
|
||||||
|
|
||||||
|
protected def publish(event: Event, subscriber: Subscriber): Unit = {
|
||||||
|
subscriber ! event
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
// Copyright (c) 2026 PSForever
|
||||||
|
package net.psforever.services.base
|
||||||
|
|
||||||
|
import akka.actor.Actor
|
||||||
|
import net.psforever.services.Service
|
||||||
|
import net.psforever.types.PlanetSideGUID
|
||||||
|
import org.log4s.Logger
|
||||||
|
|
||||||
|
trait GenericResponseEnvelope
|
||||||
|
extends GenericEventBusMsg {
|
||||||
|
def exclude: PlanetSideGUID
|
||||||
|
def reply: EventResponse
|
||||||
|
}
|
||||||
|
|
||||||
|
trait GenericMessageEnvelope {
|
||||||
|
def channel: String
|
||||||
|
def exclude: PlanetSideGUID
|
||||||
|
def msg: EventMessage
|
||||||
|
def response(outChannel: String): GenericResponseEnvelope
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class GenericEventService[OUT <: GenericResponseEnvelope](busName: String)
|
||||||
|
extends Actor {
|
||||||
|
protected lazy val log: Logger = org.log4s.getLogger(getClass.getSimpleName)
|
||||||
|
|
||||||
|
protected val eventBus = new GenericEventBus[OUT]
|
||||||
|
|
||||||
|
def commonJoinBehavior: Receive = {
|
||||||
|
case Service.Join(channel) =>
|
||||||
|
val path = formatChannelOnBusName(channel, busName)
|
||||||
|
val who = sender()
|
||||||
|
eventBus.subscribe(who, path)
|
||||||
|
}
|
||||||
|
|
||||||
|
def commonLeaveBehavior: Receive = {
|
||||||
|
case Service.Leave(None) =>
|
||||||
|
eventBus.unsubscribe(sender())
|
||||||
|
|
||||||
|
case Service.Leave(Some(channel)) =>
|
||||||
|
val path = formatChannelOnBusName(channel, busName)
|
||||||
|
eventBus.unsubscribe(sender(), path)
|
||||||
|
|
||||||
|
case Service.LeaveAll() =>
|
||||||
|
eventBus.unsubscribe(sender())
|
||||||
|
}
|
||||||
|
|
||||||
|
def receive: Receive =
|
||||||
|
commonJoinBehavior.orElse(commonLeaveBehavior)
|
||||||
|
.orElse {
|
||||||
|
case msg: GenericMessageEnvelope =>
|
||||||
|
compose(msg)
|
||||||
|
|
||||||
|
case msg => ()
|
||||||
|
log.warn(s"Unhandled message $msg from ${sender()}")
|
||||||
|
}
|
||||||
|
|
||||||
|
protected def compose(msg: GenericMessageEnvelope): Unit = {
|
||||||
|
eventBus.publish(msg.response(formatChannelOnBusName(msg.channel, busName)).asInstanceOf[OUT])
|
||||||
|
}
|
||||||
|
|
||||||
|
def formatChannelOnBusName: (String, String) => String = GenericEventService.BusOnChannelFormat
|
||||||
|
}
|
||||||
|
|
||||||
|
object GenericEventService {
|
||||||
|
final def BusOnChannelFormat(channel: String, busName: String): String = {
|
||||||
|
if (channel.trim.isEmpty) {
|
||||||
|
s"/$busName"
|
||||||
|
} else {
|
||||||
|
s"/$channel/$busName"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
// Copyright (c) 2026 PSForever
|
||||||
|
package net.psforever.services.base
|
||||||
|
|
||||||
|
import akka.actor.{ActorContext, ActorRef}
|
||||||
|
|
||||||
|
import scala.annotation.unused
|
||||||
|
|
||||||
|
trait EventServiceSupport {
|
||||||
|
def label: String
|
||||||
|
def constructor(@unused context: ActorContext): ActorRef
|
||||||
|
}
|
||||||
|
|
||||||
|
trait GenericMessageToSupportEnvelope
|
||||||
|
extends GenericMessageEnvelope {
|
||||||
|
def toSupport: String
|
||||||
|
def response(outChannel: String): GenericResponseEnvelope = null
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class GenericEventServiceWithSupport[OUT <: GenericResponseEnvelope](
|
||||||
|
busName: String,
|
||||||
|
eventSupportServices: List[EventServiceSupport]
|
||||||
|
)
|
||||||
|
extends GenericEventService[OUT](busName) {
|
||||||
|
|
||||||
|
private val supportServices: Map[String, ActorRef] =
|
||||||
|
eventSupportServices
|
||||||
|
.map { supportService => (supportService.label, supportService.constructor(context)) }
|
||||||
|
.toMap[String, ActorRef]
|
||||||
|
|
||||||
|
private def supportReceive: Receive = {
|
||||||
|
case msg: GenericMessageToSupportEnvelope =>
|
||||||
|
forwardToSupport(msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
override def receive: Receive = supportReceive.orElse(super.receive)
|
||||||
|
|
||||||
|
private def forwardToSupport(msg: GenericMessageToSupportEnvelope): Unit = {
|
||||||
|
supportServices
|
||||||
|
.get(msg.toSupport)
|
||||||
|
.map { support =>
|
||||||
|
support.forward(msg)
|
||||||
|
msg
|
||||||
|
}
|
||||||
|
.getOrElse {
|
||||||
|
log.error(s"support service ${msg.toSupport} was not found - check message routing or service params")
|
||||||
|
}
|
||||||
|
if (msg.response(outChannel = "") != null) {
|
||||||
|
compose(msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// Copyright (c) 2017 PSForever
|
// Copyright (c) 2017 PSForever
|
||||||
package net.psforever.services.support
|
package net.psforever.services.base.support
|
||||||
|
|
||||||
abstract class SimilarityComparator[A <: SupportActor.Entry] {
|
abstract class SimilarityComparator[A <: SupportActor.Entry] {
|
||||||
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// Copyright (c) 2017 PSForever
|
// Copyright (c) 2017 PSForever
|
||||||
package net.psforever.services.support
|
package net.psforever.services.base.support
|
||||||
|
|
||||||
import akka.actor.Actor
|
import akka.actor.Actor
|
||||||
import net.psforever.objects.PlanetSideGameObject
|
import net.psforever.objects.PlanetSideGameObject
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// Copyright (c) 2017 PSForever
|
// Copyright (c) 2017 PSForever
|
||||||
package net.psforever.services.support
|
package net.psforever.services.base.support
|
||||||
|
|
||||||
import net.psforever.objects.PlanetSideGameObject
|
import net.psforever.objects.PlanetSideGameObject
|
||||||
import net.psforever.objects.zones.Zone
|
import net.psforever.objects.zones.Zone
|
||||||
|
|
@ -6,6 +6,7 @@ import akka.actor.typed.{ActorRef, Behavior}
|
||||||
import akka.actor.typed.scaladsl.{AbstractBehavior, ActorContext, Behaviors}
|
import akka.actor.typed.scaladsl.{AbstractBehavior, ActorContext, Behaviors}
|
||||||
import net.psforever.objects.{Session, SessionSource}
|
import net.psforever.objects.{Session, SessionSource}
|
||||||
import net.psforever.packet.game.ChatMsg
|
import net.psforever.packet.game.ChatMsg
|
||||||
|
import net.psforever.services.base.{EventMessage, EventResponse}
|
||||||
import net.psforever.types.{ChatMessageType, PlanetSideEmpire}
|
import net.psforever.types.{ChatMessageType, PlanetSideEmpire}
|
||||||
|
|
||||||
object ChatService {
|
object ChatService {
|
||||||
|
|
@ -17,14 +18,16 @@ object ChatService {
|
||||||
new ChatService(context)
|
new ChatService(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed trait Command
|
sealed trait Command extends EventMessage {
|
||||||
|
def response(): EventResponse = null
|
||||||
|
}
|
||||||
|
|
||||||
final case class JoinChannel(actor: ActorRef[MessageResponse], sessionSource: SessionSource, 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 LeaveChannel(actor: ActorRef[MessageResponse], channel: ChatChannel) extends Command
|
||||||
final case class LeaveAllChannels(actor: ActorRef[MessageResponse]) 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 Message(session: Session, message: ChatMsg, channel: ChatChannel) extends Command
|
||||||
final case class MessageResponse(session: Session, message: ChatMsg, channel: ChatChannel)
|
final case class MessageResponse(session: Session, message: ChatMsg, channel: ChatChannel) extends EventResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
class ChatService(context: ActorContext[ChatService.Command]) extends AbstractBehavior[ChatService.Command](context) {
|
class ChatService(context: ActorContext[ChatService.Command]) extends AbstractBehavior[ChatService.Command](context) {
|
||||||
|
|
|
||||||
|
|
@ -2,26 +2,25 @@
|
||||||
package net.psforever.services.galaxy
|
package net.psforever.services.galaxy
|
||||||
|
|
||||||
import akka.actor.Actor
|
import akka.actor.Actor
|
||||||
import net.psforever.objects.zones.Zone
|
import net.psforever.services.base.GenericEventBus
|
||||||
import net.psforever.packet.game.BuildingInfoUpdateMessage
|
import net.psforever.services.Service
|
||||||
import net.psforever.services.{GenericEventBus, Service}
|
|
||||||
|
|
||||||
class GalaxyService extends Actor {
|
class GalaxyService extends Actor {
|
||||||
private[this] val log = org.log4s.getLogger
|
private[this] val log = org.log4s.getLogger
|
||||||
|
|
||||||
val GalaxyEvents = new GenericEventBus[GalaxyServiceResponse]
|
val GalaxyEvents = new GenericEventBus[GalaxyServiceResponse]
|
||||||
|
|
||||||
|
private def correctChannelName(channel: String): String = {
|
||||||
|
if (channel.isEmpty) {
|
||||||
|
s"/Galaxy"
|
||||||
|
} else {
|
||||||
|
s"/$channel/Galaxy"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
def receive: Receive = {
|
def receive: Receive = {
|
||||||
case Service.Join(faction) if "TRNCVS".containsSlice(faction) =>
|
|
||||||
val path = s"/$faction/Galaxy"
|
|
||||||
GalaxyEvents.subscribe(sender(), path)
|
|
||||||
|
|
||||||
case Service.Join("galaxy") =>
|
|
||||||
val path = s"/Galaxy"
|
|
||||||
GalaxyEvents.subscribe(sender(), path)
|
|
||||||
|
|
||||||
case Service.Join(channel) =>
|
case Service.Join(channel) =>
|
||||||
val path = s"/$channel/Galaxy"
|
val path = correctChannelName(channel)
|
||||||
GalaxyEvents.subscribe(sender(), path)
|
GalaxyEvents.subscribe(sender(), path)
|
||||||
|
|
||||||
case Service.Leave(None) =>
|
case Service.Leave(None) =>
|
||||||
|
|
@ -34,72 +33,8 @@ class GalaxyService extends Actor {
|
||||||
case Service.LeaveAll() =>
|
case Service.LeaveAll() =>
|
||||||
GalaxyEvents.unsubscribe(sender())
|
GalaxyEvents.unsubscribe(sender())
|
||||||
|
|
||||||
case GalaxyServiceMessage(forChannel, action) =>
|
case msg @ GalaxyServiceMessage(forChannel, _) =>
|
||||||
action match {
|
GalaxyEvents.publish(msg.response(correctChannelName(forChannel)))
|
||||||
case GalaxyAction.MapUpdate(msg: BuildingInfoUpdateMessage) =>
|
|
||||||
GalaxyEvents.publish(
|
|
||||||
GalaxyServiceResponse(s"/Galaxy", GalaxyResponse.MapUpdate(msg))
|
|
||||||
)
|
|
||||||
|
|
||||||
case GalaxyAction.UpdateBroadcastPrivileges(zoneId, gateMapId, fromFactions, toFactions) =>
|
|
||||||
GalaxyEvents.publish(
|
|
||||||
GalaxyServiceResponse(
|
|
||||||
s"/$forChannel/Galaxy",
|
|
||||||
GalaxyResponse.UpdateBroadcastPrivileges(zoneId, gateMapId, fromFactions, toFactions)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
case GalaxyAction.FlagMapUpdate(msg) =>
|
|
||||||
GalaxyEvents.publish(
|
|
||||||
GalaxyServiceResponse(s"/Galaxy", GalaxyResponse.FlagMapUpdate(msg))
|
|
||||||
)
|
|
||||||
|
|
||||||
case GalaxyAction.TransferPassenger(_, temp_channel, vehicle, vehicle_to_delete, manifest) =>
|
|
||||||
GalaxyEvents.publish(
|
|
||||||
GalaxyServiceResponse(
|
|
||||||
s"/$forChannel/Galaxy",
|
|
||||||
GalaxyResponse.TransferPassenger(temp_channel, vehicle, vehicle_to_delete, manifest)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
case GalaxyAction.LockedZoneUpdate(zone, time) =>
|
|
||||||
GalaxyEvents.publish(
|
|
||||||
GalaxyServiceResponse(
|
|
||||||
s"/Galaxy",
|
|
||||||
GalaxyResponse.LockedZoneUpdate(zone, time)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
case GalaxyAction.UnlockedZoneUpdate(zone) =>
|
|
||||||
GalaxyEvents.publish(
|
|
||||||
GalaxyServiceResponse(
|
|
||||||
s"/Galaxy",
|
|
||||||
GalaxyResponse.UnlockedZoneUpdate(zone)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
case GalaxyAction.LogStatusChange(name) =>
|
|
||||||
GalaxyEvents.publish(
|
|
||||||
GalaxyServiceResponse(
|
|
||||||
s"/Galaxy",
|
|
||||||
GalaxyResponse.LogStatusChange(name)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
case GalaxyAction.SendResponse(msg) =>
|
|
||||||
GalaxyEvents.publish(
|
|
||||||
GalaxyServiceResponse(
|
|
||||||
s"/Galaxy",
|
|
||||||
GalaxyResponse.SendResponse(msg)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
case _ => ;
|
|
||||||
}
|
|
||||||
|
|
||||||
case Zone.HotSpot.Update(faction, zone_num, priority, info) =>
|
|
||||||
GalaxyEvents.publish(
|
|
||||||
GalaxyServiceResponse(s"/$faction/Galaxy", GalaxyResponse.HotSpotUpdate(zone_num, priority, info))
|
|
||||||
)
|
|
||||||
|
|
||||||
case msg =>
|
case msg =>
|
||||||
log.warn(s"Unhandled message $msg from ${sender()}")
|
log.warn(s"Unhandled message $msg from ${sender()}")
|
||||||
|
|
|
||||||
|
|
@ -3,22 +3,43 @@ package net.psforever.services.galaxy
|
||||||
|
|
||||||
import net.psforever.objects.Vehicle
|
import net.psforever.objects.Vehicle
|
||||||
import net.psforever.objects.vehicles.VehicleManifest
|
import net.psforever.objects.vehicles.VehicleManifest
|
||||||
import net.psforever.objects.zones.Zone
|
import net.psforever.objects.zones.{HotSpotInfo, Zone}
|
||||||
import net.psforever.packet.PlanetSideGamePacket
|
import net.psforever.packet.PlanetSideGamePacket
|
||||||
import net.psforever.packet.game.{BuildingInfoUpdateMessage, CaptureFlagUpdateMessage}
|
import net.psforever.packet.game.{BuildingInfoUpdateMessage, CaptureFlagUpdateMessage}
|
||||||
|
import net.psforever.services.Service
|
||||||
|
import net.psforever.services.base.{EventMessage, EventResponse, GenericMessageEnvelope, SelfResponseMessage}
|
||||||
import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID}
|
import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID}
|
||||||
|
|
||||||
final case class GalaxyServiceMessage(forChannel: String, actionMessage: GalaxyAction.Action)
|
final case class GalaxyServiceMessage(channel: String, msg: EventMessage)
|
||||||
|
extends GenericMessageEnvelope {
|
||||||
|
def exclude: PlanetSideGUID = Service.defaultPlayerGUID
|
||||||
|
|
||||||
|
def response(outChannel: String): GalaxyServiceResponse = {
|
||||||
|
GalaxyServiceResponse(outChannel, msg.response())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
object GalaxyServiceMessage {
|
object GalaxyServiceMessage {
|
||||||
def apply(actionMessage: GalaxyAction.Action): GalaxyServiceMessage = GalaxyServiceMessage("", actionMessage)
|
def apply(actionMessage: GalaxyAction.Action): GalaxyServiceMessage = GalaxyServiceMessage("", actionMessage)
|
||||||
}
|
}
|
||||||
|
|
||||||
object GalaxyAction {
|
object GalaxyAction {
|
||||||
trait Action
|
trait Action extends EventMessage
|
||||||
|
trait Response extends EventResponse
|
||||||
|
|
||||||
|
final case class HotSpotUpdate(zone_id: Int, priority: Int, host_spot_info: List[HotSpotInfo])
|
||||||
|
extends Action
|
||||||
|
with Response
|
||||||
|
with SelfResponseMessage
|
||||||
|
|
||||||
|
final case class MapUpdate(msg: BuildingInfoUpdateMessage)
|
||||||
|
extends Action
|
||||||
|
with Response
|
||||||
|
with SelfResponseMessage
|
||||||
|
|
||||||
final case class MapUpdate(msg: BuildingInfoUpdateMessage) extends Action
|
|
||||||
final case class FlagMapUpdate(msg: CaptureFlagUpdateMessage) extends Action
|
final case class FlagMapUpdate(msg: CaptureFlagUpdateMessage) extends Action
|
||||||
|
with Response
|
||||||
|
with SelfResponseMessage
|
||||||
|
|
||||||
final case class TransferPassenger(
|
final case class TransferPassenger(
|
||||||
player_guid: PlanetSideGUID,
|
player_guid: PlanetSideGUID,
|
||||||
|
|
@ -27,6 +48,8 @@ object GalaxyAction {
|
||||||
vehicle_to_delete: PlanetSideGUID,
|
vehicle_to_delete: PlanetSideGUID,
|
||||||
manifest: VehicleManifest
|
manifest: VehicleManifest
|
||||||
) extends Action
|
) extends Action
|
||||||
|
with Response
|
||||||
|
with SelfResponseMessage
|
||||||
|
|
||||||
final case class UpdateBroadcastPrivileges(
|
final case class UpdateBroadcastPrivileges(
|
||||||
zoneId: Int,
|
zoneId: Int,
|
||||||
|
|
@ -34,12 +57,22 @@ object GalaxyAction {
|
||||||
fromFactions: Set[PlanetSideEmpire.Value],
|
fromFactions: Set[PlanetSideEmpire.Value],
|
||||||
toFactions: Set[PlanetSideEmpire.Value]
|
toFactions: Set[PlanetSideEmpire.Value]
|
||||||
) extends Action
|
) extends Action
|
||||||
|
with Response
|
||||||
|
with SelfResponseMessage
|
||||||
|
|
||||||
final case class LockedZoneUpdate(zone: Zone, timeUntilUnlock: Long) extends Action
|
final case class LockedZoneUpdate(zone: Zone, timeUntilUnlock: Long) extends Action
|
||||||
|
with Response
|
||||||
|
with SelfResponseMessage
|
||||||
|
|
||||||
final case class UnlockedZoneUpdate(zone: Zone) extends Action
|
final case class UnlockedZoneUpdate(zone: Zone) extends Action
|
||||||
|
with Response
|
||||||
|
with SelfResponseMessage
|
||||||
|
|
||||||
final case class LogStatusChange(name: String) extends Action
|
final case class LogStatusChange(name: String) extends Action
|
||||||
|
with Response
|
||||||
|
with SelfResponseMessage
|
||||||
|
|
||||||
final case class SendResponse(msg: PlanetSideGamePacket) extends Action
|
final case class SendResponse(msg: PlanetSideGamePacket) extends Action
|
||||||
|
with Response
|
||||||
|
with SelfResponseMessage
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,13 +7,16 @@ import net.psforever.objects.zones.{HotSpotInfo, Zone}
|
||||||
import net.psforever.packet.PlanetSideGamePacket
|
import net.psforever.packet.PlanetSideGamePacket
|
||||||
import net.psforever.packet.game.{BuildingInfoUpdateMessage, CaptureFlagUpdateMessage}
|
import net.psforever.packet.game.{BuildingInfoUpdateMessage, CaptureFlagUpdateMessage}
|
||||||
import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID}
|
import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID}
|
||||||
import net.psforever.services.GenericEventBusMsg
|
import net.psforever.services.Service
|
||||||
|
import net.psforever.services.base.{EventResponse, GenericResponseEnvelope}
|
||||||
|
|
||||||
final case class GalaxyServiceResponse(channel: String, replyMessage: GalaxyResponse.Response)
|
final case class GalaxyServiceResponse(channel: String, reply: EventResponse)
|
||||||
extends GenericEventBusMsg
|
extends GenericResponseEnvelope {
|
||||||
|
def exclude: PlanetSideGUID = Service.defaultPlayerGUID
|
||||||
|
}
|
||||||
|
|
||||||
object GalaxyResponse {
|
object GalaxyResponse {
|
||||||
trait Response
|
trait Response extends EventResponse
|
||||||
|
|
||||||
final case class HotSpotUpdate(zone_id: Int, priority: Int, host_spot_info: List[HotSpotInfo]) extends Response
|
final case class HotSpotUpdate(zone_id: Int, priority: Int, host_spot_info: List[HotSpotInfo]) extends Response
|
||||||
final case class MapUpdate(msg: BuildingInfoUpdateMessage) extends Response
|
final case class MapUpdate(msg: BuildingInfoUpdateMessage) extends Response
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@ package net.psforever.services.hart
|
||||||
import akka.actor.{Actor, ActorRef, Cancellable}
|
import akka.actor.{Actor, ActorRef, Cancellable}
|
||||||
import net.psforever.objects.Default
|
import net.psforever.objects.Default
|
||||||
import net.psforever.objects.zones.Zone
|
import net.psforever.objects.zones.Zone
|
||||||
|
import net.psforever.services.base.{EventResponse, GenericEventBus, GenericEventBusMsg}
|
||||||
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||||
import net.psforever.services.{GenericEventBus, GenericEventBusMsg}
|
|
||||||
import net.psforever.types.{HartSequence, PlanetSideGUID}
|
import net.psforever.types.{HartSequence, PlanetSideGUID}
|
||||||
|
|
||||||
import scala.concurrent.duration._
|
import scala.concurrent.duration._
|
||||||
|
|
@ -20,7 +20,7 @@ import scala.concurrent.ExecutionContext.Implicits.global
|
||||||
*/
|
*/
|
||||||
class HartTimer(zone: Zone) extends Actor {
|
class HartTimer(zone: Zone) extends Actor {
|
||||||
/** since the system is zone-locked, caching this value is fine */
|
/** since the system is zone-locked, caching this value is fine */
|
||||||
val zoneId = zone.id
|
val zoneId: String = zone.id
|
||||||
/** all of the paired HART facility amenities and the shuttle housed in that facility (in that order) */
|
/** all of the paired HART facility amenities and the shuttle housed in that facility (in that order) */
|
||||||
var padAndShuttlePairs: List[(PlanetSideGUID, PlanetSideGUID)] = List()
|
var padAndShuttlePairs: List[(PlanetSideGUID, PlanetSideGUID)] = List()
|
||||||
|
|
||||||
|
|
@ -45,8 +45,8 @@ class HartTimer(zone: Zone) extends Actor {
|
||||||
/** a message bus to which all associated orbital shuttle pads are subscribed */
|
/** a message bus to which all associated orbital shuttle pads are subscribed */
|
||||||
val padEvents = new GenericEventBus[HartTimer.Command]
|
val padEvents = new GenericEventBus[HartTimer.Command]
|
||||||
/** cache common messages */
|
/** cache common messages */
|
||||||
val shuttleDockedInThisZone = HartTimer.ShuttleDocked(zoneId)
|
val shuttleDockedInThisZone: HartTimer.ShuttleDocked = HartTimer.ShuttleDocked(zoneId)
|
||||||
val shuttleFreeFromDockInThisZone = HartTimer.ShuttleFreeFromDock(zoneId)
|
val shuttleFreeFromDockInThisZone: HartTimer.ShuttleFreeFromDock = HartTimer.ShuttleFreeFromDock(zoneId)
|
||||||
|
|
||||||
/** the behaviors common to both the inert and active operations of the hart */
|
/** the behaviors common to both the inert and active operations of the hart */
|
||||||
val commonBehavior: Receive = {
|
val commonBehavior: Receive = {
|
||||||
|
|
@ -259,7 +259,7 @@ object HartTimer {
|
||||||
* to relay instructions back to the individual facility amenity portions of this HART system.
|
* to relay instructions back to the individual facility amenity portions of this HART system.
|
||||||
* The channel is blank because it does not need special designation.
|
* The channel is blank because it does not need special designation.
|
||||||
*/
|
*/
|
||||||
trait Command extends GenericEventBusMsg { def channel: String = "" }
|
trait Command extends EventResponse with GenericEventBusMsg { def channel: String = "" }
|
||||||
/**
|
/**
|
||||||
* Forbid entry through the boartding gantry doors.
|
* Forbid entry through the boartding gantry doors.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,9 @@ import net.psforever.packet.game.{ObjectCreateMessage, TriggeredEffect, Triggere
|
||||||
import net.psforever.services.local.support.CaptureFlagManager
|
import net.psforever.services.local.support.CaptureFlagManager
|
||||||
import net.psforever.types.PlanetSideGUID
|
import net.psforever.types.PlanetSideGUID
|
||||||
import net.psforever.services.local.support._
|
import net.psforever.services.local.support._
|
||||||
import net.psforever.services.{GenericEventBus, Service}
|
import net.psforever.services.Service
|
||||||
import net.psforever.services.support.SupportActor
|
import net.psforever.services.base.GenericEventBus
|
||||||
|
import net.psforever.services.base.support.SupportActor
|
||||||
|
|
||||||
class LocalService(zone: Zone) extends Actor {
|
class LocalService(zone: Zone) extends Actor {
|
||||||
private val doorCloser = context.actorOf(
|
private val doorCloser = context.actorOf(
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ import net.psforever.packet.PlanetSideGamePacket
|
||||||
import net.psforever.packet.game.GenericObjectActionEnum.GenericObjectActionEnum
|
import net.psforever.packet.game.GenericObjectActionEnum.GenericObjectActionEnum
|
||||||
import net.psforever.packet.game.PlanetsideAttributeEnum.PlanetsideAttributeEnum
|
import net.psforever.packet.game.PlanetsideAttributeEnum.PlanetsideAttributeEnum
|
||||||
import net.psforever.packet.game.{ChatMsg, DeployableInfo, DeploymentAction, GenericAction, HackState7, TriggeredSound}
|
import net.psforever.packet.game.{ChatMsg, DeployableInfo, DeploymentAction, GenericAction, HackState7, TriggeredSound}
|
||||||
|
import net.psforever.services.base.{EventMessage, EventResponse}
|
||||||
import net.psforever.services.hart.HartTimer.OrbitalShuttleEvent
|
import net.psforever.services.hart.HartTimer.OrbitalShuttleEvent
|
||||||
import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID, Vector3}
|
import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID, Vector3}
|
||||||
|
|
||||||
|
|
@ -25,7 +26,9 @@ object LocalServiceMessage {
|
||||||
}
|
}
|
||||||
|
|
||||||
object LocalAction {
|
object LocalAction {
|
||||||
trait Action
|
trait Action extends EventMessage {
|
||||||
|
def response(): EventResponse = null
|
||||||
|
}
|
||||||
|
|
||||||
final case class DeployItem(item: Deployable) extends Action
|
final case class DeployItem(item: Deployable) extends Action
|
||||||
final case class DeployableMapIcon(
|
final case class DeployableMapIcon(
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import net.psforever.packet.game.PlanetsideAttributeEnum.PlanetsideAttributeEnum
|
||||||
import net.psforever.packet.PlanetSideGamePacket
|
import net.psforever.packet.PlanetSideGamePacket
|
||||||
import net.psforever.packet.game._
|
import net.psforever.packet.game._
|
||||||
import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID, Vector3}
|
import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID, Vector3}
|
||||||
import net.psforever.services.GenericEventBusMsg
|
import net.psforever.services.base.{EventResponse, GenericEventBusMsg}
|
||||||
import net.psforever.services.hart.HartTimer.OrbitalShuttleEvent
|
import net.psforever.services.hart.HartTimer.OrbitalShuttleEvent
|
||||||
|
|
||||||
final case class LocalServiceResponse(
|
final case class LocalServiceResponse(
|
||||||
|
|
@ -22,7 +22,7 @@ final case class LocalServiceResponse(
|
||||||
) extends GenericEventBusMsg
|
) extends GenericEventBusMsg
|
||||||
|
|
||||||
object LocalResponse {
|
object LocalResponse {
|
||||||
trait Response
|
trait Response extends EventResponse
|
||||||
|
|
||||||
final case class DeployableMapIcon(action: DeploymentAction.Value, deployInfo: DeployableInfo) extends Response
|
final case class DeployableMapIcon(action: DeploymentAction.Value, deployInfo: DeployableInfo) extends Response
|
||||||
final case class DeployableUIFor(obj: DeployedItem.Value) extends Response
|
final case class DeployableUIFor(obj: DeployedItem.Value) extends Response
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,9 @@ import akka.actor.Actor
|
||||||
import net.psforever.packet.game.{GamePropertyTarget, PropertyOverrideMessage}
|
import net.psforever.packet.game.{GamePropertyTarget, PropertyOverrideMessage}
|
||||||
import net.psforever.packet.game.PropertyOverrideMessage.GamePropertyScope
|
import net.psforever.packet.game.PropertyOverrideMessage.GamePropertyScope
|
||||||
import net.psforever.packet.game.objectcreate.ObjectClass
|
import net.psforever.packet.game.objectcreate.ObjectClass
|
||||||
|
import net.psforever.services.base.{EventMessage, EventResponse}
|
||||||
import net.psforever.zones.Zones
|
import net.psforever.zones.Zones
|
||||||
|
|
||||||
import scala.collection.mutable.ListBuffer
|
import scala.collection.mutable.ListBuffer
|
||||||
|
|
||||||
class PropertyOverrideManager extends Actor {
|
class PropertyOverrideManager extends Actor {
|
||||||
|
|
@ -87,5 +89,7 @@ class PropertyOverrideManager extends Actor {
|
||||||
}
|
}
|
||||||
|
|
||||||
object PropertyOverrideManager {
|
object PropertyOverrideManager {
|
||||||
final case object GetOverridesMessage
|
final case object GetOverridesMessage extends EventMessage {
|
||||||
|
def response(): EventResponse = null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import net.psforever.objects.Player
|
||||||
import net.psforever.objects.avatar.Certification
|
import net.psforever.objects.avatar.Certification
|
||||||
import net.psforever.objects.zones.Zone
|
import net.psforever.objects.zones.Zone
|
||||||
import net.psforever.packet.game.{WaypointEventAction, WaypointInfo, SquadAction => PacketSquadAction}
|
import net.psforever.packet.game.{WaypointEventAction, WaypointInfo, SquadAction => PacketSquadAction}
|
||||||
|
import net.psforever.services.base.{EventMessage, EventResponse}
|
||||||
import net.psforever.types.{PlanetSideGUID, SquadRequestType, SquadWaypoint, Vector3}
|
import net.psforever.types.{PlanetSideGUID, SquadRequestType, SquadWaypoint, Vector3}
|
||||||
|
|
||||||
final case class SquadServiceMessage(tplayer: Player, zone: Zone, actionMessage: Any)
|
final case class SquadServiceMessage(tplayer: Player, zone: Zone, actionMessage: Any)
|
||||||
|
|
@ -15,7 +16,9 @@ object SquadServiceMessage {
|
||||||
}
|
}
|
||||||
|
|
||||||
object SquadAction {
|
object SquadAction {
|
||||||
sealed trait Action
|
sealed trait Action extends EventMessage {
|
||||||
|
def response(): EventResponse = null
|
||||||
|
}
|
||||||
|
|
||||||
final case class InitSquadList() extends Action
|
final case class InitSquadList() extends Action
|
||||||
final case class InitCharId() extends Action
|
final case class InitCharId() extends Action
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,10 @@ import net.psforever.objects.avatar.Certification
|
||||||
import net.psforever.objects.teamwork.Squad
|
import net.psforever.objects.teamwork.Squad
|
||||||
import net.psforever.packet.game.{SquadDetail, SquadInfo, WaypointEventAction, WaypointInfo}
|
import net.psforever.packet.game.{SquadDetail, SquadInfo, WaypointEventAction, WaypointInfo}
|
||||||
import net.psforever.types.{ChatMessageType, PlanetSideGUID, SquadResponseType, SquadWaypoint}
|
import net.psforever.types.{ChatMessageType, PlanetSideGUID, SquadResponseType, SquadWaypoint}
|
||||||
import net.psforever.services.GenericEventBusMsg
|
import net.psforever.services.base.{EventResponse, GenericEventBusMsg}
|
||||||
|
|
||||||
final case class SquadServiceResponse(channel: String, exclude: Iterable[Long], response: SquadResponse.Response)
|
final case class SquadServiceResponse(channel: String, exclude: Iterable[Long], response: SquadResponse.Response)
|
||||||
extends GenericEventBusMsg
|
extends EventResponse with GenericEventBusMsg
|
||||||
|
|
||||||
object SquadServiceResponse {
|
object SquadServiceResponse {
|
||||||
def apply(toChannel: String, response: SquadResponse.Response): SquadServiceResponse =
|
def apply(toChannel: String, response: SquadResponse.Response): SquadServiceResponse =
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,11 @@
|
||||||
package net.psforever.services.teamwork
|
package net.psforever.services.teamwork
|
||||||
|
|
||||||
import akka.actor.ActorRef
|
import akka.actor.ActorRef
|
||||||
import scala.collection.mutable
|
|
||||||
|
|
||||||
|
import scala.collection.mutable
|
||||||
import net.psforever.objects.teamwork.{Squad, SquadFeatures}
|
import net.psforever.objects.teamwork.{Squad, SquadFeatures}
|
||||||
import net.psforever.packet.game.SquadDetail
|
import net.psforever.packet.game.SquadDetail
|
||||||
import net.psforever.services.GenericEventBus
|
import net.psforever.services.base.GenericEventBus
|
||||||
import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID}
|
import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID}
|
||||||
|
|
||||||
class SquadSubscriptionEntity {
|
class SquadSubscriptionEntity {
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,10 @@ import net.psforever.objects.serverobject.pad.VehicleSpawnPad
|
||||||
import net.psforever.objects.zones.Zone
|
import net.psforever.objects.zones.Zone
|
||||||
import net.psforever.packet.game.ObjectCreateMessage
|
import net.psforever.packet.game.ObjectCreateMessage
|
||||||
import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent
|
import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent
|
||||||
|
import net.psforever.services.base.GenericEventBus
|
||||||
import net.psforever.services.vehicle.support.TurretUpgrader
|
import net.psforever.services.vehicle.support.TurretUpgrader
|
||||||
import net.psforever.types.DriveState
|
import net.psforever.types.DriveState
|
||||||
import net.psforever.services.{GenericEventBus, Service}
|
import net.psforever.services.Service
|
||||||
|
|
||||||
class VehicleService(zone: Zone) extends Actor {
|
class VehicleService(zone: Zone) extends Actor {
|
||||||
private val turretUpgrade: ActorRef = context.actorOf(Props[TurretUpgrader](), s"${zone.id}-turret-upgrade-agent")
|
private val turretUpgrade: ActorRef = context.actorOf(Props[TurretUpgrader](), s"${zone.id}-turret-upgrade-agent")
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import net.psforever.objects.inventory.InventoryItem
|
||||||
import net.psforever.objects.zones.Zone
|
import net.psforever.objects.zones.Zone
|
||||||
import net.psforever.packet.PlanetSideGamePacket
|
import net.psforever.packet.PlanetSideGamePacket
|
||||||
import net.psforever.packet.game.objectcreate.ConstructorData
|
import net.psforever.packet.game.objectcreate.ConstructorData
|
||||||
|
import net.psforever.services.base.{EventMessage, EventResponse}
|
||||||
import net.psforever.types.{BailType, DriveState, PlanetSideGUID, Vector3}
|
import net.psforever.types.{BailType, DriveState, PlanetSideGUID, Vector3}
|
||||||
|
|
||||||
final case class VehicleServiceMessage(forChannel: String, actionMessage: VehicleAction.Action)
|
final case class VehicleServiceMessage(forChannel: String, actionMessage: VehicleAction.Action)
|
||||||
|
|
@ -21,7 +22,9 @@ object VehicleServiceMessage {
|
||||||
}
|
}
|
||||||
|
|
||||||
object VehicleAction {
|
object VehicleAction {
|
||||||
trait Action
|
trait Action extends EventMessage {
|
||||||
|
def response(): EventResponse = null
|
||||||
|
}
|
||||||
|
|
||||||
final case class ChangeAmmo(
|
final case class ChangeAmmo(
|
||||||
player_guid: PlanetSideGUID,
|
player_guid: PlanetSideGUID,
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import net.psforever.packet.PlanetSideGamePacket
|
||||||
import net.psforever.packet.game.objectcreate.ConstructorData
|
import net.psforever.packet.game.objectcreate.ConstructorData
|
||||||
import net.psforever.packet.game.ObjectCreateMessage
|
import net.psforever.packet.game.ObjectCreateMessage
|
||||||
import net.psforever.types.{BailType, DriveState, PlanetSideGUID, Vector3}
|
import net.psforever.types.{BailType, DriveState, PlanetSideGUID, Vector3}
|
||||||
import net.psforever.services.GenericEventBusMsg
|
import net.psforever.services.base.{EventResponse, GenericEventBusMsg}
|
||||||
|
|
||||||
final case class VehicleServiceResponse(
|
final case class VehicleServiceResponse(
|
||||||
channel: String,
|
channel: String,
|
||||||
|
|
@ -20,7 +20,7 @@ final case class VehicleServiceResponse(
|
||||||
) extends GenericEventBusMsg
|
) extends GenericEventBusMsg
|
||||||
|
|
||||||
object VehicleResponse {
|
object VehicleResponse {
|
||||||
trait Response
|
trait Response extends EventResponse
|
||||||
|
|
||||||
final case class ChangeAmmo(
|
final case class ChangeAmmo(
|
||||||
weapon_guid: PlanetSideGUID,
|
weapon_guid: PlanetSideGUID,
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import net.psforever.objects.serverobject.turret.{FacilityTurret, TurretUpgrade,
|
||||||
import net.psforever.objects.vehicles.MountedWeapons
|
import net.psforever.objects.vehicles.MountedWeapons
|
||||||
import net.psforever.objects.zones.Zone
|
import net.psforever.objects.zones.Zone
|
||||||
import net.psforever.types.PlanetSideGUID
|
import net.psforever.types.PlanetSideGUID
|
||||||
import net.psforever.services.support.{SimilarityComparator, SupportActor, SupportActorCaseConversions}
|
import net.psforever.services.base.support.{SimilarityComparator, SupportActor, SupportActorCaseConversions}
|
||||||
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||||
|
|
||||||
import scala.concurrent.Future
|
import scala.concurrent.Future
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue