Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files

Rewrite death override system to use hacky NMS (and it even supports …

…1.6! :D)

Change version back to 0.3.0-SNAPSHOT
Fix lobby signs not being properly saved or removed
Fix compatibility for builds older than whenever they changed the damn getOnlinePlayers() method
Refactor PlayerNotPresentException and ArenaNotExistsException to NoSuchPlayerException and NoSuchArenaException
  • Loading branch information...
caseif committed Aug 6, 2014
1 parent c1bb7ac commit be40e12ebd4aaeddc9004c09e1e3777f845fbe1f
@@ -4,7 +4,7 @@
<groupId>net.amigocraft.mglib</groupId>
<artifactId>MGLib</artifactId>
<packaging>jar</packaging>
<version>0.3.0</version>
<version>0.3.0-SNAPSHOT</version>
<name>MGLib</name>
<url>http://dev.bukkit.org/bukkit-plugins/mglib/</url>
<description>A high-level API for Bukkit minigame creation</description>
@@ -6,9 +6,10 @@

import net.amigocraft.mglib.api.LobbySign;
import net.amigocraft.mglib.api.LobbyType;
import net.amigocraft.mglib.api.Location3D;
import net.amigocraft.mglib.api.Minigame;
import net.amigocraft.mglib.api.Stage;
import net.amigocraft.mglib.exception.ArenaNotExistsException;
import net.amigocraft.mglib.exception.NoSuchArenaException;
import net.amigocraft.mglib.exception.InvalidLocationException;

import org.bukkit.Bukkit;
@@ -23,7 +24,7 @@

private String plugin;

HashMap<Location, LobbySign> signs = new HashMap<Location, LobbySign>();
HashMap<Location3D, LobbySign> signs = new HashMap<Location3D, LobbySign>();

/**
* Creates a new lobby manager instance.
@@ -39,7 +40,7 @@ public LobbyManager(String plugin){
* @return a hashmap of signs registered with this lobby manager.
* @since 0.1.0
*/
public HashMap<Location, LobbySign> getSigns(){
public HashMap<Location3D, LobbySign> getSigns(){
return signs;
}

@@ -58,13 +59,13 @@ public LobbyManager(String plugin){
* @param arena The name of the arena the sign will be linked to.
* @param type The type of the sign ("status" or "players")
* @param index The number of the sign (applicable only for "players" signs)
* @throws ArenaNotExistsException if the specified arena does not exist.
* @throws NoSuchArenaException if the specified arena does not exist.
* @throws InvalidLocationException if the specified location does not contain a sign.
* @throws IllegalArgumentException if the specified index for a player sign is less than 1.
* @since 0.1.0
*/
public void add(Location l, String arena, LobbyType type, int index)
throws ArenaNotExistsException, InvalidLocationException, IllegalArgumentException {
throws NoSuchArenaException, InvalidLocationException, IllegalArgumentException {
if (l.getBlock().getState() instanceof Sign){
if (MGUtil.loadArenaYaml(plugin).getConfigurationSection(arena) != null){
LobbySign ls;
@@ -79,11 +80,11 @@ else if (type == LobbyType.PLAYERS){
else
throw new NullPointerException();
save(ls);
signs.put(l, ls);
signs.put(Location3D.valueOf(l), ls);
update(arena);
}
else
throw new ArenaNotExistsException();
throw new NoSuchArenaException();
}
else
throw new InvalidLocationException();
@@ -125,9 +126,11 @@ public void remove(LobbySign s){
if (!f.exists())
f.createNewFile();
y.load(f);
Location3D l = new Location3D(y.getString(s.getIndex() + ".world"), y.getInt(s.getIndex() + ".x"),
y.getInt(s.getIndex() + ".y"), y.getInt(s.getIndex() + ".z"));
y.set(Integer.toString(s.getIndex()), null);
y.save(f);
signs.remove(s);
signs.remove(l);
}
catch (Exception ex){
ex.printStackTrace();
@@ -142,32 +145,32 @@ public void remove(LobbySign s){
* @since 0.1.0
*/
public int save(LobbySign l){
int nextKey = 0;
int key = l.getIndex();
try {
YamlConfiguration y = new YamlConfiguration();
File f = new File(Minigame.getMinigameInstance(plugin).getPlugin().getDataFolder(), "lobbies.yml");
if (!f.exists())
f.createNewFile();
y.load(f);
if (key == -1)
for (String k : y.getKeys(false))
if (MGUtil.isInteger(k) && Integer.parseInt(k) >= nextKey)
nextKey = Integer.parseInt(k) + 1;
String key = Integer.toString(nextKey);
if (MGUtil.isInteger(k) && Integer.parseInt(k) >= key)
key = Integer.parseInt(k) + 1;
y.set(key + ".world", l.getWorld());
y.set(key + ".x", l.getX());
y.set(key + ".y", l.getY());
y.set(key + ".z", l.getZ());
y.set(key + ".arena", l.getArena());
y.set(key + ".type", l.getType().toString());
y.set(key + ".number", l.getNumber());
l.setIndex(nextKey);
l.setIndex(key);
y.save(f);
}
catch (Exception ex){
ex.printStackTrace();
Main.log.warning("An error occurred while creating a lobby sign for plugin " + plugin);
}
return nextKey;
return key;
}

/**
@@ -176,7 +179,7 @@ public int save(LobbySign l){
* @return the lobby sign at the specified location, or null if it does not exist.
* @since 0.1.0
*/
public LobbySign getSign(Location location){
public LobbySign getSign(Location3D location){
return signs.get(location);
}

@@ -203,8 +206,10 @@ public void loadSigns(){
LobbyType.fromString(y.getString(k + ".type").toUpperCase()) != null &&
(LobbyType.fromString(y.getString(k + ".type").toUpperCase()) == LobbyType.STATUS || y.get(k + ".number") != null)){
Location l = new Location(w, y.getInt(k + ".x"), y.getInt(k + ".y"), y.getInt(k + ".z"));
signs.put(l, new LobbySign(l.getBlockX(), l.getBlockY(), l.getBlockZ(), plugin, w.getName(),
y.getString(k + ".arena"), y.getInt(k + ".number"), LobbyType.fromString(y.getString(k + ".type").toUpperCase())));
LobbySign ls = new LobbySign(l.getBlockX(), l.getBlockY(), l.getBlockZ(), plugin, w.getName(),
y.getString(k + ".arena"), y.getInt(k + ".number"), LobbyType.fromString(y.getString(k + ".type").toUpperCase()));
ls.setIndex(Integer.parseInt(k));
signs.put(Location3D.valueOf(l), ls);
}
else
Main.log.warning("Incomplete data for lobby sign with index of " + k + "! Removing from disk...");
@@ -15,9 +15,9 @@
import net.amigocraft.mglib.api.Round;
import net.amigocraft.mglib.event.player.MGPlayerDeathEvent;
import net.amigocraft.mglib.event.round.LobbyClickEvent;
import net.amigocraft.mglib.exception.ArenaNotExistsException;
import net.amigocraft.mglib.exception.NoSuchArenaException;
import net.amigocraft.mglib.exception.InvalidLocationException;
import net.amigocraft.mglib.exception.PlayerNotPresentException;
import net.amigocraft.mglib.exception.NoSuchPlayerException;
import net.amigocraft.mglib.exception.PlayerOfflineException;
import net.amigocraft.mglib.exception.PlayerPresentException;
import net.amigocraft.mglib.exception.RoundFullException;
@@ -27,12 +27,10 @@
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.block.Sign;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
@@ -56,7 +54,7 @@
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.entity.EntityTargetEvent;
import org.bukkit.event.entity.FoodLevelChangeEvent;
@@ -67,10 +65,8 @@
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;

class MGListener implements Listener {

@@ -182,7 +178,7 @@ else if (damager instanceof Projectile) // damager is an arrow or something
e.setCancelled(true);
return;
}
if (p != null && p.getRound() != null && p.getRound().getConfigManager().isOverrideDeathEvent()){
/*if (p != null && p.getRound() != null && p.getRound().getConfigManager().isOverrideDeathEvent()){
// override the death event with a custom one
double actualDamage = 0;
boolean force = false;
@@ -267,6 +263,8 @@ else if (en == Enchantment.PROTECTION_PROJECTILE &&
actualDamage = (int)(e.getDamage() * potionMod - armorMod - enchantMod);
force = true;
}
Main.log("damage: " + p2.getWorld().getTime() + ", " +
p2.getName() + ", " + actualDamage + ", " + ((Player)e.getEntity()).getHealth(), LogLevel.DEBUG);
if (actualDamage >= ((Player)e.getEntity()).getHealth()){
e.setCancelled(true);
MGUtil.callEvent(new MGPlayerDeathEvent(p, e.getCause(),
@@ -283,7 +281,56 @@ else if (mg.getConfigManager().isForcePreciseDamage() && force){
MGUtil.damage(p2);
}
break;
}
}*/
}
}
}

@SuppressWarnings({"unchecked", "rawtypes"})
@EventHandler
public void onPlayerDeath(PlayerDeathEvent e){
for (Minigame mg : Minigame.getMinigameInstances()){
if (mg.getConfigManager().isOverrideDeathEvent() && mg.isPlayer(e.getEntity().getName())){
e.setDeathMessage(null);
e.setKeepLevel(true);
e.getDrops().clear();
try {
// oh God why did I think this was a good idea
Class<?> packetClass;
Object packet;
try {
packetClass = MGUtil.getMCClass("PacketPlayInClientCommand");
packet = packetClass.getConstructor(MGUtil.getMCClass("EnumClientCommand"))
.newInstance(Enum.valueOf((Class<? extends Enum>)MGUtil.getMCClass("EnumClientCommand"), "PERFORM_RESPAWN"));
}
catch (Exception ex){
packetClass = MGUtil.getMCClass("Packet205ClientCommand");
packet = packetClass.getConstructor().newInstance();
packetClass.getDeclaredField("a").set(packet, 1);
}
Object nmsPlayer = MGUtil.getCraftClass("entity.CraftPlayer").getMethod("getHandle").invoke(e.getEntity(), new Object[0]);
Object conn = nmsPlayer.getClass().getDeclaredField("playerConnection").get(nmsPlayer);
conn.getClass().getMethod("a", packetClass).invoke(conn, packet);
}
catch (Exception ex){
ex.printStackTrace();
}
EntityDamageEvent ed = e.getEntity().getLastDamageCause();
MGUtil.callEvent(new MGPlayerDeathEvent(mg.getMGPlayer(e.getEntity().getName()), ed.getCause(),
ed instanceof EntityDamageByEntityEvent ?
((EntityDamageByEntityEvent)ed).getDamager() instanceof Projectile ?
(Entity)((Projectile)((EntityDamageByEntityEvent)ed).getDamager()).getShooter() :
((EntityDamageByEntityEvent)ed).getDamager() :
null));
}
}
}

@EventHandler(priority = EventPriority.HIGHEST)
public void onPlayerRespawn(PlayerRespawnEvent e){
for (Minigame mg : Minigame.getMinigameInstances()){
if (mg.getConfigManager().isOverrideDeathEvent() && mg.isPlayer(e.getPlayer().getName())){
e.setRespawnLocation(e.getPlayer().getLocation());
}
}
}
@@ -335,7 +382,7 @@ public void onPlayerTeleport(PlayerTeleportEvent e){
try {
p.removeFromRound(l);
}
catch (PlayerNotPresentException ex){} // this can never happen
catch (NoSuchPlayerException ex){} // this can never happen
catch (PlayerOfflineException ex){} // this can definitely never happen
}
else {
@@ -351,7 +398,7 @@ public void onPlayerTeleport(PlayerTeleportEvent e){
try {
p.removeFromRound(l);
}
catch (PlayerNotPresentException ex){} // this can never happen
catch (NoSuchPlayerException ex){} // this can never happen
catch (PlayerOfflineException ex){} // this can definitely never happen
}
}
@@ -680,7 +727,7 @@ public void onSignChange(SignChangeEvent e) throws IndexOutOfBoundsException, In
int index = MGUtil.isInteger(e.getLine(3)) ? Integer.parseInt(e.getLine(3)) : 0;
mg.getLobbyManager().add(e.getBlock().getLocation(), e.getLine(2), LobbyType.fromString(e.getLine(1)), index);
}
catch (ArenaNotExistsException ex){
catch (NoSuchArenaException ex){
e.getPlayer().sendMessage(ChatColor.RED + locale.getMessage("arena-not-exists"));
}
catch (IllegalArgumentException ex){
@@ -714,7 +761,7 @@ public void onPlayerInteract(PlayerInteractEvent e){
if (e.getAction() == Action.LEFT_CLICK_BLOCK || e.getAction() == Action.RIGHT_CLICK_BLOCK){
if (e.getClickedBlock().getState() instanceof Sign){
for (Minigame mg : Minigame.getMinigameInstances()){
LobbySign ls = mg.getLobbyManager().getSign(e.getClickedBlock().getLocation());
LobbySign ls = mg.getLobbyManager().getSign(Location3D.valueOf(e.getClickedBlock().getLocation()));
if (ls != null){
e.setCancelled(true);
if (e.getAction() == Action.LEFT_CLICK_BLOCK && e.getPlayer().isSneaking()){
@@ -729,7 +776,7 @@ public void onPlayerInteract(PlayerInteractEvent e){
try {
r = mg.createRound(ls.getArena());
}
catch (ArenaNotExistsException ex){
catch (NoSuchArenaException ex){
e.getPlayer().sendMessage(ChatColor.RED + locale.getMessage("arena-load-fail").replace("%", ls.getArena()));
return;
}
@@ -35,6 +35,9 @@
private static Field playerConnection;
private static Method sendPacket;

public static final String ANSI_RED = "\u001B[31m";
public static final String ANSI_WHITE = "\u001B[37m";

static {
try {
//get the constructor of the packet
@@ -234,13 +237,13 @@ public static void damage(Player p){
}
}

private static Class<?> getMCClass(String name) throws ClassNotFoundException {
public static Class<?> getMCClass(String name) throws ClassNotFoundException {
String version = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3] + ".";
String className = "net.minecraft.server." + version + name;
return Class.forName(className);
}

private static Class<?> getCraftClass(String name) throws ClassNotFoundException {
public static Class<?> getCraftClass(String name) throws ClassNotFoundException {
String version = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3] + ".";
String className = "org.bukkit.craftbukkit." + version + name;
return Class.forName(className);
@@ -1,7 +1,9 @@
package net.amigocraft.mglib;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
@@ -63,6 +65,7 @@
* Standard {@link JavaPlugin#onEnable()} override.
* @since 0.1.0
*/
@SuppressWarnings("unchecked")
public void onEnable(){

plugin = this;
@@ -98,8 +101,19 @@ public void onEnable(){

// store UUIDs of online players
List<String> names = new ArrayList<String>();
for (Player p : Bukkit.getOnlinePlayers())
names.add(p.getName());
try {
if (Bukkit.class.getMethod("getOnlinePlayers", new Class<?>[0]).getReturnType() == Collection.class)
for (Player pl :
(Collection<? extends Player>)Bukkit.class.getMethod("getOnlinePlayers", new Class<?>[0]).invoke(null, new Object[0]))
names.add(pl.getName());
else
for (Player pl :
(Player[])Bukkit.class.getMethod("getOnlinePlayers", new Class<?>[0]).invoke(null, new Object[0]))
names.add(pl.getName());
}
catch (NoSuchMethodException ex){} // can never happen
catch (InvocationTargetException ex){} // can also never happen
catch (IllegalAccessException ex){} // can still never happen
try {
new UUIDFetcher(names).call();
}
@@ -1,5 +1,4 @@
package net.amigocraft.mglib;

import java.io.File;

import net.amigocraft.mglib.api.Minigame;
@@ -15,6 +14,7 @@
import org.bukkit.block.Sign;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
@@ -26,6 +26,8 @@
private File f = null;
private YamlConfiguration y = null;
private JavaPlugin plugin = null;

EntityDamageEvent lastEvent;

/**
* Creates a new rollback manager for the specified plugin
Oops, something went wrong.

0 comments on commit be40e12

Please sign in to comment.
You can’t perform that action at this time.