Skip to content

Commit

Permalink
feat: Implement cyclic inventory saves. Closes #7
Browse files Browse the repository at this point in the history
  • Loading branch information
Philip Urban committed Dec 22, 2020
1 parent a29cc51 commit 5e52e83
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 10 deletions.
6 changes: 6 additions & 0 deletions src/main/java/de/raidcraft/rcinventory/PluginConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ public class PluginConfig extends BukkitYamlConfiguration {
private int restoreDelayMs = 500;
@Comment("Writes a chat message to player after inventory was restored")
private boolean restoreMessage = true;
@Comment("Interval in minutes to save player inventories periodically. 0 = disabled")
private int saveIntervalMin = 5;
@Comment("Enable console messages about skipped inventory save events")
private boolean logSkippedSaves = true;
@Comment("Enable console messages about successfull inventory load events")
private boolean logSuccessfulLoads = true;

public PluginConfig(Path path) {

Expand Down
5 changes: 1 addition & 4 deletions src/main/java/de/raidcraft/rcinventory/RCInventory.java
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,7 @@ public void reload() {
@Override
public void onDisable() {

// Save all player inventories here
for(Player player : Bukkit.getOnlinePlayers()) {
inventoryManager.savePlayerInventory(player);
}
inventoryManager.saveAllPlayersInventories();
}

private void loadConfig() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package de.raidcraft.rcinventory.listener;

import de.raidcraft.rcinventory.RCInventory;
import de.raidcraft.rcinventory.util.SchedulerUtil;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
Expand Down Expand Up @@ -41,7 +42,7 @@ public void onPlayerJoin(PlayerJoinEvent event) {
restoreCache.put(event.getPlayer().getUniqueId(), System.currentTimeMillis());
DelayedPlayerRestoreTask task = new DelayedPlayerRestoreTask(event.getPlayer());
Bukkit.getScheduler().runTaskLater(plugin, task,
plugin.getPluginConfig().getRestoreDelayMs() / 50 /* Ms per tick */);
SchedulerUtil.msInTicks(plugin.getPluginConfig().getRestoreDelayMs()));
}

@EventHandler(priority = EventPriority.HIGHEST)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,45 @@
import de.raidcraft.rcinventory.inventory.Base64Inventory;
import de.raidcraft.rcinventory.inventory.Inventory;
import de.raidcraft.rcinventory.database.TDatabaseInventory;
import de.raidcraft.rcinventory.util.SchedulerUtil;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitTask;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

public class InventoryManager {

RCInventory plugin;
private final static int SAVE_TASK_PROCESS_INTERVAL_MS = 60*1000;
private RCInventory plugin;
private BukkitTask saveTask = null;

public InventoryManager(RCInventory plugin) {

this.plugin = plugin;
setupSaveTask();
}

public void setupSaveTask() {

if(saveTask != null) {
Bukkit.getScheduler().cancelTask(saveTask.getTaskId());
saveTask = null;
}

PeriodicSaveTask task = new PeriodicSaveTask();
saveTask = Bukkit.getScheduler().runTaskTimer(plugin, task,
SchedulerUtil.msInTicks(SAVE_TASK_PROCESS_INTERVAL_MS),
SchedulerUtil.msInTicks(SAVE_TASK_PROCESS_INTERVAL_MS));
}

public void saveAllPlayersInventories() {

Bukkit.getOnlinePlayers().forEach(player -> savePlayerInventory(player));
}

public void savePlayerInventory(Player player) {
Expand All @@ -39,11 +67,13 @@ public void savePlayerInventory(Player player) {
// Save inventory to database
TDatabaseInventory databaseInventory = new TDatabaseInventory(inventory);
if(latestInventory != null && latestInventory.equals(databaseInventory)) {
plugin.getLogger().info("Inventory of '" + player.getDisplayName() + "' already synced");
if(plugin.getPluginConfig().isLogSkippedSaves()) {
plugin.getLogger().info("Inventory of '" + player.getDisplayName() + "' already up-to-date");
}
return;
}
databaseInventory.save();
plugin.getLogger().info("Synced inventory of '" + player.getDisplayName() + "' into database");
plugin.getLogger().info("Saved inventory of '" + player.getDisplayName() + "' into database");
}

public void restorePlayerInventory(Player player) {
Expand Down Expand Up @@ -74,6 +104,31 @@ public void restorePlayerInventory(Player player) {
if(plugin.getPluginConfig().isRestoreMessage()) {
Messages.send(player, Messages.inventoryRestored(player, inventory));
}
plugin.getLogger().info("Restored inventory of '" + player.getDisplayName() + "' from database");
if(plugin.getPluginConfig().isLogSuccessfulLoads()) {
plugin.getLogger().info("Restored inventory of '" + player.getDisplayName() + "' from database");
}
}

private class PeriodicSaveTask implements Runnable {

private Map<UUID, Long> lastSaves = new HashMap<>();

@Override
public void run() {

Bukkit.getOnlinePlayers().forEach(player -> {

// Check if last save was recently
if(lastSaves.containsKey(player.getUniqueId())) {
long timeGone = System.currentTimeMillis() - lastSaves.get(player.getUniqueId());
if(timeGone < SchedulerUtil.minInMs(plugin.getPluginConfig().getSaveIntervalMin())) {
return;
}
}

savePlayerInventory(player);
lastSaves.put(player.getUniqueId(), System.currentTimeMillis());
});
}
}
}
16 changes: 16 additions & 0 deletions src/main/java/de/raidcraft/rcinventory/util/SchedulerUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package de.raidcraft.rcinventory.util;

public class SchedulerUtil {

public final static int MS_PER_TICK = 50;

public static int msInTicks(int ms) {

return ms / MS_PER_TICK;
}

public static int minInMs(int min) {

return min * 60 * 1000;
}
}
11 changes: 10 additions & 1 deletion src/test/java/de/raidcraft/rcinventory/IntegrationTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@
import be.seeseemelk.mockbukkit.MockBukkit;
import be.seeseemelk.mockbukkit.ServerMock;
import de.raidcraft.rcinventory.database.TDatabaseInventory;
import io.ebean.Model;
import org.bukkit.entity.Player;
import org.junit.jupiter.api.*;

import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;

public class IntegrationTest {
Expand All @@ -31,15 +35,20 @@ class InventoryManagerTests {

@BeforeEach
void setUp() {
TDatabaseInventory.find.all().forEach(entry -> entry.delete());

}

@Test
@DisplayName("save-inventory")
void storeInventory() {



Player player = server.addPlayer();

// Delete all entries
TDatabaseInventory.find.all().forEach(Model::delete);

// Database must be empty
assertThat(TDatabaseInventory.find.query().findCount() == 0).isTrue();

Expand Down

0 comments on commit 5e52e83

Please sign in to comment.