From 396ce7508771db438bd6dddffae33286368188a6 Mon Sep 17 00:00:00 2001 From: NewGarbo Date: Fri, 30 Oct 2015 22:13:19 +0000 Subject: [PATCH] Bug fixes/Additions: - Being able to kill clan mates/create mode players who combat log. - Added a notice that the player was killed, when a player logs back in after being killed when combat logging. - Fixed Fall Damage making a player unsafe in safe territories. - Fixed Alligator's Tooth damage. - Fixed Alligator's Tooth working in lava. - Added a UtilFile to Mineplex.Core.Common, for all stuff files! --- .../mineplex/core/common/util/UtilFile.java | 313 ++++++++++++++++++ .../mineplex/core/common/util/UtilItem.java | 3 - .../mineplex/game/clans/clans/ClanInfo.java | 5 + .../game/clans/clans/ClansManager.java | 26 +- .../clans/gameplay/safelog/QuitCommand.java | 6 +- .../{LoggingManager.java => SafeLog.java} | 44 ++- .../gameplay/safelog/npc/CombatLogNPC.java | 67 +++- .../gameplay/safelog/npc/NPCManager.java | 24 +- .../gameplay/safelog/npc/PlayerInfo.java | 9 +- .../items/legendaries/AlligatorsTooth.java | 17 +- .../items/legendaries/GiantsBroadsword.java | 10 +- .../clans/items/legendaries/WindBlade.java | 15 +- .../game/clans/tutorials/TutorialClient.java | 2 + .../types/TutorialGettingStarted.java | 3 - .../tutorials/types/TutorialOnGoingMap.java | 6 +- .../minecraft/game/core/combat/CombatLog.java | 2 +- 16 files changed, 496 insertions(+), 56 deletions(-) create mode 100644 Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilFile.java rename Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/safelog/{LoggingManager.java => SafeLog.java} (82%) diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilFile.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilFile.java new file mode 100644 index 000000000..d64ff3ca7 --- /dev/null +++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilFile.java @@ -0,0 +1,313 @@ +package mineplex.core.common.util; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintWriter; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.UUID; + +import org.bukkit.Bukkit; + +public class UtilFile +{ + public static void writePlainFile(File file, String text) throws FileNotFoundException + { + PrintWriter writer = new PrintWriter(file); + writer.print(text); + writer.close(); + } + + /** + * Will read the specified file, and return the contents, or a null value, + * if an exception is thrown. Will handle all exceptions, and simply ignore + * them and return null. No stack trace printed or anything. + */ + public static String readIgnoreErrors(File file) + { + try + { + return readToStr(file); + } + catch (IOException exception) + { + return null; + } + } + + public static String readToStr(File file) throws IOException + { + return new String(readAllBytes(file)); + } + + public static byte[] readAllBytes(File file) throws IOException + { + return Files.readAllBytes(Paths.get(file.toURI())); + } + + public static void writePlainFile(String file, String text) throws FileNotFoundException + { + writePlainFile(new File(file), text); + } + + /** + * Will read the specified file, and return the contents, or a null value, + * if an exception is thrown. Will handle all exceptions, and simply ignore + * them and return null. No stack trace printed or anything. + */ + public static String readIgnoreErrors(String file) + { + return readIgnoreErrors(new File(file)); + } + + public static String readToStr(String file) throws IOException + { + return readToStr(new File(file)); + } + + public static byte[] readAllBytes(String file) throws IOException + { + return readAllBytes(new File(file)); + } + + public static void writeDataFile(File file, DataFileChunk... chunks) throws IOException + { + DataOutputStream stream = new DataOutputStream(new FileOutputStream(file)); + for (DataFileChunk chunk : chunks) + { + chunk.writeTo(stream); + } + stream.close(); + } + + public static DataFileReader beginReading(String file) throws FileNotFoundException + { + return beginReading(new File(file)); + } + + public static DataFileReader beginReading(File file) throws FileNotFoundException + { + return new DataFileReader(file); + } + + public static void writeDataFile(String file, DataFileChunk... chunks) throws IOException + { + writeDataFile(new File(file), chunks); + } + + public static class DataFileChunk + { + private ChunkType _type; + private Object _value; + + public DataFileChunk(ChunkType type, Object value) + { + if (type == null) + { + throw new RuntimeException("ChunkType can NOT be null."); + } + + _type = type; + + if (!_type.isValid(value)) + { + throw new RuntimeException("Invalid value provided for the specified ChunkType."); + } + + _value = value; + } + + public void writeTo(DataOutputStream stream) throws IOException + { + _type.writeTo(stream, _value); + } + } + + public static enum ChunkType + { + STRING(new ChunkImpl() + { + public void writeTo(DataOutputStream stream, Object value) throws IOException + { + String str = (String) value; + + INTEGER.writeTo(stream, str.length()); + for (char b : str.toCharArray()) + { + CHAR.writeTo(stream, b); + } + } + + public boolean isValid(Object value) + { + return value.getClass().equals(String.class); + } + + public Object readFrom(DataInputStream stream) throws IOException + { + int length = (int) INTEGER.readFrom(stream); + + StringBuilder string = new StringBuilder(); + + for (int i = 0; i < length; i++) + { + string.append(CHAR.readFrom(stream)); + } + + return string.toString(); + } + }), + DOUBLE(new ChunkImpl() + { + public void writeTo(DataOutputStream stream, Object value) throws IOException + { + double number = (double) value; + + stream.writeDouble(number); + } + + public boolean isValid(Object value) + { + return value.getClass().equals(Double.class); + } + + public Object readFrom(DataInputStream stream) throws IOException + { + return stream.readDouble(); + } + }), + INTEGER(new ChunkImpl() + { + public void writeTo(DataOutputStream stream, Object value) throws IOException + { + int number = (int) value; + + stream.writeInt(number); + } + + public boolean isValid(Object value) + { + return value.getClass().equals(Integer.class); + } + + public Object readFrom(DataInputStream stream) throws IOException + { + return stream.readInt(); + } + }), + BYTE(new ChunkImpl() + { + public void writeTo(DataOutputStream stream, Object value) throws IOException + { + byte number = (byte) value; + + stream.writeByte(number); + } + + public boolean isValid(Object value) + { + return value.getClass().equals(Byte.class); + } + + public Object readFrom(DataInputStream stream) throws IOException + { + return stream.readByte(); + } + }), + CHAR(new ChunkImpl() + { + public void writeTo(DataOutputStream stream, Object value) throws IOException + { + char number = (char) value; + + stream.writeChar(number); + } + + public boolean isValid(Object value) + { + return value.getClass().equals(Character.class); + } + + public Object readFrom(DataInputStream stream) throws IOException + { + return stream.readChar(); + } + }), + LONG(new ChunkImpl() + { + public void writeTo(DataOutputStream stream, Object value) throws IOException + { + long number = (long) value; + + stream.writeLong(number); + } + + public boolean isValid(Object value) + { + return value.getClass().equals(Long.class); + } + + public Object readFrom(DataInputStream stream) throws IOException + { + return stream.readLong(); + } + }); + + private ChunkImpl _impl; + + ChunkType(ChunkImpl impl) + { + _impl = impl; + } + + protected void writeTo(DataOutputStream stream, Object value) throws IOException + { + _impl.writeTo(stream, value); + } + + protected boolean isValid(Object value) + { + return value != null && _impl.isValid(value); + } + + public Object readFrom(DataInputStream stream) throws IOException + { + return _impl.readFrom(stream); + } + } + + public static class DataFileReader + { + private DataInputStream _stream; + + public DataFileReader(File file) throws FileNotFoundException + { + _stream = new DataInputStream(new FileInputStream(file)); + } + + public Object readChunk(ChunkType type) throws IOException + { + return type.readFrom(_stream); + } + + public void close() throws IOException + { + _stream.close(); + } + } + + protected interface ChunkImpl + { + void writeTo(DataOutputStream stream, Object value) throws IOException; + + Object readFrom(DataInputStream stream) throws IOException; + + boolean isValid(Object value); + } + +} diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilItem.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilItem.java index f879aafac..7398ce072 100644 --- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilItem.java +++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilItem.java @@ -1,7 +1,6 @@ package mineplex.core.common.util; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.EnumSet; import java.util.HashMap; @@ -15,8 +14,6 @@ import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import mineplex.core.common.structs.ItemContainer; -import mineplex.core.common.util.UtilItem.ArmourMaterial; -import mineplex.core.common.util.UtilItem.ItemCategory; public class UtilItem { diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClanInfo.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClanInfo.java index 80dc2df89..2ec050910 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClanInfo.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClanInfo.java @@ -197,6 +197,11 @@ public class ClanInfo { return getMembers().containsKey(player.getUniqueId()); } + + public boolean isMember(UUID uuid) + { + return getMembers().containsKey(uuid); + } public boolean isAlly(String other) { diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansManager.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansManager.java index 20933ff9f..71b445c8f 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansManager.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansManager.java @@ -1,5 +1,6 @@ package mineplex.game.clans.clans; +import java.io.File; import java.util.HashSet; import java.util.Set; import java.util.TimeZone; @@ -14,8 +15,8 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.block.Action; import org.bukkit.event.block.BlockBreakEvent; -import org.bukkit.event.entity.EntityShootBowEvent; import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; +import org.bukkit.event.entity.EntityShootBowEvent; import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.player.AsyncPlayerChatEvent; import org.bukkit.event.player.PlayerInteractEvent; @@ -27,9 +28,6 @@ import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.java.JavaPlugin; -import net.minecraft.server.v1_7_R4.EnumToolMaterial; -import net.minecraft.server.v1_7_R4.Item; -import net.minecraft.server.v1_7_R4.ItemSword; import mineplex.core.MiniClientPlugin; import mineplex.core.account.CoreClientManager; import mineplex.core.achievement.AchievementManager; @@ -41,14 +39,12 @@ import mineplex.core.common.util.F; import mineplex.core.common.util.NautHashMap; import mineplex.core.common.util.UtilPlayer; import mineplex.core.common.util.UtilServer; -import mineplex.core.common.util.UtilWorld; import mineplex.core.creature.Creature; import mineplex.core.creature.event.CreatureSpawnCustomEvent; import mineplex.core.disguise.DisguiseManager; import mineplex.core.donation.DonationManager; import mineplex.core.energy.Energy; import mineplex.core.explosion.Explosion; -import mineplex.core.gui.SimpleGuiItem; import mineplex.core.hologram.HologramManager; import mineplex.core.movement.Movement; import mineplex.core.npc.NpcManager; @@ -78,7 +74,6 @@ import mineplex.game.clans.clans.scoreboard.ClansScoreboardManager; import mineplex.game.clans.clans.supplyDrop.SupplyDropManager; import mineplex.game.clans.clans.tntGenerator.TntGeneratorManager; import mineplex.game.clans.clans.war.WarManager; -import mineplex.game.clans.economy.GoldManager; import mineplex.game.clans.clans.worldevent.WorldEventManager; import mineplex.game.clans.core.ClanDeleteCommand; import mineplex.game.clans.core.ClanLoadCommand; @@ -86,9 +81,10 @@ import mineplex.game.clans.core.repository.ClanTerritory; import mineplex.game.clans.core.repository.tokens.ClanMemberToken; import mineplex.game.clans.core.repository.tokens.ClanTerritoryToken; import mineplex.game.clans.core.repository.tokens.ClanToken; +import mineplex.game.clans.economy.GoldManager; import mineplex.game.clans.fields.Field; import mineplex.game.clans.gameplay.Gameplay; -import mineplex.game.clans.gameplay.safelog.LoggingManager; +import mineplex.game.clans.gameplay.safelog.SafeLog; import mineplex.game.clans.gameplay.safelog.npc.NPCManager; import mineplex.game.clans.items.GearManager; import mineplex.game.clans.spawn.Spawn; @@ -108,11 +104,10 @@ import mineplex.minecraft.game.core.condition.ConditionManager; import mineplex.minecraft.game.core.damage.DamageManager; import mineplex.minecraft.game.core.fire.Fire; import mineplex.minecraft.game.core.mechanics.Weapon; -import mineplex.serverdata.Region; import mineplex.serverdata.commands.ServerCommandManager; -import mineplex.serverdata.redis.RedisDataRepository; -import mineplex.serverdata.servers.ConnectionData; -import mineplex.serverdata.servers.ServerManager; +import net.minecraft.server.v1_7_R4.EnumToolMaterial; +import net.minecraft.server.v1_7_R4.Item; +import net.minecraft.server.v1_7_R4.ItemSword; public class ClansManager extends MiniClientPlugin implements IRelation { @@ -169,6 +164,8 @@ public class ClansManager extends MiniClientPlugin implements IRelat private NautHashMap _clanMemberUuidMap = new NautHashMap(); private NautHashMap _claimMap = new NautHashMap(); private NautHashMap _unclaimMap = new NautHashMap(); + + public String UserDataPath = UtilServer.getServer().getWorlds().get(0).getWorldFolder().getPath() + "\\..\\CLANS_USER_DATA\\"; // Spawn area @@ -229,7 +226,7 @@ public class ClansManager extends MiniClientPlugin implements IRelat // Required managers to be initialized new Spawn(plugin, this); new NPCManager(this, _hologramManager); - new LoggingManager(plugin, this); + new SafeLog(plugin, this); new ObserverManager(plugin, _condition, this); new Weapon(plugin, energy); @@ -392,7 +389,6 @@ public class ClansManager extends MiniClientPlugin implements IRelat public long lastPower = System.currentTimeMillis(); - @EventHandler public void savePlayerActiveBuild(PlayerQuitEvent event) { @@ -415,7 +411,7 @@ public class ClansManager extends MiniClientPlugin implements IRelat public void onPlayerKick(PlayerKickEvent event) { // Players using wind blade should not get kicked - if (event.getPlayer().getItemInHand().getItemMeta() != null && (C.cGold + "Wind Blade").equals(event.getPlayer().getItemInHand().getItemMeta().getDisplayName())) + if (event.getPlayer().getItemInHand() != null && event.getPlayer().getItemInHand().getItemMeta() != null && (C.cGold + "Wind Blade").equals(event.getPlayer().getItemInHand().getItemMeta().getDisplayName())) { if (event.getReason().contains("flying is not enabled")) { diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/safelog/QuitCommand.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/safelog/QuitCommand.java index 363d8db23..e0ad5eafc 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/safelog/QuitCommand.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/safelog/QuitCommand.java @@ -7,11 +7,11 @@ import mineplex.core.common.Rank; import mineplex.core.common.util.F; import mineplex.core.common.util.UtilPlayer; -public class QuitCommand extends CommandBase +public class QuitCommand extends CommandBase { - private LoggingManager _loggingManager; + private SafeLog _loggingManager; - public QuitCommand(LoggingManager plugin) + public QuitCommand(SafeLog plugin) { super(plugin, Rank.ALL, "quit", "log", "logout"); diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/safelog/LoggingManager.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/safelog/SafeLog.java similarity index 82% rename from Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/safelog/LoggingManager.java rename to Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/safelog/SafeLog.java index 8357f95f7..fd260836f 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/safelog/LoggingManager.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/safelog/SafeLog.java @@ -1,5 +1,6 @@ package mineplex.game.clans.gameplay.safelog; +import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -21,6 +22,9 @@ import org.bukkit.plugin.java.JavaPlugin; import mineplex.core.MiniPlugin; import mineplex.core.common.util.C; import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilFile; +import mineplex.core.common.util.UtilFile.ChunkType; +import mineplex.core.common.util.UtilFile.DataFileReader; import mineplex.core.common.util.UtilPlayer; import mineplex.core.common.util.UtilServer; import mineplex.core.common.util.UtilTextMiddle; @@ -31,7 +35,7 @@ import mineplex.core.updater.event.UpdateEvent; import mineplex.game.clans.clans.ClansManager; import mineplex.game.clans.gameplay.safelog.npc.NPCManager; -public class LoggingManager extends MiniPlugin +public class SafeLog extends MiniPlugin { public static final String SAFE_LOG_MESSAGE = "You have safely logged out!"; public static final double SAFE_LOG_RANGE = 1.5d; // Distance a player can @@ -46,13 +50,15 @@ public class LoggingManager extends MiniPlugin private ClansManager _clansManager; private HashMap _hint; - public LoggingManager(JavaPlugin plugin, ClansManager clansManager) + public SafeLog(JavaPlugin plugin, ClansManager clansManager) { - super("Logout Manager", plugin); + super("SafeLog", plugin); _logouts = new HashMap<>(); _hint = new HashMap<>(); _clansManager = clansManager; + + new File(plugin.getServer().getWorlds().get(0).getWorldFolder().getPath() + "\\..\\CLANS_USER_DATA\\").mkdir(); } public void onPlayerQuit(Player player) @@ -72,13 +78,43 @@ public class LoggingManager extends MiniPlugin } } - public void onPlayerJoin(Player player) + public void onPlayerJoin(final Player player) { // Despawn the player's logout NPC if they have one existing on login if (NPCManager.getInstance().hasLogoutNpc(player)) { NPCManager.getInstance().despawnLogoutNpc(player); } + + File deathFile = new File(_clansManager.UserDataPath + String.format("DEATH_%s.dat", player.getUniqueId().toString())); + + if (deathFile.exists()) + { + try + { + DataFileReader reader = UtilFile.beginReading(_clansManager.UserDataPath + String.format("DEATH_%s.dat", player.getUniqueId().toString())); + + final long time = (long) reader.readChunk(ChunkType.LONG); + final String killerName = (String) reader.readChunk(ChunkType.STRING); + + UtilServer.getServer().getScheduler().scheduleSyncDelayedTask(getPlugin(), new Runnable() + { + public void run() + { + UtilPlayer.message(player, F.main("SafeLog", "You were killed by " + F.elem(killerName) + " when you logged out unsafely! This happened about " + F.time(UtilTime.MakeStr(System.currentTimeMillis() - time))) + " ago."); + UtilTextMiddle.display("You were killed!", "Whilst combat logged, " + F.elem(killerName) + " killed you", 15, 80, 40, player); + } + }, 15); + reader.close(); + + deathFile.delete(); + } + catch (Exception e) + { + e.printStackTrace(); + // Ignore for now + } + } } @EventHandler diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/safelog/npc/CombatLogNPC.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/safelog/npc/CombatLogNPC.java index 23f7dddfe..1c2cfc2e9 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/safelog/npc/CombatLogNPC.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/safelog/npc/CombatLogNPC.java @@ -1,10 +1,12 @@ package mineplex.game.clans.gameplay.safelog.npc; import java.io.File; +import java.io.IOException; import java.util.List; import org.bukkit.Location; import org.bukkit.World; +import org.bukkit.craftbukkit.v1_7_R4.entity.CraftLivingEntity; import org.bukkit.craftbukkit.v1_7_R4.entity.CraftPlayer; import org.bukkit.entity.EntityType; import org.bukkit.entity.LivingEntity; @@ -12,15 +14,19 @@ import org.bukkit.entity.Player; import org.bukkit.entity.Skeleton; import mineplex.core.common.util.C; +import mineplex.core.common.util.F; import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilFile; +import mineplex.core.common.util.UtilFile.ChunkType; +import mineplex.core.common.util.UtilFile.DataFileChunk; import mineplex.core.common.util.UtilMath; import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; import mineplex.core.common.util.UtilTime; import mineplex.core.disguise.DisguiseManager; import mineplex.core.disguise.disguises.DisguisePlayer; import mineplex.core.hologram.Hologram; import mineplex.core.hologram.HologramManager; -import mineplex.game.clans.gameplay.safelog.LogoutData; public class CombatLogNPC { @@ -35,16 +41,24 @@ public class CombatLogNPC private final long _endingTime; private double _spawnHealth; + private boolean _creative; + private LivingEntity _npc; + private CraftLivingEntity _lastDamager; + + private String _userDataPath; + public int getEntityId() { return _npc.getEntityId(); } - public CombatLogNPC(Player player, DisguiseManager disguiseManager, HologramManager hologramManager) + public CombatLogNPC(Player player, DisguiseManager disguiseManager, HologramManager hologramManager, boolean wasCreative, String userDataPath) { _playerInfo = new PlayerInfo(player); + _creative = wasCreative; + _userDataPath = userDataPath; _disguiseManager = disguiseManager; _hologram = new Hologram(hologramManager, player.getEyeLocation().add(0, 0.65, 0), C.cYellow + UtilTime.MakeStr(NPCManager.COMBAT_LOG_DURATION) + C.cWhite + " Seconds left before despawn"); @@ -58,7 +72,7 @@ public class CombatLogNPC * Called when the {@code _npc} associated with this CombatLogNPC is killed * and thus drops all the owner's items. */ - public void onDeath() + public void onDeath(CraftLivingEntity killer) { Location location = _npc.getLocation(); World world = location.getWorld(); @@ -66,6 +80,32 @@ public class CombatLogNPC File file = new File(world.getWorldFolder(), String.format("playerdata/%s.dat", _playerInfo.getPlayerUuid())); file.delete(); // Delete the player's .dat file so they will join with // empty inventory/respawn on next login + if (killer != null) + { + String killerName = "Unknown"; + + if (killer instanceof CraftPlayer) + { + killerName = ((CraftPlayer) killer).getName(); + } + else if (killer != null) + { + killerName = UtilEnt.getName(killer); + } + + System.out.println(killerName); + + try + { + UtilFile.writeDataFile(new File(_userDataPath + String.format("DEATH_%s.dat", _playerInfo.getPlayerUuid())), new DataFileChunk(ChunkType.LONG, System.currentTimeMillis()), new DataFileChunk(ChunkType.STRING, killerName)); + } + catch (IOException e) + { + System.out.println(String.format("FATAL ERROR while trying to create player death lock for %s, meaning %s will not be informed that they died next time they log in.", _playerInfo.getPlayerName(), _playerInfo.getPlayerName())); + } + + UtilServer.broadcast(F.main("Death", F.elem(_playerInfo.getPlayerName()) + " was killed by " + F.elem(killerName) + " while combat logged.")); + } _playerInfo.dropItems(location); _disguiseManager.undisguise(_npc); @@ -120,6 +160,11 @@ public class CombatLogNPC _hologram = null; } + public PlayerInfo getPlayerInfo() + { + return _playerInfo; + } + public Player getPlayer() { return _playerInfo.getPlayer(); @@ -154,4 +199,20 @@ public class CombatLogNPC return skel; } + + public boolean wasCreative() + { + return _creative; + } + + public CraftLivingEntity getLastDamager() + { + return _lastDamager; + } + + public void setLastDamager(CraftLivingEntity damager) + { + _lastDamager = damager; + } + } diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/safelog/npc/NPCManager.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/safelog/npc/NPCManager.java index 67ce0b577..70fa2b0ae 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/safelog/npc/NPCManager.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/safelog/npc/NPCManager.java @@ -4,6 +4,8 @@ import java.util.HashSet; import java.util.Iterator; import java.util.Set; +import org.bukkit.GameMode; +import org.bukkit.craftbukkit.v1_7_R4.entity.CraftLivingEntity; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -14,8 +16,8 @@ import mineplex.core.MiniPlugin; import mineplex.core.hologram.HologramManager; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.ClanInfo; import mineplex.game.clans.clans.ClansManager; -import mineplex.game.clans.gameplay.safelog.LogoutData; import mineplex.minecraft.game.core.damage.CustomDamageEvent; public class NPCManager extends MiniPlugin @@ -65,7 +67,7 @@ public class NPCManager extends MiniPlugin { if (!hasLogoutNpc(player)) { - CombatLogNPC npc = new CombatLogNPC(player, _clansManager.getDisguiseManager(), _hologramManager); + CombatLogNPC npc = new CombatLogNPC(player, _clansManager.getDisguiseManager(), _hologramManager, player.getGameMode().equals(GameMode.CREATIVE), _clansManager.UserDataPath); npc.spawn(); _logoutNpcs.add(npc); log(String.format("Spawned combat log NPC for %s!", player.getName())); @@ -109,7 +111,7 @@ public class NPCManager extends MiniPlugin if (logoutNpc != null) { - logoutNpc.onDeath(); + logoutNpc.onDeath(logoutNpc.getLastDamager()); event.getDrops().clear(); // Clear the entity's item drops. Manually // drops combat log items earlier } @@ -120,8 +122,22 @@ public class NPCManager extends MiniPlugin { CombatLogNPC logoutNpc = getLogoutNpc(event.GetDamageeEntity()); - if (logoutNpc != null) + if (logoutNpc != null && event.GetDamagerPlayer(true) != null) { + ClanInfo clan = this._clansManager.getClan(event.GetDamagerPlayer(true)); + if (logoutNpc.wasCreative()) + { + event.SetCancelled("Cannot hurt creative player"); + return; + } + + if (clan != null && clan.isMember(logoutNpc.getPlayerInfo().getUniqueId())) + { + event.SetCancelled("Cannot hurt clan member."); + return; + } + + logoutNpc.setLastDamager(((CraftLivingEntity) event.GetDamagerEntity(true))); event.SetKnockback(false); } } diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/safelog/npc/PlayerInfo.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/safelog/npc/PlayerInfo.java index ff286b091..1cdd4cef1 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/safelog/npc/PlayerInfo.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/safelog/npc/PlayerInfo.java @@ -2,6 +2,7 @@ package mineplex.game.clans.gameplay.safelog.npc; import java.util.HashSet; import java.util.Set; +import java.util.UUID; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -13,12 +14,12 @@ import org.bukkit.inventory.PlayerInventory; public class PlayerInfo { - private String _playerName; public String getPlayerName() { return _playerName; } - private String _playerUuid; - public String getPlayerUuid() { return _playerUuid; } + private UUID _playerUuid; + public String getPlayerUuid() { return _playerUuid.toString(); } + public UUID getUniqueId() { return _playerUuid; } private Set _items; public Set getItems() { return _items; } @@ -26,7 +27,7 @@ public class PlayerInfo public PlayerInfo(Player player) { _playerName = player.getName(); - _playerUuid = player.getUniqueId().toString(); + _playerUuid = player.getUniqueId(); _items = fetchItems(player.getInventory()); } diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/AlligatorsTooth.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/AlligatorsTooth.java index 59b29366f..5197fc77e 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/AlligatorsTooth.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/AlligatorsTooth.java @@ -7,7 +7,6 @@ import org.bukkit.potion.PotionEffectType; import org.bukkit.util.Vector; import mineplex.core.common.util.UtilParticle; -import mineplex.core.common.util.UtilPlayer; import mineplex.core.common.util.UtilParticle.ParticleType; import mineplex.core.common.util.UtilParticle.ViewDist; import mineplex.game.clans.items.generation.ValueDistribution; @@ -15,11 +14,10 @@ import mineplex.minecraft.game.core.damage.CustomDamageEvent; public class AlligatorsTooth extends LegendaryItem { - private static ValueDistribution boostGen = generateDistribution(0.6d, 1.2d); - private static ValueDistribution damageGen = generateDistribution(1.0d, 6.0d); - private double _damageBonus; + private double _landDamageBonus = 7; + private double _waterDamageBonus = 10; private double _swimSpeed; private int _soundUpdateCounter; @@ -28,7 +26,6 @@ public class AlligatorsTooth extends LegendaryItem { super("Alligators Tooth", "Grants bonus damage in water and special ability to swim fast!", Material.RECORD_3); - _damageBonus = damageGen.generateValue(); _swimSpeed = boostGen.generateValue(); } @@ -47,7 +44,7 @@ public class AlligatorsTooth extends LegendaryItem if (++_soundUpdateCounter % 3 == 0) { wielder.playSound(wielder.getLocation(), Sound.SPLASH2, .5f, 1.25f); - UtilParticle.PlayParticle(ParticleType.BUBBLE, wielder.getLocation().add(0,0.5,0), (float) Math.random(), (float) Math.random(), (float) Math.random(), 0.2F, 20, ViewDist.NORMAL); + UtilParticle.PlayParticle(ParticleType.BUBBLE, wielder.getLocation().add(0, 0.5, 0), (float) Math.random(), (float) Math.random(), (float) Math.random(), 0.2F, 20, ViewDist.NORMAL); } } } @@ -58,9 +55,13 @@ public class AlligatorsTooth extends LegendaryItem { if (isInWater(wielder)) { - event.AddMod("Alligators Tooth", _damageBonus); + event.AddMod("Alligators Tooth", _waterDamageBonus); event.AddKnockback("Alligators Tooth", 0.5d); } + else + { + event.AddMod("Alligators Tooth", _landDamageBonus); + } } @@ -73,6 +74,6 @@ public class AlligatorsTooth extends LegendaryItem private boolean isInWater(Player player) { - return player.getLocation().getBlock().isLiquid(); + return player.getLocation().getBlock().getType() == Material.WATER || player.getLocation().getBlock().getType() == Material.STATIONARY_WATER; } } diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/GiantsBroadsword.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/GiantsBroadsword.java index 0a55d0806..58ea29e4b 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/GiantsBroadsword.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/GiantsBroadsword.java @@ -4,13 +4,17 @@ import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.potion.PotionEffectType; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilParticle.ViewDist; import mineplex.minecraft.game.core.damage.CustomDamageEvent; public class GiantsBroadsword extends LegendaryItem { public static final int SLOW_AMPLIFIER = 4; public static final int REGEN_AMPLIFIER = 1; - public static final int EFFECT_DURATION = 10; // Duration of potion effect (in ticks) + public static final int EFFECT_DURATION = 10; // Duration of potion effect + // (in ticks) public GiantsBroadsword() { @@ -24,12 +28,14 @@ public class GiantsBroadsword extends LegendaryItem { buffPlayer(wielder); } + + UtilParticle.PlayParticle(ParticleType.MAGIC_CRIT, wielder.getLocation().add(0, 1, 0), 0, 0, 0, .2f, 3, ViewDist.NORMAL); } @Override public void onAttack(CustomDamageEvent event, Player wielder) { - double bonusDamage = 2.0d; // Too much? + double bonusDamage = 2.0d; // Too much? event.AddMod("Giants Bonus", bonusDamage); event.AddKnockback("Giants Sword", 0.5d); } diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/WindBlade.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/WindBlade.java index ac38b81f5..f2e739326 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/WindBlade.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/WindBlade.java @@ -4,7 +4,11 @@ import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.util.Vector; +import mineplex.core.common.util.UtilEnt; import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilParticle.ViewDist; import mineplex.core.common.util.UtilTextBottom; public class WindBlade extends LegendaryItem @@ -26,16 +30,17 @@ public class WindBlade extends LegendaryItem // Check if player is attempting to fly and activate if (isHoldingRightClick() && canPropel()) { - removePower(.88); + removePower(UtilEnt.isGrounded(wielder) ? 1.17 : .88); propelPlayer(wielder); + UtilParticle.PlayParticle(ParticleType.MOB_SPELL, wielder.getLocation().add(0, 1, 0), -.5f + (float) Math.random(), -.5f + (float) Math.random(), -.5f + (float) Math.random(), 1f, 3, ViewDist.NORMAL); } - if (wielder.isOnGround()) + if (UtilEnt.isGrounded(wielder)) { addPower(0.33); } - UtilTextBottom.displayProgress(_power / 80, wielder); + UtilTextBottom.displayProgress(UtilMath.clamp(_power, .0, 80.) / 80., wielder); } private void propelPlayer(Player player) @@ -54,11 +59,11 @@ public class WindBlade extends LegendaryItem private void addPower(double power) { - _power = UtilMath.clamp(_power + power, 0, 80); + _power = UtilMath.clamp(_power + power, -20, 80); } private void removePower(double power) { - _power = UtilMath.clamp(_power - power, 0, 80); + _power = UtilMath.clamp(_power - power, -20, 80); } } diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/tutorials/TutorialClient.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/tutorials/TutorialClient.java index ae21b938b..e3d8d1833 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/tutorials/TutorialClient.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/tutorials/TutorialClient.java @@ -68,6 +68,8 @@ public class TutorialClient public void setTaskFinished(final int taskID) { _currentTask = taskID + 1; + + _tutorial.getTask(taskID).onFinish(_player); } public boolean hasFinishedTask(final TutorialTask task) diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/tutorials/types/TutorialGettingStarted.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/tutorials/types/TutorialGettingStarted.java index 665472a32..8ec099490 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/tutorials/types/TutorialGettingStarted.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/tutorials/types/TutorialGettingStarted.java @@ -8,8 +8,6 @@ import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.inventory.ItemStack; import mineplex.core.common.util.F; @@ -176,7 +174,6 @@ public class TutorialGettingStarted extends Tutorial public void onTerritory(final PlayerEnterTerritoryEvent event) { final Player player = event.getPlayer(); - final String oldTerritory = event.getLastTerritory(); final String newTerritory = event.getNewTerritory(); if (isInTutorial(player) && newTerritory.contains("Spawn") && get(player).hasFinishedTask(getTask("Viewing Clan Info")) && !get(player).hasFinishedTask(getTask("Leave Spawn"))) diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/tutorials/types/TutorialOnGoingMap.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/tutorials/types/TutorialOnGoingMap.java index fc3ffc462..a93a8ce72 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/tutorials/types/TutorialOnGoingMap.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/tutorials/types/TutorialOnGoingMap.java @@ -26,8 +26,12 @@ public class TutorialOnGoingMap extends Tutorial @EventHandler public void onEnterTerritory(final PlayerEnterTerritoryEvent event) { + if (event.getLastTerritory().equals(event.getNewTerritory())) + { + return; + } + final Player player = event.getPlayer(); - final String oldTerritory = event.getLastTerritory(); final String newTerritory = event.getNewTerritory(); if (!_taskManager.hasCompletedTask(player, "ClansOnGoingOptOut")) diff --git a/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/combat/CombatLog.java b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/combat/CombatLog.java index 6fce4fe6d..752b71fa6 100644 --- a/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/combat/CombatLog.java +++ b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/combat/CombatLog.java @@ -56,7 +56,7 @@ public class CombatLog // Set Last LastDamager = comp; _lastDamaged = System.currentTimeMillis(); - _lastCombat = System.currentTimeMillis(); +// _lastCombat = System.currentTimeMillis(); } public CombatComponent GetEnemy(String name, LivingEntity ent)