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:
Fate-JH 2021-04-14 21:06:01 -04:00 committed by GitHub
parent 0143f3b072
commit 51d46d86d3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 96 additions and 84 deletions

View file

@ -117,7 +117,7 @@ class ChatActor(
case LeaveChannel(channel) =>
chatService ! ChatService.LeaveChannel(chatServiceAdapter, channel)
channels = channels.filter(_ == channel)
channels = channels.filterNot(_ == channel)
Behaviors.same
case Message(message) =>

View file

@ -775,7 +775,6 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
None
)
}
.toList
)
)
@ -3303,6 +3302,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
*/
def ZoneChangeSquadSetup(): Unit = {
RespawnSquadSetup()
squadService ! SquadServiceMessage(player, continent, SquadServiceAction.InitSquadList())
GiveSquadColorsInZone()
squadSetup = RespawnSquadSetup
}

View file

@ -33,10 +33,11 @@ class SquadFeatures(val Squad: Squad) {
* <br>
* All of the waypoints constantly exist as long as the squad to which they are attached exists.
* 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.
* Waypoints manifest in the game world as a far-off beam of light that extends into the sky
* When "activated," the waypoint knows on which continent to appear
* 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.
* 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.
* @see `Start`
*/
@ -44,10 +45,10 @@ class SquadFeatures(val Squad: Squad) {
/**
* 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`.
* Only one position may bne actively recruited at a time in this case.
* When -1, indicates distributed `ProximityIvite` messages as recorded by `proxyInvites`.
* Only one position may be actively recruited at a time in this case.
* 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.
*/
private var searchForRole: Option[Int] = None
@ -58,14 +59,14 @@ class SquadFeatures(val Squad: Squad) {
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
* such as Looking For Squad checks and proximity invitation,
* the unique character identifier numbers in this list are skipped.
* Direct invitation requests from the non sqad member should remain functional.
*/
private var refusedPlayers: List[Long] = Nil
private var autoApproveInvitationRequests: Boolean = true
private var autoApproveInvitationRequests: Boolean = false
private var locationFollowsSquadLead: Boolean = true
private var listed: Boolean = false

View file

@ -50,21 +50,21 @@ class ChatService(context: ActorContext[ChatService.Command]) extends AbstractBe
this
case LeaveChannel(actor, channel) =>
subscriptions = subscriptions.filter {
case JoinChannel(a, _, c) => actor != a && channel != c
subscriptions = subscriptions.filterNot {
case JoinChannel(a, _, c) => actor == a && channel == c
}
this
case LeaveAllChannels(actor) =>
subscriptions = subscriptions.filter {
case JoinChannel(a, _, _) => actor != a
subscriptions = subscriptions.filterNot {
case JoinChannel(a, _, _) => actor == a
}
this
case Message(session, message, channel) =>
(channel, message.messageType) match {
case (ChatChannel.Squad(_), CMT_SQUAD) =>
case (ChatChannel.Default(), messageType) if messageType != CMT_SQUAD =>
case (ChatChannel.Squad(_), CMT_SQUAD) => ;
case (ChatChannel.Default(), messageType) if messageType != CMT_SQUAD => ;
case _ =>
log.error(s"invalid chat channel $channel for messageType ${message.messageType}")
return this

View file

@ -553,7 +553,9 @@ class SquadService extends Actor {
case (Some(squad1), Some(squad2)) if squad2.Size == 1 =>
//both players belong to squads, but the invitedPlayer's squad (squad2) is underutilized by comparison
//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
AddInviteAndRespond(
invitedPlayer,
@ -561,16 +563,20 @@ class SquadService extends Actor {
charId,
tplayer.Name
)
} else {
debug(s"$invitedPlayer repeated a previous refusal to $invitingPlayer's invitation offer")
}
case (Some(squad1), Some(squad2)) if squad1.Size == 1 =>
//both players belong to squads, but the invitingPlayer's squad is underutilized by comparison
//treat the same as "indirection ..." using squad2
val leader = squad2.Leader.CharId
if (Refused(invitingPlayer).contains(invitedPlayer)) {
debug(s"$invitedPlayer repeated a previous refusal to $invitingPlayer's invitation offer")
if (squad2.Size == squad2.Capacity) {
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)) {
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 {
AddInviteAndRespond(
leader,
@ -582,7 +588,9 @@ class SquadService extends Actor {
case (Some(squad), None) =>
//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(
invitedPlayer,
VacancyInvite(tplayer.CharId, tplayer.Name, squad.GUID),
@ -596,10 +604,12 @@ class SquadService extends Actor {
case (None, Some(squad)) =>
//indirection; we're trying to invite ourselves to someone else's squad
val leader = squad.Leader.CharId
if (Refused(invitingPlayer).contains(invitedPlayer)) {
debug(s"$invitedPlayer repeated a previous refusal to $invitingPlayer's invitation offer")
if (squad.Size == squad.Capacity) {
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)) {
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 {
AddInviteAndRespond(
squad.Leader.CharId,
@ -658,62 +668,64 @@ class SquadService extends Actor {
//positions that can be recruited to
val positions = squad.Membership.zipWithIndex
.collect { case (member, index) if member.CharId == 0 && squad.Availability(index) => member }
/*
players who are:
- the same faction as the squad
- have Looking For Squad enabled
- do not currently belong to a squad
- are denied the opportunity to be invited
- are a certain distance from the squad leader (n < 25m)
*/
(zone.LivePlayers
.collect {
case player
if player.Faction == faction && player.avatar.lookingForSquad &&
(memberToSquad.get(player.CharId).isEmpty || memberToSquad(player.CharId).Size == 1) &&
!excusedInvites
.contains(player.CharId) && Refused(player.CharId).contains(squad.Leader.CharId) &&
Vector3.DistanceSquared(player.Position, center) < 625f && {
positions
.map { role =>
val requirementsToMeet = role.Requirements
requirementsToMeet.intersect(player.avatar.certifications) == requirementsToMeet
}
.foldLeft(false)(_ || _)
} =>
player.CharId
if (positions.nonEmpty) {
/*
players who are:
- the same faction as the squad
- have Looking For Squad enabled
- do not currently belong to a squad
- are denied the opportunity to be invited
- are a certain distance from the squad leader (n < 25m)
*/
(zone.LivePlayers
.collect {
case player
if player.Faction == faction && player.avatar.lookingForSquad &&
(memberToSquad.get(player.CharId).isEmpty || memberToSquad(player.CharId).Size == 1) &&
!excusedInvites
.contains(player.CharId) && Refused(player.CharId).contains(squad.Leader.CharId) &&
Vector3.DistanceSquared(player.Position, center) < 625f && {
positions
.map { role =>
val requirementsToMeet = role.Requirements
requirementsToMeet.intersect(player.avatar.certifications) == requirementsToMeet
}
.foldLeft(false)(_ || _)
} =>
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.
* 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.
* 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.
* 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.
@ -2908,7 +2920,7 @@ class SquadService extends Actor {
.unzip { case (member, index) => (member.CharId, index) }
val toChannel = features.ToChannel
memberCharIds.foreach { charId =>
SquadEvents.subscribe(events, s"/$toChannel/Squad")
SquadEvents.subscribe(UserEvents(charId), s"/$toChannel/Squad")
Publish(
charId,
SquadResponse.Join(
@ -2923,8 +2935,7 @@ class SquadService extends Actor {
InitSquadDetail(squad)
} else {
//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
Publish(
charId,
@ -2938,7 +2949,7 @@ class SquadService extends Actor {
)
)
//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)
InitSquadDetail(squad.GUID, Seq(charId), squad)
UpdateSquadDetail(