Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] Save Command (and tweaks to logging) #4167

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 2 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
@@ -0,0 +1,39 @@
package io.github.thebusybiscuit.slimefun4.core.commands.subcommands;

import io.github.thebusybiscuit.slimefun4.core.commands.SlimefunCommand;
import io.github.thebusybiscuit.slimefun4.core.commands.SubCommand;
import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuide;
import io.github.thebusybiscuit.slimefun4.core.services.AutoSavingService;
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;

import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;

public class SaveCommand extends SubCommand {
private final AutoSavingService service;

@ParametersAreNonnullByDefault
SaveCommand(Slimefun plugin, SlimefunCommand cmd) {
super(plugin, cmd, "save", false);
this.service = Slimefun.getAutoSavingService();
}

@Override
public void onExecute(@Nonnull CommandSender sender, @Nonnull String[] args) {
if (!(sender instanceof Player)) {
Slimefun.getLocalization().sendMessage(sender, "messages.only-players", true);
return;
}
JustAHuman-xD marked this conversation as resolved.
Show resolved Hide resolved

if (sender.hasPermission("slimefun.command.save")) {
boolean savedPlayers = this.service.saveAllPlayers(false);
Slimefun.getLocalization().sendMessage(sender, "commands.save.players." + savedPlayers, true);
boolean savedBlocks = this.service.saveAllBlocks(false);
Slimefun.getLocalization().sendMessage(sender, "commands.save.blocks." + savedBlocks, true);
} else {
Slimefun.getLocalization().sendMessage(sender, "messages.no-permission", true);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public static Collection<SubCommand> getAllCommands(@Nonnull SlimefunCommand cmd
commands.add(new BackpackCommand(plugin, cmd));
commands.add(new ChargeCommand(plugin, cmd));
commands.add(new DebugCommand(plugin, cmd));
commands.add(new SaveCommand(plugin, cmd))

return commands;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
public class AutoSavingService {

private int interval;
private boolean savingPlayers;
private boolean savingBlocks;

/**
* This method starts the {@link AutoSavingService} with the given interval.
Expand All @@ -41,19 +43,25 @@ public class AutoSavingService {
public void start(@Nonnull Slimefun plugin, int interval) {
this.interval = interval;

plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, this::saveAllPlayers, 2000L, interval * 60L * 20L);
plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, this::saveAllBlocks, 2000L, interval * 60L * 20L);
plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, () -> saveAllPlayers(true), 2000L, interval * 60L * 20L);
plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, () -> saveAllBlocks(true), 2000L, interval * 60L * 20L);
}

/**
* This method saves every {@link PlayerProfile} in memory and removes profiles
* that were marked for deletion.
*/
private void saveAllPlayers() {
public boolean saveAllPlayers(boolean auto) {
if (this.savingPlayers) {
return false;
}

this.savingPlayers = true;
long startTime = System.currentTimeMillis();
Iterator<PlayerProfile> iterator = PlayerProfile.iterator();
int players = 0;

Debug.log(TestCase.PLAYER_PROFILE_DATA, "Saving all players data");
Debug.log(TestCase.PLAYER_PROFILE_DATA, "Saving all player data");

while (iterator.hasNext()) {
PlayerProfile profile = iterator.next();
Expand Down Expand Up @@ -81,14 +89,28 @@ private void saveAllPlayers() {
}

if (players > 0) {
Slimefun.logger().log(Level.INFO, "Auto-saved all player data for {0} player(s)!", players);
if (auto) {
Slimefun.logger().log(Level.INFO, "Auto-saved all player data for {0} player(s)!", players);
} else {
Slimefun.logger().log(Level.INFO, "Saved all player data for {0} player(s)!", players);
}
Slimefun.logger().log(Level.INFO, "Took {0}ms!", System.currentTimeMillis() - startTime);
JustAHuman-xD marked this conversation as resolved.
Show resolved Hide resolved
}

this.savingPlayers = false;
return true;
}

/**
* This method saves the data of every {@link Block} marked dirty by {@link BlockStorage}.
*/
private void saveAllBlocks() {
public boolean saveAllBlocks(boolean auto) {
if (this.savingBlocks) {
return false;
}

this.savingBlocks = true;
long startTime = System.currentTimeMillis();
Set<BlockStorage> worlds = new HashSet<>();

for (World world : Bukkit.getWorlds()) {
Expand All @@ -104,14 +126,22 @@ private void saveAllBlocks() {
}

if (!worlds.isEmpty()) {
Slimefun.logger().log(Level.INFO, "Auto-saving block data... (Next auto-save: {0}m)", interval);
if (auto) {
Slimefun.logger().log(Level.INFO, "Auto-saving block data... (Next auto-save: {0}m)", interval);
} else {
Slimefun.logger().log(Level.INFO, "Saving block data...");
JustAHuman-xD marked this conversation as resolved.
Show resolved Hide resolved
}

for (BlockStorage storage : worlds) {
storage.save();
}
}

BlockStorage.saveChunks();
Slimefun.logger().log(Level.INFO, "Saved all block data, took {0}ms!", System.currentTimeMillis() - startTime);
JustAHuman-xD marked this conversation as resolved.
Show resolved Hide resolved

this.savingBlocks = false;
return true;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -828,6 +828,11 @@ private static void validateInstance() {
return instance.blockDataService;
}

public static @Nonnull AutoSavingService getAutoSavingService() {
validateInstance();
return instance.autoSavingService;
}

/**
* This method returns out world settings service.
* That service is responsible for managing item settings per
Expand Down
8 changes: 8 additions & 0 deletions src/main/resources/languages/en/messages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,14 @@ commands:
running: '&7Running debug mode with test: &6%test%'
disabled: '&7Disabled debug mode.'

save:
players:
true: 'Successfully saved player-data!'
false: 'Player-data is already saving!'
blocks:
true: 'Successfully saved blockstorage!'
false: 'Blockstorage is already saving!'
JustAHuman-xD marked this conversation as resolved.
Show resolved Hide resolved

placeholderapi:
profile-loading: 'Loading...'

Expand Down
Loading