Skip to content

Commit

Permalink
Merge pull request #1448 from madsboddum/fix/tipping/cash-range-check
Browse files Browse the repository at this point in the history
/tip range check
  • Loading branch information
Josh-Larson committed Dec 3, 2023
2 parents a6037b4 + 9c24eb5 commit bd85bcd
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ private enum class TipType {

class CmdTip : ICmdCallback {
override fun execute(player: Player, target: SWGObject?, args: String) {
val tipType = tipType(args)
val amount = args.replace(" bank", "").toIntOrNull()

if (amount == null) {
Expand Down Expand Up @@ -73,18 +72,27 @@ class CmdTip : ICmdCallback {
return
}

val tipType = tipType(args, player, target)
if (tipType == TipType.CASH) {
CashTipIntent.broadcast(player, targetPlayer, amount)
} else if (tipType == TipType.BANK) {
BankTipIntent.broadcast(player, targetPlayer, amount)
}
}

private fun tipType(args: String): TipType {
return if (args.endsWith(" bank")) {
TipType.BANK
} else {
TipType.CASH
private fun tipType(args: String, player: Player, target: SWGObject): TipType {
if (args.endsWith(" bank")) {
return TipType.BANK
}

if (player.creatureObject.terrain != target.terrain) {
return TipType.BANK
}

if (player.creatureObject.worldLocation.distanceTo(target.worldLocation) > 16) {
return TipType.BANK
}

return TipType.CASH
}
}
31 changes: 30 additions & 1 deletion src/test/java/com/projectswg/holocore/headless/admin.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@
***********************************************************************************/
package com.projectswg.holocore.headless

import com.projectswg.common.data.location.Terrain
import com.projectswg.common.network.packets.swg.zone.UpdateContainmentMessage
import com.projectswg.common.network.packets.swg.zone.UpdateTransformMessage
import com.projectswg.common.network.packets.swg.zone.UpdateTransformWithParentMessage
import com.projectswg.common.network.packets.swg.zone.chat.ChatSystemMessage
import com.projectswg.common.network.packets.swg.zone.deltas.DeltasMessage
import com.projectswg.holocore.resources.support.objects.swg.SWGObject
Expand All @@ -47,4 +51,29 @@ fun ZonedInCharacter.adminKill(target: SWGObject?) {
fun ZonedInCharacter.adminGrantSkill(skill: String) {
sendCommand("grantSkill", args = skill)
player.waitForNextPacket(DeltasMessage::class.java, 50, TimeUnit.MILLISECONDS) ?: java.lang.IllegalStateException("No known packet received")
}
}

/**
* Admin command /teleport
* @param target The object to teleport. If null, the player executing the command will be teleported.
* @param planet The planet to teleport to
* @param x The x coordinate to teleport to
* @param y The y coordinate to teleport to
* @param z The z coordinate to teleport to
*/
fun ZonedInCharacter.adminTeleport(target: SWGObject? = null, planet: Terrain, x: Number, y: Number, z: Number) {
val argList = mutableListOf<String>()
if (target != null) {
val targetFirstName = target.objectName.split(" ").first()
argList.add(targetFirstName)
}

argList.add(planet.getName())
argList.add(x.toInt().toString())
argList.add(y.toInt().toString())
argList.add(z.toInt().toString())

sendCommand("teleport", args = argList.joinToString(separator = " "))

player.waitForNextPacket(setOf(UpdateContainmentMessage::class.java, UpdateTransformMessage::class.java, UpdateTransformWithParentMessage::class.java), 50, TimeUnit.MILLISECONDS) ?: java.lang.IllegalStateException("No known packet received")
}
28 changes: 25 additions & 3 deletions src/test/java/com/projectswg/holocore/headless/tipping.kt
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,37 @@ import com.projectswg.common.network.packets.swg.zone.server_ui.SuiCreatePageMes
import com.projectswg.holocore.resources.support.objects.swg.SWGObject
import java.util.concurrent.TimeUnit

fun ZonedInCharacter.tipCash(target: SWGObject, amount: Int) {
/**
* Simulates the /tip <amount> command on a target.
* This includes expected behavior such as the bank tip window opening, if the target is too far away.
*/
fun ZonedInCharacter.tip(target: SWGObject, amount: Int): SuiWindow? {
val differentPlanets = player.creatureObject.terrain != target.terrain
val tooFarAway = player.creatureObject.worldLocation.distanceTo(target.worldLocation) > 16

if (differentPlanets || tooFarAway) {
sendCommand("tip", target, amount.toString())
return awaitBankTipResponse()
}

sendCommand("tip", target, amount.toString())
val packet = player.waitForNextPacket(ChatSystemMessage::class.java, 50, TimeUnit.MILLISECONDS) ?: throw IllegalStateException("No known packet received")
checkSystemMessage(packet)
return null
}

/**
* Simulates the /tip <amount> bank command on a target.
*/
fun ZonedInCharacter.tipBank(target: SWGObject, amount: Int): SuiWindow {
sendCommand("tip", target, "$amount bank")
val packet = player.waitForNextPacket(setOf(SuiCreatePageMessage::class.java, ChatSystemMessage::class.java), 50, TimeUnit.MILLISECONDS) ?: throw IllegalStateException("No known packet received")
return awaitBankTipResponse()
}

private fun ZonedInCharacter.awaitBankTipResponse(): SuiWindow {
val packet = player.waitForNextPacket(
setOf(SuiCreatePageMessage::class.java, ChatSystemMessage::class.java), 50, TimeUnit.MILLISECONDS
) ?: throw IllegalStateException("No known packet received")

if (packet is SuiCreatePageMessage) {
val suiWindowId = packet.window.id
Expand All @@ -49,7 +71,7 @@ fun ZonedInCharacter.tipBank(target: SWGObject, amount: Int): SuiWindow {
} else if (packet is ChatSystemMessage) {
checkSystemMessage(packet)
}

throw IllegalStateException()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@
***********************************************************************************/
package com.projectswg.holocore.services.gameplay.player

import com.projectswg.common.data.location.Terrain
import com.projectswg.holocore.headless.*
import com.projectswg.holocore.resources.support.global.player.AccessLevel
import com.projectswg.holocore.test.runners.IntegrationTest
import org.junit.jupiter.api.Assertions.*
import org.junit.jupiter.api.Test
Expand All @@ -40,7 +42,7 @@ class TipCreditsTest : IntegrationTest() {
val tipAmount = -50

assertThrows(TipException::class.java) {
zonedInCharacter1.tipCash(zonedInCharacter2.player.creatureObject, tipAmount)
zonedInCharacter1.tip(zonedInCharacter2.player.creatureObject, tipAmount)
}
}

Expand All @@ -61,7 +63,7 @@ class TipCreditsTest : IntegrationTest() {
val womprat = spawnNPC("creature_womprat", zonedInCharacter1.player.creatureObject.location)

assertThrows(TipException::class.java) {
zonedInCharacter1.tipCash(womprat, 1)
zonedInCharacter1.tip(womprat, 1)
}
}

Expand All @@ -70,7 +72,7 @@ class TipCreditsTest : IntegrationTest() {
val zonedInCharacter1 = createZonedInCharacter("Playerone", "Charone")

assertThrows(TipException::class.java) {
zonedInCharacter1.tipCash(zonedInCharacter1.player.creatureObject, 1)
zonedInCharacter1.tip(zonedInCharacter1.player.creatureObject, 1)
}
}

Expand All @@ -82,7 +84,7 @@ class TipCreditsTest : IntegrationTest() {
val char2Before = CreditsSnapshot(zonedInCharacter2)
val tipAmount = 1

zonedInCharacter1.tipCash(zonedInCharacter2.player.creatureObject, tipAmount)
zonedInCharacter1.tip(zonedInCharacter2.player.creatureObject, tipAmount)

val char1After = CreditsSnapshot(zonedInCharacter1)
val char2After = CreditsSnapshot(zonedInCharacter2)
Expand All @@ -92,17 +94,6 @@ class TipCreditsTest : IntegrationTest() {
)
}

@Test
fun insufficientCash() {
val zonedInCharacter1 = createZonedInCharacter("Playerone", "Charone")
val zonedInCharacter2 = createZonedInCharacter("Playertwo", "Chartwo")
val tipAmount = zonedInCharacter1.player.creatureObject.cashBalance * 2

assertThrows(TipException::class.java) {
zonedInCharacter1.tipCash(zonedInCharacter2.player.creatureObject, tipAmount)
}
}

@Test
fun sufficientBank() {
val zonedInCharacter1 = createZonedInCharacter("Playerone", "Charone")
Expand All @@ -124,6 +115,38 @@ class TipCreditsTest : IntegrationTest() {
)
}

@Test
fun tooFarAway() {
val zonedInCharacter1 = createZonedInCharacter("Playerone", "Charone")
val zonedInCharacter2 = createZonedInCharacter("Playertwo", "Chartwo")
zonedInCharacter2.adminTeleport(
planet = zonedInCharacter1.player.creatureObject.terrain,
x = zonedInCharacter1.player.creatureObject.x + 20,
y = zonedInCharacter1.player.creatureObject.y,
z = zonedInCharacter1.player.creatureObject.z
)

val suiWindow = zonedInCharacter1.tip(zonedInCharacter2.player.creatureObject, 100)

assertNotNull(suiWindow, "Expected a bank tip window to open")
}

@Test
fun differentPlanet() {
val zonedInCharacter1 = createZonedInCharacter("Playerone", "Charone")
val zonedInCharacter2 = createZonedInCharacter("Playertwo", "Chartwo")
zonedInCharacter2.adminTeleport( // Same coordinates, but different planet
planet = Terrain.DANTOOINE,
x = zonedInCharacter1.player.creatureObject.x,
y = zonedInCharacter1.player.creatureObject.y,
z = zonedInCharacter1.player.creatureObject.z
)

val suiWindow = zonedInCharacter1.tip(zonedInCharacter2.player.creatureObject, 100)

assertNotNull(suiWindow, "Expected a bank tip window to open")
}

@Test
fun insufficientBank() {
val zonedInCharacter1 = createZonedInCharacter("Playerone", "Charone")
Expand All @@ -138,7 +161,7 @@ class TipCreditsTest : IntegrationTest() {

private fun createZonedInCharacter(username: String, characterName: String): ZonedInCharacter {
val password = "password"
addUser(username, password)
addUser(username, password, accessLevel = AccessLevel.DEV)
return HeadlessSWGClient.createZonedInCharacter(username, password, characterName)
}

Expand Down

0 comments on commit bd85bcd

Please sign in to comment.