Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1093,7 +1093,8 @@ private void registerVehicleIntegration(boolean full) {
vehicleRegistryClaimService, vehicleFeeStore, vehicleFeeConfirmations, this::saveVehicleFees,
getLogger()), this);
} else {
getServer().getPluginManager().registerEvents(new VehicleClaimsOff(), this);
getServer().getPluginManager().registerEvents(
net.tfminecraft.simplefactions.vehicles.owners.VehicleClaimGuards.create(), this);
}
// VehicleFramework loads its vehicles as it enables, so wait before reading owners.
getServer().getScheduler().runTaskLater(this, this::recordVehicleOwners, 200L);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package net.tfminecraft.simplefactions.vehicles.owners;

import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;

import net.tfminecraft.vehicleframework.events.VehicleOwnerClaimedEvent;

/** Compatibility bridge, loaded only when the provider lacks the modern event. */
public final class LegacyVehicleClaimsOff implements Listener {
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onClaim(VehicleOwnerClaimedEvent event) {
VehicleClaimGuards.refuse(event.getPlayer(), event);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package net.tfminecraft.simplefactions.vehicles.owners;

import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Listener;

import net.tfminecraft.simplefactions.utils.Permissions;

/** Selects a claim guard without loading listener types absent from the installed provider. */
public final class VehicleClaimGuards {
public static final String MESSAGE = "§cClaiming vehicles is off until VehicleFramework is updated.";

private VehicleClaimGuards() {}

public static Listener create() {
return create("net.tfminecraft.vehicleframework.events.VehicleOwnershipChangeEvent",
"net.tfminecraft.vehicleframework.events.VehicleOwnerClaimedEvent");
}

static Listener create(String modernEvent, String legacyEvent) {
if (present(modernEvent)) return new VehicleClaimsOff();
if (present(legacyEvent)) return new LegacyVehicleClaimsOff();
throw new IllegalStateException("VehicleFramework has no supported claim event");
}

private static boolean present(String eventClass) {
try {
Class.forName(eventClass);
return true;
} catch (ClassNotFoundException | LinkageError missing) {
return false;
}
}

static void refuse(Player player, Cancellable event) {
if (player == null || Permissions.isAdmin(player)) return;
event.setCancelled(true);
player.sendMessage(MESSAGE);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,21 @@
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;

import net.tfminecraft.simplefactions.utils.Permissions;
import net.tfminecraft.vehicleframework.events.VehicleOwnerClaimedEvent;
import net.tfminecraft.vehicleframework.api.OwnershipReason;
import net.tfminecraft.vehicleframework.events.VehicleOwnershipChangeEvent;

/**
* Without VehicleFramework 2.13 in characters mode, SimpleFactions cannot record a
* character payer for a claim, so non-staff claims are refused. The claim event exists
* in every VehicleFramework version, so this listener loads on older ones too.
* character payer for a claim, so non-staff claims are refused.
* Load this listener only after probing the modern ownership event.
*/
public final class VehicleClaimsOff implements Listener {
public static final String MESSAGE = "§cClaiming vehicles is off until VehicleFramework is updated.";
public static final String MESSAGE = VehicleClaimGuards.MESSAGE;

@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onClaim(VehicleOwnerClaimedEvent event) {
if (event.getPlayer() == null || Permissions.isAdmin(event.getPlayer())) return;
event.setCancelled(true);
event.getPlayer().sendMessage(MESSAGE);
public void onClaim(VehicleOwnershipChangeEvent event) {
if (event.getReason() == OwnershipReason.CLAIM) {
VehicleClaimGuards.refuse(event.getPlayer(), event);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,6 @@ void materialDepositsConsumeOnlySupportedMaterialsAtAnOwnedBank(String state) {
assertEquals(state.equals("deposit") ? 0 : 7, material.getAmount());
long credited = net.tfminecraft.denareconomy.api.Denars.balance(net.tfminecraft.denareconomy.api.Denars.bank(ref));
assertEquals(87.5, credited / 100d + material.getAmount() * coin.getValue());
verify(money, never()).addMoneyToAccount(anyString(), anyDouble(), anyBoolean(), anyBoolean(), any());
}

@ParameterizedTest
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@
import net.tfminecraft.vehicleframework.database.VehicleSnapshot;
import net.tfminecraft.vehicleframework.enums.VehicleDeath;
import net.tfminecraft.vehicleframework.enums.VehicleRemoveReason;
import net.tfminecraft.vehicleframework.events.VehicleOwnerClaimedEvent;
import net.tfminecraft.vehicleframework.events.VehiclePreInteractEvent;
import net.tfminecraft.vehicleframework.events.VehicleRemoveEvent;
import net.tfminecraft.vehicleframework.events.VehicleSpawnEvent;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
package net.tfminecraft.simplefactions.vehicles.owners;

import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;

import java.util.UUID;
import org.bukkit.entity.Player;
import org.junit.jupiter.api.Test;

import net.tfminecraft.vehicleframework.api.OwnershipReason;
import net.tfminecraft.vehicleframework.events.VehicleOwnerClaimedEvent;
import net.tfminecraft.vehicleframework.events.VehicleOwnershipChangeEvent;
import net.tfminecraft.vehicleframework.vehicles.ActiveVehicle;

class VehicleClaimsOffTest {
Expand All @@ -19,18 +18,51 @@ void withoutCharacterOwnershipOnlyStaffMayClaim() {
Player player = mock(Player.class);
Player staff = mock(Player.class);
when(staff.hasPermission("simplefactions.admin")).thenReturn(true);
ActiveVehicle vehicle = mock(ActiveVehicle.class);

VehicleOwnerClaimedEvent claim = new VehicleOwnerClaimedEvent(player, vehicle, "none", "player_Steve");
VehicleOwnershipChangeEvent claim = claim(player, OwnershipReason.CLAIM);
guard.onClaim(claim);
VehicleOwnerClaimedEvent staffClaim = new VehicleOwnerClaimedEvent(staff, vehicle, "none", "player_Admin");
VehicleOwnershipChangeEvent staffClaim = claim(staff, OwnershipReason.CLAIM);
guard.onClaim(staffClaim);
VehicleOwnerClaimedEvent nobody = new VehicleOwnerClaimedEvent(null, vehicle, "none", "player_x");
guard.onClaim(nobody);

VehicleOwnershipChangeEvent other = claim(player, OwnershipReason.TAKEOVER);
guard.onClaim(other);
assertTrue(claim.isCancelled());
verify(player).sendMessage(VehicleClaimsOff.MESSAGE);
assertFalse(staffClaim.isCancelled());
assertFalse(nobody.isCancelled());
assertFalse(other.isCancelled());
}

@Test
void legacyBridgeKeepsTheOldStaffAndMissingPlayerPolicy() {
LegacyVehicleClaimsOff guard = new LegacyVehicleClaimsOff();
Player player = mock(Player.class);
Player staff = mock(Player.class);
when(staff.hasPermission("simplefactions.admin")).thenReturn(true);
VehicleOwnerClaimedEvent claim = new VehicleOwnerClaimedEvent(player, null, "none", "player_A");
VehicleOwnerClaimedEvent allowed = new VehicleOwnerClaimedEvent(staff, null, "none", "player_Staff");
VehicleOwnerClaimedEvent absent = new VehicleOwnerClaimedEvent(null, null, "none", "player_X");
guard.onClaim(claim);
guard.onClaim(allowed);
guard.onClaim(absent);
assertTrue(claim.isCancelled());
verify(player).sendMessage(VehicleClaimsOff.MESSAGE);
assertFalse(allowed.isCancelled());
assertFalse(absent.isCancelled());
}

@Test
void selectsModernBeforeLegacyAndRefusesAnUnknownProvider() {
String legacy = VehicleOwnerClaimedEvent.class.getName();
assertInstanceOf(VehicleClaimsOff.class, VehicleClaimGuards.create());
assertInstanceOf(LegacyVehicleClaimsOff.class, VehicleClaimGuards.create("missing.Modern", legacy));
assertInstanceOf(LegacyVehicleClaimsOff.class, VehicleClaimGuards.create(BrokenEvent.class.getName(), legacy));
assertThrows(IllegalStateException.class, () -> VehicleClaimGuards.create("missing.Modern", "missing.Legacy"));
}

static final class BrokenEvent {
static { if (true) throw new NoClassDefFoundError("missing dependency"); }
}

private static VehicleOwnershipChangeEvent claim(Player player, OwnershipReason reason) {
return new VehicleOwnershipChangeEvent(player, mock(ActiveVehicle.class), reason, UUID.randomUUID(),
null, false, null, null, "none", "player_A");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import org.junit.jupiter.api.Test;

import net.tfminecraft.simplefactions.loaders.VehiclesConfigLoader;
import net.tfminecraft.vehicleframework.events.VehicleOwnerClaimedEvent;
import net.tfminecraft.vehicleframework.events.VehiclePreInteractEvent;

class VehicleRegistryClaimListenerTest {
private Path tempDir;
Expand Down Expand Up @@ -52,8 +52,8 @@ void tearDown() throws IOException {
@Test
void handleClaimResult_cancelsOnSlotLimit() {
Player player = mock(Player.class);
VehicleOwnerClaimedEvent event =
new VehicleOwnerClaimedEvent(player, null, "none", "player_Test");
VehiclePreInteractEvent event =
new VehiclePreInteractEvent(player, null);

VehicleRegistryClaimListener.handleClaimResult(
event,
Expand All @@ -68,8 +68,8 @@ void handleClaimResult_cancelsOnSlotLimit() {
@Test
void handleClaimResult_allowsRegistered() {
Player player = mock(Player.class);
VehicleOwnerClaimedEvent event =
new VehicleOwnerClaimedEvent(player, null, "none", "player_Test");
VehiclePreInteractEvent event =
new VehiclePreInteractEvent(player, null);

VehicleRegistryClaimListener.handleClaimResult(
event,
Expand Down
Loading