Upgrade cooldown management to allow syncs and add more settings

This commit is contained in:
GeorgH93 2018-06-07 22:10:11 +02:00
parent 71b2e3f447
commit 09cd1a0fb2
No known key found for this signature in database
GPG Key ID: D1630D37F9E4B3C8
11 changed files with 210 additions and 52 deletions

View File

@ -26,11 +26,18 @@ MaxSize: 6
# AllowedGameModes: [ "SURVIVAL", "ADVENTURE" ]
AllowedGameModes: [ "SURVIVAL" ]
# Defines how long a player have to wait till he can reopen his backpack.
# Time is in seconds. Values < 1 disable the cooldown.
CommandCooldown: -1
# If enabled whe cooldown will be synced between servers (BungeeCord network). It will also prevent players from leaving and joining to bypass the cooldown.
SyncCooldown: false
Cooldown:
# Defines how long a player have to wait till he can reopen his backpack.
# Time is in seconds. Values < 1 disable the cooldown.
Command: -1
# If enabled whe cooldown will be synced between servers (BungeeCord network). It will also allow to keep cooldown through server restarts.
# You should only use it with long lasting cooldowns.
Sync: false
AddOnJoin: true
# You can turn this on when using sync to reduce the memory consumption a little bit
ClearOnLeave: false
# Removes old cooldowns from the cache to free memory. Time in seconds.
CleanupInterval: 600
# Controls for the auto pickup on full inventory function
FullInventory:

View File

@ -11,8 +11,8 @@ Language:
InvalidBackpack: "Invalid backpack."
NotAllowedInBackpack: "&c{ItemName} is not allowed in the backpack."
Open:
#Parameter: {TimeLeft} time in seconds till he can reopen his backpack
Cooldown: "&2Please wait {TimeLeft} seconds till you reopen your backpack."
#Parameter: {TimeLeft} time in seconds till he can reopen his backpack, {TimeSpanLeft}
Cooldown: "&2Please wait {TimeSpanLeft} seconds till you reopen your backpack."
#Parameter: {CurrentGameMode}, {AllowedGameModes}
WrongGameMode: "You are not allowed to open your backpack in your current game-mode."
Clean:

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2016, 2017 GeorgH93
* Copyright (C) 2016-2018 GeorgH93
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@ -18,6 +18,7 @@
package at.pcgamingfreaks.Minepacks.Bukkit.Command;
import at.pcgamingfreaks.Bukkit.Message.Message;
import at.pcgamingfreaks.Calendar.TimeSpan;
import at.pcgamingfreaks.Command.HelpData;
import at.pcgamingfreaks.Minepacks.Bukkit.API.MinepacksCommand;
import at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;
@ -35,8 +36,6 @@ public class OpenCommand extends MinepacksCommand
{
private final Message messageCooldown, messageWrongGameMode;
private final String allowedGameModes, descriptionOpenOthers, helpParam;
private final long cooldown;
private final boolean syncCooldown;
private final Minepacks plugin;
public OpenCommand(Minepacks plugin)
@ -44,14 +43,11 @@ public OpenCommand(Minepacks plugin)
super(plugin, "open", plugin.getLanguage().getTranslated("Commands.Description.Backpack"), "backpack.use", true, plugin.getLanguage().getCommandAliases("Open"));
this.plugin = plugin;
messageCooldown = plugin.getLanguage().getMessage("Ingame.Open.Cooldown").replaceAll("\\{TimeLeft}", "%1\\$.1f");
messageWrongGameMode = plugin.getLanguage().getMessage("Ingame.Open.WrongGameMode").replaceAll("\\{CurrentGameMode}", "%1\\$s").replaceAll("\\{AllowedGameModes}", "%1\\$s");
messageCooldown = plugin.getLanguage().getMessage("Ingame.Open.Cooldown").replaceAll("\\{TimeLeft}", "%1\\$.1f").replaceAll("\\{TimeSpanLeft}", "%2\\$s");
messageWrongGameMode = plugin.getLanguage().getMessage("Ingame.Open.WrongGameMode").replaceAll("\\{CurrentGameMode}", "%1\\$s").replaceAll("\\{AllowedGameModes}", "%1\\$s");
descriptionOpenOthers = plugin.getLanguage().getTranslated("Commands.Description.OpenOthers");
helpParam = "<" + plugin.getLanguage().get("Commands.PlayerNameVariable") + ">";
cooldown = plugin.getConfiguration().getCommandCooldown();
syncCooldown = plugin.getConfiguration().isCommandCooldownSyncEnabled();
StringBuilder allowedGameModesBuilder = new StringBuilder();
for(GameMode gameMode : plugin.getConfiguration().getAllowedGameModes())
{
@ -72,24 +68,16 @@ public void execute(@NotNull CommandSender sender, @NotNull String main, @NotNul
{
if(getMinepacksPlugin().isPlayerGameModeAllowed(player))
{
if(cooldown > 0 && !player.hasPermission("backpack.noCooldown"))
if(plugin.getCooldownManager() != null && !player.hasPermission("backpack.noCooldown"))
{
if(plugin.cooldowns.containsKey(player.getUniqueId()))
long cd = plugin.getCooldownManager().getRemainingCooldown(player);
if(cd > 0)
{
long cd = plugin.cooldowns.get(player.getUniqueId());
if(cd < System.currentTimeMillis())
{
cd = cd - System.currentTimeMillis();
messageCooldown.send(sender, cd / 1000f);
return;
}
TimeSpan ts = new TimeSpan(cd, true);
messageCooldown.send(sender, cd / 1000f, ts.toString());
return;
}
final long cooldownTime = System.currentTimeMillis() + cooldown;
if(syncCooldown)
{
plugin.getDatabase().syncCooldown(player, cooldownTime);
}
plugin.cooldowns.put(player.getUniqueId(), cooldownTime);
plugin.getCooldownManager().setCooldown(player);
}
plugin.openBackpack(player, player, true);
}

View File

@ -0,0 +1,125 @@
/*
* Copyright (C) 2018 GeorgH93
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package at.pcgamingfreaks.Minepacks.Bukkit;
import at.pcgamingfreaks.Minepacks.Bukkit.API.Callback;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class CooldownManager extends BukkitRunnable implements Listener
{
private final Minepacks plugin;
private final Map<UUID, Long> cooldowns = new HashMap<>();
private final long cooldown;
private final boolean syncCooldown, addOnJoin, clearOnLeave;
public CooldownManager(Minepacks plugin)
{
this.plugin = plugin;
cooldown = plugin.getConfiguration().getCommandCooldown();
syncCooldown = plugin.getConfiguration().isCommandCooldownSyncEnabled();
addOnJoin = plugin.getConfiguration().isCommandCooldownAddOnJoinEnabled();
clearOnLeave = plugin.getConfiguration().isCommandCooldownClearOnLeaveEnabled();
plugin.getServer().getPluginManager().registerEvents(this, plugin);
runTaskTimer(plugin, plugin.getConfiguration().getCommandCooldownCleanupInterval(), plugin.getConfiguration().getCommandCooldownCleanupInterval());
}
public void close()
{
cancel();
HandlerList.unregisterAll(this);
}
public void setCooldown(Player player)
{
final long cooldownTime = System.currentTimeMillis() + cooldown;
if(syncCooldown)
{
plugin.getDatabase().syncCooldown(player, cooldownTime);
}
cooldowns.put(player.getUniqueId(), cooldownTime);
}
@SuppressWarnings("unused")
public boolean isInCooldown(Player player)
{
return cooldowns.getOrDefault(player.getUniqueId(), 0L) > System.currentTimeMillis();
}
public long getRemainingCooldown(Player player)
{
long cd = cooldowns.getOrDefault(player.getUniqueId(), 0L);
if(cd > System.currentTimeMillis())
{
return cd - System.currentTimeMillis();
}
return 0;
}
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerJoinEvent(PlayerJoinEvent event)
{
if(syncCooldown)
{
final UUID uuid = event.getPlayer().getUniqueId();
cooldowns.put(uuid, System.currentTimeMillis() + cooldown); // Temporary cooldown till the data is loaded from the database
plugin.getDatabase().getCooldown(event.getPlayer(), new Callback<Long>() {
@Override
public void onResult(Long dbCooldownTime)
{
if(dbCooldownTime > System.currentTimeMillis())
{
cooldowns.put(uuid, dbCooldownTime);
}
}
@Override
public void onFail() {}
});
}
else if(addOnJoin)
{
setCooldown(event.getPlayer());
}
}
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerLeaveEvent(PlayerQuitEvent event)
{
if(clearOnLeave) cooldowns.remove(event.getPlayer().getUniqueId());
}
@Override
public void run()
{
cooldowns.entrySet().removeIf(entry -> entry.getValue() < System.currentTimeMillis());
}
}

View File

@ -198,12 +198,27 @@ public boolean isBungeeCordModeEnabled()
public long getCommandCooldown()
{
return getConfig().getInt("CommandCooldown", -1) * 1000L;
return getConfig().getInt("Cooldown.Command", -1) * 1000L;
}
public boolean isCommandCooldownSyncEnabled()
{
return getConfig().getBoolean("SyncCooldown", false);
return getConfig().getBoolean("Cooldown.Sync", false);
}
public boolean isCommandCooldownClearOnLeaveEnabled()
{
return getConfig().getBoolean("Cooldown.ClearOnLeave", false);
}
public boolean isCommandCooldownAddOnJoinEnabled()
{
return getConfig().getBoolean("Cooldown.AddOnJoin", true);
}
public long getCommandCooldownCleanupInterval()
{
return getConfig().getInt("Cooldown.CleanupInterval", 600) * 20L;
}
public Collection<GameMode> getAllowedGameModes()

View File

@ -222,7 +222,9 @@ public void updatePlayerAndLoadBackpack(Player player)
public abstract void saveBackpack(Backpack backpack);
public abstract void syncCooldown(Player player, long time);
public void syncCooldown(Player player, long time) {}
public void getCooldown(final Player player, final Callback<Long> callback) {}
protected abstract void loadBackpack(final OfflinePlayer player, final Callback<Backpack> callback);
}

View File

@ -143,12 +143,6 @@ public void saveBackpack(Backpack backpack)
}
}
@Override
public void syncCooldown(Player player, long time)
{
// There is no reason for cooldown syncing in file mode
}
@Override
protected void loadBackpack(final OfflinePlayer player, final Callback<Backpack> callback)
{

View File

@ -41,8 +41,8 @@ public static void updateConfig(YAML oldYAML, YAML newYAML)
}
switch(key)
{
case "CommandCooldown": oldKey = "command_cooldown"; break;
case "SyncCooldown": oldKey = "sync_cooldown"; break;
case "Cooldown.Command": oldKey = "command_cooldown"; break;
case "Cooldown.Sync": oldKey = "sync_cooldown"; break;
case "DropOnDeath": oldKey = "drop_on_death"; break;
case "MaxSize": oldKey = "max_size"; break;
case "AllowedGameModes": oldKey = "allowed_game_modes"; break;

View File

@ -40,7 +40,7 @@
import java.util.*;
public abstract class SQL extends Database
{ //TODO load cooldown
{
private HikariDataSource dataSource;
protected String tablePlayers, tableBackpacks, tableCooldowns; // Table Names
@ -212,6 +212,7 @@ protected final void buildQuerys()
queryGetPlayerID = "SELECT {FieldPlayerID} FROM {TablePlayers} WHERE {FieldUUID}=?;";
queryGetBP += "{FieldUUID}=?;";
querySyncCooldown = "INSERT INTO {TableCooldowns} ({FieldCDPlayer},{FieldCDTime}) SELECT {FieldPlayerID},? FROM {TablePlayers} WHERE {FieldUUID}=?;";
queryGetCooldown = "SELECT * FROM {TableCooldowns} WHERE {FieldCDPlayer} IN (SELECT {FieldPlayerID} FROM {TablePlayers} WHERE {FieldUUID}=?);";
}
else
{
@ -219,6 +220,7 @@ protected final void buildQuerys()
queryGetPlayerID = "SELECT {FieldPlayerID} FROM {TablePlayers} WHERE {FieldName}=?;";
queryGetBP += "{FieldName}=?;";
querySyncCooldown = "INSERT INTO {TableCooldowns} ({FieldCDPlayer},{FieldCDTime}) SELECT {FieldPlayerID},? FROM {TablePlayers} WHERE {FieldName}=?;";
queryGetCooldown = "SELECT * FROM {TableCooldowns} WHERE {FieldCDPlayer} IN (SELECT {FieldPlayerID} FROM {TablePlayers} WHERE {FieldName}=?);";
}
queryInsertBp = "REPLACE INTO {TableBackpacks} ({FieldBPOwner},{FieldBPITS},{FieldBPVersion}) VALUES (?,?,?);";
queryUpdateBp = "UPDATE {TableBackpacks} SET {FieldBPITS}=?,{FieldBPVersion}=?,{FieldBPLastUpdate}={NOW} WHERE {FieldBPOwner}=?;";
@ -251,6 +253,7 @@ protected void setTableAndFieldNames()
queryDeleteOldBackpacks = replacePlaceholders(queryDeleteOldBackpacks.replaceAll("\\{VarMaxAge}", maxAge + ""));
queryGetUnsetOrInvalidUUIDs = replacePlaceholders(queryGetUnsetOrInvalidUUIDs);
querySyncCooldown = replacePlaceholders(querySyncCooldown);
queryGetCooldown = replacePlaceholders(queryGetCooldown);
queryDeleteOldCooldowns = replacePlaceholders(queryDeleteOldCooldowns);
}
@ -320,7 +323,7 @@ public void saveBackpack(final Backpack backpack)
{
if(rs.next())
{
final int newID = rs.getInt(1);
final int newID = rs.getInt(fieldPlayerID);
DBTools.runStatement(connection, queryInsertBp, newID, data, usedSerializer);
plugin.getServer().getScheduler().runTask(plugin, () -> backpack.setOwnerID(newID));
}
@ -374,9 +377,9 @@ protected void loadBackpack(final OfflinePlayer player, final Callback<Backpack>
{
if(rs.next())
{
bpID = rs.getInt(1);
version = rs.getInt(3);
data = rs.getBytes(2);
bpID = rs.getInt(fieldBpOwner);
version = rs.getInt(fieldBpVersion);
data = rs.getBytes(fieldBpIts);
}
else
{
@ -410,4 +413,25 @@ public void syncCooldown(Player player, long cooldownTime)
{
runStatementAsync(querySyncCooldown, new Timestamp(cooldownTime), getPlayerNameOrUUID(player));
}
@Override
public void getCooldown(final Player player, final Callback<Long> callback)
{
plugin.getServer().getScheduler().runTaskAsynchronously(plugin, () -> {
try(Connection conn = getConnection(); PreparedStatement ps = conn.prepareStatement(queryGetCooldown))
{
ps.setString(1, getPlayerNameOrUUID(player));
try(ResultSet rs = ps.executeQuery())
{
final long time = (rs.next()) ? rs.getLong(fieldCdTime) : 0;
plugin.getServer().getScheduler().runTask(plugin, () -> callback.onResult(time));
}
}
catch(SQLException e)
{
e.printStackTrace();
plugin.getServer().getScheduler().runTask(plugin, () -> callback.onResult(0L));
}
});
}
}

View File

@ -55,9 +55,6 @@
import java.io.File;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class Minepacks extends JavaPlugin implements MinepacksPlugin
{
@ -69,8 +66,6 @@ public class Minepacks extends JavaPlugin implements MinepacksPlugin
private Language lang;
private Database database;
public final Map<UUID, Long> cooldowns = new HashMap<>();
public String backpackTitleOther = "%s Backpack", backpackTitle = "Backpack";
public Message messageNoPermission, messageInvalidBackpack, messageWorldDisabled, messageNotFromConsole;
@ -80,6 +75,7 @@ public class Minepacks extends JavaPlugin implements MinepacksPlugin
private ItemsCollector collector;
private CommandManager commandManager;
private Collection<GameMode> gameModes;
private CooldownManager cooldownManager = null;
public static Minepacks getInstance()
{
@ -194,6 +190,7 @@ private void load()
}
gameModes = config.getAllowedGameModes();
if(config.getCommandCooldown() > 0) cooldownManager = new CooldownManager(this);
}
private void unload()
@ -204,7 +201,8 @@ private void unload()
HandlerList.unregisterAll(this); // Stop the listeners
getServer().getScheduler().cancelTasks(this); // Kill all running task
database.close(); // Close the DB connection, we won't need them any longer
cooldowns.clear();
if(cooldownManager != null) cooldownManager.close();
cooldownManager = null;
}
public void reload()
@ -328,4 +326,9 @@ public boolean isPlayerGameModeAllowed(Player player)
{
return gameModes.contains(player.getGameMode()) || player.hasPermission("backpack.ignoreGameMode");
}
public @Nullable CooldownManager getCooldownManager()
{
return cooldownManager;
}
}