diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionRentableSpace.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionRentableSpace.java index 8bd18bd3..e900e4f6 100644 --- a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionRentableSpace.java +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionRentableSpace.java @@ -3,6 +3,7 @@ package com.eu.habbo.habbohotel.items.interactions; import com.eu.habbo.Emulator; import com.eu.habbo.habbohotel.gameclients.GameClient; import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.permissions.Permission; import com.eu.habbo.habbohotel.rooms.Room; import com.eu.habbo.habbohotel.rooms.RoomLayout; import com.eu.habbo.habbohotel.rooms.RoomUnit; @@ -133,12 +134,18 @@ public class InteractionRentableSpace extends HabboItem { if (habbo.getHabboStats().isRentingSpace()) return; - if (habbo.getHabboInfo().getCredits() < this.rentCost()) + int cost = this.rentCost(); + boolean hasInfiniteCredits = habbo.hasPermission(Permission.ACC_INFINITE_CREDITS); + if (!hasInfiniteCredits && habbo.getHabboInfo().getCredits() < cost) return; if (habbo.getHabboStats().getClubExpireTimestamp() < Emulator.getIntUnixTimestamp()) return; + if (!hasInfiniteCredits) { + habbo.giveCredits(-cost); + } + this.setRenterId(habbo.getHabboInfo().getId()); this.setRenterName(habbo.getHabboInfo().getUsername()); this.setEndTimestamp(Emulator.getIntUnixTimestamp() + (7 * 86400)); diff --git a/Emulator/src/test/java/com/eu/habbo/habbohotel/items/interactions/RentableSpaceChargeContractTest.java b/Emulator/src/test/java/com/eu/habbo/habbohotel/items/interactions/RentableSpaceChargeContractTest.java new file mode 100644 index 00000000..24cb1818 --- /dev/null +++ b/Emulator/src/test/java/com/eu/habbo/habbohotel/items/interactions/RentableSpaceChargeContractTest.java @@ -0,0 +1,31 @@ +package com.eu.habbo.habbohotel.items.interactions; + +import org.junit.jupiter.api.Test; + +import java.nio.file.Files; +import java.nio.file.Path; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +class RentableSpaceChargeContractTest { + @Test + void rentingSpaceChargesCreditsBeforeMarkingSpaceRented() throws Exception { + String source = Files.readString(Path.of("src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionRentableSpace.java")); + int rentMethod = source.indexOf("public void rent(Habbo habbo)"); + + assertTrue(rentMethod >= 0, "InteractionRentableSpace must keep explicit rent handling"); + + String rentHandling = source.substring(rentMethod, Math.min(source.length(), rentMethod + 1400)); + + assertTrue(rentHandling.contains("int cost = this.rentCost();"), + "Rent cost must be computed once before charging"); + assertTrue(rentHandling.contains("boolean hasInfiniteCredits = habbo.hasPermission(Permission.ACC_INFINITE_CREDITS);"), + "Renting must honor infinite-credit staff permission before charging"); + assertTrue(rentHandling.contains("!hasInfiniteCredits && habbo.getHabboInfo().getCredits() < cost"), + "Renting must reject non-staff users without enough credits for the computed cost"); + assertTrue(rentHandling.contains("habbo.giveCredits(-cost);"), + "Renting must deduct the computed credit cost"); + assertTrue(rentHandling.indexOf("habbo.giveCredits(-cost);") < rentHandling.indexOf("this.setRenterId"), + "Credits must be charged before the rentable space is marked as rented"); + } +}