From a2bd6999aba6daf8641d2cdd4cb3f50d595a8fc5 Mon Sep 17 00:00:00 2001 From: "Jason_DiDonato@yahoo.com" Date: Sat, 17 Apr 2021 08:35:13 -0400 Subject: [PATCH 1/4] moved the point where the cooldown timer for the vehicle order would apply to the avatar to later, when the player is first seated, rather than earlier, when then order is first returned --- .../psforever/actors/session/SessionActor.scala | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/main/scala/net/psforever/actors/session/SessionActor.scala b/src/main/scala/net/psforever/actors/session/SessionActor.scala index 0c2cde475..9a64ac1da 100644 --- a/src/main/scala/net/psforever/actors/session/SessionActor.scala +++ b/src/main/scala/net/psforever/actors/session/SessionActor.scala @@ -2681,14 +2681,6 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con case Some(_) => sendResponse(ItemTransactionResultMessage(msg.terminal_guid, TransactionType.Buy, success = false)) case None => - avatarActor ! AvatarActor.UpdatePurchaseTime(vehicle.Definition) - Avatar.purchaseCooldowns.get(vehicle.Definition) match { - case Some(cooldown) => - sendResponse( - AvatarVehicleTimerMessage(tplayer.GUID, vehicle.Definition.Name, cooldown.toSeconds, unk1 = true) - ) - case None => ; - } val pad = continent.GUID(padGuid).get.asInstanceOf[VehicleSpawnPad] vehicle.Faction = tplayer.Faction vehicle.Position = pad.Position @@ -2950,6 +2942,12 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con } sendResponse(PlanetsideAttributeMessage(vehicle_guid, 22, 1L)) //mount points off sendResponse(PlanetsideAttributeMessage(player.GUID, 21, vehicle_guid)) //ownership + avatarActor ! AvatarActor.UpdatePurchaseTime(vehicle.Definition) + Avatar.purchaseCooldowns.get(vehicle.Definition) match { + case Some(cooldown) => + sendResponse(AvatarVehicleTimerMessage(player.GUID, vehicle.Definition.Name, cooldown.toSeconds, unk1 = true)) + case None => ; + } vehicle.MountPoints.find { case (_, mp) => mp.seatIndex == 0 } match { case Some((mountPoint, _)) => vehicle.Actor ! Mountable.TryMount(player, mountPoint) case _ => ; From 0b7930eeff3397706ba4351874883d0b0e1e66b6 Mon Sep 17 00:00:00 2001 From: "Jason_DiDonato@yahoo.com" Date: Sun, 18 Apr 2021 09:07:03 -0400 Subject: [PATCH 2/4] more concise management of purchase timers --- .../actors/session/AvatarActor.scala | 88 +++++++++++-------- .../actors/session/SessionActor.scala | 9 +- 2 files changed, 52 insertions(+), 45 deletions(-) diff --git a/src/main/scala/net/psforever/actors/session/AvatarActor.scala b/src/main/scala/net/psforever/actors/session/AvatarActor.scala index 38fecd82c..bedf93b19 100644 --- a/src/main/scala/net/psforever/actors/session/AvatarActor.scala +++ b/src/main/scala/net/psforever/actors/session/AvatarActor.scala @@ -725,8 +725,7 @@ class AvatarActor( } else { // TODO save to db avatar = avatar.copy(purchaseTimes = avatar.purchaseTimes.updated(definition.Name, time)) - // we could be more selective and only send what changed, but it doesn't hurt to refresh everything - context.self ! RefreshPurchaseTimes() + refreshPurchaseTimes(Set(definition.Name)) } Behaviors.same @@ -738,38 +737,7 @@ class AvatarActor( Behaviors.same case RefreshPurchaseTimes() => - avatar.purchaseTimes.foreach { - case (name, purchaseTime) => - val secondsSincePurchase = Seconds.secondsBetween(purchaseTime, LocalDateTime.now()).getSeconds - - Avatar.purchaseCooldowns.find(_._1.Name == name) match { - case Some((obj, cooldown)) if cooldown.toSeconds - secondsSincePurchase > 0 => - val faction: String = avatar.faction.toString.toLowerCase - val name = obj match { - case GlobalDefinitions.trhev_dualcycler | GlobalDefinitions.nchev_scattercannon | - GlobalDefinitions.vshev_quasar => - s"${faction}hev_antipersonnel" - case GlobalDefinitions.trhev_pounder | GlobalDefinitions.nchev_falcon | - GlobalDefinitions.vshev_comet => - s"${faction}hev_antivehicular" - case GlobalDefinitions.trhev_burster | GlobalDefinitions.nchev_sparrow | - GlobalDefinitions.vshev_starfire => - s"${faction}hev_antiaircraft" - case _ => obj.Name - } - - sessionActor ! SessionActor.SendResponse( - AvatarVehicleTimerMessage( - session.get.player.GUID, - name, - cooldown.toSeconds - secondsSincePurchase, - unk1 = true - ) - ) - - case _ => ; - } - } + refreshPurchaseTimes(avatar.purchaseTimes.keys.toSet) Behaviors.same case SetVehicle(vehicle) => @@ -1281,8 +1249,8 @@ class AvatarActor( loadout.items.split("/").foreach { case value => val (objectType, objectIndex, objectId, toolAmmo) = value.split(",") match { - case Array(a, b, c) => (a, b.toInt, c.toInt, None) - case Array(a, b, c, d) => (a, b.toInt, c.toInt, Some(d)) + case Array(a, b: String, c: String) => (a, b.toInt, c.toInt, None) + case Array(a, b: String, c: String, d) => (a, b.toInt, c.toInt, Some(d)) } objectType match { @@ -1305,9 +1273,9 @@ class AvatarActor( } toolAmmo foreach { toolAmmo => - toolAmmo.split("_").drop(1).foreach { value => + toolAmmo.toString.split("_").drop(1).foreach { value => val (ammoSlots, ammoTypeIndex, ammoBoxDefinition) = value.split("-") match { - case Array(a, b, c) => (a.toInt, b.toInt, c.toInt) + case Array(a: String, b: String, c: String) => (a.toInt, b.toInt, c.toInt) } doll.Slot(objectIndex).Equipment.get.asInstanceOf[Tool].AmmoSlots(ammoSlots).AmmoTypeIndex = ammoTypeIndex @@ -1355,4 +1323,48 @@ class AvatarActor( }) } + def refreshPurchaseTimes(keys: Set[String]): Unit = { + var keysToDrop: Seq[String] = Nil + keys.foreach { key => + avatar.purchaseTimes.find { case (name, _) => name.equals(key) } match { + case Some((name, purchaseTime)) => + val secondsSincePurchase = Seconds.secondsBetween(purchaseTime, LocalDateTime.now()).getSeconds + Avatar.purchaseCooldowns.find(_._1.Name == name) match { + case Some((obj, cooldown)) if cooldown.toSeconds - secondsSincePurchase > 0 => + val faction : String = avatar.faction.toString.toLowerCase + val name = obj match { + case GlobalDefinitions.trhev_dualcycler | + GlobalDefinitions.nchev_scattercannon | + GlobalDefinitions.vshev_quasar => + s"${faction}hev_antipersonnel" + case GlobalDefinitions.trhev_pounder | + GlobalDefinitions.nchev_falcon | + GlobalDefinitions.vshev_comet => + s"${faction}hev_antivehicular" + case GlobalDefinitions.trhev_burster | + GlobalDefinitions.nchev_sparrow | + GlobalDefinitions.vshev_starfire => + s"${faction}hev_antiaircraft" + case _ => + obj.Name + } + sessionActor ! SessionActor.SendResponse( + AvatarVehicleTimerMessage( + session.get.player.GUID, + name, + cooldown.toSeconds - secondsSincePurchase, + unk1 = true //TODO? vehicles = true, everything else = false + ) + ) + + case _ => + keysToDrop = keysToDrop :+ key //key has timed-out + } + case _ => ; + } + } + if (keysToDrop.nonEmpty) { + avatar.copy(purchaseTimes = avatar.purchaseTimes.removedAll(keysToDrop)) + } + } } diff --git a/src/main/scala/net/psforever/actors/session/SessionActor.scala b/src/main/scala/net/psforever/actors/session/SessionActor.scala index 9a64ac1da..749c54939 100644 --- a/src/main/scala/net/psforever/actors/session/SessionActor.scala +++ b/src/main/scala/net/psforever/actors/session/SessionActor.scala @@ -1292,7 +1292,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con case PlayerLoaded(tplayer) => //same zone - log.info(s"Player ${tplayer.Name} will respawn") + log.info(s"${tplayer.Name} will respawn") tplayer.avatar = avatar session = session.copy(player = tplayer) setupAvatarFunc() @@ -2478,7 +2478,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con case Mountable.CanMount(obj: Vehicle, seat_number, _) => CancelZoningProcessWithDescriptiveReason("cancel_mount") - log.info(s"${player.Name} mounts ${obj.Definition.Name} in ${ + log.info(s"${player.Name} mounts the ${obj.Definition.Name} in ${ obj.SeatPermissionGroup(seat_number) match { case Some(AccessPermissionGroup.Driver) => "the driver seat" case Some(seatType) => s"a $seatType seat, #$seat_number" @@ -2943,11 +2943,6 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con sendResponse(PlanetsideAttributeMessage(vehicle_guid, 22, 1L)) //mount points off sendResponse(PlanetsideAttributeMessage(player.GUID, 21, vehicle_guid)) //ownership avatarActor ! AvatarActor.UpdatePurchaseTime(vehicle.Definition) - Avatar.purchaseCooldowns.get(vehicle.Definition) match { - case Some(cooldown) => - sendResponse(AvatarVehicleTimerMessage(player.GUID, vehicle.Definition.Name, cooldown.toSeconds, unk1 = true)) - case None => ; - } vehicle.MountPoints.find { case (_, mp) => mp.seatIndex == 0 } match { case Some((mountPoint, _)) => vehicle.Actor ! Mountable.TryMount(player, mountPoint) case _ => ; From 7e2d7a2089645343982d626cd8f747632a21d572 Mon Sep 17 00:00:00 2001 From: "Jason_DiDonato@yahoo.com" Date: Sun, 18 Apr 2021 10:17:08 -0400 Subject: [PATCH 3/4] even more concise --- .../actors/session/AvatarActor.scala | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/main/scala/net/psforever/actors/session/AvatarActor.scala b/src/main/scala/net/psforever/actors/session/AvatarActor.scala index 22c41dfb0..266b91f92 100644 --- a/src/main/scala/net/psforever/actors/session/AvatarActor.scala +++ b/src/main/scala/net/psforever/actors/session/AvatarActor.scala @@ -721,13 +721,14 @@ class AvatarActor( Behaviors.same case UpdatePurchaseTime(definition, time) => - if (!Avatar.purchaseCooldowns.contains(definition)) { - // TODO only send for items with cooldowns + //only send for items with cooldowns + Avatar.purchaseCooldowns.get(definition) match { + case Some(cooldown) => + // TODO save to db + avatar = avatar.copy(purchaseTimes = avatar.purchaseTimes.updated(definition.Name, time)) + updatePurchaseTimer(definition.Name, cooldown.toSeconds, unk1 = true) + case None => ; //log.warn(s"UpdatePurchaseTime message for item '${definition.Name}' without cooldown") - } else { - // TODO save to db - avatar = avatar.copy(purchaseTimes = avatar.purchaseTimes.updated(definition.Name, time)) - refreshPurchaseTimes(Set(definition.Name)) } Behaviors.same @@ -1360,14 +1361,7 @@ class AvatarActor( case _ => obj.Name } - sessionActor ! SessionActor.SendResponse( - AvatarVehicleTimerMessage( - session.get.player.GUID, - name, - cooldown.toSeconds - secondsSincePurchase, - unk1 = true //TODO? vehicles = true, everything else = false - ) - ) + updatePurchaseTimer(name, cooldown.toSeconds - secondsSincePurchase, unk1 = true) case _ => keysToDrop = keysToDrop :+ key //key has timed-out @@ -1379,4 +1373,11 @@ class AvatarActor( avatar.copy(purchaseTimes = avatar.purchaseTimes.removedAll(keysToDrop)) } } + + def updatePurchaseTimer(name: String, time: Long, unk1: Boolean): Unit = { + //TODO? unk1 is: vehicles = true, everything else = false + sessionActor ! SessionActor.SendResponse( + AvatarVehicleTimerMessage(session.get.player.GUID, name, time, unk1 = true) + ) + } } From e41c76ebbcbfb5b4611261d9b85457810515aef6 Mon Sep 17 00:00:00 2001 From: "Jason_DiDonato@yahoo.com" Date: Sun, 18 Apr 2021 23:04:09 -0400 Subject: [PATCH 4/4] avatar = ... --- src/main/scala/net/psforever/actors/session/AvatarActor.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/net/psforever/actors/session/AvatarActor.scala b/src/main/scala/net/psforever/actors/session/AvatarActor.scala index 266b91f92..3f2ec18ba 100644 --- a/src/main/scala/net/psforever/actors/session/AvatarActor.scala +++ b/src/main/scala/net/psforever/actors/session/AvatarActor.scala @@ -1370,7 +1370,7 @@ class AvatarActor( } } if (keysToDrop.nonEmpty) { - avatar.copy(purchaseTimes = avatar.purchaseTimes.removedAll(keysToDrop)) + avatar = avatar.copy(purchaseTimes = avatar.purchaseTimes.removedAll(keysToDrop)) } }