commit
627b793257
13 changed files with 974 additions and 0 deletions
@ -0,0 +1,113 @@ |
|||||||
|
# User-specific stuff |
||||||
|
.idea/ |
||||||
|
|
||||||
|
*.iml |
||||||
|
*.ipr |
||||||
|
*.iws |
||||||
|
|
||||||
|
# IntelliJ |
||||||
|
out/ |
||||||
|
|
||||||
|
# Compiled class file |
||||||
|
*.class |
||||||
|
|
||||||
|
# Log file |
||||||
|
*.log |
||||||
|
|
||||||
|
# BlueJ files |
||||||
|
*.ctxt |
||||||
|
|
||||||
|
# Package Files # |
||||||
|
*.jar |
||||||
|
*.war |
||||||
|
*.nar |
||||||
|
*.ear |
||||||
|
*.zip |
||||||
|
*.tar.gz |
||||||
|
*.rar |
||||||
|
|
||||||
|
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml |
||||||
|
hs_err_pid* |
||||||
|
|
||||||
|
*~ |
||||||
|
|
||||||
|
# temporary files which can be created if a process still has a handle open of a deleted file |
||||||
|
.fuse_hidden* |
||||||
|
|
||||||
|
# KDE directory preferences |
||||||
|
.directory |
||||||
|
|
||||||
|
# Linux trash folder which might appear on any partition or disk |
||||||
|
.Trash-* |
||||||
|
|
||||||
|
# .nfs files are created when an open file is removed but is still being accessed |
||||||
|
.nfs* |
||||||
|
|
||||||
|
# General |
||||||
|
.DS_Store |
||||||
|
.AppleDouble |
||||||
|
.LSOverride |
||||||
|
|
||||||
|
# Icon must end with two \r |
||||||
|
Icon |
||||||
|
|
||||||
|
# Thumbnails |
||||||
|
._* |
||||||
|
|
||||||
|
# Files that might appear in the root of a volume |
||||||
|
.DocumentRevisions-V100 |
||||||
|
.fseventsd |
||||||
|
.Spotlight-V100 |
||||||
|
.TemporaryItems |
||||||
|
.Trashes |
||||||
|
.VolumeIcon.icns |
||||||
|
.com.apple.timemachine.donotpresent |
||||||
|
|
||||||
|
# Directories potentially created on remote AFP share |
||||||
|
.AppleDB |
||||||
|
.AppleDesktop |
||||||
|
Network Trash Folder |
||||||
|
Temporary Items |
||||||
|
.apdisk |
||||||
|
|
||||||
|
# Windows thumbnail cache files |
||||||
|
Thumbs.db |
||||||
|
Thumbs.db:encryptable |
||||||
|
ehthumbs.db |
||||||
|
ehthumbs_vista.db |
||||||
|
|
||||||
|
# Dump file |
||||||
|
*.stackdump |
||||||
|
|
||||||
|
# Folder config file |
||||||
|
[Dd]esktop.ini |
||||||
|
|
||||||
|
# Recycle Bin used on file shares |
||||||
|
$RECYCLE.BIN/ |
||||||
|
|
||||||
|
# Windows Installer files |
||||||
|
*.cab |
||||||
|
*.msi |
||||||
|
*.msix |
||||||
|
*.msm |
||||||
|
*.msp |
||||||
|
|
||||||
|
# Windows shortcuts |
||||||
|
*.lnk |
||||||
|
|
||||||
|
target/ |
||||||
|
|
||||||
|
pom.xml.tag |
||||||
|
pom.xml.releaseBackup |
||||||
|
pom.xml.versionsBackup |
||||||
|
pom.xml.next |
||||||
|
|
||||||
|
release.properties |
||||||
|
dependency-reduced-pom.xml |
||||||
|
buildNumber.properties |
||||||
|
.mvn/timing.properties |
||||||
|
.mvn/wrapper/maven-wrapper.jar |
||||||
|
.flattened-pom.xml |
||||||
|
|
||||||
|
# Common working directory |
||||||
|
run/ |
@ -0,0 +1 @@ |
|||||||
|
xcopy IntelliJ_IDEA\Sharehealth\target\Sharehealth.jar Minecraft_Servers\Server_1.16.4\plugins\ /Y |
@ -0,0 +1 @@ |
|||||||
|
cp IntelliJ_IDEA/Sharehealth_1.16.4/target/sharehealth-1.0-SNAPSHOT.jar Minecraft_Servers/Server_1.16.4/plugins/ |
@ -0,0 +1,13 @@ |
|||||||
|
name: Sharehealth |
||||||
|
version: 1.0 |
||||||
|
main: com.benjocraeft.sharehealth.Sharehealth |
||||||
|
api-version: 1.16 |
||||||
|
authors: [ BenjoCraeft ] |
||||||
|
description: This plugin makes all players on the server share their health, if one dies, everybody dies. |
||||||
|
website: https://mc.benjocraeft.com |
||||||
|
|
||||||
|
commands: |
||||||
|
sharehealth: |
||||||
|
usage: /<command> |
||||||
|
aliases: [sh] |
||||||
|
description: Defined by ShareHealth plugin |
@ -0,0 +1,133 @@ |
|||||||
|
package com.benjocraeft.sharehealth; |
||||||
|
|
||||||
|
import org.bukkit.command.CommandExecutor; |
||||||
|
import org.apache.commons.lang.math.NumberUtils; |
||||||
|
import org.bukkit.Bukkit; |
||||||
|
import org.bukkit.ChatColor; |
||||||
|
import org.bukkit.command.Command; |
||||||
|
import org.bukkit.command.CommandSender; |
||||||
|
import org.bukkit.entity.Player; |
||||||
|
|
||||||
|
public class Commands implements CommandExecutor { |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args){ |
||||||
|
|
||||||
|
if (args.length != 0){ |
||||||
|
if (args[0].equalsIgnoreCase("reset")){ |
||||||
|
commandSetHealth(20, true); |
||||||
|
} |
||||||
|
else if (args[0].equalsIgnoreCase("set")){ |
||||||
|
if (args.length > 1){ |
||||||
|
if (NumberUtils.isNumber(args[1])){ |
||||||
|
double num = NumberUtils.createDouble(args[1]); |
||||||
|
commandSetHealth(num); |
||||||
|
} else if (args[1].equalsIgnoreCase("max")){ |
||||||
|
if (args.length > 2){ |
||||||
|
if (NumberUtils.isNumber(args[2])){ |
||||||
|
double num = NumberUtils.createDouble(args[2]); |
||||||
|
commandSetMaxHealth(num); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
else if (args[0].equalsIgnoreCase("get")){ |
||||||
|
if (args.length > 1){ |
||||||
|
if (args[1].equalsIgnoreCase("max")){ |
||||||
|
if (args.length > 2){ |
||||||
|
if (args[2].equalsIgnoreCase("raw")){ |
||||||
|
commandGetMaxHealth(sender, true); |
||||||
|
} |
||||||
|
} else { |
||||||
|
commandGetMaxHealth(sender, false); |
||||||
|
} |
||||||
|
} |
||||||
|
} else { |
||||||
|
commandGetHealth(sender); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
else if (args[0].equalsIgnoreCase("log")){ |
||||||
|
if (args.length > 1){ |
||||||
|
if (args[1].equalsIgnoreCase("off")){ |
||||||
|
commandSetLogging(false); |
||||||
|
} |
||||||
|
if (args[1].equalsIgnoreCase("on")){ |
||||||
|
commandSetLogging(true); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
else if(args[0].equalsIgnoreCase("stats")){ |
||||||
|
commandSendStats(); |
||||||
|
} |
||||||
|
else if (args[0].equalsIgnoreCase("help")){ |
||||||
|
commandGetHelp(sender); |
||||||
|
} else { |
||||||
|
unknownCommand(sender); |
||||||
|
} |
||||||
|
} else { |
||||||
|
commandGetHelp(sender); |
||||||
|
} |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
private void commandSetMaxHealth(double health){ |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
private void commandSetHealth(double health, boolean reset){ |
||||||
|
Sharehealth.Instance.getHealthManager().setHealth(health); |
||||||
|
if (reset){ |
||||||
|
Sharehealth.Instance.reset(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void commandSetHealth(double health){ |
||||||
|
commandSetHealth(health, false); |
||||||
|
} |
||||||
|
|
||||||
|
private void commandGetHealth(CommandSender sender){ |
||||||
|
sender.sendMessage("Current health: " + Sharehealth.Instance.getHealthManager().getHealthString()); |
||||||
|
} |
||||||
|
|
||||||
|
private void commandGetMaxHealth(CommandSender sender, boolean raw){ |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
private void commandSetLogging(boolean log){ |
||||||
|
Sharehealth.Instance.getMessenger().setLogging(log); |
||||||
|
} |
||||||
|
|
||||||
|
private void commandSendStats(){ |
||||||
|
StringBuilder stats = new StringBuilder("Statistics:\n"); |
||||||
|
Sharehealth.Instance.getStatistics().getStatistics().forEach(((uuid, values) -> { |
||||||
|
Player player = Bukkit.getPlayer(uuid); |
||||||
|
if (player != null){ |
||||||
|
String playerName = player.getDisplayName(); |
||||||
|
String stat = ChatColor.AQUA + playerName + ChatColor.WHITE + |
||||||
|
": Damage caused: " + ChatColor.RED + String.format("%.2f", values.first) + ChatColor.WHITE + |
||||||
|
" Healing done: " + ChatColor.GREEN + String.format("%.2f", values.second) + "\n"; |
||||||
|
stats.append(stat); |
||||||
|
} |
||||||
|
})); |
||||||
|
Bukkit.getOnlinePlayers().forEach((Player p) -> p.sendMessage(stats.toString())); |
||||||
|
} |
||||||
|
|
||||||
|
private void commandGetHelp(CommandSender sender){ |
||||||
|
String help = "Usage:\n" + |
||||||
|
"get -> returns current globally shared health\n" + |
||||||
|
"set [number] -> sets new globally shared health\n" + |
||||||
|
"reset -> heals every player and resets 'isFailed' to false\n" + |
||||||
|
"log [on/off] -> activates/deactivates player log messages about damage and healings" + |
||||||
|
"stats -> sends everyone statistics for every player"; |
||||||
|
sender.sendMessage(help); |
||||||
|
} |
||||||
|
|
||||||
|
private void unknownCommand(CommandSender sender){ |
||||||
|
String msg = "Unknown command, use help."; |
||||||
|
sender.sendMessage(msg); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,137 @@ |
|||||||
|
package com.benjocraeft.sharehealth; |
||||||
|
|
||||||
|
import java.io.*; |
||||||
|
import java.util.*; |
||||||
|
|
||||||
|
public class FileManager { |
||||||
|
|
||||||
|
final private File settingsFile; |
||||||
|
final private File statisticsFile; |
||||||
|
final private File statusFile; |
||||||
|
|
||||||
|
|
||||||
|
public FileManager(){ |
||||||
|
File pluginFolder = new File(System.getProperty("user.dir"), "plugins/sharehealth"); |
||||||
|
String pluginPath = pluginFolder.getPath(); |
||||||
|
|
||||||
|
//Prepare storage folder
|
||||||
|
if (pluginFolder.mkdirs()){ |
||||||
|
//TODO Log
|
||||||
|
} |
||||||
|
|
||||||
|
settingsFile = new File(pluginPath + "/settings.txt"); |
||||||
|
statisticsFile = new File(pluginPath + "/statistics.txt"); |
||||||
|
statusFile = new File(pluginPath + "/status.txt"); |
||||||
|
try { |
||||||
|
if (settingsFile.createNewFile()){ |
||||||
|
//TODO Log
|
||||||
|
} |
||||||
|
if (statisticsFile.createNewFile()){ |
||||||
|
//TODO Log
|
||||||
|
} |
||||||
|
if (statusFile.createNewFile()){ |
||||||
|
//TODO Log
|
||||||
|
} |
||||||
|
} catch(IOException e){ |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public Map<String, String> loadSettings(){ |
||||||
|
return loadFromFile(settingsFile); |
||||||
|
} |
||||||
|
public Map<UUID, Pair<Double, Double>> loadStatistics(){ |
||||||
|
Map<String, String> map = loadFromFile(statisticsFile); |
||||||
|
|
||||||
|
Map<UUID, Pair<Double, Double>> statisticsMap = new HashMap<>(); |
||||||
|
map.forEach((String s1, String s2) -> { |
||||||
|
UUID uuid = UUID.fromString(s1); |
||||||
|
|
||||||
|
String[] split = s2.split(","); |
||||||
|
Double damage = Double.parseDouble(split[0]); |
||||||
|
Double healing = Double.parseDouble(split[1]); |
||||||
|
Pair<Double, Double> statistics = Pair.pair(damage, healing); |
||||||
|
|
||||||
|
statisticsMap.put(uuid, statistics); |
||||||
|
}); |
||||||
|
|
||||||
|
return statisticsMap; |
||||||
|
} |
||||||
|
public Map<String, Object> loadStatus(){ |
||||||
|
Map<String, String> map = loadFromFile(statusFile); |
||||||
|
Map<String, Object> statusMap = new HashMap<>(); |
||||||
|
|
||||||
|
map.putIfAbsent("health", "20"); |
||||||
|
map.putIfAbsent("isFailed", "false"); |
||||||
|
|
||||||
|
statusMap.put("health", Double.parseDouble(map.get("health"))); |
||||||
|
statusMap.put("isFailed", Boolean.parseBoolean(map.get("isFailed"))); |
||||||
|
|
||||||
|
return statusMap; |
||||||
|
} |
||||||
|
|
||||||
|
public void saveStatistics(Map<UUID, Pair<Double, Double>> statistics){ |
||||||
|
Map<String, Object> map = new HashMap<>(); |
||||||
|
|
||||||
|
statistics.forEach((UUID uuid, Pair<Double, Double> pair) -> { |
||||||
|
String uuidString = uuid.toString(); |
||||||
|
map.put(uuidString, Statistics.Rounded(pair.first) + "," + Statistics.Rounded(pair.second)); |
||||||
|
}); |
||||||
|
|
||||||
|
saveToFile(statisticsFile, map); |
||||||
|
} |
||||||
|
|
||||||
|
public void saveStatus(Map<String, Object> statusMap){ |
||||||
|
saveToFile(statusFile, statusMap); |
||||||
|
} |
||||||
|
|
||||||
|
private Map<String, String> loadFromFile(File file) { |
||||||
|
Map<String, String> map = new HashMap<>(); |
||||||
|
|
||||||
|
try{ |
||||||
|
DataInputStream input = new DataInputStream(new FileInputStream(file)); |
||||||
|
BufferedReader reader = new BufferedReader(new InputStreamReader(input)); |
||||||
|
|
||||||
|
try{ |
||||||
|
String line; |
||||||
|
while((line = reader.readLine()) != null){ |
||||||
|
String[] split = line.split("="); |
||||||
|
map.put(split[0], split[1]); |
||||||
|
} |
||||||
|
} catch (NullPointerException ignore){} |
||||||
|
|
||||||
|
reader.close(); |
||||||
|
input.close(); |
||||||
|
} catch(IOException e){ |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
|
||||||
|
return map; |
||||||
|
} |
||||||
|
|
||||||
|
private void saveToFile(File file, Map<String, Object> content){ |
||||||
|
try{ |
||||||
|
FileWriter stream = new FileWriter(file); |
||||||
|
BufferedWriter out = new BufferedWriter(stream); |
||||||
|
|
||||||
|
content.forEach((String key, Object obj) -> { |
||||||
|
try { |
||||||
|
String value = obj.toString(); |
||||||
|
if (obj instanceof Double){ |
||||||
|
value = new Formatter(Locale.US).format("%.2f", obj).toString(); |
||||||
|
} |
||||||
|
out.write(key + "=" + value); |
||||||
|
out.write("\n"); |
||||||
|
} catch (IOException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
out.close(); |
||||||
|
stream.close(); |
||||||
|
} catch (IOException e){ |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,74 @@ |
|||||||
|
package com.benjocraeft.sharehealth; |
||||||
|
|
||||||
|
import org.bukkit.Bukkit; |
||||||
|
import org.bukkit.GameMode; |
||||||
|
import org.bukkit.entity.Player; |
||||||
|
|
||||||
|
import java.util.Formatter; |
||||||
|
import java.util.Locale; |
||||||
|
|
||||||
|
public class HealthManager { |
||||||
|
|
||||||
|
private double health = 20; |
||||||
|
|
||||||
|
double getHealth(){ |
||||||
|
return health; |
||||||
|
} |
||||||
|
|
||||||
|
void setHealth(double health){ |
||||||
|
if (health > 20) |
||||||
|
health = 20; |
||||||
|
if (health < 0) |
||||||
|
health = 0; |
||||||
|
this.health = health; |
||||||
|
} |
||||||
|
|
||||||
|
String getHealthString(){ |
||||||
|
return new Formatter(Locale.US).format("%.2f", health).toString(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public HealthManager() { |
||||||
|
|
||||||
|
} |
||||||
|
public void updatePlayer(Player player){ |
||||||
|
if (player.getGameMode().equals(GameMode.SURVIVAL)) |
||||||
|
player.setHealth(health); |
||||||
|
if (player.getGameMode().equals(GameMode.SPECTATOR)) |
||||||
|
player.setHealth(20); |
||||||
|
} |
||||||
|
|
||||||
|
private void subtractHealth(double sub){ |
||||||
|
setHealth(health - sub); |
||||||
|
} |
||||||
|
|
||||||
|
void addHealth(double add){ |
||||||
|
setHealth(health + add); |
||||||
|
} |
||||||
|
|
||||||
|
void reset(){ |
||||||
|
health = 20; |
||||||
|
Bukkit.getOnlinePlayers().forEach(p -> p.setHealth(health)); |
||||||
|
} |
||||||
|
|
||||||
|
boolean onPlayerGotDamage(Player player, double damage){ |
||||||
|
subtractHealth(damage); |
||||||
|
setHealthByPlayer(player); |
||||||
|
|
||||||
|
return health > 0; |
||||||
|
} |
||||||
|
|
||||||
|
void onPlayerRegainedHealth(Player player, double regainedHealth){ |
||||||
|
addHealth(regainedHealth); |
||||||
|
setHealthByPlayer(player); |
||||||
|
} |
||||||
|
|
||||||
|
void setHealthByPlayer(Player player){ |
||||||
|
for (Player p : Sharehealth.GetAlivePlayers()){ |
||||||
|
if (p.equals(player)) |
||||||
|
continue; |
||||||
|
p.setHealth(health); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,40 @@ |
|||||||
|
package com.benjocraeft.sharehealth; |
||||||
|
|
||||||
|
import org.bukkit.attribute.Attribute; |
||||||
|
import org.bukkit.entity.Player; |
||||||
|
import org.bukkit.scheduler.BukkitRunnable; |
||||||
|
|
||||||
|
import java.util.Objects; |
||||||
|
|
||||||
|
public class HealthRegenTask extends BukkitRunnable { |
||||||
|
|
||||||
|
final private HealthManager healthManager; |
||||||
|
|
||||||
|
|
||||||
|
HealthRegenTask(HealthManager healthManager){ |
||||||
|
this.healthManager = healthManager; |
||||||
|
runTaskTimer(Sharehealth.Instance, 80, 80); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void run(){ |
||||||
|
int allPlayersCount = Sharehealth.GetAlivePlayers().size(); |
||||||
|
if (allPlayersCount == 0) |
||||||
|
return; |
||||||
|
|
||||||
|
int allFoodPoints = 0; |
||||||
|
for (Player p : Sharehealth.GetAlivePlayers()){ |
||||||
|
allFoodPoints += p.getFoodLevel(); |
||||||
|
} |
||||||
|
|
||||||
|
//According to MinecraftWiki, players automatically regen if their food level
|
||||||
|
// is greater than or equal to 18 of 20 (90%)
|
||||||
|
//Here, we look for the average food level
|
||||||
|
if (allFoodPoints / allPlayersCount >= 18 && this.healthManager.getHealth() != 0){ |
||||||
|
this.healthManager.addHealth(1); |
||||||
|
this.healthManager.setHealthByPlayer(null); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,110 @@ |
|||||||
|
package com.benjocraeft.sharehealth; |
||||||
|
|
||||||
|
import org.bukkit.Bukkit; |
||||||
|
import org.bukkit.ChatColor; |
||||||
|
import org.bukkit.GameMode; |
||||||
|
import org.bukkit.block.Block; |
||||||
|
import org.bukkit.entity.Entity; |
||||||
|
import org.bukkit.entity.Player; |
||||||
|
import org.bukkit.entity.Projectile; |
||||||
|
import org.bukkit.event.entity.EntityDamageEvent; |
||||||
|
import org.bukkit.event.entity.EntityDamageEvent.DamageCause; |
||||||
|
import org.bukkit.event.entity.EntityRegainHealthEvent; |
||||||
|
import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason; |
||||||
|
|
||||||
|
import java.util.Objects; |
||||||
|
import java.util.logging.Logger; |
||||||
|
|
||||||
|
public class Messenger { |
||||||
|
|
||||||
|
private boolean logging = true; |
||||||
|
void setLogging(boolean logging){ |
||||||
|
this.logging = logging; |
||||||
|
} |
||||||
|
|
||||||
|
private Logger logger; |
||||||
|
|
||||||
|
Messenger(Logger logger){ |
||||||
|
this.logger = logger; |
||||||
|
} |
||||||
|
|
||||||
|
void onPlayerRegainedHealth(Player player, double amount, RegainReason reason){ |
||||||
|
if (!logging || amount <= 0) |
||||||
|
return; |
||||||
|
String message = healMessage(player, amount, reason); |
||||||
|
Bukkit.getOnlinePlayers().forEach(p -> p.sendMessage(message)); |
||||||
|
} |
||||||
|
|
||||||
|
void sendFailedMessage(Player cause){ |
||||||
|
Bukkit.getOnlinePlayers().forEach(p -> { |
||||||
|
String message = "Mission failed, go next! CAUSE: " + ChatColor.RED + cause.getDisplayName(); |
||||||
|
p.sendMessage(message); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
void onPlayerGotDamageMessage(Player player, double damage, DamageCause cause){ |
||||||
|
if (!logging) |
||||||
|
return; |
||||||
|
String message = damageMessage(player, damage, cause); |
||||||
|
Bukkit.getOnlinePlayers().forEach(p -> p.sendMessage(message)); |
||||||
|
} |
||||||
|
|
||||||
|
void onPlayerGotDamageMessage(Player player, double damage, Entity damager){ |
||||||
|
if (!logging) |
||||||
|
return; |
||||||
|
String message = damageMessage(player, damage, damager); |
||||||
|
Bukkit.getOnlinePlayers().forEach(p -> p.sendMessage(message)); |
||||||
|
} |
||||||
|
|
||||||
|
void onPlayerGotDamageMessage(Player player, double damage, Block damager){ |
||||||
|
if (!logging) |
||||||
|
return; |
||||||
|
String message = damageMessage(player, damage, damager); |
||||||
|
Bukkit.getOnlinePlayers().forEach(p -> p.sendMessage(message)); |
||||||
|
} |
||||||
|
|
||||||
|
private String damageMessage(Player player, double damage){ |
||||||
|
String playerS = player.getDisplayName(); |
||||||
|
String damageS = String.format("%.2f", damage / 2); |
||||||
|
return ChatColor.AQUA + playerS |
||||||
|
+ ChatColor.WHITE + " shared " |
||||||
|
+ ChatColor.RED + damageS |
||||||
|
+ ChatColor.WHITE + " hearts damage!"; |
||||||
|
} |
||||||
|
|
||||||
|
private String damageMessage(Player player, double damage, DamageCause cause){ |
||||||
|
return damageMessage(player, damage) + ChatColor.YELLOW + " Cause: " + cause; |
||||||
|
} |
||||||
|
|
||||||
|
private String damageMessage(Player player, double damage, Entity damager){ |
||||||
|
String name = damager.getName(); |
||||||
|
if (damager instanceof Projectile){ |
||||||
|
name = Objects.requireNonNull(((Projectile) damager).getShooter()).toString(); |
||||||
|
} |
||||||
|
return damageMessage(player, damage) + ChatColor.YELLOW + " Attacker: " + name; |
||||||
|
} |
||||||
|
|
||||||
|
private String damageMessage(Player player, double damage, Block damager){ |
||||||
|
String name; |
||||||
|
try{ |
||||||
|
name = damager.getType().name(); |
||||||
|
} catch(NullPointerException e){ |
||||||
|
name = "Unknown"; |
||||||
|
e.printStackTrace(); |
||||||
|
logger.info("Unknown error. Proceeding"); |
||||||
|
} |
||||||
|
return damageMessage(player, damage) + ChatColor.YELLOW + " Block: " + name; |
||||||
|
} |
||||||
|
|
||||||
|
private String healMessage(Player player, double regainedHealth, RegainReason reason){ |
||||||
|
String playerS = player.getDisplayName(); |
||||||
|
String healingS = Double.toString(regainedHealth / 2); |
||||||
|
String causeS = reason.toString(); |
||||||
|
return ChatColor.AQUA + playerS |
||||||
|
+ ChatColor.WHITE + " shared " |
||||||
|
+ ChatColor.GREEN + healingS |
||||||
|
+ ChatColor.WHITE + " hearts healing!" |
||||||
|
+ ChatColor.YELLOW + " Cause: " + causeS; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,18 @@ |
|||||||
|
package com.benjocraeft.sharehealth; |
||||||
|
|
||||||
|
|
||||||
|
public class Pair<F, S> { |
||||||
|
|
||||||
|
|
||||||
|
public F first; |
||||||
|
public S second; |
||||||
|
|
||||||
|
public Pair(F first, S second){ |
||||||
|
this.first = first; |
||||||
|
this.second = second; |
||||||
|
} |
||||||
|
|
||||||
|
public static <F, S> Pair<F, S> pair(F first, S second){ |
||||||
|
return new Pair<>(first, second); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,104 @@ |
|||||||
|
package com.benjocraeft.sharehealth; |
||||||
|
|
||||||
|
import org.bukkit.block.Block; |
||||||
|
import org.bukkit.entity.Entity; |
||||||
|
import org.bukkit.entity.Player; |
||||||
|
import org.bukkit.event.EventHandler; |
||||||
|
import org.bukkit.event.Listener; |
||||||
|
import org.bukkit.event.entity.*; |
||||||
|
import org.bukkit.event.entity.EntityDamageEvent.DamageCause; |
||||||
|
import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason; |
||||||
|
import org.bukkit.event.player.PlayerJoinEvent; |
||||||
|
import org.bukkit.event.player.PlayerRespawnEvent; |
||||||
|
import org.bukkit.potion.PotionEffect; |
||||||
|
import org.bukkit.potion.PotionEffectType; |
||||||
|
|
||||||
|
|
||||||
|
public class PlayerListeners implements Listener{ |
||||||
|
|
||||||
|
@EventHandler |
||||||
|
public void onJoin(PlayerJoinEvent e){ |
||||||
|
Sharehealth.Instance.onPlayerJoin(e.getPlayer()); |
||||||
|
} |
||||||
|
|
||||||
|
@EventHandler |
||||||
|
public void onPlayerRespawn(final PlayerRespawnEvent event){ |
||||||
|
Sharehealth.Instance.onPlayerRespawn(event.getPlayer()); |
||||||
|
} |
||||||
|
|
||||||
|
@EventHandler |
||||||
|
public void onEntityGotDamage(final EntityDamageEvent event){ |
||||||
|
Entity entity = event.getEntity(); |
||||||
|
double damage = event.getFinalDamage(); |
||||||
|
DamageCause cause = event.getCause(); |
||||||
|
|
||||||
|
DamageCause[] notAllowed = new DamageCause[]{ |
||||||
|
DamageCause.ENTITY_ATTACK, |
||||||
|
DamageCause.ENTITY_EXPLOSION, |
||||||
|
DamageCause.PROJECTILE, |
||||||
|
DamageCause.CONTACT |
||||||
|
}; |
||||||
|
|
||||||
|
if (entity instanceof Player){ |
||||||
|
boolean allowed = true; |
||||||
|
for (DamageCause damageCause : notAllowed) { |
||||||
|
if (cause.equals(damageCause)){ |
||||||
|
allowed = false; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
Sharehealth.Instance.onPlayerGotDamage((Player) entity, damage, cause, allowed); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@EventHandler |
||||||
|
public void onEntityGotDamageByEntity(final EntityDamageByEntityEvent event){ |
||||||
|
Entity entity = event.getEntity(); |
||||||
|
double damage = event.getFinalDamage(); |
||||||
|
Entity cause = event.getDamager(); |
||||||
|
|
||||||
|
if (entity instanceof Player) { |
||||||
|
Sharehealth.Instance.onPlayerGotDamageByEntity((Player)entity, damage, cause); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@EventHandler |
||||||
|
public void onEntityGotDamageByBlock(final EntityDamageByBlockEvent event){ |
||||||
|
Entity entity = event.getEntity(); |
||||||
|
double damage = event.getFinalDamage(); |
||||||
|
Block cause = event.getDamager(); |
||||||
|
|
||||||
|
if (entity instanceof Player) { |
||||||
|
Sharehealth.Instance.onPlayerGotDamageByBlock((Player)entity, damage, cause); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@EventHandler |
||||||
|
public void onEntityRegainedHealth(final EntityRegainHealthEvent event){ |
||||||
|
Entity entity = event.getEntity(); |
||||||
|
double amount = event.getAmount(); |
||||||
|
RegainReason reason = event.getRegainReason(); |
||||||
|
|
||||||
|
if (entity instanceof Player){ |
||||||
|
Player player = (Player) entity; |
||||||
|
if (!Sharehealth.Instance.onPlayerRegainedHealth(player, amount, reason)){ |
||||||
|
event.setCancelled(true); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@EventHandler |
||||||
|
public void onEntityPotionEffectModified(final EntityPotionEffectEvent event){ |
||||||
|
Entity entity = event.getEntity(); |
||||||
|
if (entity instanceof Player){ |
||||||
|
PotionEffect newEffect = event.getNewEffect(); |
||||||
|
if (newEffect != null){ |
||||||
|
if (newEffect.getType().equals(PotionEffectType.ABSORPTION)){ |
||||||
|
event.setCancelled(true); |
||||||
|
int level = newEffect.getAmplifier(); |
||||||
|
Sharehealth.Instance.onAbsorptionPrevented(level); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,184 @@ |
|||||||
|
package com.benjocraeft.sharehealth; |
||||||
|
|
||||||
|
import org.bukkit.*; |
||||||
|
import org.bukkit.block.Block; |
||||||
|
import org.bukkit.entity.*; |
||||||
|
import org.bukkit.event.entity.EntityDamageEvent.DamageCause; |
||||||
|
import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason; |
||||||
|
import org.bukkit.plugin.java.JavaPlugin; |
||||||
|
|
||||||
|
import java.util.*; |
||||||
|
|
||||||
|
public class Sharehealth extends JavaPlugin { |
||||||
|
|
||||||
|
static Sharehealth Instance; |
||||||
|
|
||||||
|
private FileManager fileManager; |
||||||
|
public FileManager getFileManager(){ |
||||||
|
return fileManager; |
||||||
|
} |
||||||
|
|
||||||
|
private HealthManager healthManager; |
||||||
|
public HealthManager getHealthManager(){ |
||||||
|
return healthManager; |
||||||
|
} |
||||||
|
|
||||||
|
private Messenger messenger; |
||||||
|
public Messenger getMessenger(){ |
||||||
|
return messenger; |
||||||
|
} |
||||||
|
|
||||||
|
private Statistics statistics; |
||||||
|
public Statistics getStatistics(){ |
||||||
|
return statistics; |
||||||
|
} |
||||||
|
|
||||||
|
boolean isFailed = false; |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onEnable(){ |
||||||
|
|
||||||
|
//Singleton setup
|
||||||
|
Instance = this; |
||||||
|
|
||||||
|
//Create File Manager for saving stats and settings
|
||||||
|
fileManager = new FileManager(); |
||||||
|
|
||||||
|
//Starting Health Manager for controlling actual health
|
||||||
|
healthManager = new HealthManager(); |
||||||
|
|
||||||
|
//Messenger
|
||||||
|
messenger = new Messenger(getLogger()); |
||||||
|
|
||||||
|
//Create statistics from file
|
||||||
|
statistics = new Statistics(fileManager.loadStatistics()); |
||||||
|
|
||||||
|
loadStatus(); |
||||||
|
|
||||||
|
//Starts custom health regeneration
|
||||||
|
new HealthRegenTask(healthManager); |
||||||
|
|
||||||
|
//Register Events and Commands
|
||||||
|
Bukkit.getPluginManager().registerEvents(new PlayerListeners(), this); |
||||||
|
Objects.requireNonNull(getCommand("sharehealth")).setExecutor(new Commands()); |
||||||
|
|
||||||
|
//Ready to go
|
||||||
|
getLogger().info("ShareHealth has been enabled!"); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onDisable() { |
||||||
|
getLogger().info("ShareHealth has been disabled!"); |
||||||
|
} |
||||||
|
|
||||||
|
void onPlayerJoin(Player player){ |
||||||
|
updateGameMode(player); |
||||||
|
|
||||||
|
healthManager.updatePlayer(player); |
||||||
|
statistics.onPlayerJoined(player); |
||||||
|
fileManager.saveStatistics(statistics.getStatistics()); |
||||||
|
} |
||||||
|
|
||||||
|
void onPlayerRespawn(Player player){ |
||||||
|
updateGameMode(player); |
||||||
|
|
||||||
|
healthManager.updatePlayer(player); |
||||||
|
} |
||||||
|
|
||||||
|
void onPlayerGotDamage(Player player, double damage, DamageCause cause, boolean allowed){ |
||||||
|
if (isFailed) |
||||||
|
return; |
||||||
|
|
||||||
|
if (allowed) |
||||||
|
messenger.onPlayerGotDamageMessage(player, damage, cause); |
||||||
|
|
||||||
|
statistics.onPlayerGotDamage(player, damage); |
||||||
|
if (!healthManager.onPlayerGotDamage(player, damage)){ |
||||||
|
failed(player); |
||||||
|
} |
||||||
|
|
||||||
|
saveStatus(); |
||||||
|
} |
||||||
|
void onPlayerGotDamageByEntity(Player player, double damage, Entity cause){ |
||||||
|
if (isFailed) |
||||||
|
return; |
||||||
|
|
||||||
|
messenger.onPlayerGotDamageMessage(player, damage, cause); |
||||||
|
} |
||||||
|
void onPlayerGotDamageByBlock(Player player, double damage, Block cause){ |
||||||
|
if (isFailed) |
||||||
|
return; |
||||||
|
|
||||||
|
messenger.onPlayerGotDamageMessage(player, damage, cause); |
||||||
|
} |
||||||
|
|
||||||
|
boolean onPlayerRegainedHealth(Player player, double amount, RegainReason reason){ |
||||||
|
if (isFailed) |
||||||
|
return true; |
||||||
|
|
||||||
|
if (reason.equals(RegainReason.REGEN) || reason.equals(RegainReason.SATIATED)){ |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
messenger.onPlayerRegainedHealth(player, amount, reason); |
||||||
|
statistics.onPlayerRegainedHealth(player, amount); |
||||||
|
healthManager.onPlayerRegainedHealth(player, amount); |
||||||
|
|
||||||
|
saveStatus(); |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
void onAbsorptionPrevented(int level){ |
||||||
|
getLogger().info("Add " + level * 2 + "hearts!"); |
||||||
|
} |
||||||
|
|
||||||
|
private void failed(Player cause){ |
||||||
|
if (isFailed) |
||||||
|
return; |
||||||
|
isFailed = true; |
||||||
|
messenger.sendFailedMessage(cause); |
||||||
|
Bukkit.getOnlinePlayers().forEach(p -> p.setGameMode(GameMode.SPECTATOR)); |
||||||
|
|
||||||
|
saveStatus(); |
||||||
|
} |
||||||
|
|
||||||
|
void reset(){ |
||||||
|
isFailed = false; |
||||||
|
healthManager.reset(); |
||||||
|
Bukkit.getOnlinePlayers().forEach(p -> p.setGameMode(GameMode.SURVIVAL)); |
||||||
|
|
||||||
|
saveStatus(); |
||||||
|
} |
||||||
|
|
||||||
|
private void updateGameMode(Player player){ |
||||||
|
if (!isFailed){ |
||||||
|
player.setGameMode(GameMode.SURVIVAL); |
||||||
|
} else { |
||||||
|
player.setGameMode(GameMode.SPECTATOR); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static List<Player> GetAlivePlayers(){ |
||||||
|
List<Player> list = new ArrayList<>(Bukkit.getOnlinePlayers()); |
||||||
|
list.removeIf(Entity::isDead); |
||||||
|
return list; |
||||||
|
} |
||||||
|
|
||||||
|
void saveStatus(){ |
||||||
|
Map<String, Object> map = new HashMap<>(); |
||||||
|
|
||||||
|
map.put("health", healthManager.getHealth()); |
||||||
|
map.put("isFailed", isFailed); |
||||||
|
|
||||||
|
fileManager.saveStatus(map); |
||||||
|
} |
||||||
|
|
||||||
|
private void loadStatus(){ |
||||||
|
Map<String, Object> map = fileManager.loadStatus(); |
||||||
|
|
||||||
|
healthManager.setHealth((Double)map.get("health")); |
||||||
|
isFailed = (boolean) map.get("isFailed"); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,46 @@ |
|||||||
|
package com.benjocraeft.sharehealth; |
||||||
|
|
||||||
|
import org.bukkit.entity.Player; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Map; |
||||||
|
import java.util.UUID; |
||||||
|
|
||||||
|
public class Statistics { |
||||||
|
|
||||||
|
final private Map<UUID, Pair<Double, Double>> statistics = new HashMap<>(); |
||||||
|
public Map<UUID, Pair<Double, Double>> getStatistics(){ |
||||||
|
return statistics; |
||||||
|
} |
||||||
|
|
||||||
|
public static Double Rounded(Double value, int afterComma){ |
||||||
|
return Math.round(value * Math.pow(10, afterComma)) / Math.pow(10, afterComma); |
||||||
|
} |
||||||
|
public static Double Rounded(Double value){ |
||||||
|
return Rounded(value, 2); |
||||||
|
} |
||||||
|
|
||||||
|
public Statistics(Map<UUID, Pair<Double, Double>> statistics){ |
||||||
|
getStatistics().putAll(statistics); |
||||||
|
} |
||||||
|
|
||||||
|
public void onPlayerJoined(Player player){ |
||||||
|
UUID uuid = player.getUniqueId(); |
||||||
|
Pair<Double, Double> empty = Pair.pair(0., 0.); |
||||||
|
statistics.putIfAbsent(uuid, empty); |
||||||
|
} |
||||||
|
|
||||||
|
void onPlayerRegainedHealth(Player player, double amount){ |
||||||
|
UUID uuid = player.getUniqueId(); |
||||||
|
Pair<Double, Double> oldPair = statistics.get(uuid); |
||||||
|
statistics.put(uuid, Pair.pair(oldPair.first, oldPair.second + amount)); |
||||||
|
} |
||||||
|
|
||||||
|
void onPlayerGotDamage(Player player, double amount){ |
||||||
|
UUID uuid = player.getUniqueId(); |
||||||
|
Pair<Double, Double> oldPair = statistics.get(uuid); |
||||||
|
statistics.put(uuid, Pair.pair(oldPair.first + amount, oldPair.second)); |
||||||
|
} |
||||||
|
|
||||||
|
} |
Loading…
Reference in new issue