package com.alecgorge.minecraft.jsonapi.chat;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import org.bukkit.Bukkit;
import org.bukkit.Server;
import org.bukkit.entity.*;
import org.bukkit.entity.Entity;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.event.player.PlayerChatEvent;
import com.alecgorge.minecraft.jsonapi.JSONAPI;
import com.alecgorge.minecraft.jsonapi.util.OfflinePlayerLoader;
//#ifdefined mcversion
//$import net.minecraft.server./*$mcversion$*/.*;
//$import org.bukkit.craftbukkit./*$mcversion$*/.*;
//$import org.bukkit.craftbukkit./*$mcversion$*/.entity.*;
//$import org.bukkit.craftbukkit./*$mcversion$*/.util.*;
//#else
import net.minecraft.server.v1_11_R1.*;
import org.bukkit.craftbukkit.v1_11_R1.*;
import org.bukkit.craftbukkit.v1_11_R1.entity.*;
import org.bukkit.craftbukkit.v1_11_R1.util.*;
//#endif
@SuppressWarnings("deprecation")
public class BukkitRealisticChat implements IRealisticChat {
private Server Server = JSONAPI.instance.getServer();
public Server getServer() {
return Server;
}
public class FauxPlayer extends CraftPlayer {
String name = null;
UUID fakeUUID = null;
public FauxPlayer(String fakeName, UUID fakeUUID, CraftPlayer player) {
super((CraftServer)player.getServer(), player.getHandle());
name = fakeName;
this.fakeUUID = fakeUUID;
}
@Override
public String getName() {
if(name == null) {
return super.getName();
}
return name;
}
@Override
public String getDisplayName() {
if(name == null) {
return super.getDisplayName();
}
return name;
}
@Override
public UUID getUniqueId() {
if(fakeUUID == null) {
return super.getUniqueId();
}
return super.getUniqueId();
}
/**
* This method exists for legacy reasons to provide backwards
* compatibility. It will not exist at runtime and should not be used
* under any circumstances.
*
* @return damage taken since the last no damage ticks time period
*/
@Override
public int _INVALID_getLastDamage() {
return 0;
}
/**
* This method exists for legacy reasons to provide backwards
* compatibility. It will not exist at runtime and should not be used
* under any circumstances.
*
* @param damage amount of damage
*/
@Override
public void _INVALID_setLastDamage(int damage) {
}
/**
* This method exists for legacy reasons to provide backwards
* compatibility. It will not exist at runtime and should not be used
* under any circumstances.
*
* @param amount Amount of damage to deal
*/
@Override
public void _INVALID_damage(int amount) {
}
/**
* This method exists for legacy reasons to provide backwards
* compatibility. It will not exist at runtime and should not be used
* under any circumstances.
*
* @param amount Amount of damage to deal
* @param source Entity which to attribute this damage from
*/
@Override
public void _INVALID_damage(int amount, Entity source) {
}
/**
* This method exists for legacy reasons to provide backwards
* compatibility. It will not exist at runtime and should not be used
* under any circumstances.
*
* @return Health represented from 0 to max
*/
@Override
public int _INVALID_getHealth() {
return 0;
}
/**
* This method exists for legacy reasons to provide backwards
* compatibility. It will not exist at runtime and should not be used
* under any circumstances.
*
* @param health New health represented from 0 to max
* @throws IllegalArgumentException Thrown if the health is {@literal < 0 or >}
* {@link #getMaxHealth()}
*/
@Override
public void _INVALID_setHealth(int health) {
}
/**
* This method exists for legacy reasons to provide backwards
* compatibility. It will not exist at runtime and should not be used
* under any circumstances.
*
* @return Maximum health
*/
@Override
public int _INVALID_getMaxHealth() {
return 0;
}
/**
* This method exists for legacy reasons to provide backwards
* compatibility. It will not exist at runtime and should not be used
* under any circumstances.
*
* @param health amount of health to set the maximum to
*/
@Override
public void _INVALID_setMaxHealth(int health) {
}
}
public boolean chatWithNameForPlayer(String message, String name, String playerToExtend) {
Player player = getServer().getPlayerExact(name);
// player isn't online
if (player == null) {
player = JSONAPI.loadOfflinePlayer(name);
}
// player doesn't exist. better fake something.
if (player == null) {
Player pe = null;
FauxPlayer f = null;
if(getServer().getOfflinePlayers().length > 0) {
pe = OfflinePlayerLoader.loadFromOfflinePlayer(getServer().getOfflinePlayers()[0]);
}
else if(getServer().getOnlinePlayers().size() > 0) {
pe = getServer().getOnlinePlayers().iterator().next();
}
if(playerToExtend == null) {
f = new FauxPlayer(name, UUID.randomUUID(), (CraftPlayer)pe);
}
else {
f = new FauxPlayer(name, UUID.randomUUID(), (CraftPlayer)pe);
}
return chatWithPlayer(message, f);
}
return chatWithPlayer(message, player);
}
public boolean chatWithName(String message, String name) {
return chatWithNameForPlayer(message, name, null);
}
public void pluginDisable() {
}
@Override
public boolean canHandleChats() {
return true;
}
public boolean chatWithPlayer(String message, Player player) {
try {
String s = message;
boolean async = false;
// based on
// net/minecraft/server/v1_9_R1/PlayerConnection.java#chat(String, boolean)
final MinecraftServer minecraftServer;
if (getServer() instanceof CraftServer) {
minecraftServer = ((CraftServer) getServer()).getServer();
} else {
System.err.println("Whoa, getServer() isn't a CraftServer?! I can't send a chat message now! It is a " + getServer().getClass().getCanonicalName());
return false;
}
AsyncPlayerChatEvent event = new AsyncPlayerChatEvent(async, player, s, new LazyPlayerSet(minecraftServer));
getServer().getPluginManager().callEvent(event);
Waitable<Void> waitable;
if (PlayerChatEvent.getHandlerList().getRegisteredListeners().length != 0) {
final PlayerChatEvent queueEvent = new PlayerChatEvent(player, event.getMessage(), event.getFormat(), event.getRecipients());
queueEvent.setCancelled(event.isCancelled());
waitable = new Waitable<Void>() {
protected Void evaluate() {
Bukkit.getPluginManager().callEvent(queueEvent);
if (queueEvent.isCancelled()) {
return null;
}
String message = String.format(queueEvent.getFormat(), new Object[] { queueEvent.getPlayer().getDisplayName(),queueEvent.getMessage() });
minecraftServer.console.sendMessage(message);
if (((LazyPlayerSet) queueEvent.getRecipients()).isLazy()) {
for (EntityPlayer player : (List<EntityPlayer>) minecraftServer.getPlayerList().players) {
player.sendMessage(CraftChatMessage.fromString(message));
}
}
else {
for (Player player : queueEvent.getRecipients()) {
player.sendMessage(message);
}
}
return null;
}
};
if (async)
minecraftServer.processQueue.add(waitable);
else
waitable.run();
try {
waitable.get();
}
catch (InterruptedException localInterruptedException) {
Thread.currentThread().interrupt();
}
catch (ExecutionException e) {
throw new RuntimeException("Exception processing chat event", e.getCause());
}
}
else {
if (event.isCancelled()) {
JSONAPI.dbug("Chat event cancelled");
return false;
}
s = String.format(event.getFormat(), new Object[] { event.getPlayer().getDisplayName(),event.getMessage() });
minecraftServer.console.sendMessage(s);
if (((LazyPlayerSet) event.getRecipients()).isLazy()) {
for (EntityPlayer recipient : (List<EntityPlayer>) minecraftServer.getPlayerList().players) {
recipient.sendMessage(CraftChatMessage.fromString(s));
}
}
else {
for (Player p : event.getRecipients()) {
p.sendMessage(message);
}
}
}
return true;
}
catch (Exception e) {
e.printStackTrace();
return false;
}
}
}