mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-07-13 15:34:42 +00:00
Squad Chat Disabled (#761)
* spin up a test server where the chat channel for squads never gets interested with * where art thou, oh, squad leader? * leave only one channel, not be left with only one channel * once again, filtering is wrong * squad list reloads after zoning; squad size is checked against squad capacity before handling standard invitations
This commit is contained in:
parent
0143f3b072
commit
51d46d86d3
5 changed files with 96 additions and 84 deletions
|
|
@ -117,7 +117,7 @@ class ChatActor(
|
||||||
|
|
||||||
case LeaveChannel(channel) =>
|
case LeaveChannel(channel) =>
|
||||||
chatService ! ChatService.LeaveChannel(chatServiceAdapter, channel)
|
chatService ! ChatService.LeaveChannel(chatServiceAdapter, channel)
|
||||||
channels = channels.filter(_ == channel)
|
channels = channels.filterNot(_ == channel)
|
||||||
Behaviors.same
|
Behaviors.same
|
||||||
|
|
||||||
case Message(message) =>
|
case Message(message) =>
|
||||||
|
|
|
||||||
|
|
@ -775,7 +775,6 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
|
||||||
None
|
None
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.toList
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -3303,6 +3302,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
|
||||||
*/
|
*/
|
||||||
def ZoneChangeSquadSetup(): Unit = {
|
def ZoneChangeSquadSetup(): Unit = {
|
||||||
RespawnSquadSetup()
|
RespawnSquadSetup()
|
||||||
|
squadService ! SquadServiceMessage(player, continent, SquadServiceAction.InitSquadList())
|
||||||
GiveSquadColorsInZone()
|
GiveSquadColorsInZone()
|
||||||
squadSetup = RespawnSquadSetup
|
squadSetup = RespawnSquadSetup
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,10 +33,11 @@ class SquadFeatures(val Squad: Squad) {
|
||||||
* <br>
|
* <br>
|
||||||
* All of the waypoints constantly exist as long as the squad to which they are attached exists.
|
* All of the waypoints constantly exist as long as the squad to which they are attached exists.
|
||||||
* They are merely "activated" and "deactivated."
|
* They are merely "activated" and "deactivated."
|
||||||
* When "activated," the waypoint knows on which continent to appear and where on the map and in the game world to be positioned.
|
* When "activated," the waypoint knows on which continent to appear
|
||||||
* Waypoints manifest in the game world as a far-off beam of light that extends into the sky
|
* and where on the map and in the game world to be positioned.
|
||||||
|
* Waypoints manifest in the game world as a (usually far-off) beam of light that extends into the sky
|
||||||
* and whose ground contact utilizes a downwards pulsating arrow.
|
* and whose ground contact utilizes a downwards pulsating arrow.
|
||||||
* On the continental map and deployment map, they appear as a diamond, with a differentiating number where applicable.
|
* On the continental map and deployment map, they appear as a diamond, with a different number where applicable.
|
||||||
* The squad leader experience rally, for example, does not have a number like the preceding four waypoints.
|
* The squad leader experience rally, for example, does not have a number like the preceding four waypoints.
|
||||||
* @see `Start`
|
* @see `Start`
|
||||||
*/
|
*/
|
||||||
|
|
@ -44,10 +45,10 @@ class SquadFeatures(val Squad: Squad) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The particular position being recruited right at the moment.
|
* The particular position being recruited right at the moment.
|
||||||
* When `None`. no highlighted searches have been indicated.
|
* When `None`, no highlighted searches have been indicated.
|
||||||
* When a positive integer or 0, indicates distributed `LookingForSquadRoleInvite` messages as recorded by `proxyInvites`.
|
* When a positive integer or 0, indicates distributed `LookingForSquadRoleInvite` messages as recorded by `proxyInvites`.
|
||||||
* Only one position may bne actively recruited at a time in this case.
|
* Only one position may be actively recruited at a time in this case.
|
||||||
* When -1, indicates distributed `ProximityIvite` messages as recorded by `proxyInvites`.
|
* When -1, indicates distributed `ProximityInvite` messages as recorded by `proxyInvites`.
|
||||||
* Previous efforts may or may not be forgotten if there is a switch between the two modes.
|
* Previous efforts may or may not be forgotten if there is a switch between the two modes.
|
||||||
*/
|
*/
|
||||||
private var searchForRole: Option[Int] = None
|
private var searchForRole: Option[Int] = None
|
||||||
|
|
@ -58,14 +59,14 @@ class SquadFeatures(val Squad: Squad) {
|
||||||
private var proxyInvites: List[Long] = Nil
|
private var proxyInvites: List[Long] = Nil
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* These useres rejected invitation to this squad.
|
* These users rejected invitation to this squad.
|
||||||
* For the purposes of wide-searches for membership
|
* For the purposes of wide-searches for membership
|
||||||
* such as Looking For Squad checks and proximity invitation,
|
* such as Looking For Squad checks and proximity invitation,
|
||||||
* the unique character identifier numbers in this list are skipped.
|
* the unique character identifier numbers in this list are skipped.
|
||||||
* Direct invitation requests from the non sqad member should remain functional.
|
* Direct invitation requests from the non sqad member should remain functional.
|
||||||
*/
|
*/
|
||||||
private var refusedPlayers: List[Long] = Nil
|
private var refusedPlayers: List[Long] = Nil
|
||||||
private var autoApproveInvitationRequests: Boolean = true
|
private var autoApproveInvitationRequests: Boolean = false
|
||||||
private var locationFollowsSquadLead: Boolean = true
|
private var locationFollowsSquadLead: Boolean = true
|
||||||
|
|
||||||
private var listed: Boolean = false
|
private var listed: Boolean = false
|
||||||
|
|
|
||||||
|
|
@ -50,21 +50,21 @@ class ChatService(context: ActorContext[ChatService.Command]) extends AbstractBe
|
||||||
this
|
this
|
||||||
|
|
||||||
case LeaveChannel(actor, channel) =>
|
case LeaveChannel(actor, channel) =>
|
||||||
subscriptions = subscriptions.filter {
|
subscriptions = subscriptions.filterNot {
|
||||||
case JoinChannel(a, _, c) => actor != a && channel != c
|
case JoinChannel(a, _, c) => actor == a && channel == c
|
||||||
}
|
}
|
||||||
this
|
this
|
||||||
|
|
||||||
case LeaveAllChannels(actor) =>
|
case LeaveAllChannels(actor) =>
|
||||||
subscriptions = subscriptions.filter {
|
subscriptions = subscriptions.filterNot {
|
||||||
case JoinChannel(a, _, _) => actor != a
|
case JoinChannel(a, _, _) => actor == a
|
||||||
}
|
}
|
||||||
this
|
this
|
||||||
|
|
||||||
case Message(session, message, channel) =>
|
case Message(session, message, channel) =>
|
||||||
(channel, message.messageType) match {
|
(channel, message.messageType) match {
|
||||||
case (ChatChannel.Squad(_), CMT_SQUAD) =>
|
case (ChatChannel.Squad(_), CMT_SQUAD) => ;
|
||||||
case (ChatChannel.Default(), messageType) if messageType != CMT_SQUAD =>
|
case (ChatChannel.Default(), messageType) if messageType != CMT_SQUAD => ;
|
||||||
case _ =>
|
case _ =>
|
||||||
log.error(s"invalid chat channel $channel for messageType ${message.messageType}")
|
log.error(s"invalid chat channel $channel for messageType ${message.messageType}")
|
||||||
return this
|
return this
|
||||||
|
|
|
||||||
|
|
@ -553,7 +553,9 @@ class SquadService extends Actor {
|
||||||
case (Some(squad1), Some(squad2)) if squad2.Size == 1 =>
|
case (Some(squad1), Some(squad2)) if squad2.Size == 1 =>
|
||||||
//both players belong to squads, but the invitedPlayer's squad (squad2) is underutilized by comparison
|
//both players belong to squads, but the invitedPlayer's squad (squad2) is underutilized by comparison
|
||||||
//treat the same as "the classic situation" using squad1
|
//treat the same as "the classic situation" using squad1
|
||||||
if (!Refused(invitedPlayer).contains(invitingPlayer)) {
|
if (squad1.Size == squad1.Capacity) {
|
||||||
|
debug(s"$invitingPlayer tried to invite $invitedPlayer to a squad without available positions")
|
||||||
|
} else if (!Refused(invitedPlayer).contains(invitingPlayer)) {
|
||||||
val charId = tplayer.CharId
|
val charId = tplayer.CharId
|
||||||
AddInviteAndRespond(
|
AddInviteAndRespond(
|
||||||
invitedPlayer,
|
invitedPlayer,
|
||||||
|
|
@ -561,16 +563,20 @@ class SquadService extends Actor {
|
||||||
charId,
|
charId,
|
||||||
tplayer.Name
|
tplayer.Name
|
||||||
)
|
)
|
||||||
|
} else {
|
||||||
|
debug(s"$invitedPlayer repeated a previous refusal to $invitingPlayer's invitation offer")
|
||||||
}
|
}
|
||||||
|
|
||||||
case (Some(squad1), Some(squad2)) if squad1.Size == 1 =>
|
case (Some(squad1), Some(squad2)) if squad1.Size == 1 =>
|
||||||
//both players belong to squads, but the invitingPlayer's squad is underutilized by comparison
|
//both players belong to squads, but the invitingPlayer's squad is underutilized by comparison
|
||||||
//treat the same as "indirection ..." using squad2
|
//treat the same as "indirection ..." using squad2
|
||||||
val leader = squad2.Leader.CharId
|
val leader = squad2.Leader.CharId
|
||||||
if (Refused(invitingPlayer).contains(invitedPlayer)) {
|
if (squad2.Size == squad2.Capacity) {
|
||||||
debug(s"$invitedPlayer repeated a previous refusal to $invitingPlayer's invitation offer")
|
debug(s"$invitingPlayer's invitation got reversed to $invitedPlayer's squad, but the squad has no available positions")
|
||||||
|
} else if (Refused(invitingPlayer).contains(invitedPlayer)) {
|
||||||
|
debug(s"$invitingPlayer's invitation got reversed to $invitedPlayer's squad, but $invitedPlayer repeated a previous refusal to $invitingPlayer's invitation offer")
|
||||||
} else if (Refused(invitingPlayer).contains(leader)) {
|
} else if (Refused(invitingPlayer).contains(leader)) {
|
||||||
debug(s"$invitedPlayer repeated a previous refusal to $leader's invitation offer")
|
debug(s"$invitingPlayer's invitation got reversed to $invitedPlayer's squad, but $leader repeated a previous refusal to $invitingPlayer's invitation offer")
|
||||||
} else {
|
} else {
|
||||||
AddInviteAndRespond(
|
AddInviteAndRespond(
|
||||||
leader,
|
leader,
|
||||||
|
|
@ -582,7 +588,9 @@ class SquadService extends Actor {
|
||||||
|
|
||||||
case (Some(squad), None) =>
|
case (Some(squad), None) =>
|
||||||
//the classic situation
|
//the classic situation
|
||||||
if (!Refused(invitedPlayer).contains(invitingPlayer)) {
|
if (squad.Size == squad.Capacity) {
|
||||||
|
debug(s"$invitingPlayer tried to invite $invitedPlayer to a squad without available positions")
|
||||||
|
} else if (!Refused(invitedPlayer).contains(invitingPlayer)) {
|
||||||
AddInviteAndRespond(
|
AddInviteAndRespond(
|
||||||
invitedPlayer,
|
invitedPlayer,
|
||||||
VacancyInvite(tplayer.CharId, tplayer.Name, squad.GUID),
|
VacancyInvite(tplayer.CharId, tplayer.Name, squad.GUID),
|
||||||
|
|
@ -596,10 +604,12 @@ class SquadService extends Actor {
|
||||||
case (None, Some(squad)) =>
|
case (None, Some(squad)) =>
|
||||||
//indirection; we're trying to invite ourselves to someone else's squad
|
//indirection; we're trying to invite ourselves to someone else's squad
|
||||||
val leader = squad.Leader.CharId
|
val leader = squad.Leader.CharId
|
||||||
if (Refused(invitingPlayer).contains(invitedPlayer)) {
|
if (squad.Size == squad.Capacity) {
|
||||||
debug(s"$invitedPlayer repeated a previous refusal to $invitingPlayer's invitation offer")
|
debug(s"$invitingPlayer tried to invite to $invitedPlayer's squad, but the squad has no available positions")
|
||||||
|
} else if (Refused(invitingPlayer).contains(invitedPlayer)) {
|
||||||
|
debug(s"invitingPlayer tried to invite to $invitedPlayer's squad, but $invitedPlayer repeated a previous refusal to $invitingPlayer's invitation offer")
|
||||||
} else if (Refused(invitingPlayer).contains(leader)) {
|
} else if (Refused(invitingPlayer).contains(leader)) {
|
||||||
debug(s"$invitedPlayer repeated a previous refusal to $leader's invitation offer")
|
debug(s"invitingPlayer tried to invite to $invitedPlayer's squad, but $leader repeated a previous refusal to $invitingPlayer's invitation offer")
|
||||||
} else {
|
} else {
|
||||||
AddInviteAndRespond(
|
AddInviteAndRespond(
|
||||||
squad.Leader.CharId,
|
squad.Leader.CharId,
|
||||||
|
|
@ -658,62 +668,64 @@ class SquadService extends Actor {
|
||||||
//positions that can be recruited to
|
//positions that can be recruited to
|
||||||
val positions = squad.Membership.zipWithIndex
|
val positions = squad.Membership.zipWithIndex
|
||||||
.collect { case (member, index) if member.CharId == 0 && squad.Availability(index) => member }
|
.collect { case (member, index) if member.CharId == 0 && squad.Availability(index) => member }
|
||||||
/*
|
if (positions.nonEmpty) {
|
||||||
players who are:
|
/*
|
||||||
- the same faction as the squad
|
players who are:
|
||||||
- have Looking For Squad enabled
|
- the same faction as the squad
|
||||||
- do not currently belong to a squad
|
- have Looking For Squad enabled
|
||||||
- are denied the opportunity to be invited
|
- do not currently belong to a squad
|
||||||
- are a certain distance from the squad leader (n < 25m)
|
- are denied the opportunity to be invited
|
||||||
*/
|
- are a certain distance from the squad leader (n < 25m)
|
||||||
(zone.LivePlayers
|
*/
|
||||||
.collect {
|
(zone.LivePlayers
|
||||||
case player
|
.collect {
|
||||||
if player.Faction == faction && player.avatar.lookingForSquad &&
|
case player
|
||||||
(memberToSquad.get(player.CharId).isEmpty || memberToSquad(player.CharId).Size == 1) &&
|
if player.Faction == faction && player.avatar.lookingForSquad &&
|
||||||
!excusedInvites
|
(memberToSquad.get(player.CharId).isEmpty || memberToSquad(player.CharId).Size == 1) &&
|
||||||
.contains(player.CharId) && Refused(player.CharId).contains(squad.Leader.CharId) &&
|
!excusedInvites
|
||||||
Vector3.DistanceSquared(player.Position, center) < 625f && {
|
.contains(player.CharId) && Refused(player.CharId).contains(squad.Leader.CharId) &&
|
||||||
positions
|
Vector3.DistanceSquared(player.Position, center) < 625f && {
|
||||||
.map { role =>
|
positions
|
||||||
val requirementsToMeet = role.Requirements
|
.map { role =>
|
||||||
requirementsToMeet.intersect(player.avatar.certifications) == requirementsToMeet
|
val requirementsToMeet = role.Requirements
|
||||||
}
|
requirementsToMeet.intersect(player.avatar.certifications) == requirementsToMeet
|
||||||
.foldLeft(false)(_ || _)
|
}
|
||||||
} =>
|
.foldLeft(false)(_ || _)
|
||||||
player.CharId
|
} =>
|
||||||
|
player.CharId
|
||||||
|
}
|
||||||
|
.partition { charId => outstandingActiveInvites.contains(charId) } match {
|
||||||
|
case (Nil, Nil) =>
|
||||||
|
//no one found
|
||||||
|
outstandingActiveInvites foreach RemoveInvite
|
||||||
|
features.ProxyInvites = Nil
|
||||||
|
None
|
||||||
|
case (outstandingPlayerList, invitedPlayerList) =>
|
||||||
|
//players who were actively invited for the previous position and are eligible for the new position
|
||||||
|
features.SearchForRole = Some(-1)
|
||||||
|
outstandingPlayerList.foreach { charId =>
|
||||||
|
val bid = invites(charId).asInstanceOf[LookingForSquadRoleInvite]
|
||||||
|
invites(charId) = ProximityInvite(bid.char_id, bid.name, sguid)
|
||||||
|
}
|
||||||
|
//players who were actively invited for the previous position but are ineligible for the new position
|
||||||
|
(features.ProxyInvites filterNot (outstandingPlayerList contains)) foreach RemoveInvite
|
||||||
|
features.ProxyInvites = outstandingPlayerList ++ invitedPlayerList
|
||||||
|
Some(invitedPlayerList)
|
||||||
|
}) match {
|
||||||
|
//add invitations for position in squad
|
||||||
|
case Some(invitedPlayers) =>
|
||||||
|
val invitingPlayer = tplayer.CharId
|
||||||
|
val name = tplayer.Name
|
||||||
|
invitedPlayers.foreach { invitedPlayer =>
|
||||||
|
AddInviteAndRespond(
|
||||||
|
invitedPlayer,
|
||||||
|
ProximityInvite(invitingPlayer, name, sguid),
|
||||||
|
invitingPlayer,
|
||||||
|
name
|
||||||
|
)
|
||||||
|
}
|
||||||
|
case None => ;
|
||||||
}
|
}
|
||||||
.partition { charId => outstandingActiveInvites.contains(charId) } match {
|
|
||||||
case (Nil, Nil) =>
|
|
||||||
//no one found
|
|
||||||
outstandingActiveInvites foreach RemoveInvite
|
|
||||||
features.ProxyInvites = Nil
|
|
||||||
None
|
|
||||||
case (outstandingPlayerList, invitedPlayerList) =>
|
|
||||||
//players who were actively invited for the previous position and are eligible for the new position
|
|
||||||
features.SearchForRole = Some(-1)
|
|
||||||
outstandingPlayerList.foreach { charId =>
|
|
||||||
val bid = invites(charId).asInstanceOf[LookingForSquadRoleInvite]
|
|
||||||
invites(charId) = ProximityInvite(bid.char_id, bid.name, sguid)
|
|
||||||
}
|
|
||||||
//players who were actively invited for the previous position but are ineligible for the new position
|
|
||||||
(features.ProxyInvites filterNot (outstandingPlayerList contains)) foreach RemoveInvite
|
|
||||||
features.ProxyInvites = outstandingPlayerList ++ invitedPlayerList
|
|
||||||
Some(invitedPlayerList)
|
|
||||||
}) match {
|
|
||||||
//add invitations for position in squad
|
|
||||||
case Some(invitedPlayers) =>
|
|
||||||
val invitingPlayer = tplayer.CharId
|
|
||||||
val name = tplayer.Name
|
|
||||||
invitedPlayers.foreach { invitedPlayer =>
|
|
||||||
AddInviteAndRespond(
|
|
||||||
invitedPlayer,
|
|
||||||
ProximityInvite(invitingPlayer, name, sguid),
|
|
||||||
invitingPlayer,
|
|
||||||
name
|
|
||||||
)
|
|
||||||
}
|
|
||||||
case None => ;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2772,7 +2784,7 @@ class SquadService extends Actor {
|
||||||
* At this point in the squad join process, the only consent required is that of the squad leader.
|
* At this point in the squad join process, the only consent required is that of the squad leader.
|
||||||
* An automatic consent flag exists on the squad;
|
* An automatic consent flag exists on the squad;
|
||||||
* but, if that is not set, then the squad leader must be asked whether or not to accept or to reject the recruit.
|
* but, if that is not set, then the squad leader must be asked whether or not to accept or to reject the recruit.
|
||||||
* If the squad leader changes in the middle of the latter half of the process,
|
* If the squad leader changes in the middle or the latter half of the process,
|
||||||
* the invitation may still fail even if the old squad leader accepts.
|
* the invitation may still fail even if the old squad leader accepts.
|
||||||
* If the squad leader changes in the middle of the latter half of the process,
|
* If the squad leader changes in the middle of the latter half of the process,
|
||||||
* the inquiry might be posed again of the new squad leader, of whether to accept or to reject the recruit.
|
* the inquiry might be posed again of the new squad leader, of whether to accept or to reject the recruit.
|
||||||
|
|
@ -2908,7 +2920,7 @@ class SquadService extends Actor {
|
||||||
.unzip { case (member, index) => (member.CharId, index) }
|
.unzip { case (member, index) => (member.CharId, index) }
|
||||||
val toChannel = features.ToChannel
|
val toChannel = features.ToChannel
|
||||||
memberCharIds.foreach { charId =>
|
memberCharIds.foreach { charId =>
|
||||||
SquadEvents.subscribe(events, s"/$toChannel/Squad")
|
SquadEvents.subscribe(UserEvents(charId), s"/$toChannel/Squad")
|
||||||
Publish(
|
Publish(
|
||||||
charId,
|
charId,
|
||||||
SquadResponse.Join(
|
SquadResponse.Join(
|
||||||
|
|
@ -2923,8 +2935,7 @@ class SquadService extends Actor {
|
||||||
InitSquadDetail(squad)
|
InitSquadDetail(squad)
|
||||||
} else {
|
} else {
|
||||||
//joining an active squad; everybody updates differently
|
//joining an active squad; everybody updates differently
|
||||||
val updatedIndex = List(position)
|
val toChannel = features.ToChannel
|
||||||
val toChannel = features.ToChannel
|
|
||||||
//new member gets full squad UI updates
|
//new member gets full squad UI updates
|
||||||
Publish(
|
Publish(
|
||||||
charId,
|
charId,
|
||||||
|
|
@ -2938,7 +2949,7 @@ class SquadService extends Actor {
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
//other squad members see new member joining the squad
|
//other squad members see new member joining the squad
|
||||||
Publish(toChannel, SquadResponse.Join(squad, updatedIndex, ""))
|
Publish(toChannel, SquadResponse.Join(squad, List(position), ""))
|
||||||
InitWaypoints(charId, squad.GUID)
|
InitWaypoints(charId, squad.GUID)
|
||||||
InitSquadDetail(squad.GUID, Seq(charId), squad)
|
InitSquadDetail(squad.GUID, Seq(charId), squad)
|
||||||
UpdateSquadDetail(
|
UpdateSquadDetail(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue