diff --git a/src/main/java/net/tfminecraft/recycler/ownership/CharacterQueueEstate.java b/src/main/java/net/tfminecraft/recycler/ownership/CharacterQueueEstate.java index c7b2bc0..7963ddf 100644 --- a/src/main/java/net/tfminecraft/recycler/ownership/CharacterQueueEstate.java +++ b/src/main/java/net/tfminecraft/recycler/ownership/CharacterQueueEstate.java @@ -17,11 +17,17 @@ public final class CharacterQueueEstate implements EstateParticipant { private final Recycler plugin; private final Map> reported = new java.util.HashMap<>(); + static final long HOUR_TICKS = 72_000L; + /** 45 minutes: keeps the hourly pass off the tick other plugins' hourly jobs share (enable + 1 h). */ + static final long HOURLY_OFFSET_TICKS = 54_000L; public CharacterQueueEstate(Recycler plugin) { this.plugin = plugin; } public static void start(Recycler plugin) { CharacterQueueEstate participant = new CharacterQueueEstate(plugin); plugin.getServer().getServicesManager().register(EstateParticipant.class, participant, plugin, ServicePriority.Normal); - plugin.getServer().getScheduler().runTaskTimer(plugin, participant::reconcile, 1L, 72_000L); + var scheduler = plugin.getServer().getScheduler(); + // Boot pass on the first tick as before; the hourly passes then run 45 minutes later than they did. + scheduler.runTaskLater(plugin, participant::reconcile, 1L); + scheduler.runTaskTimer(plugin, participant::reconcile, 1L + HOUR_TICKS + HOURLY_OFFSET_TICKS, HOUR_TICKS); } public String id() { return "recycler"; } public Outcome settle(EstateDecision decision) { diff --git a/src/test/java/net/tfminecraft/recycler/ownership/QueueEstateTest.java b/src/test/java/net/tfminecraft/recycler/ownership/QueueEstateTest.java index 77573b4..5296b98 100644 --- a/src/test/java/net/tfminecraft/recycler/ownership/QueueEstateTest.java +++ b/src/test/java/net/tfminecraft/recycler/ownership/QueueEstateTest.java @@ -61,6 +61,10 @@ class QueueEstateTest { } var server=mock(org.bukkit.Server.class);var services=mock(org.bukkit.plugin.ServicesManager.class);var scheduler=mock(org.bukkit.scheduler.BukkitScheduler.class); when(plugin.getServer()).thenReturn(server);when(server.getServicesManager()).thenReturn(services);when(server.getScheduler()).thenReturn(scheduler); - QueueEstate.start(plugin);verify(services).register(eq(EstateParticipant.class),any(CharacterQueueEstate.class),eq(plugin),eq(org.bukkit.plugin.ServicePriority.Normal));verify(scheduler).runTaskTimer(eq(plugin),any(Runnable.class),eq(1L),eq(72_000L)); + QueueEstate.start(plugin);verify(services).register(eq(EstateParticipant.class),any(CharacterQueueEstate.class),eq(plugin),eq(org.bukkit.plugin.ServicePriority.Normal)); + // Boot pass on the first tick; hourly passes 45 minutes off the enable + 1 h tick other plugins use. + var boot=org.mockito.ArgumentCaptor.forClass(Runnable.class);var hourly=org.mockito.ArgumentCaptor.forClass(Runnable.class); + verify(scheduler).runTaskLater(eq(plugin),boot.capture(),eq(1L));verify(scheduler).runTaskTimer(eq(plugin),hourly.capture(),eq(1L+72_000L+54_000L),eq(72_000L));verifyNoMoreInteractions(scheduler); + try(var estates=mockStatic(Estates.class)){boot.getValue().run();hourly.getValue().run();estates.verify(Estates::decided,times(2));} } }