mirror of
https://github.com/TotalFreedomMC/TF-ProjectKorra.git
synced 2024-12-23 00:15:05 +00:00
Added new cooldown system
This commit is contained in:
parent
3641f4ab9b
commit
aee46d53c3
8 changed files with 395 additions and 44 deletions
|
@ -5,6 +5,7 @@ import java.util.UUID;
|
|||
|
||||
import co.aikar.timings.lib.MCTiming;
|
||||
|
||||
import com.projectkorra.projectkorra.cooldown.CooldownManager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.World;
|
||||
|
@ -49,6 +50,10 @@ public class BendingManager implements Runnable {
|
|||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated handled by {@link CooldownManager}.
|
||||
*/
|
||||
@Deprecated
|
||||
public void handleCooldowns() {
|
||||
for (final UUID uuid : BendingPlayer.getPlayers().keySet()) {
|
||||
final BendingPlayer bPlayer = BendingPlayer.getPlayers().get(uuid);
|
||||
|
|
230
src/com/projectkorra/projectkorra/cooldown/CooldownManager.java
Normal file
230
src/com/projectkorra/projectkorra/cooldown/CooldownManager.java
Normal file
|
@ -0,0 +1,230 @@
|
|||
package com.projectkorra.projectkorra.cooldown;
|
||||
|
||||
import com.projectkorra.projectkorra.event.PlayerCooldownChangeEvent;
|
||||
import com.projectkorra.projectkorra.module.DatabaseModule;
|
||||
import com.projectkorra.projectkorra.module.ModuleManager;
|
||||
import com.projectkorra.projectkorra.player.BendingPlayer;
|
||||
import com.projectkorra.projectkorra.player.BendingPlayerLoadedEvent;
|
||||
import com.projectkorra.projectkorra.player.BendingPlayerManager;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.PriorityQueue;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class CooldownManager extends DatabaseModule<CooldownRepository>
|
||||
{
|
||||
private final BendingPlayerManager _bendingPlayerManager;
|
||||
|
||||
private final Map<UUID, Map<String, Cooldown>> _cooldownMap = new HashMap<>();
|
||||
private final Map<UUID, PriorityQueue<Cooldown>> _cooldownQueue = new HashMap<>();
|
||||
|
||||
private final Function<UUID, PriorityQueue<Cooldown>> _queueFunction = uuid -> new PriorityQueue<>(Comparator.comparing(cooldown -> cooldown.ExpireTime));
|
||||
|
||||
private CooldownManager()
|
||||
{
|
||||
super("Cooldown", new CooldownRepository());
|
||||
|
||||
_bendingPlayerManager = ModuleManager.getModule(BendingPlayerManager.class);
|
||||
|
||||
runAsync(() ->
|
||||
{
|
||||
try
|
||||
{
|
||||
getRepository().createTables();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
|
||||
runTimer(() ->
|
||||
{
|
||||
_cooldownQueue.forEach((uuid, cooldowns) ->
|
||||
{
|
||||
long currentTime = System.currentTimeMillis();
|
||||
|
||||
while (!cooldowns.isEmpty())
|
||||
{
|
||||
Cooldown cooldown = cooldowns.peek();
|
||||
|
||||
if (currentTime < cooldown.ExpireTime)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
_cooldownMap.get(uuid).remove(cooldown.AbilityName);
|
||||
cooldowns.poll();
|
||||
|
||||
if (cooldown.Permanent)
|
||||
{
|
||||
int playerId = _bendingPlayerManager.getBendingPlayer(uuid).getId();
|
||||
|
||||
runAsync(() ->
|
||||
{
|
||||
try
|
||||
{
|
||||
getRepository().deleteCooldown(playerId, cooldown.AbilityName);
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
_cooldownMap.values().removeIf(Map::isEmpty);
|
||||
_cooldownQueue.values().removeIf(PriorityQueue::isEmpty);
|
||||
}, 1, 1);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onBendingPlayerLoaded(BendingPlayerLoadedEvent event)
|
||||
{
|
||||
Player player = event.getPlayer();
|
||||
BendingPlayer bendingPlayer = event.getBendingPlayer();
|
||||
|
||||
runAsync(() ->
|
||||
{
|
||||
try
|
||||
{
|
||||
Map<String, Cooldown> cooldowns = getRepository().selectCooldowns(bendingPlayer.getId());
|
||||
|
||||
_cooldownMap.computeIfAbsent(player.getUniqueId(), k -> new HashMap<>()).putAll(cooldowns);
|
||||
_cooldownQueue.computeIfAbsent(player.getUniqueId(), _queueFunction).addAll(cooldowns.values());
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onQuit(PlayerQuitEvent event)
|
||||
{
|
||||
_cooldownMap.remove(event.getPlayer().getUniqueId());
|
||||
_cooldownQueue.remove(event.getPlayer().getUniqueId());
|
||||
}
|
||||
|
||||
public void addCooldown(Player player, String abilityName, long duration, boolean permanent)
|
||||
{
|
||||
if (duration <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
PlayerCooldownChangeEvent event = new PlayerCooldownChangeEvent(player, abilityName, duration, PlayerCooldownChangeEvent.Result.ADDED);
|
||||
getPlugin().getServer().getPluginManager().callEvent(event);
|
||||
|
||||
if (event.isCancelled())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
long expireTime = System.currentTimeMillis() + duration;
|
||||
Cooldown cooldown = new Cooldown(abilityName, expireTime, permanent);
|
||||
|
||||
_cooldownMap.computeIfAbsent(player.getUniqueId(), k -> new HashMap<>()).put(abilityName, cooldown);
|
||||
_cooldownQueue.computeIfAbsent(player.getUniqueId(), _queueFunction).add(cooldown);
|
||||
|
||||
if (permanent)
|
||||
{
|
||||
int playerId = _bendingPlayerManager.getBendingPlayer(player).getId();
|
||||
|
||||
runAsync(() ->
|
||||
{
|
||||
try
|
||||
{
|
||||
getRepository().insertCooldown(playerId, abilityName, expireTime);
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public long getCooldown(Player player, String abilityName)
|
||||
{
|
||||
Map<String, Cooldown> cooldowns = _cooldownMap.get(player.getUniqueId());
|
||||
|
||||
if (cooldowns != null && cooldowns.containsKey(abilityName))
|
||||
{
|
||||
return cooldowns.get(abilityName).ExpireTime;
|
||||
}
|
||||
|
||||
return -1L;
|
||||
}
|
||||
|
||||
public boolean isOnCooldown(Player player, String abilityName)
|
||||
{
|
||||
Map<String, Cooldown> cooldowns = _cooldownMap.get(player.getUniqueId());
|
||||
|
||||
return cooldowns != null && cooldowns.containsKey(abilityName);
|
||||
}
|
||||
|
||||
public void removeCooldown(Player player, Cooldown cooldown)
|
||||
{
|
||||
UUID uuid = player.getUniqueId();
|
||||
|
||||
if (_cooldownMap.containsKey(uuid))
|
||||
{
|
||||
_cooldownMap.get(uuid).remove(cooldown.AbilityName);
|
||||
}
|
||||
|
||||
if (_cooldownQueue.containsKey(uuid))
|
||||
{
|
||||
_cooldownQueue.get(uuid).remove(cooldown);
|
||||
}
|
||||
|
||||
if (cooldown.Permanent)
|
||||
{
|
||||
int playerId = _bendingPlayerManager.getBendingPlayer(player).getId();
|
||||
|
||||
runAsync(() ->
|
||||
{
|
||||
try
|
||||
{
|
||||
getRepository().deleteCooldown(playerId, cooldown.AbilityName);
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public static class Cooldown
|
||||
{
|
||||
final String AbilityName;
|
||||
final long ExpireTime;
|
||||
final boolean Permanent;
|
||||
|
||||
public Cooldown(String abilityName, long expireTime)
|
||||
{
|
||||
this(abilityName, expireTime, false);
|
||||
}
|
||||
|
||||
public Cooldown(String abilityName, long expireTime, boolean permanent)
|
||||
{
|
||||
AbilityName = abilityName;
|
||||
ExpireTime = expireTime;
|
||||
Permanent = permanent;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
package com.projectkorra.projectkorra.cooldown;
|
||||
|
||||
import com.projectkorra.projectkorra.database.DatabaseQuery;
|
||||
import com.projectkorra.projectkorra.database.DatabaseRepository;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class CooldownRepository extends DatabaseRepository
|
||||
{
|
||||
private static final DatabaseQuery CREATE_TABLE_COOLDOWNS = DatabaseQuery.newBuilder()
|
||||
.query("CREATE TABLE IF NOT EXISTS pk_cooldowns (player_id INTEGER REFERENCES pk_bending_players (player_id), ability_name VARCHAR(100) NOT NULL, expire_time BIGINT NOT NULL, PRIMARY KEY (player_id, ability_name));")
|
||||
.build();
|
||||
|
||||
private static final DatabaseQuery SELECT_COOLDOWNS = DatabaseQuery.newBuilder()
|
||||
.query("SELECT * FROM pk_cooldowns WHERE player_id = ?")
|
||||
.build();
|
||||
|
||||
private static final DatabaseQuery INSERT_COOLDOWN = DatabaseQuery.newBuilder()
|
||||
.query("INSERT INTO pk_cooldowns VALUES (?, ?, ?);")
|
||||
.build();
|
||||
|
||||
private static final DatabaseQuery DELETE_COOLDOWN = DatabaseQuery.newBuilder()
|
||||
.query("DELETE FROM pk_cooldowns WHERE player_id = ? AND ability_name = ?;")
|
||||
.build();
|
||||
|
||||
protected void createTables() throws SQLException
|
||||
{
|
||||
Connection connection = getDatabase().getConnection();
|
||||
|
||||
try (PreparedStatement statement = connection.prepareStatement(CREATE_TABLE_COOLDOWNS.getQuery()))
|
||||
{
|
||||
statement.executeUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
protected Map<String, CooldownManager.Cooldown> selectCooldowns(int playerId) throws SQLException
|
||||
{
|
||||
Connection connection = getDatabase().getConnection();
|
||||
|
||||
try (PreparedStatement statement = connection.prepareStatement(SELECT_COOLDOWNS.getQuery()))
|
||||
{
|
||||
statement.setInt(1, playerId);
|
||||
|
||||
Map<String, CooldownManager.Cooldown> cooldowns = new HashMap<>();
|
||||
|
||||
try (ResultSet rs = statement.executeQuery())
|
||||
{
|
||||
while (rs.next())
|
||||
{
|
||||
String abilityName = rs.getString("ability_name");
|
||||
long expireTime = rs.getLong("expire_time");
|
||||
|
||||
cooldowns.put(abilityName, new CooldownManager.Cooldown(abilityName, expireTime, true));
|
||||
}
|
||||
|
||||
return cooldowns;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void insertCooldown(int playerId, String abilityName, long expireTime) throws SQLException
|
||||
{
|
||||
Connection connection = getDatabase().getConnection();
|
||||
|
||||
try (PreparedStatement statement = connection.prepareStatement(INSERT_COOLDOWN.getQuery()))
|
||||
{
|
||||
statement.setInt(1, playerId);
|
||||
statement.setString(2, abilityName);
|
||||
statement.setLong(3, expireTime);
|
||||
|
||||
statement.executeUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
protected void deleteCooldown(int playerId, String abilityName) throws SQLException
|
||||
{
|
||||
Connection connection = getDatabase().getConnection();
|
||||
|
||||
try (PreparedStatement statement = connection.prepareStatement(DELETE_COOLDOWN.getQuery()))
|
||||
{
|
||||
statement.setInt(1, playerId);
|
||||
statement.setString(2, abilityName);
|
||||
|
||||
statement.executeUpdate();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -103,7 +103,7 @@ public class ElementManager extends DatabaseModule<ElementRepository>
|
|||
.map(_elements::get)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
bendingPlayer.addElements(elements);
|
||||
// bendingPlayer.addElements(elements);
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
|
|
|
@ -65,6 +65,16 @@ public abstract class Module implements Listener
|
|||
getPlugin().getServer().getScheduler().runTaskAsynchronously(getPlugin(), runnable);
|
||||
}
|
||||
|
||||
protected final void runTimer(Runnable runnable, long delay, long period)
|
||||
{
|
||||
getPlugin().getServer().getScheduler().runTaskTimer(getPlugin(), runnable, delay, period);
|
||||
}
|
||||
|
||||
protected final void runAsyncTimer(Runnable runnable, long delay, long period)
|
||||
{
|
||||
getPlugin().getServer().getScheduler().runTaskTimerAsynchronously(getPlugin(), runnable, delay, period);
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return this.name;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.projectkorra.projectkorra.module;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.projectkorra.projectkorra.cooldown.CooldownManager;
|
||||
import com.projectkorra.projectkorra.database.DatabaseManager;
|
||||
import com.projectkorra.projectkorra.element.ElementManager;
|
||||
import com.projectkorra.projectkorra.player.BendingPlayerManager;
|
||||
|
@ -63,12 +64,14 @@ public class ModuleManager {
|
|||
registerModule(DatabaseManager.class);
|
||||
registerModule(BendingPlayerManager.class);
|
||||
registerModule(ElementManager.class);
|
||||
registerModule(CooldownManager.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable all our core {@link Module}s onDisable.
|
||||
*/
|
||||
public static void shutdown() {
|
||||
registerModule(CooldownManager.class);
|
||||
registerModule(ElementManager.class);
|
||||
getModule(BendingPlayerManager.class).disable();
|
||||
getModule(DatabaseManager.class).disable();
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
package com.projectkorra.projectkorra.player;
|
||||
|
||||
import com.projectkorra.projectkorra.element.Element;
|
||||
import com.projectkorra.projectkorra.element.SubElement;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -16,7 +14,6 @@ public class BendingPlayer
|
|||
private final long _firstLogin;
|
||||
|
||||
private final List<Element> _elements;
|
||||
private final List<SubElement> _subElements;
|
||||
|
||||
public BendingPlayer(int playerId, UUID uuid, String playerName, long firstLogin)
|
||||
{
|
||||
|
@ -26,7 +23,6 @@ public class BendingPlayer
|
|||
_firstLogin = firstLogin;
|
||||
|
||||
_elements = new ArrayList<>();
|
||||
_subElements = new ArrayList<>();
|
||||
}
|
||||
|
||||
public int getId()
|
||||
|
@ -38,19 +34,4 @@ public class BendingPlayer
|
|||
{
|
||||
return _firstLogin;
|
||||
}
|
||||
|
||||
public void addElements(Collection<Element> elements)
|
||||
{
|
||||
for (Element element : elements)
|
||||
{
|
||||
if (element instanceof SubElement)
|
||||
{
|
||||
_subElements.add((SubElement) element);
|
||||
}
|
||||
else
|
||||
{
|
||||
_elements.add(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
package com.projectkorra.projectkorra.player;
|
||||
|
||||
import com.projectkorra.projectkorra.GeneralMethods;
|
||||
import com.projectkorra.projectkorra.event.PlayerCooldownChangeEvent;
|
||||
import com.projectkorra.projectkorra.module.DatabaseModule;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.player.PlayerLoginEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
|
@ -24,47 +27,74 @@ public class BendingPlayerManager extends DatabaseModule<BendingPlayerRepository
|
|||
try
|
||||
{
|
||||
getRepository().createTables();
|
||||
|
||||
for (Player player : getPlugin().getServer().getOnlinePlayers())
|
||||
{
|
||||
loadBendingPlayer(player);
|
||||
}
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
runSync(() ->
|
||||
{
|
||||
log("Created database table.");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onLogin(PlayerLoginEvent event)
|
||||
{
|
||||
Player player = event.getPlayer();
|
||||
|
||||
runAsync(() ->
|
||||
{
|
||||
try
|
||||
{
|
||||
BendingPlayer bendingPlayer = getRepository().selectPlayer(player);
|
||||
|
||||
runSync(() ->
|
||||
{
|
||||
_players.put(player.getUniqueId(), bendingPlayer);
|
||||
|
||||
BendingPlayerLoadedEvent bendingPlayerLoadedEvent = new BendingPlayerLoadedEvent(player, bendingPlayer);
|
||||
getPlugin().getServer().getPluginManager().callEvent(bendingPlayerLoadedEvent);
|
||||
});
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
loadBendingPlayer(event.getPlayer());
|
||||
});
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onQuit(PlayerQuitEvent event)
|
||||
{
|
||||
// TODO Queue disconnected players and execute in a batch
|
||||
_players.remove(event.getPlayer().getUniqueId());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onCooldownChange(PlayerCooldownChangeEvent event)
|
||||
{
|
||||
Player player = event.getPlayer();
|
||||
BendingPlayer bendingPlayer = _players.get(player.getUniqueId());
|
||||
|
||||
String ability = event.getAbility();
|
||||
|
||||
// TODO Check bound ability
|
||||
GeneralMethods.displayMovePreview(player);
|
||||
}
|
||||
|
||||
private void loadBendingPlayer(Player player)
|
||||
{
|
||||
try
|
||||
{
|
||||
BendingPlayer bendingPlayer = getRepository().selectPlayer(player);
|
||||
|
||||
runSync(() ->
|
||||
{
|
||||
_players.put(player.getUniqueId(), bendingPlayer);
|
||||
|
||||
BendingPlayerLoadedEvent bendingPlayerLoadedEvent = new BendingPlayerLoadedEvent(player, bendingPlayer);
|
||||
getPlugin().getServer().getPluginManager().callEvent(bendingPlayerLoadedEvent);
|
||||
});
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public BendingPlayer getBendingPlayer(Player player)
|
||||
{
|
||||
return _players.get(player.getUniqueId());
|
||||
return getBendingPlayer(player.getUniqueId());
|
||||
}
|
||||
|
||||
public BendingPlayer getBendingPlayer(UUID uuid)
|
||||
{
|
||||
return _players.get(uuid);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue