mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-03-04 12:40:20 +00:00
better support for the various ways to join a squad, and the various ways to leave a squad; squad-based messages; jury-rigged 'player wants to join' operations
This commit is contained in:
parent
24691ec239
commit
e5b2efd381
7 changed files with 681 additions and 331 deletions
|
|
@ -16,9 +16,26 @@ import shapeless.{::, HNil}
|
|||
abstract class SquadAction(val code : Int)
|
||||
|
||||
object SquadAction{
|
||||
object SearchMode extends Enumeration {
|
||||
type Type = Value
|
||||
|
||||
val
|
||||
AnyPositions,
|
||||
AvailablePositions,
|
||||
SomeCertifications,
|
||||
AllCertifications
|
||||
= Value
|
||||
|
||||
implicit val codec : Codec[SearchMode.Value] = PacketHelpers.createEnumerationCodec(enum = this, uint(bits = 3))
|
||||
}
|
||||
|
||||
final case class DisplaySquad() extends SquadAction(0)
|
||||
|
||||
final case class AnswerSquadJoinRequest() extends SquadAction(1)
|
||||
/**
|
||||
* Dispatched from client to server to indicate a squad detail update that has no foundation entry to update?
|
||||
* Not dissimilar from `DisplaySquad`.
|
||||
*/
|
||||
final case class DisplayFullSquad() extends SquadAction(1)
|
||||
|
||||
final case class SaveSquadFavorite() extends SquadAction(3)
|
||||
|
||||
|
|
@ -58,12 +75,14 @@ object SquadAction{
|
|||
|
||||
final case class LocationFollowsSquadLead(state : Boolean) extends SquadAction(31)
|
||||
|
||||
final case class SearchForSquadsWithParticularRole(u1: String, u2 : Long, u3: Int, u4 : Int) extends SquadAction(34)
|
||||
final case class SearchForSquadsWithParticularRole(role: String, requirements : Set[CertificationType.Value], zone_id: Int, mode : SearchMode.Value) extends SquadAction(34)
|
||||
|
||||
final case class CancelSquadSearch() extends SquadAction(35)
|
||||
|
||||
final case class AssignSquadMemberToRole(position : Int, char_id : Long) extends SquadAction(38)
|
||||
|
||||
final case class NoSquadSearchResults() extends SquadAction(39)
|
||||
|
||||
final case class FindLfsSoldiersForRole(state : Int) extends SquadAction(40)
|
||||
|
||||
final case class CancelFind() extends SquadAction(41)
|
||||
|
|
@ -91,10 +110,10 @@ object SquadAction{
|
|||
}
|
||||
)
|
||||
|
||||
val answerSquadJoinRequestCodec = everFailCondition.xmap[AnswerSquadJoinRequest] (
|
||||
_ => AnswerSquadJoinRequest(),
|
||||
val displayFullSquadCodec = everFailCondition.xmap[DisplayFullSquad] (
|
||||
_ => DisplayFullSquad(),
|
||||
{
|
||||
case AnswerSquadJoinRequest() => None
|
||||
case DisplayFullSquad() => None
|
||||
}
|
||||
)
|
||||
|
||||
|
|
@ -243,12 +262,12 @@ object SquadAction{
|
|||
PacketHelpers.encodedWideStringAligned(6) ::
|
||||
ulongL(46) ::
|
||||
uint16L ::
|
||||
uintL(3)).xmap[SearchForSquadsWithParticularRole] (
|
||||
SearchMode.codec).xmap[SearchForSquadsWithParticularRole] (
|
||||
{
|
||||
case u1 :: u2 :: u3 :: u4 :: HNil => SearchForSquadsWithParticularRole(u1, u2, u3, u4)
|
||||
case u1 :: u2 :: u3 :: u4 :: HNil => SearchForSquadsWithParticularRole(u1, CertificationType.fromEncodedLong(u2), u3, u4)
|
||||
},
|
||||
{
|
||||
case SearchForSquadsWithParticularRole(u1, u2, u3, u4) => u1 :: u2 :: u3 :: u4 :: HNil
|
||||
case SearchForSquadsWithParticularRole(u1, u2, u3, u4) => u1 :: CertificationType.toEncodedLong(u2) :: u3 :: u4 :: HNil
|
||||
}
|
||||
)
|
||||
|
||||
|
|
@ -268,6 +287,13 @@ object SquadAction{
|
|||
}
|
||||
)
|
||||
|
||||
val noSquadSearchResultsCodec = everFailCondition.xmap[NoSquadSearchResults] (
|
||||
_ => NoSquadSearchResults(),
|
||||
{
|
||||
case NoSquadSearchResults() => None
|
||||
}
|
||||
)
|
||||
|
||||
val findLfsSoldiersForRoleCodec = uint4.xmap[FindLfsSoldiersForRole] (
|
||||
state => FindLfsSoldiersForRole(state),
|
||||
{
|
||||
|
|
@ -326,6 +352,7 @@ object SquadAction{
|
|||
* `18` - UNKNOWN<br>
|
||||
* `26` - Reset All<br>
|
||||
* `35` - Cancel Squad Search<br>
|
||||
* `39` - No Squad Search Results<br>
|
||||
* `41` - Cancel Find<br>
|
||||
* `42` - UNKNOWN<br>
|
||||
* `43` - UNKNOWN<br>
|
||||
|
|
@ -388,7 +415,7 @@ object SquadDefinitionActionMessage extends Marshallable[SquadDefinitionActionMe
|
|||
import scala.annotation.switch
|
||||
((code : @switch) match {
|
||||
case 0 => displaySquadCodec
|
||||
case 1 => answerSquadJoinRequestCodec
|
||||
case 1 => displayFullSquadCodec
|
||||
case 3 => saveSquadFavoriteCodec
|
||||
case 4 => loadSquadFavoriteCodec
|
||||
case 5 => deleteSquadFavoriteCodec
|
||||
|
|
@ -411,12 +438,13 @@ object SquadDefinitionActionMessage extends Marshallable[SquadDefinitionActionMe
|
|||
case 34 => searchForSquadsWithParticularRoleCodec
|
||||
case 35 => cancelSquadSearchCodec
|
||||
case 38 => assignSquadMemberToRoleCodec
|
||||
case 39 => noSquadSearchResultsCodec
|
||||
case 40 => findLfsSoldiersForRoleCodec
|
||||
case 41 => cancelFindCodec
|
||||
case 2 | 6 | 11 |
|
||||
12 | 13 | 14 | 16 |
|
||||
18 | 29 | 30 | 32 | 33 |
|
||||
36 | 37 | 39 | 42 | 43 => unknownCodec(code)
|
||||
36 | 37 | 42 | 43 => unknownCodec(code)
|
||||
case _ => failureCodec(code)
|
||||
}).asInstanceOf[Codec[SquadAction]]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,18 +12,18 @@ object MemberEvent extends Enumeration {
|
|||
val
|
||||
Add,
|
||||
Remove,
|
||||
Unknown2,
|
||||
Promote,
|
||||
UpdateZone,
|
||||
Unknown4
|
||||
= Value
|
||||
|
||||
implicit val codec = PacketHelpers.createEnumerationCodec(this, uint(3))
|
||||
implicit val codec = PacketHelpers.createEnumerationCodec(enum = this, uint(bits = 3))
|
||||
}
|
||||
|
||||
final case class SquadMemberEvent(unk1 : Int,
|
||||
final case class SquadMemberEvent(action : MemberEvent.Value,
|
||||
unk2 : Int,
|
||||
char_id : Long,
|
||||
member_position : Int,
|
||||
position : Int,
|
||||
player_name : Option[String],
|
||||
zone_number : Option[Int],
|
||||
unk7 : Option[Long])
|
||||
|
|
@ -34,40 +34,46 @@ final case class SquadMemberEvent(unk1 : Int,
|
|||
}
|
||||
|
||||
object SquadMemberEvent extends Marshallable[SquadMemberEvent] {
|
||||
def apply(unk1 : Int, unk2 : Int, char_id : Long, member_position : Int) : SquadMemberEvent =
|
||||
SquadMemberEvent(unk1, unk2, char_id, member_position, None, None, None)
|
||||
def apply(action : MemberEvent.Value, unk2 : Int, char_id : Long, position : Int) : SquadMemberEvent =
|
||||
SquadMemberEvent(action, unk2, char_id, position, None, None, None)
|
||||
|
||||
def apply(unk2 : Int, char_id : Long, member_position : Int, player_name : String, zone_number : Int, unk7 : Long) : SquadMemberEvent =
|
||||
SquadMemberEvent(0, unk2, char_id, member_position, Some(player_name), Some(zone_number), Some(unk7))
|
||||
def Add(unk2 : Int, char_id : Long, position : Int, player_name : String, zone_number : Int, unk7 : Long) : SquadMemberEvent =
|
||||
SquadMemberEvent(MemberEvent.Add, unk2, char_id, position, Some(player_name), Some(zone_number), Some(unk7))
|
||||
|
||||
def apply(unk2 : Int, char_id : Long, member_position : Int, zone_number : Int) : SquadMemberEvent =
|
||||
SquadMemberEvent(3, unk2, char_id, member_position, None, Some(zone_number), None)
|
||||
def Remove(unk2 : Int, char_id : Long, position : Int) : SquadMemberEvent =
|
||||
SquadMemberEvent(MemberEvent.Remove, unk2, char_id, position, None, None, None)
|
||||
|
||||
def apply(unk2 : Int, char_id : Long, member_position : Int, unk7 : Long) : SquadMemberEvent =
|
||||
SquadMemberEvent(4, unk2, char_id, member_position, None, None, Some(unk7))
|
||||
def Promote(unk2 : Int, char_id : Long) : SquadMemberEvent =
|
||||
SquadMemberEvent(MemberEvent.Promote, unk2, char_id, 0, None, None, None)
|
||||
|
||||
def UpdateZone(unk2 : Int, char_id : Long, position : Int, zone_number : Int) : SquadMemberEvent =
|
||||
SquadMemberEvent(MemberEvent.UpdateZone, unk2, char_id, position, None, Some(zone_number), None)
|
||||
|
||||
def Unknown4(unk2 : Int, char_id : Long, position : Int, unk7 : Long) : SquadMemberEvent =
|
||||
SquadMemberEvent(MemberEvent.Unknown4, unk2, char_id, position, None, None, Some(unk7))
|
||||
|
||||
implicit val codec : Codec[SquadMemberEvent] = (
|
||||
("unk1" | uint(3)) >>:~ { unk1 =>
|
||||
("action" | MemberEvent.codec) >>:~ { action =>
|
||||
("unk2" | uint16L) ::
|
||||
("char_id" | uint32L) ::
|
||||
("member_position" | uint4) ::
|
||||
conditional(unk1 == 0, "player_name" | PacketHelpers.encodedWideStringAligned(1)) ::
|
||||
conditional(unk1 == 0 || unk1 == 3, "zone_number" | uint16L) ::
|
||||
conditional(unk1 == 0 || unk1 == 4, "unk7" | uint32L)
|
||||
("position" | uint4) ::
|
||||
conditional(action == MemberEvent.Add, "player_name" | PacketHelpers.encodedWideStringAligned(1)) ::
|
||||
conditional(action == MemberEvent.Add || action == MemberEvent.UpdateZone, "zone_number" | uint16L) ::
|
||||
conditional(action == MemberEvent.Add || action == MemberEvent.Unknown4, "unk7" | uint32L)
|
||||
}).exmap[SquadMemberEvent] (
|
||||
{
|
||||
case unk1 :: unk2 :: char_id :: member_position :: player_name :: zone_number :: unk7 :: HNil =>
|
||||
Attempt.Successful(SquadMemberEvent(unk1, unk2, char_id, member_position, player_name, zone_number, unk7))
|
||||
case action :: unk2 :: char_id :: member_position :: player_name :: zone_number :: unk7 :: HNil =>
|
||||
Attempt.Successful(SquadMemberEvent(action, unk2, char_id, member_position, player_name, zone_number, unk7))
|
||||
},
|
||||
{
|
||||
case data @ SquadMemberEvent(0, unk2, char_id, member_position, Some(player_name), Some(zone_number), Some(unk7)) =>
|
||||
Attempt.Successful(0 :: unk2 :: char_id :: member_position :: Some(player_name) :: Some(zone_number) :: Some(unk7) :: HNil)
|
||||
case data @ SquadMemberEvent(3, unk2, char_id, member_position, None, Some(zone_number), None) =>
|
||||
Attempt.Successful(3 :: unk2 :: char_id :: member_position :: None :: Some(zone_number) :: None :: HNil)
|
||||
case data @ SquadMemberEvent(4, unk2, char_id, member_position, None, None, Some(unk7)) =>
|
||||
Attempt.Successful(4 :: unk2 :: char_id :: member_position :: None :: None :: Some(unk7) :: HNil)
|
||||
case data @ SquadMemberEvent(unk1, unk2, char_id, member_position, None, None, None) =>
|
||||
Attempt.Successful(unk1 :: unk2 :: char_id :: member_position :: None :: None :: None :: HNil)
|
||||
case SquadMemberEvent(MemberEvent.Add, unk2, char_id, member_position, Some(player_name), Some(zone_number), Some(unk7)) =>
|
||||
Attempt.Successful(MemberEvent.Add :: unk2 :: char_id :: member_position :: Some(player_name) :: Some(zone_number) :: Some(unk7) :: HNil)
|
||||
case SquadMemberEvent(MemberEvent.UpdateZone, unk2, char_id, member_position, None, Some(zone_number), None) =>
|
||||
Attempt.Successful(MemberEvent.UpdateZone :: unk2 :: char_id :: member_position :: None :: Some(zone_number) :: None :: HNil)
|
||||
case SquadMemberEvent(MemberEvent.Unknown4, unk2, char_id, member_position, None, None, Some(unk7)) =>
|
||||
Attempt.Successful(MemberEvent.Unknown4 :: unk2 :: char_id :: member_position :: None :: None :: Some(unk7) :: HNil)
|
||||
case SquadMemberEvent(action, unk2, char_id, member_position, None, None, None) =>
|
||||
Attempt.Successful(action :: unk2 :: char_id :: member_position :: None :: None :: None :: HNil)
|
||||
case data =>
|
||||
Attempt.Failure(Err(s"SquadMemberEvent can not encode with this pattern - $data"))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,10 +18,14 @@ object SquadResponse {
|
|||
final case class Unknown17(squad : Squad, char_id : Long) extends Response
|
||||
final case class Membership(request_type : SquadResponseType.Value, unk1 : Int, unk2 : Int, unk3 : Long, unk4 : Option[Long], player_name : String, unk5 : Boolean, unk6 : Option[Option[String]]) extends Response //see SquadMembershipResponse
|
||||
final case class Invite(from_char_id : Long, to_char_id : Long, name : String) extends Response
|
||||
final case class WantsSquadPosition(bid_name : String) extends Response
|
||||
final case class Join(squad : Squad, positionsToUpdate : List[Int]) extends Response
|
||||
final case class Leave(squad : Squad, positionsToUpdate : List[(Long, Int)]) extends Response
|
||||
final case class UpdateMembers(squad : Squad, update_info : List[SquadAction.Update]) extends Response
|
||||
final case class AssignMember(squad : Squad, from_index : Int, to_index : Int) extends Response
|
||||
final case class PromoteMember(squad : Squad, char_id : Long, from_index : Int, to_index : Int) extends Response
|
||||
|
||||
final case class Detail(guid : PlanetSideGUID, squad_detail : SquadDetail) extends Response
|
||||
|
||||
final case class SquadSearchResults() extends Response
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,13 +22,14 @@ class SquadService extends Actor {
|
|||
private var memberToSquad : mutable.LongMap[Squad] = mutable.LongMap[Squad]()
|
||||
private var idToSquad : TrieMap[PlanetSideGUID, Squad] = new TrieMap[PlanetSideGUID, Squad]()
|
||||
private var idToSwitchboard : TrieMap[PlanetSideGUID, ActorRef] = new TrieMap[PlanetSideGUID, ActorRef]()
|
||||
private var i : Int = 1
|
||||
private var sid : Int = 1
|
||||
private val publishedLists : TrieMap[PlanetSideEmpire.Value, ListBuffer[SquadInfo]] = TrieMap[PlanetSideEmpire.Value, ListBuffer[SquadInfo]](
|
||||
PlanetSideEmpire.TR -> ListBuffer.empty,
|
||||
PlanetSideEmpire.NC -> ListBuffer.empty,
|
||||
PlanetSideEmpire.VS -> ListBuffer.empty
|
||||
)
|
||||
private val bids : mutable.LongMap[PositionBid] = mutable.LongMap[PositionBid]()
|
||||
private val invites : mutable.LongMap[Invitation] = mutable.LongMap[Invitation]()
|
||||
private val queuedInvites : mutable.LongMap[List[Invitation]] = mutable.LongMap[List[Invitation]]()
|
||||
private val viewDetails : mutable.LongMap[PlanetSideGUID] = mutable.LongMap[PlanetSideGUID]()
|
||||
|
||||
private [this] val log = org.log4s.getLogger
|
||||
|
|
@ -36,56 +37,70 @@ class SquadService extends Actor {
|
|||
override def preStart : Unit = {
|
||||
log.info("Starting...")
|
||||
|
||||
val testSquad = new Squad(PlanetSideGUID(3), PlanetSideEmpire.VS)
|
||||
testSquad.Task = "\\#66CCFF Sentinels of Auraxis\\#FFFFFF ... \\#40FF40 Squad Up!!"
|
||||
testSquad.ZoneId = 5
|
||||
testSquad.Membership(0).Name = "Wizkid45"
|
||||
testSquad.Membership(0).Role = "Fearless Leader"
|
||||
testSquad.Membership(0).CharId = 30910985L
|
||||
testSquad.Membership(0).ZoneId = 5
|
||||
testSquad.Membership(0).Health = 64
|
||||
testSquad.Membership(0).Armor = 34
|
||||
testSquad.Membership(0).Position = Vector3(5526.5234f, 3818.7344f, 54.59375f)
|
||||
testSquad.Membership(1).Name = "xoBLADEox"
|
||||
testSquad.Membership(1).Role = "Right Hand"
|
||||
testSquad.Membership(1).CharId = 42781919L
|
||||
testSquad.Membership(1).ZoneId = 5
|
||||
testSquad.Membership(1).Health = 54
|
||||
testSquad.Membership(1).Armor = 44
|
||||
testSquad.Membership(1).Position = Vector3(4673.5312f, 2604.8047f, 40.015625f)
|
||||
testSquad.Membership(3).Name = "cabal0428"
|
||||
testSquad.Membership(3).Role = "Left Hand"
|
||||
testSquad.Membership(3).CharId = 353380L
|
||||
testSquad.Membership(3).ZoneId = 5
|
||||
testSquad.Membership(3).Health = 44
|
||||
testSquad.Membership(3).Armor = 54
|
||||
testSquad.Membership(3).Position = Vector3(4727.492f, 2613.5312f, 51.390625f)
|
||||
testSquad.Membership(4).Name = "xSkiku"
|
||||
testSquad.Membership(4).Role = "Right Foot's Middle Toe's Nail"
|
||||
testSquad.Membership(4).CharId = 41588340L
|
||||
testSquad.Membership(4).ZoneId = 5
|
||||
testSquad.Membership(4).Health = 34
|
||||
testSquad.Membership(4).Armor = 64
|
||||
testSquad.Membership(4).Position = Vector3(3675.0f, 4789.8047f, 63.21875f)
|
||||
idToSquad(PlanetSideGUID(3)) = testSquad
|
||||
testSquad.Listed = true
|
||||
UpdateSquadList(testSquad, None)
|
||||
// val testSquad = new Squad(PlanetSideGUID(3), PlanetSideEmpire.VS)
|
||||
// testSquad.Task = "\\#66CCFF Sentinels of Auraxis\\#FFFFFF ... \\#40FF40 Squad Up!!"
|
||||
// testSquad.ZoneId = 5
|
||||
// testSquad.Membership(0).Name = "Wizkid45"
|
||||
// testSquad.Membership(0).Role = "Fearless Leader"
|
||||
// testSquad.Membership(0).CharId = 30910985L
|
||||
// testSquad.Membership(0).ZoneId = 5
|
||||
// testSquad.Membership(0).Health = 64
|
||||
// testSquad.Membership(0).Armor = 34
|
||||
// testSquad.Membership(0).Position = Vector3(5526.5234f, 3818.7344f, 54.59375f)
|
||||
// testSquad.Membership(1).Name = "xoBLADEox"
|
||||
// testSquad.Membership(1).Role = "Right Hand"
|
||||
// testSquad.Membership(1).CharId = 42781919L
|
||||
// testSquad.Membership(1).ZoneId = 5
|
||||
// testSquad.Membership(1).Health = 54
|
||||
// testSquad.Membership(1).Armor = 44
|
||||
// testSquad.Membership(1).Position = Vector3(4673.5312f, 2604.8047f, 40.015625f)
|
||||
// testSquad.Membership(3).Name = "cabal0428"
|
||||
// testSquad.Membership(3).Role = "Left Hand"
|
||||
// testSquad.Membership(3).CharId = 353380L
|
||||
// testSquad.Membership(3).ZoneId = 5
|
||||
// testSquad.Membership(3).Health = 44
|
||||
// testSquad.Membership(3).Armor = 54
|
||||
// testSquad.Membership(3).Position = Vector3(4727.492f, 2613.5312f, 51.390625f)
|
||||
// testSquad.Membership(4).Name = "xSkiku"
|
||||
// testSquad.Membership(4).Role = "Right Foot's Middle Toe's Nail"
|
||||
// testSquad.Membership(4).CharId = 41588340L
|
||||
// testSquad.Membership(4).ZoneId = 5
|
||||
// testSquad.Membership(4).Health = 34
|
||||
// testSquad.Membership(4).Armor = 64
|
||||
// testSquad.Membership(4).Position = Vector3(3675.0f, 4789.8047f, 63.21875f)
|
||||
// idToSquad(PlanetSideGUID(3)) = testSquad
|
||||
// testSquad.Listed = true
|
||||
// UpdateSquadList(testSquad, None)
|
||||
}
|
||||
|
||||
def GetNextSquadId() : PlanetSideGUID = {
|
||||
val out = i
|
||||
val j = i + 1
|
||||
val out = sid
|
||||
val j = sid + 1
|
||||
if(j == 65536) {
|
||||
i = 1
|
||||
sid = 1
|
||||
}
|
||||
else {
|
||||
i = j
|
||||
sid = j
|
||||
}
|
||||
PlanetSideGUID(out)
|
||||
}
|
||||
|
||||
def TryResetSquadId() : Boolean = {
|
||||
if(idToSquad.isEmpty) {
|
||||
sid = 1
|
||||
true
|
||||
}
|
||||
else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
def GetParticipatingSquad(player : Player) : Option[Squad] = {
|
||||
memberToSquad.get(player.CharId) match {
|
||||
GetParticipatingSquad(player.CharId)
|
||||
}
|
||||
|
||||
def GetParticipatingSquad(charId : Long) : Option[Squad] = {
|
||||
memberToSquad.get(charId) match {
|
||||
case opt @ Some(_) =>
|
||||
opt
|
||||
case None =>
|
||||
|
|
@ -114,24 +129,49 @@ class SquadService extends Actor {
|
|||
}
|
||||
}
|
||||
|
||||
def StartSquad(player : Player) : Squad = {
|
||||
def GetLeadingSquad(charId : Long, opt : Option[Squad]) : Option[Squad] = {
|
||||
opt.orElse(memberToSquad.get(charId)) match {
|
||||
case Some(squad) =>
|
||||
if(squad.Leader.CharId == charId) {
|
||||
Some(squad)
|
||||
}
|
||||
else {
|
||||
None
|
||||
}
|
||||
case _ =>
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
def CreateSquad(player : Player) : Squad = {
|
||||
val charId = player.CharId
|
||||
val faction = player.Faction
|
||||
val id = GetNextSquadId()
|
||||
val name = player.Name
|
||||
val squad = new Squad(id, faction)
|
||||
val squad = new Squad(GetNextSquadId(), faction)
|
||||
val leadPosition = squad.Membership(squad.LeaderPositionIndex)
|
||||
leadPosition.Name = name
|
||||
leadPosition.CharId = charId
|
||||
leadPosition.CharId = player.CharId
|
||||
leadPosition.Health = player.Health
|
||||
leadPosition.Armor = player.Armor
|
||||
leadPosition.Position = player.Position
|
||||
leadPosition.ZoneId = 1
|
||||
log.info(s"$name-$faction has started a new squad")
|
||||
squad
|
||||
}
|
||||
|
||||
def StartSquad(squad : Squad) : Squad = {
|
||||
val charId = squad.Leader.CharId
|
||||
val id = squad.GUID
|
||||
val switchboard = context.actorOf(Props[SquadSwitchboard], s"squad${id.guid}")
|
||||
memberToSquad += charId -> squad
|
||||
idToSquad += id -> squad
|
||||
idToSwitchboard += id -> switchboard
|
||||
log.info(s"$name-$faction has started a new squad")
|
||||
squad
|
||||
}
|
||||
|
||||
def StartSquad(player : Player) : Squad = {
|
||||
val squad = CreateSquad(player)
|
||||
StartSquad(squad)
|
||||
squad
|
||||
}
|
||||
|
||||
|
|
@ -199,137 +239,253 @@ class SquadService extends Actor {
|
|||
case Service.Leave(None) | Service.LeaveAll() => ;
|
||||
|
||||
case SquadServiceMessage(tplayer, squad_action) => squad_action match {
|
||||
case SquadAction.Membership(request_type, char_id, optional_char_id, _, _) => request_type match {
|
||||
case SquadRequestType.Invite =>
|
||||
//char_id is the inviter, e.g., the (prospective) squad leader
|
||||
//this is just busy work; for actual joining operations, see SquadRequestType.Accept
|
||||
(optional_char_id, memberToSquad.get(char_id)) match {
|
||||
case (Some(invitee), Some(squad)) =>
|
||||
bids(invitee) = VacancyBid(char_id, squad.GUID)
|
||||
log.info(s"$invitee has been invited to squad ${squad.Task} by $char_id")
|
||||
SquadEvents.publish( SquadServiceResponse(s"/$invitee/Squad", SquadResponse.Membership(SquadResponseType.Invite, 0, 0, char_id, Some(invitee), tplayer.Name, false, Some(None))) )
|
||||
SquadEvents.publish( SquadServiceResponse(s"/$char_id/Squad", SquadResponse.Membership(SquadResponseType.Invite, 0, 0, invitee, Some(char_id), tplayer.Name, true, Some(None))) )
|
||||
case (Some(invitee), None) =>
|
||||
//the inviter does not currently belong to a squad; check for an existing placeholder, or create a new one
|
||||
val ourSquad = {
|
||||
bids.find { case (inviter, _) => inviter == char_id } match {
|
||||
case Some((_, SpontaneousBid(_, _squad))) =>
|
||||
_squad //borrow
|
||||
case _ =>
|
||||
val _squad = StartSquad(tplayer)
|
||||
memberToSquad.remove(char_id) //completely unlist until assured the squad is necessary
|
||||
_squad
|
||||
}
|
||||
}
|
||||
bids(invitee) = SpontaneousBid(char_id, ourSquad)
|
||||
SquadEvents.publish( SquadServiceResponse(s"/$invitee/Squad", SquadResponse.Membership(SquadResponseType.Invite, 0, 0, char_id, Some(invitee), tplayer.Name, false, Some(None))) )
|
||||
SquadEvents.publish( SquadServiceResponse(s"/$char_id/Squad", SquadResponse.Membership(SquadResponseType.Invite, 0, 0, invitee, Some(char_id), tplayer.Name, true, Some(None))) )
|
||||
case _ => ;
|
||||
}
|
||||
case SquadAction.Membership(SquadRequestType.Invite, invitingPlayer, Some(invitedPlayer), _, _) =>
|
||||
//this is just busy work; for actual joining operations, see SquadRequestType.Accept
|
||||
// FindBid(invitingPlayer, invitedPlayer) match {
|
||||
// case Some(bid) =>
|
||||
// //invitingPlayer and invitedPlayer have both tried to join each others's squads
|
||||
// //treat this junction as consent
|
||||
// self ! SquadServiceMessage(tplayer, SquadAction.Membership(SquadRequestType.Accept, invitingPlayer, Some(invitedPlayer), "", None))
|
||||
// case _ => ;
|
||||
// }
|
||||
(memberToSquad.get(invitingPlayer), memberToSquad.get(invitedPlayer)) match {
|
||||
case (Some(squad1), Some(squad2)) =>
|
||||
//both players are in squads
|
||||
if(squad1.GUID == squad2.GUID) {
|
||||
//both players are in the same squad; no need to do anything
|
||||
}
|
||||
else {
|
||||
//we might do some platoon chicanery with this case later
|
||||
//TODO platoons
|
||||
}
|
||||
|
||||
case SquadRequestType.Accept =>
|
||||
//char_id is the invitee, e.g., the person joining the squad
|
||||
bids.remove(char_id) match {
|
||||
case Some(NormalBid(_/*inviterCharId*/, squadGUID, line)) if idToSquad.get(squadGUID).nonEmpty =>
|
||||
//player requested to join a squad's specific position
|
||||
JoinSquad(tplayer, idToSquad(squadGUID), line)
|
||||
case (Some(squad), None) =>
|
||||
//the classic situation
|
||||
log.info(s"$invitedPlayer has been invited to squad ${squad.Task} by $invitingPlayer")
|
||||
val leader = squad.Leader
|
||||
val leaderCharId = leader.CharId
|
||||
val bid = VacancyInvite(leaderCharId, leader.Name, squad.GUID)
|
||||
AddInvite(invitedPlayer, bid) match {
|
||||
case out @ Some(_) if out.contains(bid) =>
|
||||
SquadEvents.publish(SquadServiceResponse(s"/$invitedPlayer/Squad", SquadResponse.Membership(SquadResponseType.Invite, 0, 0, leaderCharId, Some(invitedPlayer), tplayer.Name, false, Some(None))))
|
||||
SquadEvents.publish(SquadServiceResponse(s"/$leaderCharId/Squad", SquadResponse.Membership(SquadResponseType.Invite, 0, 0, invitedPlayer, Some(leaderCharId), tplayer.Name, true, Some(None))))
|
||||
case Some(_) =>
|
||||
SquadEvents.publish(SquadServiceResponse(s"/$leaderCharId/Squad", SquadResponse.Membership(SquadResponseType.Invite, 0, 0, invitedPlayer, Some(leaderCharId), tplayer.Name, true, Some(None))))
|
||||
case _ => ;
|
||||
}
|
||||
|
||||
case Some(VacancyBid(inviterCharId, squadGUID)) if idToSquad.get(squadGUID).nonEmpty =>
|
||||
//we were invited by the squad leader into an existing squad
|
||||
val squad = idToSquad(squadGUID)
|
||||
case (None, Some(squad)) =>
|
||||
//flip around the roles - the inviting becomes the invited
|
||||
//TODO needs work
|
||||
log.info(s"$invitedPlayer has asked $invitingPlayer for an invition to squad ${squad.Task}")
|
||||
val bid = VacancyInvite(invitedPlayer, "", squad.GUID)
|
||||
AddInvite(invitingPlayer, bid) match {
|
||||
case out @ Some(_) if out.contains(bid) =>
|
||||
SquadEvents.publish(SquadServiceResponse(s"/$invitingPlayer/Squad", SquadResponse.Membership(SquadResponseType.Invite, 0, 0, invitedPlayer, Some(invitingPlayer), tplayer.Name, false, Some(None))))
|
||||
SquadEvents.publish(SquadServiceResponse(s"/$invitedPlayer/Squad", SquadResponse.Membership(SquadResponseType.Invite, 0, 0, invitingPlayer, Some(invitedPlayer), tplayer.Name, true, Some(None))))
|
||||
case Some(_) =>
|
||||
SquadEvents.publish(SquadServiceResponse(s"/$invitedPlayer/Squad", SquadResponse.Membership(SquadResponseType.Invite, 0, 0, invitingPlayer, Some(invitedPlayer), tplayer.Name, true, Some(None))))
|
||||
case _ => ;
|
||||
}
|
||||
|
||||
case (None, None) =>
|
||||
//neither the invited player nor the inviting player belong to any squad
|
||||
log.info(s"$invitedPlayer has been invited to join $invitingPlayer's spontaneous squad")
|
||||
val bid = SpontaneousInvite(tplayer)
|
||||
AddInvite(invitedPlayer, bid) match {
|
||||
case out @ Some(_) if out.contains(bid) =>
|
||||
SquadEvents.publish(SquadServiceResponse(s"/$invitedPlayer/Squad", SquadResponse.Membership(SquadResponseType.Invite, 0, 0, invitingPlayer, Some(invitedPlayer), tplayer.Name, false, Some(None))))
|
||||
SquadEvents.publish(SquadServiceResponse(s"/$invitingPlayer/Squad", SquadResponse.Membership(SquadResponseType.Invite, 0, 0, invitedPlayer, Some(invitingPlayer), tplayer.Name, true, Some(None))))
|
||||
case Some(_) =>
|
||||
SquadEvents.publish(SquadServiceResponse(s"/$invitingPlayer/Squad", SquadResponse.Membership(SquadResponseType.Invite, 0, 0, invitedPlayer, Some(invitingPlayer), tplayer.Name, true, Some(None))))
|
||||
case _ => ;
|
||||
}
|
||||
|
||||
case _ => ;
|
||||
}
|
||||
|
||||
case SquadAction.Membership(SquadRequestType.Accept, invitedPlayer, _, _, _) =>
|
||||
val acceptedInvite = RemoveInvite(invitedPlayer)
|
||||
acceptedInvite match {
|
||||
case Some(BidForPosition(petitioner, guid, position)) if idToSquad.get(guid).nonEmpty =>
|
||||
//player requested to join a squad's specific position
|
||||
//invitedPlayer is actually the squad leader; petitioner is the actual "invitedPlayer"
|
||||
if(memberToSquad.get(petitioner.CharId).isEmpty) {
|
||||
JoinSquad(petitioner, idToSquad(guid), position)
|
||||
}
|
||||
else {
|
||||
log.warn("Accept -> Bid: the invited player is already a member of a squad and can not join a second one")
|
||||
}
|
||||
|
||||
case Some(VacancyInvite(invitingPlayer, _, guid))
|
||||
if idToSquad.get(guid).nonEmpty =>
|
||||
//we were invited by the squad leader into an existing squad
|
||||
if(memberToSquad.get(invitedPlayer).isEmpty) {
|
||||
val squad = idToSquad(guid)
|
||||
squad.Membership.zipWithIndex.find({ case (member, index) =>
|
||||
ValidOpenSquadPosition(squad, index, member, tplayer.Certifications)
|
||||
}) match {
|
||||
case Some((_, line)) =>
|
||||
SquadEvents.publish( SquadServiceResponse(s"/$inviterCharId/Squad", SquadResponse.Membership(SquadResponseType.Accept, 0, 0, inviterCharId, Some(char_id), tplayer.Name, false, Some(None))) )
|
||||
SquadEvents.publish( SquadServiceResponse(s"/$char_id/Squad", SquadResponse.Membership(SquadResponseType.Accept, 0, 0, char_id, Some(inviterCharId), "", true, Some(None))) )
|
||||
SquadEvents.publish(SquadServiceResponse(s"/$invitingPlayer/Squad", SquadResponse.Membership(SquadResponseType.Accept, 0, 0, invitingPlayer, Some(invitedPlayer), tplayer.Name, false, Some(None))))
|
||||
SquadEvents.publish(SquadServiceResponse(s"/$invitedPlayer/Squad", SquadResponse.Membership(SquadResponseType.Accept, 0, 0, invitedPlayer, Some(invitingPlayer), "", true, Some(None))))
|
||||
JoinSquad(tplayer, squad, line)
|
||||
RemoveQueuedInvites(invitedPlayer) //TODO deal with these somehow
|
||||
case _ => ;
|
||||
}
|
||||
}
|
||||
else {
|
||||
log.warn("Accept -> Invite: the invited player is already a member of a squad and can not join a second one")
|
||||
}
|
||||
|
||||
case Some(SpontaneousBid(inviterCharId, placeholderSquad)) =>
|
||||
//we were invited by someone into a new squad they would form
|
||||
(GetParticipatingSquad(tplayer) match {
|
||||
case Some(participating) =>
|
||||
if(participating.Leader.CharId == inviterCharId) {
|
||||
Some(participating)
|
||||
case Some(SpontaneousInvite(invitingPlayer)) =>
|
||||
//we were invited by someone into a new squad they would form
|
||||
val invitingPlayerCharId = invitingPlayer.CharId
|
||||
(GetParticipatingSquad(invitingPlayer) match {
|
||||
case Some(participating) =>
|
||||
if(participating.Leader.CharId == invitingPlayerCharId) {
|
||||
Some(participating)
|
||||
}
|
||||
else {
|
||||
//inviter joined a squad and is not its leader; bounce this request off of the squad leader
|
||||
participating.Membership.zipWithIndex.find({ case (member, index) =>
|
||||
ValidOpenSquadPosition(participating, index, member, tplayer.Certifications)
|
||||
}) match {
|
||||
case Some((_, line)) =>
|
||||
val bid = BidForPosition(tplayer, participating.GUID, line)
|
||||
AddInvite(participating.Leader.CharId, bid) match {
|
||||
case out @ Some(_) if out.contains(bid) =>
|
||||
HandleBidForPosition(bid, tplayer)
|
||||
case _ => ;
|
||||
}
|
||||
case _ => ;
|
||||
}
|
||||
else {
|
||||
//inviter joined a squad and is not its leader; bounce this request off of the squad leader
|
||||
//TODO squad leader receives "<player> wants to join squad" prompt
|
||||
val leaderCharId = participating.Leader.CharId
|
||||
bids(char_id) = VacancyBid(leaderCharId, participating.GUID) //reframed request
|
||||
SquadEvents.publish(SquadServiceResponse(s"/$leaderCharId/Squad", SquadResponse.Invite(char_id, leaderCharId, tplayer.Name)))
|
||||
None
|
||||
}
|
||||
case None =>
|
||||
placeholderSquad.Task = s"${tplayer.Name}'s Squad"
|
||||
memberToSquad(inviterCharId) = placeholderSquad
|
||||
SquadEvents.publish(SquadServiceResponse(s"/$inviterCharId/Squad", SquadResponse.InitSquad(placeholderSquad.GUID)))
|
||||
Some(placeholderSquad)
|
||||
}) match {
|
||||
None
|
||||
}
|
||||
case None =>
|
||||
val squad = StartSquad(invitingPlayer)
|
||||
squad.Task = s"${tplayer.Name}'s Squad"
|
||||
SquadEvents.publish(SquadServiceResponse(s"/$invitingPlayer/Squad", SquadResponse.InitSquad(squad.GUID)))
|
||||
Some(squad)
|
||||
}) match {
|
||||
case Some(squad) =>
|
||||
squad.Membership.zipWithIndex.find({ case (member, index) =>
|
||||
ValidOpenSquadPosition(squad, index, member, tplayer.Certifications)
|
||||
}) match {
|
||||
case Some((_, line)) =>
|
||||
SquadEvents.publish( SquadServiceResponse(s"/$inviterCharId/Squad", SquadResponse.Membership(SquadResponseType.Accept, 0, 0, inviterCharId, Some(char_id), tplayer.Name, false, Some(None))) )
|
||||
SquadEvents.publish( SquadServiceResponse(s"/$char_id/Squad", SquadResponse.Membership(SquadResponseType.Accept, 0, 0, char_id, Some(inviterCharId), "", true, Some(None))) )
|
||||
SquadEvents.publish( SquadServiceResponse(s"/$invitedPlayer/Squad", SquadResponse.Membership(SquadResponseType.Accept, 0, 0, invitedPlayer, Some(invitingPlayerCharId), "", true, Some(None))) )
|
||||
JoinSquad(tplayer, squad, line)
|
||||
SquadEvents.publish( SquadServiceResponse(s"/$invitingPlayerCharId/Squad", SquadResponse.Membership(SquadResponseType.Accept, 0, 0, invitingPlayerCharId, Some(invitedPlayer), tplayer.Name, false, Some(None))) )
|
||||
RemoveQueuedInvites(invitedPlayer) //TODO deal with these somehow
|
||||
case _ => ;
|
||||
}
|
||||
case None => ;
|
||||
}
|
||||
|
||||
case _ => ;
|
||||
}
|
||||
|
||||
case SquadRequestType.Leave =>
|
||||
//char_id is the player leaving
|
||||
val squad = memberToSquad(char_id)
|
||||
val leader = squad.Leader.CharId
|
||||
if(char_id == leader) {
|
||||
//squad leader is leaving his own squad, so it will be disbanded
|
||||
squad.Membership
|
||||
.filterNot { _.CharId == leader }
|
||||
.foreach { member =>
|
||||
val charId = member.CharId
|
||||
SquadEvents.publish(SquadServiceResponse(s"/$charId/Squad", SquadResponse.Membership(SquadResponseType.Disband, 0, 0, charId, None, "", false, Some(None))))
|
||||
}
|
||||
CloseOutSquad(squad)
|
||||
SquadEvents.publish(SquadServiceResponse(s"/$leader/Squad", SquadResponse.Membership(SquadResponseType.Disband, 0, 0, leader, None, "", true, Some(None))))
|
||||
}
|
||||
else {
|
||||
if(optional_char_id.contains(char_id)) {
|
||||
//leaving the squad of our own accord
|
||||
LeaveSquad(tplayer, squad)
|
||||
}
|
||||
else if(optional_char_id.contains(leader)) {
|
||||
//kicked by the squad leader
|
||||
SquadEvents.publish( SquadServiceResponse(s"/$char_id/Squad", SquadResponse.Membership(SquadResponseType.Leave, 0, 0, char_id, Some(leader), tplayer.Name, false, Some(None))) )
|
||||
SquadEvents.publish( SquadServiceResponse(s"/$leader/Squad", SquadResponse.Membership(SquadResponseType.Leave, 0, 0, leader, Some(char_id), "", true, Some(None))) )
|
||||
LeaveSquad(tplayer, squad)
|
||||
|
||||
case None =>
|
||||
//the invite either timed-out or was withdrawn; select a new one?
|
||||
NextInvite(invitedPlayer) match {
|
||||
case Some(bid : BidForPosition) if !acceptedInvite.contains(bid) =>
|
||||
HandleBidForPosition(bid, tplayer)
|
||||
case Some(bid) if !acceptedInvite.contains(bid) =>
|
||||
SquadEvents.publish(SquadServiceResponse(s"/$invitedPlayer/Squad", SquadResponse.Membership(SquadResponseType.Invite, 0, 0, bid.InviterCharId, Some(invitedPlayer), bid.InviterName, false, Some(None))))
|
||||
case None => ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case SquadRequestType.Reject =>
|
||||
//a player has opted out of joining a squad
|
||||
(bids.remove(char_id) match {
|
||||
case Some(SpontaneousBid(inviterCharId, squad)) if squad.Leader.CharId != char_id =>
|
||||
(inviterCharId, squad)
|
||||
case Some(VacancyBid(inviterCharId, guid)) if idToSquad(guid).Leader.CharId != char_id =>
|
||||
(inviterCharId, idToSquad.get(guid))
|
||||
case _ => ;
|
||||
(0L, None)
|
||||
}) match {
|
||||
case (inviterCharId, Some(squad)) =>
|
||||
SquadEvents.publish( SquadServiceResponse(s"/$inviterCharId/Squad", SquadResponse.Membership(SquadResponseType.Reject, 0, 0, inviterCharId, Some(char_id), tplayer.Name, false, Some(None))) )
|
||||
SquadEvents.publish( SquadServiceResponse(s"/$char_id/Squad", SquadResponse.Membership(SquadResponseType.Reject, 0, 0, char_id, Some(inviterCharId), "", true, Some(None))) )
|
||||
case _ => ;
|
||||
case SquadAction.Membership(SquadRequestType.Leave, leavingPlayer, optionalPlayer, _, _) =>
|
||||
val squad = memberToSquad(leavingPlayer)
|
||||
val leader = squad.Leader.CharId
|
||||
if(leavingPlayer == leader || squad.Size == 2) {
|
||||
//squad leader is leaving his own squad, so it will be disbanded
|
||||
//alternately, squad is only composed of two people, so it will be closed-out when one of them leaves
|
||||
val membership = squad.Membership.collect { case member if member.CharId > 0 => member.CharId }
|
||||
membership.foreach { charId =>
|
||||
SquadEvents.publish(SquadServiceResponse(s"/$charId/Squad", SquadResponse.Membership(SquadResponseType.Leave, 0, 0, charId, None, "", false, Some(None))))
|
||||
}
|
||||
CloseOutSquad(squad)
|
||||
SquadEvents.publish(SquadServiceResponse(s"/$leader/Squad", SquadResponse.Membership(SquadResponseType.Disband, 0, 0, leader, None, "", true, Some(None))))
|
||||
membership
|
||||
.filterNot(_ == leader)
|
||||
.foreach { charId =>
|
||||
SquadEvents.publish(SquadServiceResponse(s"/$charId/Squad", SquadResponse.Membership(SquadResponseType.Disband, 0, 0, charId, None, "", false, Some(None))))
|
||||
}
|
||||
SquadEvents.publish( SquadServiceResponse(s"/$leader/Squad", SquadResponse.InitSquad(PlanetSideGUID(0))) )
|
||||
SquadEvents.publish( SquadServiceResponse(s"/$leader/Squad", SquadResponse.Detail(PlanetSideGUID(0), SquadDetail().Complete)) )
|
||||
}
|
||||
else {
|
||||
if(optionalPlayer.contains(leavingPlayer)) {
|
||||
//leaving the squad of own accord
|
||||
LeaveSquad(tplayer, squad)
|
||||
}
|
||||
else if(optionalPlayer.contains(leader)) {
|
||||
//kicked by the squad leader
|
||||
SquadEvents.publish( SquadServiceResponse(s"/$leavingPlayer/Squad", SquadResponse.Membership(SquadResponseType.Leave, 0, 0, leavingPlayer, Some(leader), tplayer.Name, false, Some(None))) )
|
||||
SquadEvents.publish( SquadServiceResponse(s"/$leader/Squad", SquadResponse.Membership(SquadResponseType.Leave, 0, 0, leader, Some(leavingPlayer), "", true, Some(None))) )
|
||||
LeaveSquad(tplayer, squad)
|
||||
}
|
||||
}
|
||||
|
||||
case _ => ;
|
||||
}
|
||||
case SquadAction.Membership(SquadRequestType.Reject, rejectingPlayer, optionalPlayer, _, _) =>
|
||||
val rejectedBid = RemoveInvite(rejectingPlayer)
|
||||
//(A, B) -> person who made the rejection, person who was rejected
|
||||
(rejectedBid match {
|
||||
case Some(SpontaneousInvite(invitingPlayer)) =>
|
||||
//rejectingPlayer is the would-be squad member
|
||||
(Some(rejectingPlayer), Some(invitingPlayer.CharId))
|
||||
case Some(VacancyInvite(invitingPlayer, _, guid)) if idToSquad(guid).Leader.CharId != rejectingPlayer =>
|
||||
//rejectingPlayer is the would-be squad member
|
||||
(Some(rejectingPlayer), Some(invitingPlayer))
|
||||
case Some(BidForPosition(_, guid, _)) if idToSquad(guid).Leader.CharId != rejectingPlayer =>
|
||||
//rejectingPlayer is the squad leader
|
||||
(Some(rejectingPlayer), None)
|
||||
case _ => ;
|
||||
(None, None)
|
||||
}) match {
|
||||
case (Some(rejected), Some(invited)) =>
|
||||
SquadEvents.publish( SquadServiceResponse(s"/$rejected/Squad", SquadResponse.Membership(SquadResponseType.Reject, 0, 0, rejected, Some(invited), "", true, Some(None))) )
|
||||
SquadEvents.publish( SquadServiceResponse(s"/$invited/Squad", SquadResponse.Membership(SquadResponseType.Reject, 0, 0, invited, Some(rejected), tplayer.Name, false, Some(None))) )
|
||||
case (Some(rejected), None) =>
|
||||
SquadEvents.publish( SquadServiceResponse(s"/$rejected/Squad", SquadResponse.Membership(SquadResponseType.Reject, 0, 0, rejected, Some(rejected), "", true, Some(None))) )
|
||||
case _ => ;
|
||||
}
|
||||
NextInvite(rejectingPlayer) match {
|
||||
case Some(bid : BidForPosition) if rejectedBid.isEmpty || !rejectedBid.contains(bid) =>
|
||||
HandleBidForPosition(bid, tplayer)
|
||||
case Some(bid) if rejectedBid.isEmpty || !rejectedBid.contains(bid) =>
|
||||
SquadEvents.publish(SquadServiceResponse(s"/$rejectingPlayer/Squad", SquadResponse.Membership(SquadResponseType.Invite, 0, 0, bid.InviterCharId, Some(rejectingPlayer), bid.InviterName, false, Some(None))))
|
||||
case None => ;
|
||||
}
|
||||
|
||||
case SquadAction.Membership(SquadRequestType.Promote, promotingPlayer, Some(promotedPlayer), _, _) =>
|
||||
(memberToSquad.get(promotingPlayer), memberToSquad.get(promotedPlayer)) match {
|
||||
case (Some(squad), Some(squad2)) if squad.GUID == squad2.GUID && squad.Leader.CharId == promotingPlayer =>
|
||||
val membership = squad.Membership.filter { _member => _member.CharId > 0 }
|
||||
val (leader, position) = (squad.Leader, 0)
|
||||
val (member, index) = membership.zipWithIndex.find { case (_member, _) => _member.CharId == promotedPlayer }.get
|
||||
SwapMemberPosition(squad, leader, member)
|
||||
log.info(s"Promoting player ${leader.Name} to be the leader of ${squad.Task}")
|
||||
membership.foreach { _member =>
|
||||
SquadEvents.publish(SquadServiceResponse(s"/${_member.CharId}/Squad", SquadResponse.PromoteMember(squad, promotedPlayer, index, position)))
|
||||
}
|
||||
SquadEvents.publish(SquadServiceResponse(s"/$promotingPlayer/Squad", SquadResponse.InitSquad(PlanetSideGUID(0))))
|
||||
SquadEvents.publish(SquadServiceResponse(s"/$promotedPlayer/Squad", SquadResponse.InitSquad(squad.GUID)))
|
||||
UpdateSquadListWhenListed(
|
||||
squad,
|
||||
SquadInfo().Leader(leader.Name)
|
||||
)
|
||||
UpdateSquadDetail(squad.GUID, squad,
|
||||
SquadDetail()
|
||||
.LeaderCharId(leader.CharId)
|
||||
.Field3(value = 0L)
|
||||
.LeaderName(leader.Name)
|
||||
.Members(List(
|
||||
SquadPositionEntry(position, SquadPositionDetail().CharId(member.CharId).Name(member.Name)),
|
||||
SquadPositionEntry(index, SquadPositionDetail().CharId(leader.CharId).Name(leader.Name))
|
||||
))
|
||||
)
|
||||
|
||||
case _ => ;
|
||||
}
|
||||
|
||||
case SquadAction.Update(char_id, health, max_health, armor, max_armor, pos, zone_number) =>
|
||||
memberToSquad.get(char_id) match {
|
||||
|
|
@ -387,14 +543,14 @@ class SquadService extends Actor {
|
|||
val squad = lSquadOpt.getOrElse(StartSquad(tplayer))
|
||||
squad.Task = purpose
|
||||
UpdateSquadListWhenListed(squad, SquadInfo().Task(purpose))
|
||||
UpdateSquadDetailWhenListed(squad.GUID, squad, SquadDetail().Task(purpose))
|
||||
UpdateSquadDetail(squad.GUID, squad, SquadDetail().Task(purpose))
|
||||
|
||||
case ChangeSquadZone(zone) =>
|
||||
log.info(s"${tplayer.Name}-${tplayer.Faction} has changed squad's ops zone to $zone")
|
||||
val squad = lSquadOpt.getOrElse(StartSquad(tplayer))
|
||||
squad.ZoneId = zone.zoneId.toInt
|
||||
UpdateSquadListWhenListed(squad, SquadInfo().ZoneId(zone))
|
||||
UpdateSquadDetailWhenListed(squad.GUID, squad, SquadDetail().ZoneId(zone))
|
||||
UpdateSquadDetail(squad.GUID, squad, SquadDetail().ZoneId(zone))
|
||||
|
||||
case CloseSquadMemberPosition(position) =>
|
||||
val squad = lSquadOpt.getOrElse(StartSquad(tplayer))
|
||||
|
|
@ -411,7 +567,7 @@ class SquadService extends Actor {
|
|||
}
|
||||
memberPosition.Close()
|
||||
UpdateSquadListWhenListed(squad, listingChanged)
|
||||
UpdateSquadDetailWhenListed(squad.GUID, squad,
|
||||
UpdateSquadDetail(squad.GUID, squad,
|
||||
SquadDetail().Members(List(SquadPositionEntry(position, SquadPositionDetail.Closed)))
|
||||
)
|
||||
case Some(false) | None => ;
|
||||
|
|
@ -424,7 +580,7 @@ class SquadService extends Actor {
|
|||
log.info(s"${tplayer.Name}-${tplayer.Faction} has opened the #$position position in squad")
|
||||
squad.Availability.update(position, true)
|
||||
UpdateSquadListWhenListed(squad, SquadInfo().Capacity(squad.Capacity))
|
||||
UpdateSquadDetailWhenListed(squad.GUID, squad,
|
||||
UpdateSquadDetail(squad.GUID, squad,
|
||||
SquadDetail().Members(List(SquadPositionEntry(position, SquadPositionDetail.Open)))
|
||||
)
|
||||
case Some(true) | None => ;
|
||||
|
|
@ -436,7 +592,7 @@ class SquadService extends Actor {
|
|||
case Some(true) =>
|
||||
log.info(s"${tplayer.Name}-${tplayer.Faction} has changed the role of squad position #$position")
|
||||
squad.Membership(position).Role = role
|
||||
UpdateSquadDetailWhenListed(squad.GUID, squad,
|
||||
UpdateSquadDetail(squad.GUID, squad,
|
||||
SquadDetail().Members(List(SquadPositionEntry(position, SquadPositionDetail().Role(role))))
|
||||
)
|
||||
case Some(false) | None => ;
|
||||
|
|
@ -448,7 +604,7 @@ class SquadService extends Actor {
|
|||
case Some(true) =>
|
||||
log.info(s"${tplayer.Name}-${tplayer.Faction} has changed the orders for squad position #$position")
|
||||
squad.Membership(position).Orders = orders
|
||||
UpdateSquadDetailWhenListed(squad.GUID, squad,
|
||||
UpdateSquadDetail(squad.GUID, squad,
|
||||
SquadDetail().Members(List(SquadPositionEntry(position, SquadPositionDetail().DetailedOrders(orders))))
|
||||
)
|
||||
case Some(false) | None => ;
|
||||
|
|
@ -460,7 +616,7 @@ class SquadService extends Actor {
|
|||
case Some(true) =>
|
||||
log.info(s"${tplayer.Name}-${tplayer.Faction} has changed the requirements for squad position #$position")
|
||||
squad.Membership(position).Requirements = certs
|
||||
UpdateSquadDetailWhenListed(squad.GUID, squad,
|
||||
UpdateSquadDetail(squad.GUID, squad,
|
||||
SquadDetail().Members(List(SquadPositionEntry(position, SquadPositionDetail().Requirements(certs))))
|
||||
)
|
||||
case Some(false) | None => ;
|
||||
|
|
@ -519,7 +675,7 @@ class SquadService extends Actor {
|
|||
squad.LocationFollowsSquadLead = false
|
||||
squad.AutoApproveInvitationRequests = false
|
||||
UpdateSquadListWhenListed(squad, SquadInfo().Task("").ZoneId(None).Capacity(squad.Capacity))
|
||||
UpdateSquadDetailWhenListed(squad.GUID, squad)
|
||||
UpdateSquadDetail(squad.GUID, squad)
|
||||
|
||||
case _ =>
|
||||
}
|
||||
|
|
@ -530,6 +686,9 @@ class SquadService extends Actor {
|
|||
log.info(s"${tplayer.Name} would like the #${position+1} spot in this squad")
|
||||
val membership = squad.Membership.zipWithIndex
|
||||
val toMember = squad.Membership(position)
|
||||
if(squad.Leader.CharId == tplayer.CharId) {
|
||||
//TODO squad leader currently disallowed
|
||||
} else
|
||||
//the squad leader may swap to any open position; a normal member has to validate against requirements
|
||||
if((squad.Leader.CharId == tplayer.CharId && toMember.CharId == 0) || ValidOpenSquadPosition(squad, position, toMember, tplayer.Certifications)) {
|
||||
membership.find { case (member, _) => member.CharId == tplayer.CharId } match {
|
||||
|
|
@ -538,12 +697,15 @@ class SquadService extends Actor {
|
|||
if(fromIndex == squad.LeaderPositionIndex) {
|
||||
squad.LeaderPositionIndex = position
|
||||
}
|
||||
//RemoveInvite(tplayer.CharId).foreach { _ =>
|
||||
//close the old bids out
|
||||
//}
|
||||
membership
|
||||
.filter { case (_member, _) => _member.CharId > 0 }
|
||||
.foreach { case (_member, _) =>
|
||||
SquadEvents.publish(SquadServiceResponse(s"/${_member.CharId}/Squad", SquadResponse.AssignMember(squad, fromIndex, position)))
|
||||
}
|
||||
UpdateSquadDetailWhenListed(squad.GUID, squad)
|
||||
UpdateSquadDetail(squad.GUID, squad)
|
||||
case _ => ;
|
||||
//somehow, this is not our squad; do nothing, for now
|
||||
}
|
||||
|
|
@ -561,10 +723,14 @@ class SquadService extends Actor {
|
|||
if(ValidOpenSquadPosition(squad, position, toMember, tplayer.Certifications)) {
|
||||
//we could join but we may need permission from the squad leader first
|
||||
log.info(s"Player ${tplayer.Name} would like to join the squad ${squad.Task}.")
|
||||
bids(tplayer.CharId) = NormalBid(squad.Leader.CharId, guid, position)
|
||||
//val leader = squad.Leader
|
||||
//TODO ask permission from the squad leader, unless auto-approve is in effect
|
||||
self ! SquadServiceMessage(tplayer, SquadAction.Membership(SquadRequestType.Accept, tplayer.CharId, None, "", None))
|
||||
val leader = squad.Leader
|
||||
val bid = BidForPosition(tplayer, guid, position)
|
||||
val leaderCharId = leader.CharId
|
||||
AddInvite(leaderCharId, bid) match {
|
||||
case out @ Some(_) if out.contains(bid) =>
|
||||
HandleBidForPosition(bid, tplayer)
|
||||
case _ => ;
|
||||
}
|
||||
}
|
||||
case None => ;
|
||||
//squad does not exist? assume old local data; force update to correct discrepancy
|
||||
|
|
@ -574,16 +740,19 @@ class SquadService extends Actor {
|
|||
case (Some(squad), AssignSquadMemberToRole(position, char_id)) =>
|
||||
val membership = squad.Membership.zipWithIndex
|
||||
(membership.find({ case (member, _) => member.CharId == char_id}), membership(position)) match {
|
||||
case (Some((fromMember, fromPosition)), (toMember, _)) =>
|
||||
//TODO squad leader currently disallowed
|
||||
case (Some((fromMember, fromPosition)), (toMember, _)) if fromPosition != 0 =>
|
||||
val name = fromMember.Name
|
||||
SwapMemberPosition(squad, toMember, fromMember)
|
||||
//
|
||||
if(fromPosition == squad.LeaderPositionIndex) {
|
||||
squad.LeaderPositionIndex = position
|
||||
}
|
||||
membership
|
||||
.filter({ case (_member, _) => _member.CharId > 0 })
|
||||
.foreach { case (_member, _) =>
|
||||
SquadEvents.publish(SquadServiceResponse(s"/${_member.CharId}/Squad", SquadResponse.AssignMember(squad, fromPosition, position)))
|
||||
}
|
||||
UpdateSquadDetailWhenListed(squad.GUID, squad,
|
||||
UpdateSquadDetail(squad.GUID, squad,
|
||||
SquadDetail().Members(List(
|
||||
SquadPositionEntry(position, SquadPositionDetail().CharId(fromMember.CharId).Name(fromMember.Name)),
|
||||
SquadPositionEntry(fromPosition, SquadPositionDetail().CharId(char_id).Name(name))
|
||||
|
|
@ -597,7 +766,15 @@ class SquadService extends Actor {
|
|||
idToSquad.get(guid) match {
|
||||
case Some(squad) =>
|
||||
viewDetails(tplayer.CharId) = guid
|
||||
sender ! SquadServiceResponse(s"/${tplayer.CharId}/Squad", SquadResponse.Detail(squad.GUID, SquadService.Detail.Publish(squad)))
|
||||
sender ! SquadServiceResponse("", SquadResponse.Detail(squad.GUID, SquadService.Detail.Publish(squad)))
|
||||
case None => ;
|
||||
}
|
||||
|
||||
//the following message is feedback from a specific client, awaiting proper initialization
|
||||
case (_, DisplayFullSquad()) =>
|
||||
idToSquad.get(guid) match {
|
||||
case Some(squad) =>
|
||||
sender ! SquadServiceResponse("", SquadResponse.InitSquad(squad.GUID))
|
||||
case None => ;
|
||||
}
|
||||
|
||||
|
|
@ -609,6 +786,122 @@ class SquadService extends Actor {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param invitedPlayer
|
||||
* @param bid
|
||||
* @return an optional invite;
|
||||
* if added to the active invite position, return the parameter bid;
|
||||
* if added to the queued invite, return the invite in the active position;
|
||||
* if not added, return `None`
|
||||
*/
|
||||
def AddInvite(invitedPlayer : Long, bid : Invitation) : Option[Invitation] = {
|
||||
invites.get(invitedPlayer) match {
|
||||
case Some(_bid) =>
|
||||
queuedInvites.get(invitedPlayer) match {
|
||||
case Some(bidList) =>
|
||||
if(_bid.InviterCharId != bid.InviterCharId && !bidList.exists { eachBid => eachBid.InviterCharId == bid.InviterCharId }) {
|
||||
log.debug(s"Invite from ${bid.InviterCharId} to $invitedPlayer stored in queue while active invite request pending")
|
||||
queuedInvites(invitedPlayer) = bid match {
|
||||
case _: BidForPosition =>
|
||||
val (normals, others) = bidList.partition(_.isInstanceOf[BidForPosition])
|
||||
(normals :+ bid) ++ others
|
||||
case _ =>
|
||||
bidList :+ bid
|
||||
}
|
||||
None
|
||||
}
|
||||
else {
|
||||
Some(_bid)
|
||||
}
|
||||
case None =>
|
||||
if(_bid.InviterCharId != bid.InviterCharId) {
|
||||
log.debug(s"Invite from ${bid.InviterCharId} to $invitedPlayer stored while active invite request pending")
|
||||
queuedInvites(invitedPlayer) = List[Invitation](bid)
|
||||
}
|
||||
Some(_bid)
|
||||
}
|
||||
|
||||
case None =>
|
||||
invites(invitedPlayer) = bid
|
||||
Some(bid)
|
||||
}
|
||||
}
|
||||
|
||||
def RemoveInvite(invitedPlayer : Long) : Option[Invitation] = {
|
||||
invites.remove(invitedPlayer)
|
||||
}
|
||||
|
||||
def RemoveQueuedInvites(invitedPlayer : Long) : List[Invitation] = {
|
||||
queuedInvites.remove(invitedPlayer) match {
|
||||
case Some(_bidList) => _bidList.toList
|
||||
case None => Nil
|
||||
}
|
||||
}
|
||||
|
||||
def RemoveInvites(invitedPlayer : Long, invitingPlayer : Long) : Unit = {
|
||||
queuedInvites.get(invitedPlayer) match {
|
||||
case Some(bidList) =>
|
||||
val list = bidList.filterNot { _.InviterCharId == invitingPlayer }
|
||||
if(list.nonEmpty) {
|
||||
queuedInvites(invitedPlayer) = list
|
||||
}
|
||||
else {
|
||||
queuedInvites.remove(invitedPlayer)
|
||||
}
|
||||
case None => ;
|
||||
}
|
||||
invites.get(invitedPlayer) match {
|
||||
case Some(_bid) =>
|
||||
if(_bid.InviterCharId == invitingPlayer) {
|
||||
//drop bid, try reload new bid
|
||||
}
|
||||
case None => ;
|
||||
}
|
||||
}
|
||||
|
||||
def NextInvite(invitedPlayer : Long) : Option[Invitation] = {
|
||||
invites.get(invitedPlayer) match {
|
||||
case None =>
|
||||
queuedInvites.get(invitedPlayer) match {
|
||||
case Some(list) =>
|
||||
list match {
|
||||
case Nil =>
|
||||
None
|
||||
case x :: Nil =>
|
||||
invites(invitedPlayer) = x
|
||||
queuedInvites.remove(invitedPlayer)
|
||||
Some(x)
|
||||
case x :: xs =>
|
||||
invites(invitedPlayer) = x
|
||||
queuedInvites(invitedPlayer) = xs
|
||||
Some(x)
|
||||
}
|
||||
|
||||
case None =>
|
||||
None
|
||||
}
|
||||
case Some(_) =>
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
def HandleBidForPosition(bid : BidForPosition, player : Player) : Unit = {
|
||||
idToSquad.get(bid.squad_guid) match {
|
||||
case Some(squad) =>
|
||||
val leaderCharId = squad.Leader.CharId
|
||||
if(squad.AutoApproveInvitationRequests) {
|
||||
self ! SquadServiceMessage(player, SquadAction.Membership(SquadRequestType.Accept, leaderCharId, None, "", None))
|
||||
}
|
||||
else {
|
||||
SquadEvents.publish(SquadServiceResponse(s"/$leaderCharId/Squad", SquadResponse.WantsSquadPosition(bid.player.Name)))
|
||||
}
|
||||
case _ =>
|
||||
//squad is missing; will this properly short-circuit?
|
||||
log.error(s"Attempted to process ${bid.InviterName}'s bid for a position in a squad (id:${bid.squad_guid.guid}) that does not exist")
|
||||
}
|
||||
}
|
||||
|
||||
def JoinSquad(player : Player, squad : Squad, line : Int) : Boolean = {
|
||||
val charId = player.CharId
|
||||
val position = squad.Membership(line)
|
||||
|
|
@ -652,7 +945,7 @@ class SquadService extends Actor {
|
|||
.foreach { member =>
|
||||
SquadEvents.publish(SquadServiceResponse(s"/${member.CharId}/Squad", SquadResponse.Join(squad, updatedIndex)))
|
||||
}
|
||||
UpdateSquadDetailWhenListed(squad.GUID, squad,
|
||||
UpdateSquadDetail(squad.GUID, squad,
|
||||
SquadDetail().Members(List(SquadPositionEntry(line, SquadPositionDetail().CharId(charId).Name(player.Name))))
|
||||
)
|
||||
}
|
||||
|
|
@ -670,30 +963,18 @@ class SquadService extends Actor {
|
|||
membership.find { case (_member, _) => _member.CharId == charId } match {
|
||||
case Some((member, index)) =>
|
||||
val updateList = membership.collect({ case (_member, _index) if _member.CharId > 0 => (_member.CharId, _index) }).toList
|
||||
//member leaves the squad completely
|
||||
memberToSquad.remove(charId)
|
||||
member.Name = ""
|
||||
member.CharId = 0
|
||||
|
||||
val size = squad.Size
|
||||
if(size < 2) {
|
||||
//squad is rendered to just one person or less; collapse it
|
||||
squad.Membership.foreach { _member =>
|
||||
SquadEvents.publish(SquadServiceResponse(s"/${_member.CharId}/Squad", SquadResponse.Membership(SquadResponseType.Disband, 0, 0, charId, None, "", false, Some(None))))
|
||||
sender ! SquadServiceResponse("", SquadResponse.Leave(squad, updateList))
|
||||
//other squad members see the member leaving
|
||||
val leavingMember = List((charId, index))
|
||||
membership
|
||||
.filter { case (_member, _) => _member.CharId > 0 }
|
||||
.foreach { case (_member, _) =>
|
||||
SquadEvents.publish( SquadServiceResponse(s"/${_member.CharId}/Squad", SquadResponse.Leave(squad, leavingMember)) )
|
||||
}
|
||||
CloseOutSquad(squad, membership, updateList)
|
||||
}
|
||||
else {
|
||||
//squad continues, despite player's parting
|
||||
//member leaves the squad completely
|
||||
sender ! SquadServiceResponse("", SquadResponse.Leave(squad, updateList))
|
||||
//other squad members see the member leaving
|
||||
val leavingMember = List((charId, index))
|
||||
membership
|
||||
.filter { case (_member, _) => _member.CharId > 0 }
|
||||
.foreach { case (_member, _) =>
|
||||
SquadEvents.publish( SquadServiceResponse(s"/${_member.CharId}/Squad", SquadResponse.Leave(squad, leavingMember)) )
|
||||
}
|
||||
}
|
||||
true
|
||||
case None =>
|
||||
false
|
||||
|
|
@ -720,6 +1001,7 @@ class SquadService extends Actor {
|
|||
SquadEvents.publish( SquadServiceResponse(s"/$charId/Squad", SquadResponse.Leave(squad, updateList)) )
|
||||
}
|
||||
idToSquad.remove(squad.GUID)
|
||||
UpdateSquadList(squad, None)
|
||||
}
|
||||
|
||||
def SwapMemberPosition(squad : Squad, toMember : Member, fromMember : Member) : Unit = {
|
||||
|
|
@ -744,6 +1026,13 @@ class SquadService extends Actor {
|
|||
toMember.Armor = armor
|
||||
}
|
||||
|
||||
def UpdateSquadList(faction : PlanetSideEmpire.Value): Unit = {
|
||||
val factionListings = publishedLists(faction)
|
||||
SquadEvents.publish(
|
||||
SquadServiceResponse(s"/$faction/Squad", SquadResponse.InitList(factionListings.toVector))
|
||||
)
|
||||
}
|
||||
|
||||
def UpdateSquadList(squad : Squad, changes : SquadInfo) : Unit = {
|
||||
UpdateSquadList(squad, Some(changes))
|
||||
}
|
||||
|
|
@ -759,7 +1048,6 @@ class SquadService extends Actor {
|
|||
}
|
||||
|
||||
def UpdateSquadList(squad : Squad, changes : Option[SquadInfo]) : Unit = {
|
||||
val entry = SquadService.SquadList.Publish(squad)
|
||||
val faction = squad.Faction
|
||||
val factionListings = publishedLists(faction)
|
||||
factionListings.find(info => {
|
||||
|
|
@ -774,7 +1062,7 @@ class SquadService extends Actor {
|
|||
case Some(changedFields) =>
|
||||
//squad information update
|
||||
log.info(s"Squad will be updated")
|
||||
factionListings(index) = entry
|
||||
factionListings(index) = SquadService.SquadList.Publish(squad)
|
||||
SquadEvents.publish(
|
||||
SquadServiceResponse(s"/$faction/Squad", SquadResponse.UpdateList(Seq((index, changedFields))))
|
||||
)
|
||||
|
|
@ -790,7 +1078,7 @@ class SquadService extends Actor {
|
|||
case None =>
|
||||
//first time being published
|
||||
log.info(s"Squad will be introduced")
|
||||
factionListings += entry
|
||||
factionListings += SquadService.SquadList.Publish(squad)
|
||||
SquadEvents.publish(
|
||||
SquadServiceResponse(s"/$faction/Squad", SquadResponse.InitList(factionListings.toVector))
|
||||
)
|
||||
|
|
@ -798,19 +1086,7 @@ class SquadService extends Actor {
|
|||
}
|
||||
|
||||
def UpdateSquadDetail(guid : PlanetSideGUID, squad : Squad) : Unit = {
|
||||
UpdateSquadDetailWhenListed(guid, squad, SquadService.Detail.Publish(squad))
|
||||
}
|
||||
|
||||
def UpdateSquadDetailWhenListed(guid : PlanetSideGUID, squad : Squad) : Unit = {
|
||||
if(squad.Listed || squad.Size > 1) {
|
||||
UpdateSquadDetail(guid, squad, SquadService.Detail.Publish(squad))
|
||||
}
|
||||
}
|
||||
|
||||
def UpdateSquadDetailWhenListed(guid : PlanetSideGUID, squad : Squad, detail : SquadDetail) : Unit = {
|
||||
if(squad.Listed || squad.Size > 1) {
|
||||
UpdateSquadDetail(guid, squad, detail)
|
||||
}
|
||||
UpdateSquadDetail(guid, squad, SquadService.Detail.Publish(squad))
|
||||
}
|
||||
|
||||
def UpdateSquadDetail(guid : PlanetSideGUID, squad : Squad, detail : SquadDetail) : Unit = {
|
||||
|
|
@ -824,13 +1100,19 @@ class SquadService extends Actor {
|
|||
}
|
||||
|
||||
object SquadService {
|
||||
trait PositionBid
|
||||
abstract class Invitation(char_id : Long, name : String) {
|
||||
def InviterCharId : Long = char_id
|
||||
def InviterName : String = name
|
||||
}
|
||||
|
||||
final case class NormalBid(char_id : Long, squad_guid : PlanetSideGUID, position : Int) extends PositionBid
|
||||
final case class BidForPosition(player : Player, squad_guid : PlanetSideGUID, position : Int)
|
||||
extends Invitation(player.CharId, player.Name)
|
||||
|
||||
final case class VacancyBid(char_id : Long, squad_guid : PlanetSideGUID) extends PositionBid
|
||||
final case class VacancyInvite(char_id : Long, name : String, squad_guid : PlanetSideGUID)
|
||||
extends Invitation(char_id, name)
|
||||
|
||||
final case class SpontaneousBid(char_id : Long, placeholder : Squad) extends PositionBid
|
||||
final case class SpontaneousInvite(player : Player)
|
||||
extends Invitation(player.CharId, player.Name)
|
||||
|
||||
object SquadList {
|
||||
def Publish(squad : Squad) : SquadInfo = {
|
||||
|
|
|
|||
|
|
@ -222,7 +222,7 @@ class SquadDefinitionActionMessageTest extends Specification {
|
|||
case SquadDefinitionActionMessage(unk1, unk2, action) =>
|
||||
unk1 mustEqual PlanetSideGUID(0)
|
||||
unk2 mustEqual 0
|
||||
action mustEqual SearchForSquadsWithParticularRole("Badass", 0L, 1, 0)
|
||||
action mustEqual SearchForSquadsWithParticularRole("Badass", Set(), 1, SearchMode.AnyPositions)
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
|
|
@ -233,7 +233,7 @@ class SquadDefinitionActionMessageTest extends Specification {
|
|||
case SquadDefinitionActionMessage(unk1, unk2, action) =>
|
||||
unk1 mustEqual PlanetSideGUID(0)
|
||||
unk2 mustEqual 0
|
||||
action mustEqual SearchForSquadsWithParticularRole("Badass", 0L, 2, 0)
|
||||
action mustEqual SearchForSquadsWithParticularRole("Badass", Set(), 2, SearchMode.AnyPositions)
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
|
|
@ -244,7 +244,7 @@ class SquadDefinitionActionMessageTest extends Specification {
|
|||
case SquadDefinitionActionMessage(unk1, unk2, action) =>
|
||||
unk1 mustEqual PlanetSideGUID(0)
|
||||
unk2 mustEqual 0
|
||||
action mustEqual SearchForSquadsWithParticularRole("Badass", 0L, 2, 1)
|
||||
action mustEqual SearchForSquadsWithParticularRole("Badass", Set(), 2, SearchMode.AvailablePositions)
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
|
|
@ -255,7 +255,7 @@ class SquadDefinitionActionMessageTest extends Specification {
|
|||
case SquadDefinitionActionMessage(unk1, unk2, action) =>
|
||||
unk1 mustEqual PlanetSideGUID(0)
|
||||
unk2 mustEqual 0
|
||||
action mustEqual SearchForSquadsWithParticularRole("Badass", 536870928L, 2, 2)
|
||||
action mustEqual SearchForSquadsWithParticularRole("Badass", Set(CertificationType.InfiltrationSuit, CertificationType.AntiVehicular), 2, SearchMode.SomeCertifications)
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
|
|
@ -266,7 +266,7 @@ class SquadDefinitionActionMessageTest extends Specification {
|
|||
case SquadDefinitionActionMessage(unk1, unk2, action) =>
|
||||
unk1 mustEqual PlanetSideGUID(0)
|
||||
unk2 mustEqual 0
|
||||
action mustEqual SearchForSquadsWithParticularRole("Badass", 536870928L, 2, 3)
|
||||
action mustEqual SearchForSquadsWithParticularRole("Badass", Set(CertificationType.InfiltrationSuit, CertificationType.AntiVehicular), 2, SearchMode.AllCertifications)
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
|
|
@ -436,35 +436,35 @@ class SquadDefinitionActionMessageTest extends Specification {
|
|||
}
|
||||
|
||||
"encode (34a)" in {
|
||||
val msg = SquadDefinitionActionMessage(PlanetSideGUID(0), 0, SearchForSquadsWithParticularRole("Badass", 0L, 1, 0))
|
||||
val msg = SquadDefinitionActionMessage(PlanetSideGUID(0), 0, SearchForSquadsWithParticularRole("Badass", Set(), 1, SearchMode.AnyPositions))
|
||||
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
|
||||
|
||||
pkt mustEqual string_34a
|
||||
}
|
||||
|
||||
"encode (34b)" in {
|
||||
val msg = SquadDefinitionActionMessage(PlanetSideGUID(0), 0, SearchForSquadsWithParticularRole("Badass", 0L, 2, 0))
|
||||
val msg = SquadDefinitionActionMessage(PlanetSideGUID(0), 0, SearchForSquadsWithParticularRole("Badass", Set(), 2, SearchMode.AnyPositions))
|
||||
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
|
||||
|
||||
pkt mustEqual string_34b
|
||||
}
|
||||
|
||||
"encode (34c)" in {
|
||||
val msg = SquadDefinitionActionMessage(PlanetSideGUID(0), 0, SearchForSquadsWithParticularRole("Badass", 0L, 2, 1))
|
||||
val msg = SquadDefinitionActionMessage(PlanetSideGUID(0), 0, SearchForSquadsWithParticularRole("Badass", Set(), 2, SearchMode.AvailablePositions))
|
||||
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
|
||||
|
||||
pkt mustEqual string_34c
|
||||
}
|
||||
|
||||
"encode (34d)" in {
|
||||
val msg = SquadDefinitionActionMessage(PlanetSideGUID(0), 0, SearchForSquadsWithParticularRole("Badass", 536870928L, 2, 2))
|
||||
val msg = SquadDefinitionActionMessage(PlanetSideGUID(0), 0, SearchForSquadsWithParticularRole("Badass", Set(CertificationType.InfiltrationSuit, CertificationType.AntiVehicular), 2, SearchMode.SomeCertifications))
|
||||
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
|
||||
|
||||
pkt mustEqual string_34d
|
||||
}
|
||||
|
||||
"encode (34e)" in {
|
||||
val msg = SquadDefinitionActionMessage(PlanetSideGUID(0), 0, SearchForSquadsWithParticularRole("Badass", 536870928L, 2, 3))
|
||||
val msg = SquadDefinitionActionMessage(PlanetSideGUID(0), 0, SearchForSquadsWithParticularRole("Badass", Set(CertificationType.InfiltrationSuit, CertificationType.AntiVehicular), 2, SearchMode.AllCertifications))
|
||||
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
|
||||
|
||||
pkt mustEqual string_34e
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ class SquadMemberEventTest extends Specification {
|
|||
"decode" in {
|
||||
PacketCoding.DecodePacket(string).require match {
|
||||
case SquadMemberEvent(u1, u2, u3, u4, u5, u6, u7) =>
|
||||
u1 mustEqual 0
|
||||
u1 mustEqual MemberEvent.Add
|
||||
u2 mustEqual 7
|
||||
u3 mustEqual 42771010L
|
||||
u4 mustEqual 0
|
||||
|
|
@ -25,7 +25,7 @@ class SquadMemberEventTest extends Specification {
|
|||
}
|
||||
|
||||
"encode" in {
|
||||
val msg = SquadMemberEvent(0, 7, 42771010L, 0, Some("HofD"), Some(7), Some(529745L))
|
||||
val msg = SquadMemberEvent(MemberEvent.Add, 7, 42771010L, 0, Some("HofD"), Some(7), Some(529745L))
|
||||
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
|
||||
pkt mustEqual string
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue