mirror of
https://github.com/psforever/PSF-LoginServer.git
synced 2026-07-16 08:55:18 +00:00
better timing for refresh of the character select screen; potential to stop moving vehicles from anothers's perspectives
This commit is contained in:
parent
0d02d7b556
commit
b4fbebb8d7
2 changed files with 77 additions and 33 deletions
|
|
@ -1,24 +1,17 @@
|
||||||
// Copyright (c) 2019 PSForever
|
// Copyright (c) 2019 PSForever
|
||||||
package net.psforever.actors.session
|
package net.psforever.actors.session
|
||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger
|
|
||||||
import akka.actor.Cancellable
|
import akka.actor.Cancellable
|
||||||
import akka.actor.typed.scaladsl.{ActorContext, Behaviors, StashBuffer}
|
import akka.actor.typed.scaladsl.{ActorContext, Behaviors, StashBuffer}
|
||||||
import akka.actor.typed.{ActorRef, Behavior, PostStop, SupervisorStrategy}
|
import akka.actor.typed.{ActorRef, Behavior, PostStop, SupervisorStrategy}
|
||||||
import net.psforever.objects.avatar.{ProgressDecoration, SpecialCarry}
|
import java.util.concurrent.atomic.AtomicInteger
|
||||||
import net.psforever.objects.avatar.scoring.{Death, EquipmentStat, KDAStat, Kill}
|
|
||||||
import net.psforever.objects.sourcing.SourceWithHealthEntry
|
|
||||||
import net.psforever.objects.vital.projectile.ProjectileReason
|
|
||||||
import net.psforever.objects.vital.{DamagingActivity, HealingActivity, SpawningActivity, Vitality}
|
|
||||||
import net.psforever.packet.game.objectcreate.BasicCharacterData
|
|
||||||
import net.psforever.types.ExperienceType
|
|
||||||
import org.joda.time.{LocalDateTime, Seconds}
|
import org.joda.time.{LocalDateTime, Seconds}
|
||||||
|
|
||||||
import scala.collection.mutable
|
import scala.collection.mutable
|
||||||
import scala.concurrent.{ExecutionContextExecutor, Future, Promise}
|
import scala.concurrent.{ExecutionContextExecutor, Future, Promise}
|
||||||
import scala.util.{Failure, Success}
|
import scala.util.{Failure, Success}
|
||||||
import scala.concurrent.duration._
|
import scala.concurrent.duration._
|
||||||
//
|
//
|
||||||
|
import net.psforever.objects._
|
||||||
import net.psforever.objects.avatar.{
|
import net.psforever.objects.avatar.{
|
||||||
Avatar,
|
Avatar,
|
||||||
BattleRank,
|
BattleRank,
|
||||||
|
|
@ -29,25 +22,31 @@ import net.psforever.objects.avatar.{
|
||||||
Implant,
|
Implant,
|
||||||
MemberLists,
|
MemberLists,
|
||||||
PlayerControl,
|
PlayerControl,
|
||||||
Shortcut => AvatarShortcut
|
ProgressDecoration,
|
||||||
|
Shortcut => AvatarShortcut,
|
||||||
|
SpecialCarry
|
||||||
}
|
}
|
||||||
|
import net.psforever.objects.avatar.scoring.{Death, EquipmentStat, KDAStat, Kill}
|
||||||
import net.psforever.objects.definition._
|
import net.psforever.objects.definition._
|
||||||
import net.psforever.objects.definition.converter.CharacterSelectConverter
|
import net.psforever.objects.definition.converter.CharacterSelectConverter
|
||||||
import net.psforever.objects.inventory.Container
|
|
||||||
import net.psforever.objects.equipment.{Equipment, EquipmentSlot}
|
import net.psforever.objects.equipment.{Equipment, EquipmentSlot}
|
||||||
import net.psforever.objects.inventory.InventoryItem
|
import net.psforever.objects.inventory.{Container, InventoryItem}
|
||||||
import net.psforever.objects.loadouts.{InfantryLoadout, Loadout, VehicleLoadout}
|
import net.psforever.objects.loadouts.{InfantryLoadout, Loadout, VehicleLoadout}
|
||||||
import net.psforever.objects._
|
|
||||||
import net.psforever.objects.locker.LockerContainer
|
import net.psforever.objects.locker.LockerContainer
|
||||||
import net.psforever.objects.sourcing.PlayerSource
|
import net.psforever.objects.sourcing.{PlayerSource,SourceWithHealthEntry}
|
||||||
import net.psforever.objects.vital.HealFromImplant
|
import net.psforever.objects.vital.projectile.ProjectileReason
|
||||||
import net.psforever.packet.game.objectcreate.{ObjectClass, RibbonBars}
|
import net.psforever.objects.vital.{DamagingActivity, HealFromImplant, HealingActivity, SpawningActivity, Vitality}
|
||||||
|
import net.psforever.packet.game.objectcreate.{BasicCharacterData, ObjectClass, RibbonBars}
|
||||||
import net.psforever.packet.game.{Friend => GameFriend, _}
|
import net.psforever.packet.game.{Friend => GameFriend, _}
|
||||||
|
import net.psforever.persistence
|
||||||
|
import net.psforever.services.Service
|
||||||
|
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||||
import net.psforever.types.{
|
import net.psforever.types.{
|
||||||
CharacterSex,
|
CharacterSex,
|
||||||
CharacterVoice,
|
CharacterVoice,
|
||||||
Cosmetic,
|
Cosmetic,
|
||||||
ExoSuitType,
|
ExoSuitType,
|
||||||
|
ExperienceType,
|
||||||
ImplantType,
|
ImplantType,
|
||||||
LoadoutType,
|
LoadoutType,
|
||||||
MemberAction,
|
MemberAction,
|
||||||
|
|
@ -57,11 +56,7 @@ import net.psforever.types.{
|
||||||
TransactionType
|
TransactionType
|
||||||
}
|
}
|
||||||
import net.psforever.util.Database._
|
import net.psforever.util.Database._
|
||||||
import net.psforever.persistence
|
|
||||||
import net.psforever.util.{Config, Database, DefinitionUtil}
|
import net.psforever.util.{Config, Database, DefinitionUtil}
|
||||||
import net.psforever.services.Service
|
|
||||||
//import org.log4s.Logger
|
|
||||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
|
||||||
|
|
||||||
object AvatarActor {
|
object AvatarActor {
|
||||||
def apply(sessionActor: ActorRef[SessionActor.Command]): Behavior[Command] =
|
def apply(sessionActor: ActorRef[SessionActor.Command]): Behavior[Command] =
|
||||||
|
|
@ -3009,7 +3004,7 @@ class AvatarActor(
|
||||||
case Success(_) =>
|
case Success(_) =>
|
||||||
//create new character
|
//create new character
|
||||||
actuallyCreateNewCharacter(account.id, account.name, name, sex, empire, head, voice)
|
actuallyCreateNewCharacter(account.id, account.name, name, sex, empire, head, voice)
|
||||||
sendAvatars(account)
|
.onComplete(_ => sendAvatars(account))
|
||||||
case Failure(e) =>
|
case Failure(e) =>
|
||||||
log.error(e)("db failure")
|
log.error(e)("db failure")
|
||||||
sessionActor ! SessionActor.SendResponse(ActionResultMessage.Fail(error = 3))
|
sessionActor ! SessionActor.SendResponse(ActionResultMessage.Fail(error = 3))
|
||||||
|
|
@ -3029,7 +3024,7 @@ class AvatarActor(
|
||||||
} else {
|
} else {
|
||||||
//reactivate character
|
//reactivate character
|
||||||
reactivateCharacter(account.id, account.name, name)
|
reactivateCharacter(account.id, account.name, name)
|
||||||
sendAvatars(account)
|
.onComplete(_ => sendAvatars(account))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3043,7 +3038,8 @@ class AvatarActor(
|
||||||
voice: CharacterVoice.Value,
|
voice: CharacterVoice.Value,
|
||||||
bep: Long = Config.app.game.newAvatar.br.experience,
|
bep: Long = Config.app.game.newAvatar.br.experience,
|
||||||
cep: Long = Config.app.game.newAvatar.cr.experience
|
cep: Long = Config.app.game.newAvatar.cr.experience
|
||||||
): Unit = {
|
): Future[Boolean] = {
|
||||||
|
val output: Promise[Boolean] = Promise[Boolean]()
|
||||||
import ctx._
|
import ctx._
|
||||||
val result = for {
|
val result = for {
|
||||||
_ <- ctx.run(
|
_ <- ctx.run(
|
||||||
|
|
@ -3064,26 +3060,40 @@ class AvatarActor(
|
||||||
case Success(_) =>
|
case Success(_) =>
|
||||||
log.debug(s"AvatarActor: created character $name for account $accountName")
|
log.debug(s"AvatarActor: created character $name for account $accountName")
|
||||||
sessionActor ! SessionActor.SendResponse(ActionResultMessage.Pass)
|
sessionActor ! SessionActor.SendResponse(ActionResultMessage.Pass)
|
||||||
|
output.success(true)
|
||||||
case Failure(e) =>
|
case Failure(e) =>
|
||||||
log.error(e)("db failure")
|
log.error(e)("db failure")
|
||||||
sessionActor ! SessionActor.SendResponse(ActionResultMessage.Fail(error = 3))
|
sessionActor ! SessionActor.SendResponse(ActionResultMessage.Fail(error = 3))
|
||||||
|
output.success(false)
|
||||||
}
|
}
|
||||||
|
output.future
|
||||||
}
|
}
|
||||||
|
|
||||||
private def reactivateCharacter(accountId: Int, accountName: String, characterName: String): Unit = {
|
private def reactivateCharacter(
|
||||||
|
accountId: Int,
|
||||||
|
accountName: String,
|
||||||
|
characterName: String
|
||||||
|
): Future[Boolean] = {
|
||||||
|
val output: Promise[Boolean] = Promise[Boolean]()
|
||||||
import ctx._
|
import ctx._
|
||||||
ctx.run(
|
val result = for {
|
||||||
query[persistence.Avatar]
|
out <- ctx.run(
|
||||||
.filter(a => a.accountId == lift(accountId))
|
query[persistence.Avatar]
|
||||||
.filter(a => a.name ilike lift(characterName))
|
.filter(a => a.accountId == lift(accountId))
|
||||||
.update(_.deleted -> lift(false))
|
.filter(a => a.name ilike lift(characterName))
|
||||||
).onComplete {
|
.update(_.deleted -> lift(false))
|
||||||
|
)
|
||||||
|
} yield out
|
||||||
|
result.onComplete {
|
||||||
case Success(_) =>
|
case Success(_) =>
|
||||||
log.debug(s"AvatarActor: character belonging to $accountName with name $characterName reactivated")
|
log.debug(s"AvatarActor: character belonging to $accountName with name $characterName reactivated")
|
||||||
sessionActor ! SessionActor.SendResponse(ActionResultMessage.Pass)
|
sessionActor ! SessionActor.SendResponse(ActionResultMessage.Pass)
|
||||||
|
output.success(true)
|
||||||
case Failure(e) =>
|
case Failure(e) =>
|
||||||
log.error(e)("db failure")
|
log.error(e)("db failure")
|
||||||
sessionActor ! SessionActor.SendResponse(ActionResultMessage.Fail(error = 3))
|
sessionActor ! SessionActor.SendResponse(ActionResultMessage.Fail(error = 3))
|
||||||
|
output.success(false)
|
||||||
}
|
}
|
||||||
|
output.future
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ import net.psforever.packet.game.{ChatMsg, DelayedPathMountMsg, DismountVehicleM
|
||||||
import net.psforever.services.Service
|
import net.psforever.services.Service
|
||||||
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||||
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||||
import net.psforever.types.{BailType, ChatMessageType, PlanetSideGUID}
|
import net.psforever.types.{BailType, ChatMessageType, PlanetSideGUID, Vector3}
|
||||||
|
|
||||||
class SessionMountHandlers(
|
class SessionMountHandlers(
|
||||||
val sessionData: SessionData,
|
val sessionData: SessionData,
|
||||||
|
|
@ -238,7 +238,7 @@ class SessionMountHandlers(
|
||||||
}")
|
}")
|
||||||
sessionData.vehicles.ConditionalDriverVehicleControl(obj)
|
sessionData.vehicles.ConditionalDriverVehicleControl(obj)
|
||||||
sessionData.unaccessContainer(obj)
|
sessionData.unaccessContainer(obj)
|
||||||
DismountAction(tplayer, obj, seatNum)
|
DismountVehicleAction(tplayer, obj, seatNum)
|
||||||
|
|
||||||
case Mountable.CanDismount(obj: Vehicle, seat_num, _) =>
|
case Mountable.CanDismount(obj: Vehicle, seat_num, _) =>
|
||||||
continent.VehicleEvents ! VehicleServiceMessage(
|
continent.VehicleEvents ! VehicleServiceMessage(
|
||||||
|
|
@ -289,6 +289,40 @@ class SessionMountHandlers(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Common activities/procedure when a player dismounts a valid mountable object.
|
||||||
|
* @param tplayer the player
|
||||||
|
* @param obj the mountable object
|
||||||
|
* @param seatNum the mount out of which which the player is disembarking
|
||||||
|
*/
|
||||||
|
def DismountVehicleAction(tplayer: Player, obj: PlanetSideGameObject with Mountable, seatNum: Int): Unit = {
|
||||||
|
DismountAction(tplayer, obj, seatNum)
|
||||||
|
//until vehicles maintain synchronized momentum without a driver
|
||||||
|
obj match {
|
||||||
|
case v: Vehicle
|
||||||
|
if seatNum == 0 && Vector3.MagnitudeSquared(v.Velocity.getOrElse(Vector3.Zero)) > 0f =>
|
||||||
|
v.Velocity = Vector3.Zero
|
||||||
|
continent.VehicleEvents ! VehicleServiceMessage(
|
||||||
|
continent.id,
|
||||||
|
VehicleAction.VehicleState(
|
||||||
|
tplayer.GUID,
|
||||||
|
v.GUID,
|
||||||
|
unk1 = 0,
|
||||||
|
v.Position,
|
||||||
|
v.Orientation,
|
||||||
|
vel = None,
|
||||||
|
v.Flying,
|
||||||
|
unk3 = 0,
|
||||||
|
unk4 = 0,
|
||||||
|
wheel_direction = 15,
|
||||||
|
unk5 = false,
|
||||||
|
unk6 = v.Cloaked
|
||||||
|
)
|
||||||
|
)
|
||||||
|
case _ => ()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Common activities/procedure when a player dismounts a valid mountable object.
|
* Common activities/procedure when a player dismounts a valid mountable object.
|
||||||
* @param tplayer the player
|
* @param tplayer the player
|
||||||
|
|
@ -306,7 +340,7 @@ class SessionMountHandlers(
|
||||||
sendResponse(DismountVehicleMsg(playerGuid, bailType, wasKickedByDriver = false))
|
sendResponse(DismountVehicleMsg(playerGuid, bailType, wasKickedByDriver = false))
|
||||||
continent.VehicleEvents ! VehicleServiceMessage(
|
continent.VehicleEvents ! VehicleServiceMessage(
|
||||||
continent.id,
|
continent.id,
|
||||||
VehicleAction.DismountVehicle(playerGuid, bailType, unk2=false)
|
VehicleAction.DismountVehicle(playerGuid, bailType, unk2 = false)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue