mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-04-21 11:55:19 +00:00
Persistence (#337)
* constructed service actor to handle persistence of player on server beyond the reaches of WSA from one login to the next; created in PSLogin, interfaced with and updated in WSA * for what it's worth, players can be completely logged out of the world after 60s of inactivity, alive Infantry only right now; some code was removed from WSA to make it accessible to other classes but it's incomparable to the new code; broke, fixed, compromised on the code that handles loadouts, server login time, etc. * moved another common vehicle function into global space; persistence object for players in vehicles during log-out or relogging in a vehicle * support for relogging when dead/released/unfound; silenced implant slot setup during character select screen * tested and commented code for managing player avatar persistence * clarificaion of WSA postStop * test fixed * postStop change to account for WSA being cut short during initialization * clarification of SquadService logout * player died during setup; probably a relog * kill the doppelganger WSA; die when you are actually dead * created manifest to assist with vehicle gating; vehicle gating now accomodates the persistence model much better * fixed the test * fixed initial vehicle seat access permissions; moved a subscription to AvatarService to support persistence * bug fixes: safer GridInventory collision checks, plus specific exceptions; SessionRouter waits for the account intermediary before allowing itself to be started; WSA - match error colution, and MAX without arm now creates the arm it expects * adjusted insertion and removal code to make inventory management less prone to partoial insertions of removals; inventory integrity checking code writen, but no plans on implementing it yet
This commit is contained in:
parent
06ef3a08c5
commit
53ecee566a
29 changed files with 2436 additions and 1239 deletions
|
|
@ -1,10 +1,10 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package objects
|
||||
|
||||
import net.psforever.objects.{AmmoBox, SimpleItem}
|
||||
import net.psforever.objects.{AmmoBox, SimpleItem, Tool}
|
||||
import net.psforever.objects.definition.SimpleItemDefinition
|
||||
import net.psforever.objects.inventory.{GridInventory, InventoryItem, InventoryTile}
|
||||
import net.psforever.objects.GlobalDefinitions._
|
||||
import net.psforever.objects.inventory.{GridInventory, InventoryDisarrayException, InventoryItem, InventoryTile}
|
||||
import net.psforever.objects.GlobalDefinitions.{bullet_9mm, suppressor}
|
||||
import net.psforever.types.PlanetSideGUID
|
||||
import org.specs2.mutable._
|
||||
|
||||
|
|
@ -19,6 +19,18 @@ class InventoryTest extends Specification {
|
|||
bullet9mmBox2 = AmmoBox(bullet_9mm)
|
||||
bullet9mmBox2.GUID = PlanetSideGUID(2)
|
||||
|
||||
"InventoryDisarrayException" should {
|
||||
"construct" in {
|
||||
InventoryDisarrayException("slot out of bounds")
|
||||
ok
|
||||
}
|
||||
|
||||
"construct (with Throwable)" in {
|
||||
InventoryDisarrayException("slot out of bounds", new Throwable())
|
||||
ok
|
||||
}
|
||||
}
|
||||
|
||||
"GridInventory" should {
|
||||
"construct" in {
|
||||
val obj : GridInventory = GridInventory()
|
||||
|
|
@ -33,28 +45,28 @@ class InventoryTest extends Specification {
|
|||
obj.Size mustEqual 0
|
||||
}
|
||||
|
||||
"insert item" in {
|
||||
val obj : GridInventory = GridInventory(9, 6)
|
||||
obj.CheckCollisions(23, bullet9mmBox1) mustEqual Success(Nil)
|
||||
obj += 2 -> bullet9mmBox1
|
||||
obj.TotalCapacity mustEqual 54
|
||||
obj.Capacity mustEqual 45
|
||||
obj.Size mustEqual 1
|
||||
obj.hasItem(PlanetSideGUID(1)) mustEqual Some(bullet9mmBox1)
|
||||
obj.Clear()
|
||||
obj.Size mustEqual 0
|
||||
}
|
||||
|
||||
"check for collision with inventory border" in {
|
||||
val obj : GridInventory = GridInventory(3, 3)
|
||||
//safe
|
||||
obj.CheckCollisionsAsList(0, 3, 3) mustEqual Success(Nil)
|
||||
//right
|
||||
obj.CheckCollisionsAsList(-1, 3, 3).isFailure mustEqual true
|
||||
obj.CheckCollisionsAsList(-1, 3, 3) match {
|
||||
case scala.util.Failure(fail) =>
|
||||
fail.isInstanceOf[IndexOutOfBoundsException] mustEqual true
|
||||
case _ => ko
|
||||
}
|
||||
//left
|
||||
obj.CheckCollisionsAsList(1, 3, 3).isFailure mustEqual true
|
||||
obj.CheckCollisionsAsList(1, 3, 3) match {
|
||||
case scala.util.Failure(fail) =>
|
||||
fail.isInstanceOf[IndexOutOfBoundsException] mustEqual true
|
||||
case _ => ko
|
||||
}
|
||||
//bottom
|
||||
obj.CheckCollisionsAsList(3, 3, 3).isFailure mustEqual true
|
||||
obj.CheckCollisionsAsList(3, 3, 3) match {
|
||||
case scala.util.Failure(fail) =>
|
||||
fail.isInstanceOf[IndexOutOfBoundsException] mustEqual true
|
||||
case _ => ko
|
||||
}
|
||||
}
|
||||
|
||||
"check for item collision (right insert)" in {
|
||||
|
|
@ -64,7 +76,7 @@ class InventoryTest extends Specification {
|
|||
val w = bullet9mmBox2.Tile.Width
|
||||
val h = bullet9mmBox2.Tile.Height
|
||||
val list0 = obj.CheckCollisionsAsList(0, w, h)
|
||||
list0 match {
|
||||
obj.CheckCollisionsAsList(0, w, h) match {
|
||||
case scala.util.Success(list) => list.length mustEqual 1
|
||||
case scala.util.Failure(_) => ko
|
||||
}
|
||||
|
|
@ -263,35 +275,120 @@ class InventoryTest extends Specification {
|
|||
ok
|
||||
}
|
||||
|
||||
"insert item" in {
|
||||
val obj : GridInventory = GridInventory(9, 6)
|
||||
obj.CheckCollisions(23, bullet9mmBox1) mustEqual Success(Nil)
|
||||
obj += 2 -> bullet9mmBox1
|
||||
obj.TotalCapacity mustEqual 54
|
||||
obj.Capacity mustEqual 45
|
||||
obj.Size mustEqual 1
|
||||
obj.hasItem(PlanetSideGUID(1)).contains(bullet9mmBox1) mustEqual true
|
||||
obj.Clear()
|
||||
obj.Size mustEqual 0
|
||||
}
|
||||
|
||||
"not insert into an invalid slot (n < 0)" in {
|
||||
val obj : GridInventory = GridInventory(9, 6)
|
||||
obj.Capacity mustEqual 54
|
||||
obj.Size mustEqual 0
|
||||
obj.Insert(-1, bullet9mmBox1) must throwA[IndexOutOfBoundsException]
|
||||
obj.Capacity mustEqual 54
|
||||
obj.Size mustEqual 0
|
||||
}
|
||||
|
||||
"not insert into an invalid slot (n > capacity)" in {
|
||||
val obj : GridInventory = GridInventory(9, 6)
|
||||
obj.Capacity mustEqual 54
|
||||
obj.Size mustEqual 0
|
||||
obj.Insert(55, bullet9mmBox1) must throwA[IndexOutOfBoundsException]
|
||||
obj.Capacity mustEqual 54
|
||||
obj.Size mustEqual 0
|
||||
}
|
||||
|
||||
"block insertion if item collision" in {
|
||||
val obj : GridInventory = GridInventory(9, 6)
|
||||
obj += 0 -> bullet9mmBox1
|
||||
obj.Capacity mustEqual 45
|
||||
obj.hasItem(PlanetSideGUID(1)) mustEqual Some(bullet9mmBox1)
|
||||
obj.hasItem(PlanetSideGUID(1)).contains(bullet9mmBox1) mustEqual true
|
||||
obj += 2 -> bullet9mmBox2
|
||||
obj.hasItem(PlanetSideGUID(2)) mustEqual None
|
||||
obj.hasItem(PlanetSideGUID(2)).isEmpty mustEqual true
|
||||
}
|
||||
|
||||
"insert items quickly (risk overwriting entries)" in {
|
||||
val obj : GridInventory = GridInventory(6, 6)
|
||||
(obj += 0 -> bullet9mmBox1) mustEqual true
|
||||
val collision1 = obj.CheckCollisions(0,1,1)
|
||||
obj.CheckCollisions(1,1,1) mustEqual collision1
|
||||
obj.CheckCollisions(2,1,1) mustEqual collision1
|
||||
obj.CheckCollisions(6,1,1) mustEqual collision1
|
||||
obj.CheckCollisions(7,1,1) mustEqual collision1
|
||||
obj.CheckCollisions(8,1,1) mustEqual collision1
|
||||
obj.CheckCollisions(12,1,1) mustEqual collision1
|
||||
obj.CheckCollisions(13,1,1) mustEqual collision1
|
||||
obj.CheckCollisions(14,1,1) mustEqual collision1
|
||||
|
||||
(obj += 7 -> bullet9mmBox2) mustEqual false //can not insert overlapping object
|
||||
obj.CheckCollisions(0,1,1) mustEqual collision1
|
||||
obj.CheckCollisions(1,1,1) mustEqual collision1
|
||||
obj.CheckCollisions(2,1,1) mustEqual collision1
|
||||
obj.CheckCollisions(6,1,1) mustEqual collision1
|
||||
obj.CheckCollisions(7,1,1) mustEqual collision1
|
||||
obj.CheckCollisions(8,1,1) mustEqual collision1
|
||||
obj.CheckCollisions(12,1,1) mustEqual collision1
|
||||
obj.CheckCollisions(13,1,1) mustEqual collision1
|
||||
obj.CheckCollisions(14,1,1) mustEqual collision1
|
||||
|
||||
obj.InsertQuickly(7, bullet9mmBox2) mustEqual true //overwrite
|
||||
val collision2 = obj.CheckCollisions(7,1,1)
|
||||
obj.CheckCollisions(0,1,1) mustEqual collision1
|
||||
obj.CheckCollisions(1,1,1) mustEqual collision1
|
||||
obj.CheckCollisions(2,1,1) mustEqual collision1
|
||||
obj.CheckCollisions(6,1,1) mustEqual collision1
|
||||
obj.CheckCollisions(7,1,1) mustEqual collision2
|
||||
obj.CheckCollisions(8,1,1) mustEqual collision2
|
||||
obj.CheckCollisions(12,1,1) mustEqual collision1
|
||||
obj.CheckCollisions(13,1,1) mustEqual collision2
|
||||
obj.CheckCollisions(14,1,1) mustEqual collision2
|
||||
}
|
||||
|
||||
"clear all items" in {
|
||||
val obj : GridInventory = GridInventory(9, 6)
|
||||
obj += 2 -> bullet9mmBox1
|
||||
obj.Size mustEqual 1
|
||||
obj.hasItem(PlanetSideGUID(1)).contains(bullet9mmBox1) mustEqual true
|
||||
obj.Clear()
|
||||
ok
|
||||
obj.Size mustEqual 0
|
||||
obj.hasItem(PlanetSideGUID(1)).isEmpty mustEqual true
|
||||
}
|
||||
|
||||
"remove item" in {
|
||||
val obj : GridInventory = GridInventory(9, 6)
|
||||
obj += 0 -> bullet9mmBox1
|
||||
obj.hasItem(PlanetSideGUID(1)) mustEqual Some(bullet9mmBox1)
|
||||
obj.hasItem(PlanetSideGUID(1)).contains(bullet9mmBox1) mustEqual true
|
||||
obj -= PlanetSideGUID(1)
|
||||
obj.hasItem(PlanetSideGUID(1)) mustEqual None
|
||||
obj.hasItem(PlanetSideGUID(1)).isEmpty mustEqual true
|
||||
obj.Clear()
|
||||
ok
|
||||
}
|
||||
|
||||
"fail to remove from an invalid slot (n < 0)" in {
|
||||
val obj : GridInventory = GridInventory(9, 6)
|
||||
(obj -= -1) mustEqual false
|
||||
}
|
||||
|
||||
"fail to remove from an invalid slot (n > capacity)" in {
|
||||
val obj : GridInventory = GridInventory(9, 6)
|
||||
(obj -= 55) mustEqual false
|
||||
}
|
||||
|
||||
"unblock insertion on item removal" in {
|
||||
val obj : GridInventory = GridInventory(9, 6)
|
||||
obj.CheckCollisions(23, bullet9mmBox1) mustEqual Success(Nil)
|
||||
obj += 23 -> bullet9mmBox1
|
||||
obj.hasItem(PlanetSideGUID(1)) mustEqual Some(bullet9mmBox1)
|
||||
obj.hasItem(PlanetSideGUID(1)).contains(bullet9mmBox1) mustEqual true
|
||||
obj.CheckCollisions(23, bullet9mmBox1) mustEqual Success(1 :: Nil)
|
||||
obj -= PlanetSideGUID(1)
|
||||
obj.hasItem(PlanetSideGUID(1)) mustEqual None
|
||||
obj.hasItem(PlanetSideGUID(1)).isEmpty mustEqual true
|
||||
obj.CheckCollisions(23, bullet9mmBox1) mustEqual Success(Nil)
|
||||
obj.Clear()
|
||||
ok
|
||||
|
|
@ -350,41 +447,82 @@ class InventoryTest extends Specification {
|
|||
ok
|
||||
}
|
||||
|
||||
"insert items quickly (risk overwriting entries)" in {
|
||||
"confirm integrity of inventory as a grid" in {
|
||||
val obj : GridInventory = GridInventory(6, 6)
|
||||
(obj += 0 -> bullet9mmBox1) mustEqual true
|
||||
val collision1 = obj.CheckCollisions(0,1,1)
|
||||
obj.CheckCollisions(1,1,1) mustEqual collision1
|
||||
obj.CheckCollisions(2,1,1) mustEqual collision1
|
||||
obj.CheckCollisions(6,1,1) mustEqual collision1
|
||||
obj.CheckCollisions(7,1,1) mustEqual collision1
|
||||
obj.CheckCollisions(8,1,1) mustEqual collision1
|
||||
obj.CheckCollisions(12,1,1) mustEqual collision1
|
||||
obj.CheckCollisions(13,1,1) mustEqual collision1
|
||||
obj.CheckCollisions(14,1,1) mustEqual collision1
|
||||
(obj += 21 -> bullet9mmBox2) mustEqual true
|
||||
//artificially pollute the inventory grid-space
|
||||
obj.SetCells(10, 1, 1, 3)
|
||||
obj.SetCells(19, 2, 2, 4)
|
||||
obj.ElementsOnGridMatchList() mustEqual 5 //number of misses repaired
|
||||
}
|
||||
|
||||
(obj += 7 -> bullet9mmBox2) mustEqual false //can not insert overlapping object
|
||||
obj.CheckCollisions(0,1,1) mustEqual collision1
|
||||
obj.CheckCollisions(1,1,1) mustEqual collision1
|
||||
obj.CheckCollisions(2,1,1) mustEqual collision1
|
||||
obj.CheckCollisions(6,1,1) mustEqual collision1
|
||||
obj.CheckCollisions(7,1,1) mustEqual collision1
|
||||
obj.CheckCollisions(8,1,1) mustEqual collision1
|
||||
obj.CheckCollisions(12,1,1) mustEqual collision1
|
||||
obj.CheckCollisions(13,1,1) mustEqual collision1
|
||||
obj.CheckCollisions(14,1,1) mustEqual collision1
|
||||
"confirm integrity of inventory as a list (no overlap)" in {
|
||||
val obj : GridInventory = GridInventory(9, 9)
|
||||
val gun = Tool(suppressor)
|
||||
obj.InsertQuickly(0, gun)
|
||||
obj.InsertQuickly(33, bullet9mmBox1)
|
||||
//nothing should overlap
|
||||
val lists = obj.ElementsInListCollideInGrid()
|
||||
lists.size mustEqual 0
|
||||
}
|
||||
|
||||
obj.InsertQuickly(7, bullet9mmBox2) mustEqual true //overwrite
|
||||
val collision2 = obj.CheckCollisions(7,1,1)
|
||||
obj.CheckCollisions(0,1,1) mustEqual collision1
|
||||
obj.CheckCollisions(1,1,1) mustEqual collision1
|
||||
obj.CheckCollisions(2,1,1) mustEqual collision1
|
||||
obj.CheckCollisions(6,1,1) mustEqual collision1
|
||||
obj.CheckCollisions(7,1,1) mustEqual collision2
|
||||
obj.CheckCollisions(8,1,1) mustEqual collision2
|
||||
obj.CheckCollisions(12,1,1) mustEqual collision1
|
||||
obj.CheckCollisions(13,1,1) mustEqual collision2
|
||||
obj.CheckCollisions(14,1,1) mustEqual collision2
|
||||
"confirm integrity of inventory as a list (normal overlap)" in {
|
||||
val obj : GridInventory = GridInventory(9, 9)
|
||||
val gun = Tool(suppressor)
|
||||
val bullet9mmBox3 = AmmoBox(bullet_9mm)
|
||||
obj.InsertQuickly(0, gun)
|
||||
obj.InsertQuickly(18, bullet9mmBox1)
|
||||
obj.InsertQuickly(38, bullet9mmBox2)
|
||||
obj.InsertQuickly(33, bullet9mmBox3)
|
||||
//gun and box1 should overlap
|
||||
//box1 and box2 should overlap
|
||||
//box3 should not overlap with anything
|
||||
val lists = obj.ElementsInListCollideInGrid()
|
||||
lists.size mustEqual 2
|
||||
lists.foreach { list =>
|
||||
val out = list.map { _.obj }
|
||||
if(out.size == 2 && out.contains(gun) && out.contains(bullet9mmBox1)) {
|
||||
ok
|
||||
}
|
||||
else if(out.size == 2 && out.contains(bullet9mmBox1) && out.contains(bullet9mmBox2)) {
|
||||
ok
|
||||
}
|
||||
else {
|
||||
ko
|
||||
}
|
||||
}
|
||||
ok
|
||||
}
|
||||
|
||||
"confirm integrity of inventory as a list (triple overlap)" in {
|
||||
val obj : GridInventory = GridInventory(9, 9)
|
||||
val gun = Tool(suppressor)
|
||||
val bullet9mmBox3 = AmmoBox(bullet_9mm)
|
||||
val bullet9mmBox4 = AmmoBox(bullet_9mm)
|
||||
obj.InsertQuickly(0, gun)
|
||||
obj.InsertQuickly(18, bullet9mmBox1)
|
||||
obj.InsertQuickly(36, bullet9mmBox2)
|
||||
obj.InsertQuickly(38, bullet9mmBox3)
|
||||
obj.InsertQuickly(33, bullet9mmBox4)
|
||||
//gun and box1 should overlap
|
||||
//box1, box2, and box3 should overlap
|
||||
//box4 should not overlap with anything
|
||||
val lists = obj.ElementsInListCollideInGrid()
|
||||
lists.size mustEqual 2
|
||||
lists.foreach { list =>
|
||||
val out = list.map { _.obj }
|
||||
if(out.size == 2 && out.contains(gun) && out.contains(bullet9mmBox1)) {
|
||||
ok
|
||||
}
|
||||
else if(out.size == 3 && out.contains(bullet9mmBox1) && out.contains(bullet9mmBox2) && out.contains(bullet9mmBox3)) {
|
||||
ok
|
||||
}
|
||||
else {
|
||||
ko
|
||||
}
|
||||
}
|
||||
ok
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -357,6 +357,7 @@ class ZonePopulationTest extends ActorTest {
|
|||
val zone = new Zone("test", new ZoneMap(""), 0) { override def SetupNumberPools() = { } }
|
||||
val avatar = Avatar("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Voice5)
|
||||
val player = Player(avatar)
|
||||
player.GUID = PlanetSideGUID(1)
|
||||
zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), ZoneTest.TestName)
|
||||
zone.Actor ! Zone.Init()
|
||||
expectNoMsg(200 milliseconds)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue