Merge branch 'update/database' into config-population

This commit is contained in:
jayoevans 2019-10-25 22:13:09 +10:00
commit dcdd3326a5
55 changed files with 2399 additions and 292 deletions

12
pom.xml
View file

@ -74,6 +74,18 @@
<artifactId>commons-lang3</artifactId>
<version>3.8.1</version>
</dependency>
<!-- HikariCP -->
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>3.4.1</version>
</dependency>
<!-- MySQL Connector -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.18</version>
</dependency>
<!-- Factions -->
<dependency>
<groupId>me.markeh</groupId>

View file

@ -1,18 +1,12 @@
package com.projectkorra.projectkorra;
import java.util.HashMap;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.World;
import org.bukkit.entity.Player;
import co.aikar.timings.lib.MCTiming;
import com.projectkorra.projectkorra.ability.CoreAbility;
import com.projectkorra.projectkorra.ability.ElementalAbility;
import com.projectkorra.projectkorra.configuration.ConfigManager;
import com.projectkorra.projectkorra.configuration.configs.properties.FirePropertiesConfig;
import com.projectkorra.projectkorra.configuration.configs.properties.WaterPropertiesConfig;
import com.projectkorra.projectkorra.cooldown.CooldownManager;
import com.projectkorra.projectkorra.earthbending.metal.MetalClips;
import com.projectkorra.projectkorra.object.HorizontalVelocityTracker;
import com.projectkorra.projectkorra.util.ActionBar;
@ -20,8 +14,13 @@ import com.projectkorra.projectkorra.util.RevertChecker;
import com.projectkorra.projectkorra.util.TempArmor;
import com.projectkorra.projectkorra.util.TempPotionEffect;
import com.projectkorra.projectkorra.waterbending.blood.Bloodbending;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.World;
import org.bukkit.entity.Player;
import co.aikar.timings.lib.MCTiming;
import java.util.HashMap;
import java.util.UUID;
public class BendingManager implements Runnable {
@ -51,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);

View file

@ -1,23 +1,5 @@
package com.projectkorra.projectkorra;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Stream;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import com.projectkorra.projectkorra.Element.SubElement;
import com.projectkorra.projectkorra.ability.Ability;
import com.projectkorra.projectkorra.ability.AvatarAbility;
@ -35,11 +17,31 @@ import com.projectkorra.projectkorra.storage.DBConnection;
import com.projectkorra.projectkorra.util.Cooldown;
import com.projectkorra.projectkorra.util.DBCooldownManager;
import com.projectkorra.projectkorra.waterbending.blood.Bloodbending;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Stream;
/**
* Class that presents a player and stores all bending information about the
* player.
*
* @deprecated use {@link com.projectkorra.projectkorra.player.BendingPlayer}.
*/
@Deprecated
@SuppressWarnings("rawtypes")
public class BendingPlayer {

View file

@ -1,59 +1,8 @@
package com.projectkorra.projectkorra;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Color;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.Levelled;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Entity;
import org.bukkit.entity.FallingBlock;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.TNTPrimed;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Vector;
import br.net.fabiozumbi12.RedProtect.Bukkit.API.RedProtectAPI;
import br.net.fabiozumbi12.RedProtect.Bukkit.RedProtect;
import br.net.fabiozumbi12.RedProtect.Bukkit.Region;
import com.bekvon.bukkit.residence.Residence;
import com.bekvon.bukkit.residence.api.ResidenceInterface;
import com.bekvon.bukkit.residence.protection.ClaimedResidence;
@ -102,6 +51,7 @@ import com.projectkorra.projectkorra.configuration.configs.properties.ChatProper
import com.projectkorra.projectkorra.configuration.configs.properties.GeneralPropertiesConfig;
import com.projectkorra.projectkorra.earthbending.EarthBlast;
import com.projectkorra.projectkorra.earthbending.passive.EarthPassive;
import com.projectkorra.projectkorra.element.ElementManager;
import com.projectkorra.projectkorra.event.BendingPlayerCreationEvent;
import com.projectkorra.projectkorra.event.BendingReloadEvent;
import com.projectkorra.projectkorra.event.PlayerBindChangeEvent;
@ -109,6 +59,7 @@ import com.projectkorra.projectkorra.firebending.FireBlast;
import com.projectkorra.projectkorra.firebending.FireShield;
import com.projectkorra.projectkorra.firebending.combustion.Combustion;
import com.projectkorra.projectkorra.object.Preset;
import com.projectkorra.projectkorra.player.BendingPlayerManager;
import com.projectkorra.projectkorra.storage.DBConnection;
import com.projectkorra.projectkorra.util.ActionBar;
import com.projectkorra.projectkorra.util.BlockCacheElement;
@ -131,10 +82,6 @@ import com.songoda.kingdoms.constants.land.Land;
import com.songoda.kingdoms.constants.land.SimpleChunkLocation;
import com.songoda.kingdoms.constants.player.KingdomPlayer;
import com.songoda.kingdoms.manager.game.GameManagement;
import br.net.fabiozumbi12.RedProtect.Bukkit.RedProtect;
import br.net.fabiozumbi12.RedProtect.Bukkit.Region;
import br.net.fabiozumbi12.RedProtect.Bukkit.API.RedProtectAPI;
import me.markeh.factionsframework.entities.FPlayer;
import me.markeh.factionsframework.entities.FPlayers;
import me.markeh.factionsframework.entities.Faction;
@ -146,6 +93,60 @@ import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.ComponentBuilder;
import net.md_5.bungee.api.chat.HoverEvent;
import net.md_5.bungee.api.chat.TextComponent;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Color;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.Levelled;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Entity;
import org.bukkit.entity.FallingBlock;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.TNTPrimed;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.MainHand;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Vector;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
@SuppressWarnings("rawtypes")
public class GeneralMethods {
@ -323,7 +324,10 @@ public class GeneralMethods {
* @param uuid The UUID of the player
* @param player The player name
* @throws SQLException
*
* @deprecated use {@link BendingPlayerManager} and {@link ElementManager}.
*/
@Deprecated
public static void createBendingPlayer(final UUID uuid, final String player) {
new BukkitRunnable() {
@ -335,6 +339,7 @@ public class GeneralMethods {
}.runTaskAsynchronously(ProjectKorra.plugin);
}
@Deprecated
private static void createBendingPlayerAsynchronously(final UUID uuid, final String player) {
ResultSet rs = DBConnection.sql.readQuery("SELECT * FROM pk_players WHERE uuid = '" + uuid.toString() + "'");
try {
@ -725,12 +730,12 @@ public class GeneralMethods {
*/
public static Entity getClosestEntity(Location center, double radius) {
Entity found = null;
double distance = radius * radius;
Double distance = null;
for (Entity entity : GeneralMethods.getEntitiesAroundPoint(center, radius)) {
double check = center.distance(entity.getLocation());
double check = center.distanceSquared(entity.getLocation());
if (check < distance) {
if (distance == null || check < distance) {
found = entity;
distance = check;
}
@ -747,12 +752,12 @@ public class GeneralMethods {
*/
public static LivingEntity getClosestLivingEntity(Location center, double radius) {
LivingEntity le = null;
double distance = radius * radius;
Double distance = null;
for (Entity entity : GeneralMethods.getEntitiesAroundPoint(center, radius)) {
double check = center.distance(entity.getLocation());
double check = center.distanceSquared(entity.getLocation());
if (entity instanceof LivingEntity && check < distance) {
if (entity instanceof LivingEntity && (distance == null || check < distance)) {
le = (LivingEntity) entity;
distance = check;
}
@ -962,6 +967,16 @@ public class GeneralMethods {
return location.clone().subtract(new Vector(Math.cos(angle), 0, Math.sin(angle)).normalize().multiply(distance));
}
public static Location getMainHandLocation(final Player player) {
Location loc;
if (player.getMainHand() == MainHand.LEFT) {
loc = GeneralMethods.getLeftSide(player.getLocation(), .55).add(0, 1.2, 0);
} else {
loc = GeneralMethods.getRightSide(player.getLocation(), .55).add(0, 1.2, 0);
}
return loc;
}
public static Plugin getProbending() {
if (hasProbending()) {
return Bukkit.getServer().getPluginManager().getPlugin("Probending");
@ -1032,7 +1047,7 @@ public class GeneralMethods {
return getTargetedEntity(player, range, new ArrayList<Entity>());
}
public static Location getTargetedLocation(final Player player, final double range, final boolean ignoreTempBlocks, final Material... nonOpaque2) {
public static Location getTargetedLocation(final Player player, final double range, final boolean ignoreTempBlocks, final boolean checkDiagonals, final Material... nonOpaque2) {
final Location origin = player.getEyeLocation();
final Vector direction = origin.getDirection();
@ -1053,6 +1068,11 @@ public class GeneralMethods {
for (double i = 0; i < range; i += 0.2) {
location.add(vec);
if (checkDiagonals && checkDiagonalWall(location, vec)) {
location.subtract(vec);
break;
}
final Block block = location.getBlock();
if (trans.contains(block.getType())) {
@ -1068,12 +1088,16 @@ public class GeneralMethods {
return location;
}
public static Location getTargetedLocation(final Player player, final double range, final boolean ignoreTempBlocks, final Material... nonOpaque2) {
return getTargetedLocation(player, range, ignoreTempBlocks, true, nonOpaque2);
}
public static Location getTargetedLocation(final Player player, final double range, final Material... nonOpaque2) {
return getTargetedLocation(player, range, false, nonOpaque2);
}
public static Location getTargetedLocation(final Player player, final int range) {
return getTargetedLocation(player, range, Material.AIR);
return getTargetedLocation(player, range, false);
}
public static Block getTopBlock(final Location loc, final int range) {

View file

@ -1,17 +1,7 @@
package com.projectkorra.projectkorra;
import java.lang.reflect.Method;
import java.util.Base64;
import java.util.HashMap;
import java.util.logging.Logger;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Statistic;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitTask;
import co.aikar.timings.lib.MCTiming;
import co.aikar.timings.lib.TimingManager;
import com.bekvon.bukkit.residence.protection.FlagPermissions;
import com.projectkorra.projectkorra.ability.CoreAbility;
import com.projectkorra.projectkorra.ability.util.CollisionInitializer;
@ -28,6 +18,7 @@ import com.projectkorra.projectkorra.earthbending.util.EarthbendingManager;
import com.projectkorra.projectkorra.firebending.util.FirebendingManager;
import com.projectkorra.projectkorra.hooks.PlaceholderAPIHook;
import com.projectkorra.projectkorra.hooks.WorldGuardFlag;
import com.projectkorra.projectkorra.module.ModuleManager;
import com.projectkorra.projectkorra.object.Preset;
import com.projectkorra.projectkorra.storage.DBConnection;
import com.projectkorra.projectkorra.util.Metrics;
@ -36,9 +27,17 @@ import com.projectkorra.projectkorra.util.StatisticsManager;
import com.projectkorra.projectkorra.util.TempBlock;
import com.projectkorra.projectkorra.util.Updater;
import com.projectkorra.projectkorra.waterbending.util.WaterbendingManager;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Statistic;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitTask;
import co.aikar.timings.lib.MCTiming;
import co.aikar.timings.lib.TimingManager;
import java.lang.reflect.Method;
import java.util.Base64;
import java.util.HashMap;
import java.util.logging.Logger;
public class ProjectKorra extends JavaPlugin {
@ -89,6 +88,7 @@ public class ProjectKorra extends JavaPlugin {
}
Manager.startup();
ModuleManager.startup();
this.getServer().getPluginManager().registerEvents(new PKListener(this), this);
this.getServer().getScheduler().scheduleSyncRepeatingTask(this, new BendingManager(), 0, 1);

View file

@ -0,0 +1,129 @@
package com.projectkorra.projectkorra.ability;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.util.MultiAbilityManager;
import com.projectkorra.projectkorra.firebending.FireBlast;
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.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import java.sql.SQLException;
public class AbilityManager extends DatabaseModule<AbilityRepository> {
private final BendingPlayerManager bendingPlayerManager;
private AbilityManager() {
super("Ability", new AbilityRepository());
this.bendingPlayerManager = ModuleManager.getModule(BendingPlayerManager.class);
runAsync(() -> {
try {
getRepository().createTables();
} catch (SQLException e) {
e.printStackTrace();
}
runSync(() -> {
log("Created database tables.");
});
});
registerAbilities();
}
private void registerAbilities() {
registerAbility(FireBlast.class);
}
private void registerAbility(Class<? extends Ability> abilityClass) {
// TODO
}
@EventHandler
public void onBendingPlayerLoaded(BendingPlayerLoadedEvent event) {
BendingPlayer bendingPlayer = event.getBendingPlayer();
runAsync(() -> {
try {
String[] abilities = getRepository().selectPlayerAbilities(bendingPlayer.getId());
bendingPlayer.setAbilities(abilities);
} catch (SQLException e) {
e.printStackTrace();
}
});
}
public boolean bindAbility(Player player, String abilityName, int slot) {
PlayerBindAbilityEvent playerBindAbilityEvent = new PlayerBindAbilityEvent(player, abilityName);
getPlugin().getServer().getPluginManager().callEvent(playerBindAbilityEvent);
if (playerBindAbilityEvent.isCancelled()) {
String cancelMessage = playerBindAbilityEvent.getCancelMessage();
if (cancelMessage != null) {
GeneralMethods.sendBrandingMessage(player, cancelMessage);
}
return false;
}
BendingPlayer bendingPlayer = this.bendingPlayerManager.getBendingPlayer(player);
bendingPlayer.setAbility(slot, abilityName);
runAsync(() -> {
try {
getRepository().insertPlayerAbility(bendingPlayer.getId(), abilityName, slot);
} catch (SQLException e) {
e.printStackTrace();
}
});
return true;
}
public boolean unbindAbility(Player player, int slot) {
BendingPlayer bendingPlayer = this.bendingPlayerManager.getBendingPlayer(player);
String abilityName = bendingPlayer.getAbility(slot);
if (abilityName == null) {
player.sendMessage("No ability bound");
return false;
}
bendingPlayer.setAbility(slot, null);
runAsync(() -> {
try {
getRepository().deletePlayerAbility(bendingPlayer.getId(), abilityName);
} catch (SQLException e) {
e.printStackTrace();
}
});
return true;
}
public void clearBinds(Player player) {
BendingPlayer bendingPlayer = this.bendingPlayerManager.getBendingPlayer(player);
bendingPlayer.setAbilities(new String[9]);
runAsync(() -> {
try {
getRepository().deletePlayerAbilities(bendingPlayer.getId());
} catch (SQLException e) {
e.printStackTrace();
}
});
}
}

View file

@ -0,0 +1,100 @@
package com.projectkorra.projectkorra.ability;
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;
public class AbilityRepository extends DatabaseRepository {
private static final DatabaseQuery CREATE_TABLE_PLAYER_ABILITIES = DatabaseQuery.newBuilder()
.mysql("CREATE TABLE IF NOT EXISTS pk_player_abilities (player_id INTEGER REFERENCES pk_bending_players (player_id), ability_name VARCHAR(50) NOT NULL, slot TINYINT NOT NULL, PRIMARY KEY (player_id, ability_name), INDEX player_index (player_id), INDEX ability_index (ability_name));")
.sqlite("CREATE TABLE IF NOT EXISTS pk_player_abilities (player_id INTEGER REFERENCES pk_bending_players (player_id), ability_name VARCHAR(50) NOT NULL, slot TINYINT NOT NULL, PRIMARY KEY (player_id, ability_name)); CREATE INDEX player_index ON pk_player_abilities (player_id); CREATE INDEX ability_index ON pk_player_abilities (ability_name);")
.build();
private static final DatabaseQuery SELECT_PLAYER_ABILITIES = DatabaseQuery.newBuilder()
.query("SELECT ability_name, slot FROM pk_player_abilities WHERE player_id = ?;")
.build();
private static final DatabaseQuery INSERT_PLAYER_ABILITY = DatabaseQuery.newBuilder()
.query("INSERT INTO pk_player_abilities VALUES (?, ?, ?);")
.build();
private static final DatabaseQuery DELETE_PLAYER_ABILITIES = DatabaseQuery.newBuilder()
.query("DELETE FROM pk_player_abilities WHERE player_id = ?")
.build();
private static final DatabaseQuery DELETE_PLAYER_ABILITY = DatabaseQuery.newBuilder()
.query("DELETE FROM pk_player_abilities WHERE player_id = ? AND ability_name = ?;")
.build();
protected void createTables() throws SQLException {
Connection connection = getDatabase().getConnection();
try (PreparedStatement statement = connection.prepareStatement(CREATE_TABLE_PLAYER_ABILITIES.getQuery())) {
statement.executeUpdate();
}
}
protected String[] selectPlayerAbilities(int playerId) throws SQLException {
Connection connection = getDatabase().getConnection();
try (PreparedStatement statement = connection.prepareStatement(SELECT_PLAYER_ABILITIES.getQuery())) {
statement.setInt(1, playerId);
String[] abilities = new String[9];
try (ResultSet rs = statement.executeQuery()) {
while (rs.next()) {
String abilityName = rs.getString("ability_name");
int slot = rs.getInt("slot");
if (slot < 0 || slot >= abilities.length) {
// TODO Log illegal slot
continue;
}
abilities[slot] = abilityName;
}
return abilities;
}
}
}
protected void insertPlayerAbility(int playerId, String abilityName, int slot) throws SQLException {
Connection connection = getDatabase().getConnection();
try (PreparedStatement statement = connection.prepareStatement(INSERT_PLAYER_ABILITY.getQuery())) {
statement.setInt(1, playerId);
statement.setString(2, abilityName);
statement.setInt(3, slot);
statement.executeUpdate();
}
}
protected void deletePlayerAbilities(int playerId) throws SQLException {
Connection connection = getDatabase().getConnection();
try (PreparedStatement statement = connection.prepareStatement(DELETE_PLAYER_ABILITIES.getQuery())) {
statement.setInt(1, playerId);
statement.executeUpdate();
}
}
protected void deletePlayerAbility(int playerId, String abilityName) throws SQLException {
Connection connection = getDatabase().getConnection();
try (PreparedStatement statement = connection.prepareStatement(DELETE_PLAYER_ABILITY.getQuery())) {
statement.setInt(1, playerId);
statement.setString(2, abilityName);
statement.executeUpdate();
}
}
}

View file

@ -563,10 +563,10 @@ public abstract class EarthAbility<C extends AbilityConfig> extends ElementalAbi
if (block.equals(sourceblock)) {
info.getState().update(true, false);
if (RaiseEarth.blockInAllAffectedBlocks(sourceblock)) {
EarthAbility.revertBlock(sourceblock);
RaiseEarth.revertAffectedBlock(sourceblock);
}
if (RaiseEarth.blockInAllAffectedBlocks(block)) {
EarthAbility.revertBlock(block);
RaiseEarth.revertAffectedBlock(block);
}
MOVED_EARTH.remove(block);
return true;
@ -595,10 +595,10 @@ public abstract class EarthAbility<C extends AbilityConfig> extends ElementalAbi
}
if (RaiseEarth.blockInAllAffectedBlocks(sourceblock)) {
EarthAbility.revertBlock(sourceblock);
RaiseEarth.revertAffectedBlock(sourceblock);
}
if (RaiseEarth.blockInAllAffectedBlocks(block)) {
EarthAbility.revertBlock(block);
RaiseEarth.revertAffectedBlock(block);
}
MOVED_EARTH.remove(block);
}

View file

@ -0,0 +1,61 @@
package com.projectkorra.projectkorra.ability;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
public class PlayerBindAbilityEvent extends PlayerEvent implements Cancellable
{
private static final HandlerList HANDLER_LIST = new HandlerList();
private final String abilityName;
private boolean cancelled;
private String cancelMessage;
public PlayerBindAbilityEvent(Player player, String abilityName)
{
super(player);
this.abilityName = abilityName;
}
public String getAbilityName()
{
return this.abilityName;
}
@Override
public boolean isCancelled()
{
return cancelled;
}
@Override
public void setCancelled(boolean cancelled)
{
this.cancelled = cancelled;
}
public String getCancelMessage()
{
return this.cancelMessage;
}
public void setCancelMessage(String cancelMessage)
{
this.cancelMessage = cancelMessage;
}
@Override
public HandlerList getHandlers()
{
return HANDLER_LIST;
}
public static HandlerList getHandlerList()
{
return HANDLER_LIST;
}
}

View file

@ -6,9 +6,12 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import com.projectkorra.projectkorra.ability.PlayerBindAbilityEvent;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.scheduler.BukkitRunnable;
import com.projectkorra.projectkorra.BendingPlayer;
@ -17,7 +20,7 @@ import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ProjectKorra;
import com.projectkorra.projectkorra.event.PlayerBindChangeEvent;
public class MultiAbilityManager {
public class MultiAbilityManager implements Listener {
public static Map<Player, String[]> playerAbilities = new ConcurrentHashMap<>();
public static Map<Player, Integer> playerSlot = new ConcurrentHashMap<>();
@ -34,6 +37,19 @@ public class MultiAbilityManager {
waterArms.add(new MultiAbilityInfoSub("Spear", Element.ICE));
multiAbilityList.add(new MultiAbilityInfo("WaterArms", waterArms));
manage();
// TODO Properly set this up as a Module
ProjectKorra.plugin.getServer().getPluginManager().registerEvents(this, ProjectKorra.plugin);
}
@EventHandler
public void onPlayerBindAbility(PlayerBindAbilityEvent event)
{
if (playerAbilities.containsKey(event.getPlayer()))
{
event.setCancelled(true);
event.setCancelMessage(ChatColor.RED + "You can't edit your binds right now!");
}
}
/**

View file

@ -213,13 +213,24 @@ public class AirBlast extends AirAbility<AirBlastConfig> {
}
private void affect(final Entity entity) {
final boolean isUser = entity.getUniqueId() == this.player.getUniqueId();
if (entity instanceof Player) {
if (Commands.invincible.contains(((Player) entity).getName())) {
return;
}
}
final boolean isUser = entity.getUniqueId() == this.player.getUniqueId();
double knockback = this.pushFactorForOthers;
if (isUser) {
if (isFromOtherOrigin) {
knockback = this.pushFactor;
} else {
return;
}
}
if (!isUser || this.isFromOtherOrigin) {
this.pushFactor = this.pushFactorForOthers;
final Vector velocity = entity.getVelocity();
final double max = this.speed / this.speedFactor;
double factor = this.pushFactor;
final Vector push = this.direction.clone();
if (Math.abs(push.getY()) > max && !isUser) {
@ -229,56 +240,45 @@ public class AirBlast extends AirAbility<AirBlastConfig> {
push.setY(max);
}
}
if (this.location.getWorld().equals(this.origin.getWorld())) {
factor *= 1 - this.location.distance(this.origin) / (2 * this.range);
knockback *= 1 - this.location.distance(this.origin) / (2 * this.range);
}
if (isUser && GeneralMethods.isSolid(this.player.getLocation().add(0, -.5, 0).getBlock())) {
factor *= .5;
if (GeneralMethods.isSolid(entity.getLocation().add(0, -0.5, 0).getBlock()) && source == null) {
knockback *= 0.85;
}
final double comp = velocity.dot(push.clone().normalize());
if (comp > factor) {
velocity.multiply(.5);
velocity.add(push.clone().normalize().multiply(velocity.clone().dot(push.clone().normalize())));
} else if (comp + factor * .5 > factor) {
velocity.add(push.clone().multiply(factor - comp));
} else {
velocity.add(push.clone().multiply(factor * .5));
push.normalize().multiply(knockback);
if (Math.abs(entity.getVelocity().dot(push)) > knockback && entity.getVelocity().angle(push) > Math.PI / 3) {
push.normalize().add(entity.getVelocity()).multiply(knockback);
}
if (entity instanceof Player) {
if (Commands.invincible.contains(((Player) entity).getName())) {
return;
}
}
GeneralMethods.setVelocity(entity, push);
if (Double.isNaN(velocity.length())) {
return;
}
GeneralMethods.setVelocity(entity, velocity);
if (this.source != null) {
new HorizontalVelocityTracker(entity, this.player, 200l, this.source);
} else {
new HorizontalVelocityTracker(entity, this.player, 200l, this);
}
if (this.damage > 0 && entity instanceof LivingEntity && !entity.equals(this.player) && !this.affectedEntities.contains(entity)) {
if (this.source != null) {
DamageHandler.damageEntity(entity, this.damage, this.source);
} else {
DamageHandler.damageEntity(entity, this.damage, this);
}
this.affectedEntities.add(entity);
}
if (entity.getFireTicks() > 0) {
entity.getWorld().playEffect(entity.getLocation(), Effect.EXTINGUISH, 0);
}
entity.setFireTicks(0);
breakBreathbendingHold(entity);
if (this.source != null && (this.damage > 0 && entity instanceof LivingEntity && !entity.equals(this.player) && !this.affectedEntities.contains(entity))) {
DamageHandler.damageEntity(entity, this.damage, this.source);
this.affectedEntities.add(entity);
} else if (this.source == null && (this.damage > 0 && entity instanceof LivingEntity && !entity.equals(this.player) && !this.affectedEntities.contains(entity))) {
DamageHandler.damageEntity(entity, this.damage, this);
this.affectedEntities.add(entity);
}
}
}
@Override

View file

@ -325,10 +325,6 @@ public class AirBurst extends AirAbility<AirBurstConfig> {
return this.blasts;
}
public ArrayList<Entity> getAffectedEntities() {
return this.affectedEntities;
}
@Override
public Class<AirBurstConfig> getConfigType() {
return AirBurstConfig.class;

View file

@ -44,6 +44,8 @@ public class AirSuction extends AirAbility<AirSuctionConfig> {
private double radius;
@Attribute(Attribute.KNOCKBACK)
private double pushFactor;
@Attribute(Attribute.KNOCKBACK + "Others")
private double pushFactorForOthers;
private Random random;
private Location location;
private Location origin;
@ -78,7 +80,8 @@ public class AirSuction extends AirAbility<AirSuctionConfig> {
this.speed = config.Speed;
this.range = config.Range;
this.radius = config.Radius;
this.pushFactor = config.PushFactor;
this.pushFactor = config.PushFactor_Self;
this.pushFactorForOthers = config.PushFactor_Others;
this.cooldown = config.Cooldown;
this.random = new Random();
this.origin = this.getTargetLocation();
@ -203,10 +206,15 @@ public class AirSuction extends AirAbility<AirSuctionConfig> {
if ((entity.getEntityId() == this.player.getEntityId()) && !this.canAffectSelf) {
continue;
}
final Vector velocity = entity.getVelocity();
double knockback = this.pushFactor;
if (entity.getEntityId() != player.getEntityId()) {
knockback = this.pushFactorForOthers;
}
final double max = this.speed;
final Vector push = this.direction.clone();
double factor = this.pushFactor;
if (Math.abs(push.getY()) > max) {
if (push.getY() < 0) {
@ -217,20 +225,16 @@ public class AirSuction extends AirAbility<AirSuctionConfig> {
}
if (this.location.getWorld().equals(this.origin.getWorld())) {
factor *= 1 - this.location.distance(this.origin) / (2 * this.range);
knockback *= 1 - this.location.distance(this.origin) / (2 * this.range);
}
final double comp = velocity.dot(push.clone().normalize());
if (comp > factor) {
velocity.multiply(.5);
velocity.add(push.clone().normalize().multiply(velocity.clone().dot(push.clone().normalize())));
} else if (comp + factor * .5 > factor) {
velocity.add(push.clone().multiply(factor - comp));
} else {
velocity.add(push.clone().multiply(factor * .5));
push.normalize().multiply(knockback);
if (Math.abs(entity.getVelocity().dot(push)) > knockback) {
push.normalize().add(entity.getVelocity()).multiply(knockback);
}
GeneralMethods.setVelocity(entity, velocity);
GeneralMethods.setVelocity(entity, push.normalize().multiply(knockback));
new HorizontalVelocityTracker(entity, this.player, 200l, this);
entity.setFallDistance(0);

View file

@ -78,7 +78,7 @@ public class AirSwipe extends AirAbility<AirSwipeConfig> {
}
this.charging = charging;
this.origin = player.getEyeLocation();
this.origin = GeneralMethods.getMainHandLocation(player);
this.particles = config.AnimationParticleAmount;
this.arc = config.Arc;
this.arcIncrement = config.StepSize;

View file

@ -143,7 +143,6 @@ public class Suffocate extends AirAbility<SuffocateConfig> {
}
}
this.bPlayer.addCooldown(this);
this.start();
}
@ -172,7 +171,7 @@ public class Suffocate extends AirAbility<SuffocateConfig> {
if (this.player.getWorld().equals(this.targets.get(0).getWorld())) {
dist = this.player.getEyeLocation().distance(this.targets.get(0).getEyeLocation());
}
final Location targetLoc = this.player.getEyeLocation().clone().add(this.player.getEyeLocation().getDirection().normalize().multiply(dist));
final Location targetLoc = GeneralMethods.getTargetedLocation(player, dist, false, getTransparentMaterials());
final List<Entity> ents = GeneralMethods.getEntitiesAroundPoint(targetLoc, this.constantAimRadius);
for (int i = 0; i < this.targets.size(); i++) {
@ -337,6 +336,7 @@ public class Suffocate extends AirAbility<SuffocateConfig> {
@Override
public void remove() {
super.remove();
this.bPlayer.addCooldown(this);
for (int i = 0; i < this.tasks.size(); i++) {
this.tasks.get(i).cancel();
this.tasks.remove(i);

View file

@ -3,6 +3,7 @@ package com.projectkorra.projectkorra.airbending.combo;
import java.util.ArrayList;
import java.util.List;
import com.projectkorra.projectkorra.object.HorizontalVelocityTracker;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
@ -133,22 +134,23 @@ public class AirSweep extends AirAbility<AirSweepConfig> implements ComboAbility
if (this.origin == null) {
this.direction = this.player.getEyeLocation().getDirection().normalize();
this.origin = this.player.getLocation().add(this.direction.clone().multiply(10));
this.origin = GeneralMethods.getMainHandLocation(player).add(this.direction.clone().multiply(10));
}
if (this.progressCounter < 8) {
return;
}
if (this.destination == null) {
this.destination = this.player.getLocation().add(this.player.getEyeLocation().getDirection().normalize().multiply(10));
this.destination = GeneralMethods.getMainHandLocation(player).add(GeneralMethods.getMainHandLocation(player).getDirection().normalize().multiply(10));
final Vector origToDest = GeneralMethods.getDirection(this.origin, this.destination);
final Location hand = GeneralMethods.getMainHandLocation(player);
for (double i = 0; i < 30; i++) {
final Location endLoc = this.origin.clone().add(origToDest.clone().multiply(i / 30));
if (GeneralMethods.locationEqualsIgnoreDirection(this.player.getLocation(), endLoc)) {
if (GeneralMethods.locationEqualsIgnoreDirection(hand, endLoc)) {
continue;
}
final Vector vec = GeneralMethods.getDirection(this.player.getLocation(), endLoc);
final Vector vec = GeneralMethods.getDirection(hand, endLoc);
final FireComboStream fs = new FireComboStream(this.player, this, vec, this.player.getLocation(), this.range, this.speed);
final FireComboStream fs = new FireComboStream(this.player, this, vec, hand, this.range, this.speed);
fs.setDensity(1);
fs.setSpread(0F);
fs.setUseNewParticles(true);
@ -193,17 +195,17 @@ public class AirSweep extends AirAbility<AirSweepConfig> implements ComboAbility
this.remove();
return;
}
if (!entity.equals(this.player) && !this.affectedEntities.contains(entity) && !(entity instanceof Player && Commands.invincible.contains(((Player) entity).getName()))) {
this.affectedEntities.add(entity);
if (!entity.equals(this.player) && !(entity instanceof Player && Commands.invincible.contains(((Player) entity).getName()))) {
if (this.knockback != 0) {
final Vector force = fstream.getDirection();
entity.setVelocity(force.multiply(this.knockback));
final Vector force = fstream.getLocation().getDirection();
GeneralMethods.setVelocity(entity, force.clone().multiply(this.knockback));
new HorizontalVelocityTracker(entity, this.player, 200l, this);
entity.setFallDistance(0);
}
if(!this.affectedEntities.contains(entity)) {
this.affectedEntities.add(entity);
if (this.damage != 0) {
if (entity instanceof LivingEntity) {
if (fstream.getAbility().getName().equalsIgnoreCase("AirSweep")) {
DamageHandler.damageEntity(entity, this.damage, this);
} else {
DamageHandler.damageEntity(entity, this.damage, this);
}
}

View file

@ -78,8 +78,19 @@ public class PresetCommand extends PKCommand<PresetCommandConfig> {
bPlayer = BendingPlayer.getBendingPlayer(player);
}
int page = 1;
String name = null;
if (args.size() == 1 && !Arrays.asList(listaliases).contains(args.get(0))){
this.help(sender, false);
} else if (args.size() >= 2) {
if (Arrays.asList(listaliases).contains(args.get(0))) {
page = Integer.parseInt(args.get(1));
} else {
name = args.get(1);
}
}
// bending preset list.
if (args.size() == 1) {
if (Arrays.asList(listaliases).contains(args.get(0)) && this.hasPermission(sender, "list")) {
boolean firstMessage = true;
@ -95,7 +106,7 @@ public class PresetCommand extends PKCommand<PresetCommandConfig> {
presetNames.add(preset.getName());
}
for (final String s : this.getPage(presetNames, ChatColor.GOLD + "Presets: ", 1, false)) {
for (final String s : this.getPage(presetNames, ChatColor.GOLD + "Presets: ", page, false)) {
if (firstMessage) {
GeneralMethods.sendBrandingMessage(sender, s);
firstMessage = false;
@ -105,14 +116,7 @@ public class PresetCommand extends PKCommand<PresetCommandConfig> {
}
return;
} else {
this.help(sender, false);
return;
}
}
final String name = args.get(1);
if (Arrays.asList(deletealiases).contains(args.get(0)) && this.hasPermission(sender, "delete")) { // bending preset delete name.
} else if (Arrays.asList(deletealiases).contains(args.get(0)) && this.hasPermission(sender, "delete")) { // bending preset delete name.
if (!Preset.presetExists(player, name)) {
GeneralMethods.sendBrandingMessage(sender, ChatColor.RED + this.noPresetName);
return;

View file

@ -7,8 +7,8 @@ public class AirBlastConfig extends AbilityConfig {
public final long Cooldown = 500;
public final int AnimationParticleAmount = 5;
public final int SelectionParticleAmount = 5;
public final double PushFactor_Self = 2.5;
public final double PushFactor_Others = 2.5;
public final double PushFactor_Self = 2.0;
public final double PushFactor_Others = 1.6;
public final double Speed = 25;
public final double Range = 20;
public final double SelectionRange = 10;

View file

@ -7,7 +7,7 @@ public class AirBurstConfig extends AbilityConfig {
public final long Cooldown = 0;
public final long ChargeTime = 1750;
public final double FallHeightThreshold = 15;
public final double PushFactor = 2.0;
public final double PushFactor = 2.8;
public final double Damage = 0;
public final double AnglePhi = 10;
public final double AngleTheta = 10;

View file

@ -7,7 +7,8 @@ public class AirSuctionConfig extends AbilityConfig {
public final long Cooldown = 500;
public final int AnimationParticleAmount = 5;
public final int SelectionParticleAmount = 5;
public final double PushFactor = 2.5;
public final double PushFactor_Self = 2.0;
public final double PushFactor_Others = 1.3;
public final double Speed = 25;
public final double Range = 20;
public final double SelectionRange = 10;

View file

@ -4,7 +4,7 @@ import com.projectkorra.projectkorra.configuration.configs.abilities.AbilityConf
public class SuffocateConfig extends AbilityConfig {
public final long Cooldown = 0;
public final long Cooldown = 6500;
public final boolean RequireConstantAim = true;
public final double ConstantAimRadius = 3;
public final boolean CanSuffocateUndead = false;

View file

@ -0,0 +1,193 @@
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.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());
this.bendingPlayerManager = ModuleManager.getModule(BendingPlayerManager.class);
runAsync(() -> {
try {
getRepository().createTables();
} catch (SQLException e) {
e.printStackTrace();
}
});
runTimer(() -> {
this.cooldownQueue.forEach((uuid, cooldowns) -> {
long currentTime = System.currentTimeMillis();
while (!cooldowns.isEmpty()) {
Cooldown cooldown = cooldowns.peek();
if (currentTime < cooldown.ExpireTime) {
break;
}
this.cooldownMap.get(uuid).remove(cooldown.AbilityName);
cooldowns.poll();
if (cooldown.Permanent) {
int playerId = this.bendingPlayerManager.getBendingPlayer(uuid).getId();
runAsync(() -> {
try {
getRepository().deleteCooldown(playerId, cooldown.AbilityName);
} catch (SQLException e) {
e.printStackTrace();
}
});
}
}
});
this.cooldownMap.values().removeIf(Map::isEmpty);
this.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());
this.cooldownMap.computeIfAbsent(player.getUniqueId(), k -> new HashMap<>()).putAll(cooldowns);
this.cooldownQueue.computeIfAbsent(player.getUniqueId(), queueFunction).addAll(cooldowns.values());
} catch (SQLException e) {
e.printStackTrace();
}
});
}
@EventHandler
public void onQuit(PlayerQuitEvent event) {
this.cooldownMap.remove(event.getPlayer().getUniqueId());
this.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);
this.cooldownMap.computeIfAbsent(player.getUniqueId(), k -> new HashMap<>()).put(abilityName, cooldown);
this.cooldownQueue.computeIfAbsent(player.getUniqueId(), queueFunction).add(cooldown);
if (permanent) {
int playerId = this.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 = this.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 = this.cooldownMap.get(player.getUniqueId());
return cooldowns != null && cooldowns.containsKey(abilityName);
}
public void removeCooldown(Player player, String abilityName) {
UUID uuid = player.getUniqueId();
Map<String, Cooldown> cooldowns = this.cooldownMap.get(player.getUniqueId());
if (cooldowns == null) {
return;
}
Cooldown cooldown = cooldowns.remove(abilityName);
if (cooldown == null) {
return;
}
if (this.cooldownQueue.containsKey(uuid)) {
this.cooldownQueue.get(uuid).remove(cooldown);
}
if (cooldown.Permanent) {
int playerId = this.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;
}
}
}

View file

@ -0,0 +1,82 @@
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();
}
}
}

View file

@ -0,0 +1,26 @@
package com.projectkorra.projectkorra.database;
import com.projectkorra.projectkorra.configuration.Config;
public class DatabaseConfig implements Config {
public final DatabaseManager.Engine Engine = DatabaseManager.Engine.SQLITE;
public final String SQLite_File = "projectkorra.sql";
public final String MySQL_IP = "localhost";
public final String MySQL_Port = "3306";
public final String MySQL_DatabaseName = "projectkorra";
public final String MySQL_Username = "root";
public final String MySQL_Password = "password";
@Override
public String getName() {
return "Database";
}
@Override
public String[] getParents() {
return new String[0];
}
}

View file

@ -0,0 +1,52 @@
package com.projectkorra.projectkorra.database;
import com.projectkorra.projectkorra.configuration.ConfigManager;
import com.projectkorra.projectkorra.database.engine.MySQLDatabase;
import com.projectkorra.projectkorra.database.engine.SQLDatabase;
import com.projectkorra.projectkorra.database.engine.SQLiteDatabase;
import com.projectkorra.projectkorra.module.Module;
import java.util.logging.Level;
public class DatabaseManager extends Module {
private final DatabaseConfig config;
private final SQLDatabase database;
private DatabaseManager() {
super("Database");
this.config = ConfigManager.getConfig(DatabaseConfig.class);
switch (this.config.Engine) {
case MYSQL:
this.database = new MySQLDatabase(this.config);
break;
case SQLITE:
this.database = new SQLiteDatabase(this, this.config);
break;
default:
log(Level.SEVERE, "Unknown database engine.");
this.database = null;
break;
}
}
public DatabaseConfig getConfig() {
return this.config;
}
public SQLDatabase getDatabase() {
return this.database;
}
@Override
public void onDisable() {
this.database.close();
}
public enum Engine {
MYSQL,
SQLITE;
}
}

View file

@ -0,0 +1,55 @@
package com.projectkorra.projectkorra.database;
import com.projectkorra.projectkorra.module.ModuleManager;
public class DatabaseQuery {
private final String mysql;
private final String sqlite;
private DatabaseQuery(String mysql, String sqlite) {
this.mysql = mysql;
this.sqlite = sqlite;
}
public String getQuery() {
switch (ModuleManager.getModule(DatabaseManager.class).getConfig().Engine) {
case MYSQL:
return this.mysql;
case SQLITE:
return this.sqlite;
}
return null;
}
public static Builder newBuilder() {
return new Builder();
}
public static final class Builder {
private String mysql;
private String sqlite;
public Builder mysql(String mysql) {
this.mysql = mysql;
return this;
}
public Builder sqlite(String sqlite) {
this.sqlite = sqlite;
return this;
}
public Builder query(String query) {
this.mysql = query;
this.sqlite = query;
return this;
}
public DatabaseQuery build() {
return new DatabaseQuery(this.mysql, this.sqlite);
}
}
}

View file

@ -0,0 +1,17 @@
package com.projectkorra.projectkorra.database;
import com.projectkorra.projectkorra.database.engine.SQLDatabase;
import com.projectkorra.projectkorra.module.ModuleManager;
public abstract class DatabaseRepository {
private final DatabaseManager databaseManager;
public DatabaseRepository() {
this.databaseManager = ModuleManager.getModule(DatabaseManager.class);
}
protected SQLDatabase getDatabase() {
return this.databaseManager.getDatabase();
}
}

View file

@ -0,0 +1,42 @@
package com.projectkorra.projectkorra.database.engine;
import com.projectkorra.projectkorra.database.DatabaseConfig;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import java.sql.Connection;
import java.sql.SQLException;
public class MySQLDatabase implements SQLDatabase {
private final HikariDataSource hikari;
public MySQLDatabase(DatabaseConfig databaseConfig) {
HikariConfig hikariConfig = new HikariConfig();
hikariConfig.setJdbcUrl("jdbc:mysql://" + databaseConfig.MySQL_IP + ":" + databaseConfig.MySQL_Port + "/" + databaseConfig.MySQL_DatabaseName);
hikariConfig.setDriverClassName("com.mysql.jdbc.Driver");
hikariConfig.setUsername(databaseConfig.MySQL_Username);
hikariConfig.setPassword(databaseConfig.MySQL_Password);
hikariConfig.setMinimumIdle(1);
hikariConfig.setMaximumPoolSize(10);
hikariConfig.setConnectionTimeout(10000);
this.hikari = new HikariDataSource(hikariConfig);
}
@Override
public Connection getConnection() {
try (Connection connection = this.hikari.getConnection()) {
return connection;
} catch (SQLException e) {
e.printStackTrace();
return null;
}
}
@Override
public void close() {
this.hikari.close();
}
}

View file

@ -0,0 +1,10 @@
package com.projectkorra.projectkorra.database.engine;
import java.sql.Connection;
public interface SQLDatabase {
Connection getConnection();
void close();
}

View file

@ -0,0 +1,64 @@
package com.projectkorra.projectkorra.database.engine;
import com.projectkorra.projectkorra.database.DatabaseConfig;
import com.projectkorra.projectkorra.database.DatabaseManager;
import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class SQLiteDatabase implements SQLDatabase {
private final File databaseFile;
private Connection connection;
public SQLiteDatabase(DatabaseManager databaseManager, DatabaseConfig databaseConfig) {
this.databaseFile = new File(databaseManager.getPlugin().getDataFolder(), databaseConfig.SQLite_File);
if (!this.databaseFile.getParentFile().exists()) {
this.databaseFile.getParentFile().mkdirs();
}
if (!this.databaseFile.exists()) {
try {
this.databaseFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
open();
}
public void open() {
try {
this.connection = DriverManager.getConnection("jdbc:sqlite:" + databaseFile.getAbsolutePath());
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public Connection getConnection() {
try {
if (this.connection == null || this.connection.isClosed()) {
open();
}
} catch (SQLException e) {
e.printStackTrace();
}
return this.connection;
}
@Override
public void close() {
try {
this.connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}

View file

@ -11,6 +11,7 @@ import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import com.projectkorra.projectkorra.command.Commands;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.EarthAbility;
import com.projectkorra.projectkorra.attribute.Attribute;
@ -70,6 +71,9 @@ public class Catapult extends EarthAbility<CatapultConfig> {
private void moveEarth(final Vector apply, final Vector direction) {
for (final Entity entity : GeneralMethods.getEntitiesAroundPoint(this.origin, 2)) {
if (entity.getEntityId() != this.player.getEntityId()) {
if (GeneralMethods.isRegionProtectedFromBuild(this, entity.getLocation()) || ((entity instanceof Player) && Commands.invincible.contains(((Player) entity).getName()))) {
continue;
}
entity.setVelocity(apply);
}
}

View file

@ -99,7 +99,7 @@ public class Collapse extends EarthAbility<CollapseConfig> {
thisBlock = this.block.getWorld().getBlockAt(this.location.clone().add(this.direction.clone().multiply(-i)));
this.affectedBlocks.put(thisBlock, thisBlock);
if (RaiseEarth.blockInAllAffectedBlocks(thisBlock)) {
EarthAbility.revertBlock(thisBlock);
RaiseEarth.revertAffectedBlock(thisBlock);
}
}
}

View file

@ -5,6 +5,7 @@ import java.util.ArrayList;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
@ -376,8 +377,12 @@ public class EarthBlast extends EarthAbility<EarthBlastConfig> {
this.firstDestination = this.location.clone();
if (this.destination.getY() - this.location.getY() > 2) {
this.firstDestination.setY(this.destination.getY() - 1);
} else {
} else if (this.location.getY() > player.getEyeLocation().getY() && this.location.getBlock().getRelative(BlockFace.UP).isPassable()) {
this.firstDestination.subtract(0, 2, 0);
} else if (this.location.getBlock().getRelative(BlockFace.UP).isPassable() && this.location.getBlock().getRelative(BlockFace.UP, 2).isPassable()) {
this.firstDestination.add(0, 2, 0);
} else {
this.firstDestination.add(GeneralMethods.getDirection(this.location, this.destination).normalize().setY(0));
}
if (this.destination.distanceSquared(this.location) <= 1) {

View file

@ -2,7 +2,6 @@ package com.projectkorra.projectkorra.earthbending;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.bukkit.Location;
@ -15,11 +14,10 @@ import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.configuration.configs.abilities.earth.RaiseEarthConfig;
import com.projectkorra.projectkorra.util.BlockSource;
import com.projectkorra.projectkorra.util.ClickType;
import com.projectkorra.projectkorra.util.TempBlock;
public class RaiseEarth extends EarthAbility<RaiseEarthConfig> {
private static final Map<Block, Block> ALL_AFFECTED_BLOCKS = new ConcurrentHashMap<>();
private int distance;
@Attribute(Attribute.HEIGHT)
private int height;
@ -104,7 +102,7 @@ public class RaiseEarth extends EarthAbility<RaiseEarthConfig> {
private boolean canInstantiate() {
for (final Block block : this.affectedBlocks.keySet()) {
if (!this.isEarthbendable(block) || ALL_AFFECTED_BLOCKS.containsKey(block)) {
if (!this.isEarthbendable(block) || TempBlock.isTempBlock(block)) {
return false;
}
}
@ -143,11 +141,15 @@ public class RaiseEarth extends EarthAbility<RaiseEarthConfig> {
}
public static boolean blockInAllAffectedBlocks(final Block block) {
return ALL_AFFECTED_BLOCKS.containsKey(block);
for (RaiseEarth raiseEarth : getAbilities(RaiseEarth.class)) {
if (raiseEarth.affectedBlocks.contains(block)) {
return true;
}
}
return false;
}
public static void revertAffectedBlock(final Block block) {
ALL_AFFECTED_BLOCKS.remove(block);
for (final RaiseEarth raiseEarth : getAbilities(RaiseEarth.class)) {
raiseEarth.affectedBlocks.remove(block);
}

View file

@ -18,6 +18,7 @@ import org.bukkit.entity.Zombie;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;
import com.projectkorra.projectkorra.command.Commands;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.CoreAbility;
import com.projectkorra.projectkorra.ability.MetalAbility;
@ -166,7 +167,7 @@ public class MetalClips extends MetalAbility<MetalClipsConfig> {
return;
} else if (this.metalClipsCount == 3 && !this.canUse4Clips) {
return;
} else if (this.targetEntity != null && GeneralMethods.isRegionProtectedFromBuild(this, this.targetEntity.getLocation())) {
} else if (this.targetEntity != null && (GeneralMethods.isRegionProtectedFromBuild(this, this.targetEntity.getLocation()) || ((targetEntity instanceof Player) && Commands.invincible.contains(((Player) targetEntity).getName())))) {
return;
}

View file

@ -0,0 +1,38 @@
package com.projectkorra.projectkorra.element;
import org.bukkit.ChatColor;
public class Element {
private final int elementId;
private final String elementName;
private final String displayName;
private final ChatColor color;
public Element(int elementId, String elementName, String displayName, ChatColor color) {
this.elementId = elementId;
this.elementName = elementName;
this.displayName = displayName;
this.color = color;
}
public int getId() {
return this.elementId;
}
public String getName() {
return this.elementName;
}
public String getDisplayName() {
return this.displayName;
}
public ChatColor getColor() {
return this.color;
}
public String getColoredName() {
return this.color + this.displayName;
}
}

View file

@ -0,0 +1,271 @@
package com.projectkorra.projectkorra.element;
import com.google.common.base.Preconditions;
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.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
public class ElementManager extends DatabaseModule<ElementRepository> {
private static final String WATER = "water", EARTH = "earth", FIRE = "fire", AIR = "air", CHI = "chi", AVATAR = "avatar";
private static final String BLOOD = "blood", HEALING = "healing", ICE = "ice", PLANT = "plant";
private static final String LAVA = "lava", METAL = "metal", SAND = "sand";
private static final String COMBUSTION = "combustion", LIGHTNING = "lightning";
private static final String FLIGHT = "flight", SPIRITUAL = "spiritual";
private final BendingPlayerManager bendingPlayerManager;
private final Map<Integer, Element> elements = new HashMap<>();
private final Map<String, Element> names = new HashMap<>();
private final String nameRegex = "[a-zA-Z]+";
private Element water, earth, fire, air, chi, avatar;
private SubElement blood, healing, ice, plant;
private SubElement lava, metal, sand;
private SubElement combustion, lightning;
private SubElement flight, spiritual;
private ElementManager() {
super("Element", new ElementRepository());
this.bendingPlayerManager = ModuleManager.getModule(BendingPlayerManager.class);
runAsync(() -> {
try {
getRepository().createTables();
// Waterbending
this.water = addElement(WATER, "Water", ChatColor.AQUA);
this.blood = addSubElement(BLOOD, "Blood", ChatColor.DARK_AQUA, this.water);
this.healing = addSubElement(HEALING, "Healing", ChatColor.DARK_AQUA, this.water);
this.ice = addSubElement(ICE, "Ice", ChatColor.DARK_AQUA, this.water);
this.plant = addSubElement(PLANT, "Plant", ChatColor.DARK_AQUA, this.water);
// Earthbending
this.earth = addElement(EARTH, "Earth", ChatColor.AQUA);
this.lava = addSubElement(LAVA, "Lava", ChatColor.DARK_GREEN, this.earth);
this.metal = addSubElement(METAL, "Metal", ChatColor.DARK_GREEN, this.earth);
this.sand = addSubElement(SAND, "Sand", ChatColor.DARK_GREEN, this.earth);
// Firebending
this.fire = addElement(FIRE, "Fire", ChatColor.RED);
this.combustion = addSubElement(COMBUSTION, "Combustion", ChatColor.DARK_RED, this.fire);
this.lightning = addSubElement(LIGHTNING, "Lightning", ChatColor.DARK_RED, this.fire);
// Airbending
this.air = addElement(AIR, "Air", ChatColor.GRAY);
this.flight = addSubElement(FLIGHT, "Flight", ChatColor.DARK_GRAY, this.air);
this.spiritual = addSubElement(SPIRITUAL, "Spiritual", ChatColor.DARK_GRAY, this.air);
// Chiblocking
this.chi = addElement(CHI, "Chi", ChatColor.GOLD);
// Avatar
this.avatar = addElement(AVATAR, "Avatar", ChatColor.DARK_PURPLE);
} catch (SQLException e) {
e.printStackTrace();
}
runSync(() -> {
log("Populated element database tables.");
});
});
}
@EventHandler
public void onBendingPlayerLoaded(BendingPlayerLoadedEvent event) {
BendingPlayer bendingPlayer = event.getBendingPlayer();
runAsync(() -> {
try {
List<Element> elements = getRepository().selectPlayerElements(bendingPlayer.getId()).stream().map(this.elements::get).collect(Collectors.toList());
elements.forEach(bendingPlayer::addElement);
} catch (SQLException e) {
e.printStackTrace();
}
});
}
public boolean addElement(Player player, Element element) {
BendingPlayer bendingPlayer = this.bendingPlayerManager.getBendingPlayer(player);
if (!bendingPlayer.addElement(element)) {
return false;
}
runAsync(() -> {
try {
getRepository().insertPlayerElement(bendingPlayer.getId(), element.getId());
} catch (SQLException e) {
e.printStackTrace();
}
});
return true;
}
public void setElement(Player player, Element element) {
BendingPlayer bendingPlayer = this.bendingPlayerManager.getBendingPlayer(player);
bendingPlayer.clearElements();
bendingPlayer.addElement(element);
runAsync(() -> {
try {
getRepository().deletePlayerElements(bendingPlayer.getId());
getRepository().insertPlayerElement(bendingPlayer.getId(), element.getId());
} catch (SQLException e) {
e.printStackTrace();
}
});
}
public boolean removeElement(Player player, Element element) {
BendingPlayer bendingPlayer = this.bendingPlayerManager.getBendingPlayer(player);
if (!bendingPlayer.removeElement(element)) {
return false;
}
runAsync(() -> {
try {
getRepository().deletePlayerElement(bendingPlayer.getId(), element.getId());
} catch (SQLException e) {
e.printStackTrace();
}
});
return true;
}
public void clearElements(Player player) {
BendingPlayer bendingPlayer = this.bendingPlayerManager.getBendingPlayer(player);
bendingPlayer.clearElements();
runAsync(() -> {
try {
getRepository().deletePlayerElements(bendingPlayer.getId());
} catch (SQLException e) {
e.printStackTrace();
}
});
}
private Element addElement(String elementName, String displayName, ChatColor color) {
int elementId = registerElement(elementName);
Element element = new Element(elementId, elementName, displayName, color);
this.elements.put(elementId, element);
this.names.put(elementName, element);
return element;
}
private SubElement addSubElement(String elementName, String displayName, ChatColor color, Element parent) {
int elementId = registerElement(elementName);
SubElement element = new SubElement(elementId, elementName, displayName, color, parent);
this.elements.put(elementId, element);
this.names.put(elementName, element);
return element;
}
private int registerElement(String elementName) {
Preconditions.checkNotNull(elementName, "Element name cannot be null");
Preconditions.checkArgument(Pattern.matches(this.nameRegex, elementName), "Element name must only contain letters and spaces");
try {
return getRepository().selectElemenetId(elementName);
} catch (SQLException e) {
e.printStackTrace();
return -1;
}
}
public Element getWater() {
return this.water;
}
public SubElement getBlood() {
return this.blood;
}
public SubElement getHealing() {
return this.healing;
}
public SubElement getIce() {
return this.ice;
}
public SubElement getPlant() {
return this.plant;
}
public Element getEarth() {
return this.earth;
}
public SubElement getLava() {
return this.lava;
}
public SubElement getMetal() {
return this.metal;
}
public SubElement getSand() {
return this.sand;
}
public Element getFire() {
return this.fire;
}
public SubElement getCombustion() {
return this.combustion;
}
public SubElement getLightning() {
return this.lightning;
}
public Element getAir() {
return this.air;
}
public SubElement getFlight() {
return this.flight;
}
public SubElement getSpiritual() {
return this.spiritual;
}
public Element getChi() {
return this.chi;
}
public Element getAvatar() {
return this.avatar;
}
}

View file

@ -0,0 +1,136 @@
package com.projectkorra.projectkorra.element;
import com.projectkorra.projectkorra.database.DatabaseQuery;
import com.projectkorra.projectkorra.database.DatabaseRepository;
import java.sql.*;
import java.util.HashSet;
import java.util.Set;
public class ElementRepository extends DatabaseRepository {
private static final DatabaseQuery CREATE_TABLE_ELEMENTS = DatabaseQuery.newBuilder()
.mysql("CREATE TABLE IF NOT EXISTS pk_elements (element_id INTEGER PRIMARY KEY AUTO_INCREMENT, element_name VARCHAR(50) NOT NULL, UNIQUE INDEX name_index (element_name));")
.sqlite("CREATE TABLE IF NOT EXISTS pk_elements (element_id INTEGER PRIMARY KEY AUTOINCREMENT, element_name VARCHAR(50) NOT NULL); CREATE UNIQUE INDEX name_index ON pk_elements (element_name);")
.build();
private static final DatabaseQuery CREATE_TABLE_PLAYER_ELEMENTS = DatabaseQuery.newBuilder()
.mysql("CREATE TABLE IF NOT EXISTS pk_player_elements (player_id INTEGER REFERENCES pk_bending_players (player_id), element_id INTEGER REFERENCES pk_elements (element_id), PRIMARY KEY (player_id, element_id), INDEX player_index (player_id), INDEX element_index (element_id));")
.sqlite("CREATE TABLE IF NOT EXISTS pk_player_elements (player_id INTEGER REFERENCES pk_bending_players (player_id), element_id INTEGER REFERENCES pk_elements (element_id), PRIMARY KEY (player_id, element_id)); CREATE INDEX player_index ON pk_player_elements (player_id); CREATE INDEX element_index ON pk_player_elements (element_id);")
.build();
private static final DatabaseQuery SELECT_ELEMENT_ID = DatabaseQuery.newBuilder()
.query("SELECT element_id FROM pk_elements WHERE element_name = ?;")
.build();
private static final DatabaseQuery INSERT_ELEMENT_ID = DatabaseQuery.newBuilder()
.query("INSERT INTO pk_elements (element_name) VALUES (?);")
.build();
private static final DatabaseQuery SELECT_PLAYER_ELEMENTS = DatabaseQuery.newBuilder()
.query("SELECT element_id FROM pk_player_elements WHERE player_id = ?;")
.build();
private static final DatabaseQuery INSERT_PLAYER_ELEMENT = DatabaseQuery.newBuilder()
.query("INSERT INTO pk_player_elements VALUES (?, ?);")
.build();
private static final DatabaseQuery DELETE_PLAYER_ELEMENTS = DatabaseQuery.newBuilder()
.query("DELETE FROM pk_player_elements WHERE player_id = ?;")
.build();
private static final DatabaseQuery DELETE_PLAYER_ELEMENT = DatabaseQuery.newBuilder()
.query("DELETE FROM pk_player_elements WHERE player_id = ? AND element_id = ?;")
.build();
protected void createTables() throws SQLException {
Connection connection = getDatabase().getConnection();
try (PreparedStatement elements = connection.prepareStatement(CREATE_TABLE_ELEMENTS.getQuery()); PreparedStatement playerElements = connection.prepareStatement(CREATE_TABLE_PLAYER_ELEMENTS.getQuery())) {
elements.executeUpdate();
playerElements.executeUpdate();
}
}
protected int selectElemenetId(String elementName) throws SQLException {
Connection connection = getDatabase().getConnection();
try (PreparedStatement statement = connection.prepareStatement(SELECT_ELEMENT_ID.getQuery())) {
statement.setString(1, elementName);
try (ResultSet rs = statement.executeQuery()) {
if (!rs.next()) {
return insertElementId(elementName);
}
return rs.getInt("element_id");
}
}
}
private int insertElementId(String elementName) throws SQLException {
Connection connection = getDatabase().getConnection();
try (PreparedStatement statement = connection.prepareStatement(INSERT_ELEMENT_ID.getQuery(), Statement.RETURN_GENERATED_KEYS)) {
statement.setString(1, elementName);
statement.executeUpdate();
try (ResultSet rs = statement.getGeneratedKeys()) {
rs.next();
return rs.getInt(1);
}
}
}
protected Set<Integer> selectPlayerElements(int playerId) throws SQLException {
Connection connection = getDatabase().getConnection();
try (PreparedStatement statement = connection.prepareStatement(SELECT_PLAYER_ELEMENTS.getQuery())) {
statement.setInt(1, playerId);
Set<Integer> elements = new HashSet<>();
try (ResultSet rs = statement.executeQuery()) {
while (rs.next()) {
elements.add(rs.getInt("element_id"));
}
return elements;
}
}
}
protected void insertPlayerElement(int playerId, int elementId) throws SQLException {
Connection connection = getDatabase().getConnection();
try (PreparedStatement statement = connection.prepareStatement(INSERT_PLAYER_ELEMENT.getQuery())) {
statement.setInt(1, playerId);
statement.setInt(2, elementId);
statement.executeUpdate();
}
}
protected void deletePlayerElements(int playerId) throws SQLException {
Connection connection = getDatabase().getConnection();
try (PreparedStatement statement = connection.prepareStatement(DELETE_PLAYER_ELEMENTS.getQuery())) {
statement.setInt(1, playerId);
statement.executeUpdate();
}
}
protected void deletePlayerElement(int playerId, int elementId) throws SQLException {
Connection connection = getDatabase().getConnection();
try (PreparedStatement statement = connection.prepareStatement(DELETE_PLAYER_ELEMENT.getQuery())) {
statement.setInt(1, playerId);
statement.setInt(2, elementId);
statement.executeUpdate();
}
}
}

View file

@ -0,0 +1,18 @@
package com.projectkorra.projectkorra.element;
import org.bukkit.ChatColor;
public class SubElement extends Element {
private final Element parent;
public SubElement(int elementId, String elementName, String displayName, ChatColor color, Element parent) {
super(elementId, elementName, displayName, color);
this.parent = parent;
}
public Element getParent() {
return this.parent;
}
}

View file

@ -217,7 +217,7 @@ public class FireBlastCharged extends FireAbility<FireBlastConfig> {
}
boolean exploded = false;
for (final Entity entity : GeneralMethods.getEntitiesAroundPoint(this.location, 2 * this.collisionRadius)) {
for (final Entity entity : GeneralMethods.getEntitiesAroundPoint(this.location, this.collisionRadius)) {
if (entity.getEntityId() == this.player.getEntityId() || GeneralMethods.isRegionProtectedFromBuild(this, entity.getLocation())) {
continue;
}
@ -311,8 +311,10 @@ public class FireBlastCharged extends FireAbility<FireBlastConfig> {
@Override
public void remove() {
super.remove();
if (this.charged) {
this.bPlayer.addCooldown(this);
}
}
@Override
public String getName() {

View file

@ -76,8 +76,6 @@ public class FireJet extends FireAbility<FireJetConfig> {
this.start();
this.previousGlidingState = player.isGliding();
this.bPlayer.addCooldown(this);
}
}
@ -122,6 +120,7 @@ public class FireJet extends FireAbility<FireJetConfig> {
}
this.flightHandler.removeInstance(this.player, this.getName());
this.player.setFallDistance(0);
this.bPlayer.addCooldown(this);
}
@Override

View file

@ -103,7 +103,6 @@ public class WallOfFire extends FireAbility<WallOfFireConfig> {
this.initializeBlocks();
this.start();
this.bPlayer.addCooldown(this);
}
private void affect(final Entity entity) {
@ -211,6 +210,12 @@ public class WallOfFire extends FireAbility<WallOfFireConfig> {
}
}
@Override
public void remove() {
super.remove();
this.bPlayer.addCooldown(this);
}
@Override
public String getName() {
return "WallOfFire";

View file

@ -81,7 +81,6 @@ public class JetBlast extends FireAbility<JetBlastConfig> implements ComboAbilit
return;
}
this.bPlayer.addCooldown("JetBlast", this.cooldown);
this.firstTime = false;
final float spread = 0F;
ParticleEffect.EXPLOSION_LARGE.display(this.player.getLocation(), 1, spread, spread, spread, 0);
@ -108,6 +107,7 @@ public class JetBlast extends FireAbility<JetBlastConfig> implements ComboAbilit
task.remove();
}
super.remove();
this.bPlayer.addCooldown("JetBlast", this.cooldown);
}
@Override

View file

@ -90,7 +90,6 @@ public class JetBlaze extends FireAbility<JetBlazeConfig> implements ComboAbilit
this.remove();
return;
}
this.bPlayer.addCooldown("JetBlaze", this.cooldown);
this.firstTime = false;
} else if (System.currentTimeMillis() - this.time > this.duration) {
this.remove();
@ -105,7 +104,7 @@ public class JetBlaze extends FireAbility<JetBlazeConfig> implements ComboAbilit
fs.setDensity(8);
fs.setSpread(1.0F);
fs.setUseNewParticles(true);
fs.setCollisionRadius(3);
fs.setCollisionRadius(2);
fs.setParticleEffect(ParticleEffect.SMOKE_LARGE);
fs.setDamage(this.damage);
fs.setFireTicks(this.fireTicks);
@ -123,6 +122,7 @@ public class JetBlaze extends FireAbility<JetBlazeConfig> implements ComboAbilit
task.remove();
}
super.remove();
this.bPlayer.addCooldown("JetBlaze", this.cooldown);
}
@Override

View file

@ -3,6 +3,8 @@ package com.projectkorra.projectkorra.firebending.lightning;
import java.util.ArrayList;
import java.util.List;
import com.projectkorra.projectkorra.ability.CoreAbility;
import com.projectkorra.projectkorra.firebending.FireJet;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
@ -181,6 +183,9 @@ public class Lightning extends LightningAbility<LightningConfig> {
} else if (!this.bPlayer.canBendIgnoreCooldowns(this)) {
this.remove();
return;
} else if (CoreAbility.hasAbility(player, FireJet.class)){
this.removeWithTasks();
return;
}
this.locations.clear();

View file

@ -0,0 +1,18 @@
package com.projectkorra.projectkorra.module;
import com.projectkorra.projectkorra.database.DatabaseRepository;
public abstract class DatabaseModule<T extends DatabaseRepository> extends Module {
private final T repository;
protected DatabaseModule(String name, T repository) {
super(name);
this.repository = repository;
}
protected T getRepository() {
return this.repository;
}
}

View file

@ -0,0 +1,88 @@
package com.projectkorra.projectkorra.module;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.projectkorra.projectkorra.ProjectKorra;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.plugin.java.JavaPlugin;
import java.util.logging.Level;
public abstract class Module implements Listener {
private static final String LOG_FORMAT = "(%s) %s";
private final String name;
private final Gson gson = new GsonBuilder().setPrettyPrinting().create();
protected Module(String name) {
this.name = name;
}
protected final void enable() {
long startTime = System.currentTimeMillis();
log("Enabling...");
getPlugin().getServer().getPluginManager().registerEvents(this, getPlugin());
onEnable();
long finishTime = System.currentTimeMillis();
log(String.format("Enabled! [%sms]", finishTime - startTime));
}
public void onEnable() {
}
protected final void disable() {
long startTime = System.currentTimeMillis();
log("Disabling...");
HandlerList.unregisterAll(this);
onDisable();
long finishTime = System.currentTimeMillis();
log(String.format("Disabled! [%sms]", finishTime - startTime));
}
public void onDisable() {
}
protected final void runSync(Runnable runnable) {
getPlugin().getServer().getScheduler().runTask(getPlugin(), runnable);
}
protected final void runAsync(Runnable runnable) {
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;
}
protected Gson getGson() {
return this.gson;
}
public final void log(String message) {
log(Level.INFO, message);
}
public final void log(Level level, String message) {
getPlugin().getLogger().log(level, String.format(LOG_FORMAT, getName(), message));
}
public ProjectKorra getPlugin() {
return JavaPlugin.getPlugin(ProjectKorra.class);
}
}

View file

@ -0,0 +1,82 @@
package com.projectkorra.projectkorra.module;
import com.google.common.base.Preconditions;
import com.projectkorra.projectkorra.ability.AbilityManager;
import com.projectkorra.projectkorra.cooldown.CooldownManager;
import com.projectkorra.projectkorra.database.DatabaseManager;
import com.projectkorra.projectkorra.element.ElementManager;
import com.projectkorra.projectkorra.player.BendingPlayerManager;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
public class ModuleManager {
private static final Map<Class<? extends Module>, Module> MODULES = new HashMap<>();
/**
* Registers a new {@link Module} instance.
*
* @param moduleClass {@link Class} of the {@link Module} to be registered
* @throws NullPointerException if moduleClass is null
* @throws IllegalArgumentException if moduleClass has already been registered
*/
public static void registerModule(Class<? extends Module> moduleClass) {
Preconditions.checkNotNull(moduleClass, "moduleClass cannot be null");
Preconditions.checkArgument(!MODULES.containsKey(moduleClass), "moduleClass has already been registered");
try {
Constructor<? extends Module> constructor = moduleClass.getDeclaredConstructor();
boolean accessible = constructor.isAccessible();
constructor.setAccessible(true);
Module module = constructor.newInstance();
MODULES.put(moduleClass, module);
module.enable();
constructor.setAccessible(accessible);
} catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
}
}
/**
* Returns a registered {@link Module} by its {@link Class}.
*
* @param moduleClass {@link Class} of the registered {@link Module}
* @return instance of the {@link Module} class
* @throws NullPointerException if moduleClass is null
* @throws IllegalArgumentException if moduleClass has not been registered
*/
public static <T extends Module> T getModule(Class<T> moduleClass) {
Preconditions.checkNotNull(moduleClass, "moduleClass cannot be null");
Preconditions.checkArgument(MODULES.containsKey(moduleClass), "moduleClass has not been registered");
return moduleClass.cast(MODULES.get(moduleClass));
}
/**
* Register all our core {@link Module}s onEnable.
*/
public static void startup() {
registerModule(DatabaseManager.class);
registerModule(BendingPlayerManager.class);
registerModule(ElementManager.class);
registerModule(AbilityManager.class);
registerModule(CooldownManager.class);
}
/**
* Disable all our core {@link Module}s onDisable.
*/
public static void shutdown() {
registerModule(CooldownManager.class);
registerModule(AbilityManager.class);
registerModule(ElementManager.class);
getModule(BendingPlayerManager.class).disable();
getModule(DatabaseManager.class).disable();
}
}

View file

@ -0,0 +1,267 @@
package com.projectkorra.projectkorra.player;
import com.projectkorra.projectkorra.ability.Ability;
import com.projectkorra.projectkorra.ability.AbilityManager;
import com.projectkorra.projectkorra.ability.ChiAbility;
import com.projectkorra.projectkorra.ability.CoreAbility;
import com.projectkorra.projectkorra.ability.util.PassiveManager;
import com.projectkorra.projectkorra.cooldown.CooldownManager;
import com.projectkorra.projectkorra.element.Element;
import com.projectkorra.projectkorra.element.ElementManager;
import com.projectkorra.projectkorra.module.ModuleManager;
import org.bukkit.entity.Player;
import java.util.*;
public class BendingPlayer {
private final BendingPlayerManager manager;
private final ElementManager elementManager;
private final AbilityManager abilityManager;
private final CooldownManager cooldownManager;
private final int playerId;
private final UUID uuid;
private final Player player;
private final String playerName;
private final long firstLogin;
private final Set<Element> elements;
private final Set<Element> toggledElements;
private final String[] abilities;
private ChiAbility stance;
private boolean bendingRemoved;
private boolean toggled;
private boolean tremorSense;
private boolean illumination;
private boolean chiBlocked;
private long slowTime;
public BendingPlayer(int playerId, UUID uuid, String playerName, long firstLogin) {
this.manager = ModuleManager.getModule(BendingPlayerManager.class);
this.elementManager = ModuleManager.getModule(ElementManager.class);
this.abilityManager = ModuleManager.getModule(AbilityManager.class);
this.cooldownManager = ModuleManager.getModule(CooldownManager.class);
this.playerId = playerId;
this.uuid = uuid;
this.player = manager.getPlugin().getServer().getPlayer(uuid);
this.playerName = playerName;
this.firstLogin = firstLogin;
this.elements = new HashSet<>();
this.toggledElements = new HashSet<>();
this.abilities = new String[9];
}
public Set<Element> getElements() {
return new HashSet<>(this.elements);
}
public boolean addElement(Element element) {
return this.elements.add(element);
}
public boolean removeElement(Element element) {
return this.elements.remove(element);
}
public void clearElements() {
this.elements.clear();
}
public boolean hasElement(Element element) {
if (element.equals(this.elementManager.getAvatar())) {
return this.player.hasPermission("bending.avatar");
}
return this.elements.contains(element);
}
public boolean canBloodbend() {
return this.elements.contains(this.elementManager.getBlood());
}
public boolean canUseHealing() {
return this.elements.contains(this.elementManager.getHealing());
}
public boolean canIcebend() {
return this.elements.contains(this.elementManager.getIce());
}
public boolean canPlantbend() {
return this.elements.contains(this.elementManager.getPlant());
}
public boolean canLavabend() {
return this.elements.contains(this.elementManager.getLava());
}
public boolean canMetalbend() {
return this.elements.contains(this.elementManager.getMetal());
}
public boolean canSandbend() {
return this.elements.contains(this.elementManager.getSand());
}
public boolean canCombustionbend() {
return this.elements.contains(this.elementManager.getCombustion());
}
public boolean canUseLightning() {
return this.elements.contains(this.elementManager.getLightning());
}
public boolean canUseFlight() {
return this.elements.contains(this.elementManager.getFlight());
}
public boolean canUseSpiritual() {
return this.elements.contains(this.elementManager.getSpiritual());
}
public boolean isElementToggled(Element element) {
return this.toggledElements.contains(element);
}
public void toggleElement(Element element) {
if (this.toggledElements.contains(element)) {
this.toggledElements.remove(element);
} else {
this.toggledElements.add(element);
}
}
public CoreAbility getBoundAbility() {
return CoreAbility.getAbility(getBoundAbilityName());
}
public String getBoundAbilityName() {
int slot = this.player.getInventory().getHeldItemSlot();
return this.abilities[slot];
}
public String getAbility(int slot) {
return this.abilities[slot];
}
public List<String> getAbilities() {
return Arrays.asList(this.abilities);
}
public void setAbilities(String[] abilities) {
System.arraycopy(abilities, 0, this.abilities, 0, 9);
}
public void setAbility(int slot, String abilityName) {
this.abilities[slot] = abilityName;
}
public void addCooldown(Ability ability) {
addCooldown(ability, ability.getCooldown());
}
public void addCooldown(Ability ability, long duration) {
addCooldown(ability.getName(), duration);
}
public void addCooldown(Ability ability, long duration, boolean permanent) {
addCooldown(ability.getName(), duration, permanent);
}
public void addCooldown(String abilityName, long duration) {
addCooldown(abilityName, duration, false);
}
public void addCooldown(String abilityName, long duration, boolean permanent) {
this.cooldownManager.addCooldown(this.player, abilityName, duration, permanent);
}
public boolean isOnCooldown(Ability ability) {
return isOnCooldown(ability.getName());
}
public boolean isOnCooldown(String abilityName) {
return this.cooldownManager.isOnCooldown(this.player, abilityName);
}
public void removeCooldown(Ability ability) {
removeCoolldown(ability.getName());
}
public void removeCoolldown(String abilityName) {
this.cooldownManager.removeCooldown(this.player, abilityName);
}
public ChiAbility getStance() {
return this.stance;
}
public void setStance(ChiAbility stance) {
this.stance = stance;
}
public boolean isBendingRemoved() {
return this.bendingRemoved;
}
protected void setBendingRemoved(boolean bendingRemoved) {
this.bendingRemoved = bendingRemoved;
}
public boolean isToggled() {
return this.toggled;
}
public void toggleBending() {
this.toggled = !this.toggled;
PassiveManager.registerPassives(this.player); // TODO redo this passive system
}
public boolean isTremorSensing() {
return this.tremorSense;
}
public void toggleTremorSense() {
this.tremorSense = !this.tremorSense;
}
public boolean isIlluminating() {
return this.illumination;
}
public void toggleIllumination() {
this.illumination = !this.illumination;
}
public boolean isChiBlocked() {
return this.chiBlocked;
}
public void blockChi() {
this.chiBlocked = true;
}
public void unblockChi() {
this.chiBlocked = false;
}
public boolean canBeSlowed() {
return System.currentTimeMillis() > this.slowTime;
}
public void slow(long cooldown) {
this.slowTime = System.currentTimeMillis() + cooldown;
}
public int getId() {
return this.playerId;
}
public long getFirstLogin() {
return this.firstLogin;
}
}

View file

@ -0,0 +1,31 @@
package com.projectkorra.projectkorra.player;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
public class BendingPlayerLoadedEvent extends PlayerEvent {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final BendingPlayer bendingPlayer;
public BendingPlayerLoadedEvent(Player player, BendingPlayer bendingPlayer) {
super(player);
this.bendingPlayer = bendingPlayer;
}
public BendingPlayer getBendingPlayer() {
return this.bendingPlayer;
}
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}

View file

@ -0,0 +1,119 @@
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.*;
public class BendingPlayerManager extends DatabaseModule<BendingPlayerRepository> {
private final Map<UUID, BendingPlayer> players = new HashMap<>();
private final Set<UUID> disconnected = new HashSet<>();
private final long databaseSyncInterval = 20 * 30;
private BendingPlayerManager() {
super("Bending Player", new BendingPlayerRepository());
runAsync(() -> {
try {
getRepository().createTables();
for (Player player : getPlugin().getServer().getOnlinePlayers()) {
loadBendingPlayer(player);
}
} catch (SQLException e) {
e.printStackTrace();
}
});
runTimer(() -> {
this.disconnected.forEach(this.players::remove);
this.disconnected.clear();
}, this.databaseSyncInterval, this.databaseSyncInterval);
}
@EventHandler(priority = EventPriority.LOWEST)
public void onLogin(PlayerLoginEvent event) {
if (this.disconnected.remove(event.getPlayer().getUniqueId())) {
return;
}
runAsync(() -> {
loadBendingPlayer(event.getPlayer());
});
}
@EventHandler
public void onQuit(PlayerQuitEvent event) {
this.disconnected.add(event.getPlayer().getUniqueId());
}
@EventHandler
public void onCooldownChange(PlayerCooldownChangeEvent event) {
Player player = event.getPlayer();
BendingPlayer bendingPlayer = this.players.get(player.getUniqueId());
String ability = bendingPlayer.getBoundAbilityName();
if (ability != null && ability.equals(event.getAbility())) {
GeneralMethods.displayMovePreview(player);
}
}
public void removeBending(Player player) {
BendingPlayer bendingPlayer = this.players.get(player.getUniqueId());
bendingPlayer.setBendingRemoved(true);
updateBendingRemoved(bendingPlayer);
}
public void returnBending(Player player) {
BendingPlayer bendingPlayer = this.players.get(player.getUniqueId());
bendingPlayer.setBendingRemoved(false);
updateBendingRemoved(bendingPlayer);
}
private void updateBendingRemoved(BendingPlayer bendingPlayer) {
runAsync(() -> {
try {
getRepository().updateBendingRemoved(bendingPlayer);
} catch (SQLException e) {
e.printStackTrace();
}
});
}
private void loadBendingPlayer(Player player) {
try {
BendingPlayer bendingPlayer = getRepository().selectPlayer(player);
runSync(() -> {
this.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 getBendingPlayer(player.getUniqueId());
}
public BendingPlayer getBendingPlayer(UUID uuid) {
return this.players.get(uuid);
}
}

View file

@ -0,0 +1,118 @@
package com.projectkorra.projectkorra.player;
import com.projectkorra.projectkorra.database.DatabaseQuery;
import com.projectkorra.projectkorra.database.DatabaseRepository;
import org.bukkit.entity.Player;
import java.nio.ByteBuffer;
import java.sql.*;
import java.util.UUID;
public class BendingPlayerRepository extends DatabaseRepository {
private static final DatabaseQuery CREATE_TABLE_BENDING_PLAYERS = DatabaseQuery.newBuilder()
.mysql("CREATE TABLE IF NOT EXISTS pk_bending_players (player_id INTEGER PRIMARY KEY AUTO_INCREMENT, uuid BINARY(16) NOT NULL, player_name VARCHAR(16) NOT NULL, first_login BIGINT NOT NULL, bending_removed BOOLEAN, INDEX uuid_index (uuid));")
.sqlite("CREATE TABLE IF NOT EXISTS pk_bending_players (player_id INTEGER PRIMARY KEY AUTOINCREMENT, uuid BINARY(16) NOT NULL, player_name VARCHAR(16) NOT NULL, first_login BIGINT NOT NULL, bending_removed BOOLEAN); CREATE INDEX uuid_index ON pk_bending_players (uuid);")
.build();
private static final DatabaseQuery SELECT_BENDING_PLAYER = DatabaseQuery.newBuilder()
.query("SELECT player_id, player_name, first_login, bending_removed FROM pk_bending_players WHERE uuid = ?;")
.build();
private static final DatabaseQuery INSERT_BENDING_PLAYER = DatabaseQuery.newBuilder()
.query("INSERT INTO pk_bending_players (uuid, player_name, first_login) VALUES (?, ?, ?);")
.build();
private static final DatabaseQuery UPDATE_PLAYER_NAME = DatabaseQuery.newBuilder()
.query("UPDATE pk_bending_players SET player_name = ? WHERE player_id = ?;")
.build();
private static final DatabaseQuery UPDATE_BENDING_REMOVED = DatabaseQuery.newBuilder()
.query("UPDATE pk_bending_players SET bending_removed = ? WHERE player_id = ?;")
.build();
protected void createTables() throws SQLException {
Connection connection = getDatabase().getConnection();
try (PreparedStatement statement = connection.prepareStatement(CREATE_TABLE_BENDING_PLAYERS.getQuery())) {
statement.executeUpdate();
}
}
protected BendingPlayer selectPlayer(Player player) throws SQLException {
UUID uuid = player.getUniqueId();
byte[] binaryUUID = ByteBuffer.allocate(16).putLong(uuid.getMostSignificantBits()).putLong(uuid.getLeastSignificantBits()).array();
Connection connection = getDatabase().getConnection();
try (PreparedStatement statement = connection.prepareStatement(SELECT_BENDING_PLAYER.getQuery())) {
statement.setBytes(1, binaryUUID);
try (ResultSet rs = statement.executeQuery()) {
if (!rs.next()) {
return insertPlayer(player.getUniqueId(), player.getName());
}
int playerId = rs.getInt("player_id");
String playerName = rs.getString("player_name");
long firstLogin = rs.getLong("first_login");
boolean bendingRemoved = rs.getBoolean("bending_removed");
if (!player.getName().equals(playerName)) {
updatePlayerName(playerId, player.getName());
}
BendingPlayer bendingPlayer = new BendingPlayer(playerId, uuid, playerName, firstLogin);
bendingPlayer.setBendingRemoved(bendingRemoved);
return bendingPlayer;
}
}
}
private BendingPlayer insertPlayer(UUID uuid, String playerName) throws SQLException {
byte[] binaryUUID = ByteBuffer.allocate(16).putLong(uuid.getMostSignificantBits()).putLong(uuid.getLeastSignificantBits()).array();
Connection connection = getDatabase().getConnection();
long firstLogin = System.currentTimeMillis();
try (PreparedStatement statement = connection.prepareStatement(INSERT_BENDING_PLAYER.getQuery(), Statement.RETURN_GENERATED_KEYS)) {
statement.setBytes(1, binaryUUID);
statement.setString(2, playerName);
statement.setLong(3, firstLogin);
statement.executeUpdate();
try (ResultSet rs = statement.getGeneratedKeys()) {
rs.next();
int playerId = rs.getInt(1);
return new BendingPlayer(playerId, uuid, playerName, firstLogin);
}
}
}
protected void updatePlayerName(int playerId, String playerName) throws SQLException {
Connection connection = getDatabase().getConnection();
try (PreparedStatement statement = connection.prepareStatement(UPDATE_PLAYER_NAME.getQuery())) {
statement.setInt(1, playerId);
statement.setString(2, playerName);
statement.executeUpdate();
}
}
protected void updateBendingRemoved(BendingPlayer bendingPlayer) throws SQLException {
Connection connection = getDatabase().getConnection();
try (PreparedStatement statement = connection.prepareStatement(UPDATE_BENDING_REMOVED.getQuery())) {
statement.setInt(1, bendingPlayer.getId());
statement.setBoolean(2, bendingPlayer.isBendingRemoved());
statement.executeUpdate();
}
}
}

View file

@ -256,12 +256,11 @@ public class SurgeWall extends WaterAbility<SurgeConfig> {
}
final ArrayList<Block> blocks = new ArrayList<Block>();
final Location targetLoc = GeneralMethods.getTargetedLocation(this.player, (int) this.range, Material.WATER, Material.ICE);
final Location targetLoc = GeneralMethods.getTargetedLocation(this.player, (int) this.range, false, false, Material.WATER, Material.ICE);
this.location = targetLoc.clone();
final Vector eyeDir = this.player.getEyeLocation().getDirection();
Vector vector;
Block block;
for (double i = 0; i <= this.getNightFactor(this.radius); i += 0.5) {
for (double angle = 0; angle < 360; angle += 10) {
vector = GeneralMethods.getOrthogonalVector(eyeDir.clone(), angle, i);

View file

@ -116,8 +116,8 @@ public class WaterReturn extends WaterAbility<EmptyAbilityConfig> {
private void fillBottle() {
final PlayerInventory inventory = this.player.getInventory();
if (inventory.contains(Material.GLASS_BOTTLE)) {
final int index = inventory.first(Material.GLASS_BOTTLE);
if (index >= 0) {
final ItemStack item = inventory.getItem(index);
final ItemStack water = waterBottleItem();
@ -148,27 +148,15 @@ public class WaterReturn extends WaterAbility<EmptyAbilityConfig> {
return false;
}
public static boolean hasWaterBottle(final Player player) {
if (hasAbility(player, WaterReturn.class) || isBending(player)) {
return false;
}
final PlayerInventory inventory = player.getInventory();
if (inventory.contains(Material.POTION)) {
final ItemStack item = inventory.getItem(inventory.first(Material.POTION));
final PotionMeta meta = (PotionMeta) item.getItemMeta();
return meta.getBasePotionData().getType() == PotionType.WATER;
}
return false;
}
public static void emptyWaterBottle(final Player player) {
final PlayerInventory inventory = player.getInventory();
public static int firstWaterBottle(final PlayerInventory inventory) {
int index = inventory.first(Material.POTION);
// Check that the first one found is actually a WATER bottle. We aren't implementing potion bending just yet.
if (index != -1 && !((PotionMeta) inventory.getItem(index).getItemMeta()).getBasePotionData().getType().equals(PotionType.WATER)) {
for (int i = 0; i < inventory.getSize(); i++) {
if (inventory.getItem(i).getType() == Material.POTION) {
if (index != -1) {
int aux = index;
index = -1;
for (int i = aux; i < inventory.getSize(); i++) {
if (inventory.getItem(i) != null && inventory.getItem(i).getType() == Material.POTION && inventory.getItem(i).hasItemMeta()) {
final PotionMeta meta = (PotionMeta) inventory.getItem(i).getItemMeta();
if (meta.getBasePotionData().getType().equals(PotionType.WATER)) {
index = i;
@ -178,6 +166,22 @@ public class WaterReturn extends WaterAbility<EmptyAbilityConfig> {
}
}
return index;
}
public static boolean hasWaterBottle(final Player player) {
if (hasAbility(player, WaterReturn.class) || isBending(player)) {
return false;
}
final PlayerInventory inventory = player.getInventory();
return WaterReturn.firstWaterBottle(inventory) >= 0;
}
public static void emptyWaterBottle(final Player player) {
final PlayerInventory inventory = player.getInventory();
int index = WaterReturn.firstWaterBottle(inventory);
if (index != -1) {
final ItemStack item = inventory.getItem(index);
if (item.getAmount() == 1) {