mirror of
https://github.com/psforever/PSF-LoginServer.git
synced 2026-07-16 00:44:46 +00:00
WIP: Custom commands handling
This commit is contained in:
parent
6bb002e2e2
commit
75d7877f8a
1 changed files with 343 additions and 176 deletions
|
|
@ -224,6 +224,10 @@ class ChatActor(
|
||||||
session.account.gm || Config.app.development.unprivilegedGmCommands.contains(message.messageType)
|
session.account.gm || Config.app.development.unprivilegedGmCommands.contains(message.messageType)
|
||||||
|
|
||||||
(message.messageType, message.recipient.trim, message.contents.trim) match {
|
(message.messageType, message.recipient.trim, message.contents.trim) match {
|
||||||
|
/** Messages starting with ! are custom chat commands */
|
||||||
|
case (_, _, contents) if contents.startsWith("!") &&
|
||||||
|
customCommandMessages(message, session, chatService, cluster, gmCommandAllowed) => ;
|
||||||
|
|
||||||
case (CMT_FLY, recipient, contents) if gmCommandAllowed =>
|
case (CMT_FLY, recipient, contents) if gmCommandAllowed =>
|
||||||
val flying = contents match {
|
val flying = contents match {
|
||||||
case "on" => true
|
case "on" => true
|
||||||
|
|
@ -899,10 +903,6 @@ class ChatActor(
|
||||||
ZonePopulationUpdateMessage(4, 414, 138, 0, 138, 0, 138, 0, 138, contents.toInt)
|
ZonePopulationUpdateMessage(4, 414, 138, 0, 138, 0, 138, 0, 138, contents.toInt)
|
||||||
)
|
)
|
||||||
|
|
||||||
/** Messages starting with ! are custom chat commands */
|
|
||||||
case (_, _, contents) if contents.startsWith("!") &&
|
|
||||||
customCommandMessages(message, session, chatService, cluster, gmCommandAllowed) => ;
|
|
||||||
|
|
||||||
case _ =>
|
case _ =>
|
||||||
log.warn(s"Unhandled chat message $message")
|
log.warn(s"Unhandled chat message $message")
|
||||||
}
|
}
|
||||||
|
|
@ -1107,212 +1107,379 @@ class ChatActor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def customCommandMessages(
|
private def customCommandMessages(
|
||||||
message: ChatMsg,
|
message: ChatMsg,
|
||||||
session: Session,
|
session: Session,
|
||||||
chatService: ActorRef[ChatService.Command],
|
chatService: ActorRef[ChatService.Command],
|
||||||
cluster: ActorRef[InterstellarClusterService.Command],
|
cluster: ActorRef[InterstellarClusterService.Command],
|
||||||
gmCommandAllowed: Boolean
|
isGM: Boolean
|
||||||
): Boolean = {
|
): Boolean = {
|
||||||
// val messageType = message.messageType
|
|
||||||
// val recipient = message.recipient
|
var content = message.contents
|
||||||
val contents = message.contents
|
|
||||||
if (contents.startsWith("!")) {
|
// stop processing if content is not a custom command
|
||||||
if (contents.startsWith("!whitetext ") && gmCommandAllowed) {
|
if (!content.startsWith("!")) {
|
||||||
chatService ! ChatService.Message(
|
return false
|
||||||
session,
|
}
|
||||||
ChatMsg(UNK_227, wideContents=true, "", contents.replace("!whitetext ", ""), None),
|
|
||||||
ChatChannel.Default()
|
// remove ! character
|
||||||
|
content = content.drop(1)
|
||||||
|
|
||||||
|
// get command from contents
|
||||||
|
val command = content.split(" ")(0)
|
||||||
|
|
||||||
|
// remove command and space from contents
|
||||||
|
content = content.drop(command.length() + 1)
|
||||||
|
|
||||||
|
// match command and execute relevant function
|
||||||
|
// if player is GM, process GM commands first
|
||||||
|
if (isGM) {
|
||||||
|
|
||||||
|
val handled = command match {
|
||||||
|
|
||||||
|
case "whitetext" => commandGMWhiteText(message, command, content, session, chatService, cluster, isGM);
|
||||||
|
case "loc" => commandGMLoc(message, command, content, session, chatService, cluster, isGM);
|
||||||
|
case "list" => commandGMList(message, command, content, session, chatService, cluster, isGM);
|
||||||
|
case "ntu" => commandGMNTU(message, command, content, session, chatService, cluster, isGM);
|
||||||
|
case "zonerotate" => commandGMZoneRotate(message, command, content, session, chatService, cluster, isGM);
|
||||||
|
|
||||||
|
// command is not a GM command, continue with normal commands
|
||||||
|
case _ => false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// stop processing if GM command was handled
|
||||||
|
if (handled) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// process commands accessible to all players
|
||||||
|
val handled = command match {
|
||||||
|
|
||||||
|
case "suicide" => commandSuicide(message, command, content, session, chatService, cluster, isGM);
|
||||||
|
case "grenade" => commandGrenade(message, command, content, session, chatService, cluster, isGM);
|
||||||
|
case "macro" => commandMacro(message, command, content, session, chatService, cluster, isGM);
|
||||||
|
case "progress" => commandProgress(message, command, content, session, chatService, cluster, isGM);
|
||||||
|
|
||||||
|
// if no command was matched the command does not exist / is a GM only command but player is not GM
|
||||||
|
case _ => false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handled) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// command was not handled
|
||||||
|
sessionActor ! SessionActor.SendResponse(
|
||||||
|
ChatMsg(
|
||||||
|
CMT_GMOPEN, // CMT_GMTELL
|
||||||
|
message.wideContents,
|
||||||
|
"Server",
|
||||||
|
s"Unknown command !$command",
|
||||||
|
message.note
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
// stop sending the failed command in chat
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
private def commandGMWhiteText(
|
||||||
|
message: ChatMsg,
|
||||||
|
command: String,
|
||||||
|
content: String,
|
||||||
|
session: Session,
|
||||||
|
chatService: ActorRef[ChatService.Command],
|
||||||
|
cluster: ActorRef[InterstellarClusterService.Command],
|
||||||
|
isGM: Boolean
|
||||||
|
): Boolean = {
|
||||||
|
|
||||||
|
chatService ! ChatService.Message(
|
||||||
|
session,
|
||||||
|
ChatMsg(UNK_227, wideContents = true, "", content, None),
|
||||||
|
ChatChannel.Default()
|
||||||
|
)
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
private def commandGMLoc(
|
||||||
|
message: ChatMsg,
|
||||||
|
command: String,
|
||||||
|
content: String,
|
||||||
|
session: Session,
|
||||||
|
chatService: ActorRef[ChatService.Command],
|
||||||
|
cluster: ActorRef[InterstellarClusterService.Command],
|
||||||
|
isGM: Boolean
|
||||||
|
): Boolean = {
|
||||||
|
|
||||||
|
val continent = session.zone
|
||||||
|
val player = session.player
|
||||||
|
val loc = s"zone=${continent.id} pos=${player.Position.x},${player.Position.y},${player.Position.z}; ori=${player.Orientation.x},${player.Orientation.y},${player.Orientation.z}"
|
||||||
|
|
||||||
|
log.info(loc)
|
||||||
|
sessionActor ! SessionActor.SendResponse(message.copy(contents = loc))
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
private def commandGMList(
|
||||||
|
message: ChatMsg,
|
||||||
|
command: String,
|
||||||
|
content: String,
|
||||||
|
session: Session,
|
||||||
|
chatService: ActorRef[ChatService.Command],
|
||||||
|
cluster: ActorRef[InterstellarClusterService.Command],
|
||||||
|
isGM: Boolean
|
||||||
|
): Boolean = {
|
||||||
|
|
||||||
|
val zone = content.split(" ").lift(0) match {
|
||||||
|
case Some("") =>
|
||||||
|
Some(session.zone)
|
||||||
|
case Some(id) =>
|
||||||
|
Zones.zones.find(_.id == id)
|
||||||
|
}
|
||||||
|
|
||||||
|
zone match {
|
||||||
|
|
||||||
|
case Some(inZone) =>
|
||||||
|
sessionActor ! SessionActor.SendResponse(
|
||||||
|
ChatMsg(
|
||||||
|
CMT_GMOPEN,
|
||||||
|
message.wideContents,
|
||||||
|
"Server",
|
||||||
|
"\\#8Name (Faction) [ID] at PosX PosY PosZ",
|
||||||
|
message.note
|
||||||
|
)
|
||||||
)
|
)
|
||||||
true
|
(inZone.LivePlayers ++ inZone.Corpses)
|
||||||
|
.filter(_.CharId != session.player.CharId)
|
||||||
} else if (contents.startsWith("!loc ")) {
|
.filter(!_.spectator)
|
||||||
val continent = session.zone
|
.sortBy(p => (p.Name, !p.isAlive))
|
||||||
val player = session.player
|
.foreach(player => {
|
||||||
val loc =
|
val color = if (!player.isAlive) "\\#7" else ""
|
||||||
s"zone=${continent.id} pos=${player.Position.x},${player.Position.y},${player.Position.z}; ori=${player.Orientation.x},${player.Orientation.y},${player.Orientation.z}"
|
|
||||||
log.info(loc)
|
|
||||||
sessionActor ! SessionActor.SendResponse(message.copy(contents = loc))
|
|
||||||
true
|
|
||||||
|
|
||||||
} else if (contents.startsWith("!list")) {
|
|
||||||
val zone = dropFirstWord(contents).split("\\s+").headOption match {
|
|
||||||
case Some("") | None =>
|
|
||||||
Some(session.zone)
|
|
||||||
case Some(id) =>
|
|
||||||
Zones.zones.find(_.id == id)
|
|
||||||
}
|
|
||||||
zone match {
|
|
||||||
case Some(inZone) =>
|
|
||||||
sessionActor ! SessionActor.SendResponse(
|
sessionActor ! SessionActor.SendResponse(
|
||||||
ChatMsg(
|
ChatMsg(
|
||||||
CMT_GMOPEN,
|
CMT_GMOPEN,
|
||||||
message.wideContents,
|
message.wideContents,
|
||||||
"Server",
|
"Server",
|
||||||
"\\#8Name (Faction) [ID] at PosX PosY PosZ",
|
s"$color${player.Name} (${player.Faction}) [${player.CharId}] at ${player.Position.x.toInt} ${player.Position.y.toInt} ${player.Position.z.toInt}",
|
||||||
message.note
|
message.note
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(inZone.LivePlayers ++ inZone.Corpses)
|
})
|
||||||
.filter(_.CharId != session.player.CharId)
|
|
||||||
.sortBy(p => (p.Name, !p.isAlive))
|
|
||||||
.foreach(player => {
|
|
||||||
val color = if (!player.isAlive) "\\#7" else ""
|
|
||||||
sessionActor ! SessionActor.SendResponse(
|
|
||||||
ChatMsg(
|
|
||||||
CMT_GMOPEN,
|
|
||||||
message.wideContents,
|
|
||||||
"Server",
|
|
||||||
s"$color${player.Name} (${player.Faction}) [${player.CharId}] at ${player.Position.x.toInt} ${player.Position.y.toInt} ${player.Position.z.toInt}",
|
|
||||||
message.note
|
|
||||||
)
|
|
||||||
)
|
|
||||||
})
|
|
||||||
case None =>
|
|
||||||
sessionActor ! SessionActor.SendResponse(
|
|
||||||
ChatMsg(
|
|
||||||
CMT_GMOPEN,
|
|
||||||
message.wideContents,
|
|
||||||
"Server",
|
|
||||||
"Invalid zone ID",
|
|
||||||
message.note
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
true
|
|
||||||
|
|
||||||
} else if (contents.startsWith("!ntu") && gmCommandAllowed) {
|
case None =>
|
||||||
val buffer = dropFirstWord(contents).split("\\s+")
|
sessionActor ! SessionActor.SendResponse(
|
||||||
val (facility, customNtuValue) = (buffer.headOption, buffer.lift(1)) match {
|
ChatMsg(
|
||||||
case (Some(x), Some(y)) if y.toIntOption.nonEmpty => (Some(x), Some(y.toInt))
|
CMT_GMOPEN,
|
||||||
case (Some(x), None) if x.toIntOption.nonEmpty => (None, Some(x.toInt))
|
message.wideContents,
|
||||||
case _ => (None, None)
|
"Server",
|
||||||
}
|
"Invalid zone ID",
|
||||||
val silos = (facility match {
|
message.note
|
||||||
case Some(cur) if cur.toLowerCase().startsWith("curr") =>
|
)
|
||||||
val position = session.player.Position
|
)
|
||||||
session.zone.Buildings.values
|
}
|
||||||
.filter { building =>
|
|
||||||
val soi2 = building.Definition.SOIRadius * building.Definition.SOIRadius
|
true
|
||||||
Vector3.DistanceSquared(building.Position, position) < soi2
|
}
|
||||||
}
|
|
||||||
case Some(all) if all.toLowerCase.startsWith("all") =>
|
private def commandGMNTU(
|
||||||
session.zone.Buildings.values
|
message: ChatMsg,
|
||||||
case Some(x) =>
|
command: String,
|
||||||
session.zone.Buildings.values.find {
|
content: String,
|
||||||
_.Name.equalsIgnoreCase(x)
|
session: Session,
|
||||||
}.toList
|
chatService: ActorRef[ChatService.Command],
|
||||||
case _ =>
|
cluster: ActorRef[InterstellarClusterService.Command],
|
||||||
session.zone.Buildings.values
|
isGM: Boolean
|
||||||
})
|
): Boolean = {
|
||||||
.flatMap { building =>
|
|
||||||
building.Amenities.filter {
|
val buffer = content.toLowerCase.split("\\s+")
|
||||||
_.isInstanceOf[ResourceSilo]
|
val (facility, customNtuValue) = (buffer.headOption, buffer.lift(1)) match {
|
||||||
}
|
case (Some(x), Some(y)) if y.toIntOption.nonEmpty => (Some(x), Some(y.toInt))
|
||||||
|
case (Some(x), None) if x.toIntOption.nonEmpty => (None, Some(x.toInt))
|
||||||
|
case _ => (None, None)
|
||||||
|
}
|
||||||
|
|
||||||
|
val silos = (facility match {
|
||||||
|
|
||||||
|
case Some(cur) if cur.toLowerCase().startsWith("curr") =>
|
||||||
|
val position = session.player.Position
|
||||||
|
session.zone.Buildings.values
|
||||||
|
.filter { building =>
|
||||||
|
val soi2 = building.Definition.SOIRadius * building.Definition.SOIRadius
|
||||||
|
Vector3.DistanceSquared(building.Position, position) < soi2
|
||||||
}
|
}
|
||||||
ChatActor.setBaseResources(sessionActor, customNtuValue, silos, debugContent = s"$facility")
|
|
||||||
true
|
|
||||||
|
|
||||||
} else if (contents.startsWith("!zonerotate") && gmCommandAllowed) {
|
case Some(all) if all.toLowerCase.startsWith("all") =>
|
||||||
val buffer = dropFirstWord(contents).split("\\s+")
|
session.zone.Buildings.values
|
||||||
cluster ! InterstellarClusterService.CavernRotation(buffer.headOption match {
|
|
||||||
case Some("-list") | Some("-l") =>
|
|
||||||
CavernRotationService.ReportRotationOrder(sessionActor.toClassic)
|
|
||||||
case _ =>
|
|
||||||
CavernRotationService.HurryNextRotation
|
|
||||||
})
|
|
||||||
true
|
|
||||||
|
|
||||||
} else if (contents.startsWith("!suicide")) {
|
case Some(x) =>
|
||||||
//this is like CMT_SUICIDE but it ignores checks and forces a suicide state
|
session.zone.Buildings.values.find {
|
||||||
val tplayer = session.player
|
_.Name.equalsIgnoreCase(x)
|
||||||
tplayer.Revive
|
}.toList
|
||||||
tplayer.Actor ! Player.Die()
|
|
||||||
true
|
|
||||||
|
|
||||||
} else if (contents.startsWith("!grenade")) {
|
case _ =>
|
||||||
WorldSession.QuickSwapToAGrenade(session.player, DrawnSlot.Pistol1.id, log)
|
session.zone.Buildings.values
|
||||||
true
|
})
|
||||||
|
.flatMap { building =>
|
||||||
|
building.Amenities.filter {
|
||||||
|
_.isInstanceOf[ResourceSilo]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} else if (contents.startsWith("!macro")) {
|
ChatActor.setBaseResources(sessionActor, customNtuValue, silos, debugContent = s"$facility")
|
||||||
val avatar = session.avatar
|
|
||||||
val args = dropFirstWord(contents).split(" ").filter(_ != "")
|
true
|
||||||
(args.headOption, args.lift(1)) match {
|
}
|
||||||
case (Some(cmd), other) =>
|
|
||||||
cmd.toLowerCase() match {
|
private def commandGMZoneRotate(
|
||||||
case "medkit" =>
|
message: ChatMsg,
|
||||||
medkitSanityTest(session.player.GUID, avatar.shortcuts)
|
command: String,
|
||||||
|
content: String,
|
||||||
|
session: Session,
|
||||||
|
chatService: ActorRef[ChatService.Command],
|
||||||
|
cluster: ActorRef[InterstellarClusterService.Command],
|
||||||
|
isGM: Boolean
|
||||||
|
): Boolean = {
|
||||||
|
|
||||||
|
val buffer = content.toLowerCase.split("\\s+")
|
||||||
|
cluster ! InterstellarClusterService.CavernRotation(buffer.headOption match {
|
||||||
|
case Some("-list") | Some("-l") =>
|
||||||
|
CavernRotationService.ReportRotationOrder(sessionActor.toClassic)
|
||||||
|
case _ =>
|
||||||
|
CavernRotationService.HurryNextRotation
|
||||||
|
})
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
private def commandSuicide(
|
||||||
|
message: ChatMsg,
|
||||||
|
command: String,
|
||||||
|
content: String,
|
||||||
|
session: Session,
|
||||||
|
chatService: ActorRef[ChatService.Command],
|
||||||
|
cluster: ActorRef[InterstellarClusterService.Command],
|
||||||
|
isGM: Boolean
|
||||||
|
): Boolean = {
|
||||||
|
|
||||||
|
// this is like CMT_SUICIDE but it ignores checks and forces a suicide state
|
||||||
|
val tplayer = session.player
|
||||||
|
|
||||||
|
tplayer.Revive
|
||||||
|
tplayer.Actor ! Player.Die()
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
private def commandGrenade(
|
||||||
|
message: ChatMsg,
|
||||||
|
command: String,
|
||||||
|
content: String,
|
||||||
|
session: Session,
|
||||||
|
chatService: ActorRef[ChatService.Command],
|
||||||
|
cluster: ActorRef[InterstellarClusterService.Command],
|
||||||
|
isGM: Boolean
|
||||||
|
): Boolean = {
|
||||||
|
|
||||||
|
WorldSession.QuickSwapToAGrenade(session.player, DrawnSlot.Pistol1.id, log)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
private def commandMacro(
|
||||||
|
message: ChatMsg,
|
||||||
|
command: String,
|
||||||
|
content: String,
|
||||||
|
session: Session,
|
||||||
|
chatService: ActorRef[ChatService.Command],
|
||||||
|
cluster: ActorRef[InterstellarClusterService.Command],
|
||||||
|
isGM: Boolean
|
||||||
|
): Boolean = {
|
||||||
|
|
||||||
|
val avatar = session.avatar
|
||||||
|
val args = content.split(" ").filter(_ != "")
|
||||||
|
|
||||||
|
(args.headOption, args.lift(1)) match {
|
||||||
|
|
||||||
|
case (Some(cmd), other) =>
|
||||||
|
cmd.toLowerCase() match {
|
||||||
|
|
||||||
|
case "medkit" =>
|
||||||
|
medkitSanityTest(session.player.GUID, avatar.shortcuts)
|
||||||
|
true
|
||||||
|
|
||||||
|
case "implants" =>
|
||||||
|
//implant shortcut sanity test
|
||||||
|
implantSanityTest(
|
||||||
|
session.player.GUID,
|
||||||
|
avatar.implants.collect {
|
||||||
|
case Some(implant) if implant.definition.implantType != ImplantType.None => implant.definition
|
||||||
|
},
|
||||||
|
avatar.shortcuts
|
||||||
|
)
|
||||||
|
true
|
||||||
|
|
||||||
|
case name
|
||||||
|
if ImplantType.values.exists { a => a.shortcut.tile.equals(name) } =>
|
||||||
|
avatar.implants.find {
|
||||||
|
case Some(implant) => implant.definition.Name.equalsIgnoreCase(name)
|
||||||
|
case None => false
|
||||||
|
} match {
|
||||||
|
|
||||||
|
case Some(Some(implant)) =>
|
||||||
|
//specific implant shortcut sanity test
|
||||||
|
implantSanityTest(session.player.GUID, Seq(implant.definition), avatar.shortcuts)
|
||||||
true
|
true
|
||||||
|
|
||||||
case "implants" =>
|
case _ if other.nonEmpty =>
|
||||||
//implant shortcut sanity test
|
//add macro?
|
||||||
implantSanityTest(
|
|
||||||
session.player.GUID,
|
|
||||||
avatar.implants.collect {
|
|
||||||
case Some(implant) if implant.definition.implantType != ImplantType.None => implant.definition
|
|
||||||
},
|
|
||||||
avatar.shortcuts
|
|
||||||
)
|
|
||||||
true
|
|
||||||
|
|
||||||
case name
|
|
||||||
if ImplantType.values.exists { a => a.shortcut.tile.equals(name) } =>
|
|
||||||
avatar.implants.find {
|
|
||||||
case Some(implant) => implant.definition.Name.equalsIgnoreCase(name)
|
|
||||||
case None => false
|
|
||||||
} match {
|
|
||||||
case Some(Some(implant)) =>
|
|
||||||
//specific implant shortcut sanity test
|
|
||||||
implantSanityTest(session.player.GUID, Seq(implant.definition), avatar.shortcuts)
|
|
||||||
true
|
|
||||||
case _ if other.nonEmpty =>
|
|
||||||
//add macro?
|
|
||||||
macroSanityTest(session.player.GUID, name, args.drop(2).mkString(" "), avatar.shortcuts)
|
|
||||||
true
|
|
||||||
case _ =>
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
case name
|
|
||||||
if name.nonEmpty && other.nonEmpty =>
|
|
||||||
//add macro
|
|
||||||
macroSanityTest(session.player.GUID, name, args.drop(2).mkString(" "), avatar.shortcuts)
|
macroSanityTest(session.player.GUID, name, args.drop(2).mkString(" "), avatar.shortcuts)
|
||||||
true
|
true
|
||||||
|
|
||||||
case _ =>
|
case _ =>
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case name
|
||||||
|
if name.nonEmpty && other.nonEmpty =>
|
||||||
|
//add macro
|
||||||
|
macroSanityTest(session.player.GUID, name, args.drop(2).mkString(" "), avatar.shortcuts)
|
||||||
|
true
|
||||||
|
|
||||||
case _ =>
|
case _ =>
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
} else if (contents.startsWith("!progress")) {
|
|
||||||
val ourRank = BattleRank.withExperience(session.avatar.bep).value
|
case _ =>
|
||||||
if (!session.account.gm &&
|
false
|
||||||
(ourRank <= Config.app.game.promotion.broadcastBattleRank ||
|
}
|
||||||
ourRank > Config.app.game.promotion.resetBattleRank && ourRank < Config.app.game.promotion.maxBattleRank + 1)) {
|
}
|
||||||
setBattleRank(dropFirstWord(contents), session, AvatarActor.Progress)
|
|
||||||
true
|
private def commandProgress(
|
||||||
} else {
|
message: ChatMsg,
|
||||||
setBattleRank(contents="1", session, AvatarActor.Progress)
|
command: String,
|
||||||
false
|
content: String,
|
||||||
}
|
session: Session,
|
||||||
} else {
|
chatService: ActorRef[ChatService.Command],
|
||||||
false // unknown ! commands are ignored
|
cluster: ActorRef[InterstellarClusterService.Command],
|
||||||
}
|
isGM: Boolean
|
||||||
|
): Boolean = {
|
||||||
|
|
||||||
|
val ourRank = BattleRank.withExperience(session.avatar.bep).value
|
||||||
|
if (!session.account.gm &&
|
||||||
|
(ourRank <= Config.app.game.promotion.broadcastBattleRank ||
|
||||||
|
ourRank > Config.app.game.promotion.resetBattleRank && ourRank < Config.app.game.promotion.maxBattleRank + 1)) {
|
||||||
|
setBattleRank(content, session, AvatarActor.Progress)
|
||||||
|
true
|
||||||
} else {
|
} else {
|
||||||
false // unknown ! commands are ignored
|
setBattleRank(contents = "1", session, AvatarActor.Progress)
|
||||||
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private def dropFirstWord(str: String): String = {
|
private def setBattleRank(
|
||||||
val noExtraSpaces = str.replaceAll("\\s+", " ").toLowerCase.trim
|
|
||||||
noExtraSpaces.indexOf(" ") match {
|
|
||||||
case -1 => ""
|
|
||||||
case beforeFirstBlank => noExtraSpaces.drop(beforeFirstBlank + 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def setBattleRank(
|
|
||||||
contents: String,
|
contents: String,
|
||||||
session: Session,
|
session: Session,
|
||||||
msgFunc: Long => AvatarActor.Command
|
msgFunc: Long => AvatarActor.Command
|
||||||
|
|
@ -1345,7 +1512,7 @@ class ChatActor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def setCommandRank(
|
private def setCommandRank(
|
||||||
contents: String,
|
contents: String,
|
||||||
session: Session
|
session: Session
|
||||||
): Boolean = {
|
): Boolean = {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue