From ec3a0eb90a878db5cdcda5bd3163f310161f0c73 Mon Sep 17 00:00:00 2001 From: Ryan Barlow <7389646+ryanbarlow97@users.noreply.github.com> Date: Sun, 27 Sep 2026 15:23:39 +0000 Subject: [PATCH] Cancel a maintenance pay request after one vehicle click The pay session was only cleared when the payment succeeded. A failed attempt (no unpaid maintenance, insufficient funds or an unregistered vehicle) left it armed, so every vehicle right-click was cancelled and repeated the error until the 60-second timeout. Clear the session after any payment attempt, matching the transfer and release sessions. Players rerun the command to try again. Co-Authored-By: Claude Opus 5.5 (1M context) --- .../VehicleMaintenancePayListener.java | 12 +++++++--- .../VehicleMaintenanceBankCommandTest.java | 24 +++++++++++++++++++ 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/tfminecraft/simplefactions/vehicles/maintenance/VehicleMaintenancePayListener.java b/src/main/java/net/tfminecraft/simplefactions/vehicles/maintenance/VehicleMaintenancePayListener.java index 3f1adb6b..90c7e456 100644 --- a/src/main/java/net/tfminecraft/simplefactions/vehicles/maintenance/VehicleMaintenancePayListener.java +++ b/src/main/java/net/tfminecraft/simplefactions/vehicles/maintenance/VehicleMaintenancePayListener.java @@ -39,14 +39,20 @@ public void onVehiclePreInteract(VehiclePreInteractEvent event) { return; } + pay(leader, session, vehicle.getUUID(), vehicle.getId()); + } + + void pay(Player leader, VehicleMaintenancePaySession session, String vehicleUuid, String vehicleTypeId) { VehicleMaintenancePayResult result = payService.tryPay( leader.getUniqueId(), - vehicle.getUUID(), - vehicle.getId(), + vehicleUuid, + vehicleTypeId, session.getPaymentSource()); + // One click per armed command, whatever the outcome, so a failed payment + // does not keep swallowing vehicle interactions until the session expires. + sessionManager.clear(leader.getUniqueId()); switch (result) { case SUCCESS -> { - sessionManager.clear(leader.getUniqueId()); SimpleFactions plugin = SimpleFactions.getInstance(); if (plugin != null) { plugin.saveVehicleRegistry(); diff --git a/src/test/java/net/tfminecraft/simplefactions/vehicles/maintenance/VehicleMaintenanceBankCommandTest.java b/src/test/java/net/tfminecraft/simplefactions/vehicles/maintenance/VehicleMaintenanceBankCommandTest.java index b11fc656..86938494 100644 --- a/src/test/java/net/tfminecraft/simplefactions/vehicles/maintenance/VehicleMaintenanceBankCommandTest.java +++ b/src/test/java/net/tfminecraft/simplefactions/vehicles/maintenance/VehicleMaintenanceBankCommandTest.java @@ -127,4 +127,28 @@ void expiredBankSessionCannotCharge() { assertNull(sessions.get(payer)); verifyNoInteractions(service); } + + @Test + void failedPaymentDisarmsSessionSoLaterClicksReachTheVehicle() { + Player player = mock(Player.class); + UUID payer = UUID.randomUUID(); + when(player.getUniqueId()).thenReturn(payer); + var sessions = new VehicleMaintenancePaySessionManager(); + var session = new VehicleMaintenancePaySessionManager.VehicleMaintenancePaySession( + System.currentTimeMillis() + 60_000, PaymentSource.BANK); + sessions.put(payer, session); + var service = mock(VehicleMaintenancePayService.class); + when(service.tryPay(payer, "vehicle-uuid", "cog", PaymentSource.BANK)) + .thenReturn(VehicleMaintenancePayService.VehicleMaintenancePayResult.NOT_UNPAID); + var listener = new VehicleMaintenancePayListener(sessions, service); + + listener.pay(player, session, "vehicle-uuid", "cog"); + verify(player).sendMessage(VehicleMaintenanceMessages.notUnpaid()); + assertNull(sessions.get(payer)); + + var nextClick = new VehiclePreInteractEvent(player, null); + listener.onVehiclePreInteract(nextClick); + assertFalse(nextClick.isCancelled()); + verify(service, times(1)).tryPay(any(), any(), any(), any()); + } }