diff --git a/src/main/java/net/minecraft/entity/Entity.java b/src/main/java/net/minecraft/entity/Entity.java index 2f51940..d311a2a 100644 --- a/src/main/java/net/minecraft/entity/Entity.java +++ b/src/main/java/net/minecraft/entity/Entity.java @@ -12,13 +12,12 @@ import java.util.concurrent.Callable; import org.ultramine.server.EntityType; -import org.ultramine.server.UMHooks; +import org.ultramine.server.internal.UMHooks; import org.ultramine.server.event.EntitySetFireEvent; import com.mojang.authlib.GameProfile; import net.minecraft.block.Block; -import net.minecraft.block.BlockLiquid; import net.minecraft.block.material.Material; import net.minecraft.crash.CrashReport; import net.minecraft.crash.CrashReportCategory; diff --git a/src/main/java/net/minecraft/entity/player/EntityPlayerMP.java b/src/main/java/net/minecraft/entity/player/EntityPlayerMP.java index 2ca8b6b..3b48894 100644 --- a/src/main/java/net/minecraft/entity/player/EntityPlayerMP.java +++ b/src/main/java/net/minecraft/entity/player/EntityPlayerMP.java @@ -6,7 +6,6 @@ import io.netty.buffer.Unpooled; import java.io.IOException; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; @@ -57,7 +56,6 @@ import net.minecraft.network.play.server.S1DPacketEntityEffect; import net.minecraft.network.play.server.S1EPacketRemoveEntityEffect; import net.minecraft.network.play.server.S1FPacketSetExperience; -import net.minecraft.network.play.server.S26PacketMapChunkBulk; import net.minecraft.network.play.server.S2BPacketChangeGameState; import net.minecraft.network.play.server.S2DPacketOpenWindow; import net.minecraft.network.play.server.S2EPacketCloseWindow; @@ -74,7 +72,6 @@ import net.minecraft.scoreboard.ScoreObjective; import net.minecraft.server.MinecraftServer; import net.minecraft.server.management.ItemInWorldManager; -import net.minecraft.server.management.UserListOpsEntry; import net.minecraft.stats.AchievementList; import net.minecraft.stats.StatBase; import net.minecraft.stats.StatList; @@ -96,17 +93,15 @@ import net.minecraft.util.MathHelper; import net.minecraft.util.ReportedException; import net.minecraft.village.MerchantRecipeList; -import net.minecraft.world.ChunkCoordIntPair; import net.minecraft.world.WorldServer; import net.minecraft.world.WorldSettings; import net.minecraft.world.biome.BiomeGenBase; -import net.minecraft.world.chunk.Chunk; import org.apache.commons.io.Charsets; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.ultramine.server.PermissionHandler; -import org.ultramine.server.UMHooks; +import org.ultramine.server.internal.UMHooks; import org.ultramine.server.chunk.ChunkSendManager; import org.ultramine.server.data.player.PlayerData; import org.ultramine.server.event.UMEventFactory; @@ -116,7 +111,6 @@ import net.minecraftforge.common.ForgeHooks; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.entity.player.PlayerDropsEvent; -import net.minecraftforge.event.world.ChunkWatchEvent; public class EntityPlayerMP extends EntityPlayer implements ICrafting { diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java index c992463..65fa01a 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -83,7 +83,7 @@ import org.ultramine.scheduler.Scheduler; import org.ultramine.server.BackupManager; import org.ultramine.server.ConfigurationHandler; -import org.ultramine.server.WatchdogThread; +import org.ultramine.server.internal.WatchdogThread; import org.ultramine.server.bootstrap.UMBootstrap; import org.ultramine.server.internal.ChatComponentLogMessage; import org.ultramine.server.world.MultiWorld; diff --git a/src/main/java/net/minecraft/tileentity/TileEntity.java b/src/main/java/net/minecraft/tileentity/TileEntity.java index f8ffd2a..b83ef05 100644 --- a/src/main/java/net/minecraft/tileentity/TileEntity.java +++ b/src/main/java/net/minecraft/tileentity/TileEntity.java @@ -22,7 +22,7 @@ import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.ultramine.server.UMHooks; +import org.ultramine.server.internal.UMHooks; import com.mojang.authlib.GameProfile; diff --git a/src/main/java/org/ultramine/server/Teleporter.java b/src/main/java/org/ultramine/server/Teleporter.java index 7853151..7dd7d3d 100644 --- a/src/main/java/org/ultramine/server/Teleporter.java +++ b/src/main/java/org/ultramine/server/Teleporter.java @@ -98,7 +98,7 @@ } } - static void tick() + public static void tick() { for(Iterator it = teleporters.iterator();it.hasNext();) { diff --git a/src/main/java/org/ultramine/server/UMEventHandler.java b/src/main/java/org/ultramine/server/UMEventHandler.java deleted file mode 100644 index c49fbb9..0000000 --- a/src/main/java/org/ultramine/server/UMEventHandler.java +++ /dev/null @@ -1,334 +0,0 @@ -package org.ultramine.server; - -import org.ultramine.economy.CurrencyRegistry; -import org.ultramine.economy.PlayerHoldingsEvent; -import org.ultramine.server.UltramineServerConfig.ToolsConf.AutoBroacastConf; -import org.ultramine.server.UltramineServerConfig.ToolsConf.AutoDebugInfoConf; -import org.ultramine.server.chunk.ChunkProfiler; -import org.ultramine.server.data.player.PlayerCoreData; -import org.ultramine.server.util.BasicTypeFormatter; -import org.ultramine.server.util.BasicTypeParser; -import org.ultramine.server.util.WarpLocation; - -import cpw.mods.fml.common.eventhandler.Event; -import cpw.mods.fml.common.eventhandler.EventPriority; -import cpw.mods.fml.common.eventhandler.SubscribeEvent; -import cpw.mods.fml.common.functions.GenericIterableFactory; -import cpw.mods.fml.common.gameevent.PlayerEvent.PlayerChangedDimensionEvent; -import cpw.mods.fml.common.gameevent.PlayerEvent.PlayerLoggedInEvent; -import cpw.mods.fml.common.gameevent.TickEvent; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -import net.minecraft.entity.Entity; -import net.minecraft.entity.item.EntityItem; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.server.MinecraftServer; -import net.minecraft.util.ChatComponentStyle; -import net.minecraft.util.ChatComponentText; -import net.minecraft.util.ChatComponentTranslation; -import net.minecraft.util.ChatStyle; -import net.minecraft.util.EnumChatFormatting; -import net.minecraft.util.IChatComponent; -import net.minecraft.util.MathHelper; -import net.minecraft.world.ChunkPosition; -import net.minecraft.world.WorldServer; -import static net.minecraft.util.EnumChatFormatting.*; - -import net.minecraftforge.common.ForgeHooks; -import net.minecraftforge.event.CommandEvent; -import net.minecraftforge.event.ServerChatEvent; -import net.minecraftforge.event.entity.living.LivingAttackEvent; -import net.minecraftforge.event.entity.living.LivingDeathEvent; -import net.minecraftforge.event.entity.player.PlayerEvent; -import net.minecraftforge.event.entity.player.PlayerInteractEvent; -import net.minecraftforge.event.world.BlockEvent; - -public class UMEventHandler -{ - @SideOnly(Side.SERVER) - @SubscribeEvent(priority = EventPriority.HIGH) - public void checkChatPermission(ServerChatEvent e) - { - if(e.player.playerNetServerHandler == null || e.player.getData() == null) - return; - PlayerCoreData data = e.player.getData().core(); - if(!PermissionHandler.getInstance().has(e.player, "ability.player.chat")) - { - e.setCanceled(true); - e.player.addChatMessage(new ChatComponentTranslation("ultramine.ability.chat").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.RED))); - } - else if(data.isMuted()) - { - e.setCanceled(true); - if(data.getUnmuteTime() != Long.MAX_VALUE) - { - e.player.addChatMessage(new ChatComponentTranslation("ultramine.ability.chat.muted", - BasicTypeFormatter.formatTime(data.getUnmuteTime() - System.currentTimeMillis(), true)) - .setChatStyle(new ChatStyle().setColor(EnumChatFormatting.RED))); - } - else - { - e.player.addChatMessage(new ChatComponentTranslation("ultramine.ability.chat.muted.forever").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.RED))); - } - } - else if(e.player.isHidden()) - { - e.setCanceled(true); - e.player.addChatMessage(new ChatComponentTranslation("ultramine.hidden.chat").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.RED))); - } - } - - @SubscribeEvent - public void onServerChat(ServerChatEvent e) - { - if(e.player.playerNetServerHandler == null || e.player.getData() == null) - return; - String prefix = PermissionHandler.getInstance().getMeta(e.player, "prefix").replace('&', '\u00A7'); - String postfix = PermissionHandler.getInstance().getMeta(e.player, "postfix").replace('&', '\u00A7'); - - ChatComponentStyle username = (ChatComponentStyle) e.player.func_145748_c_(); - IChatComponent msg = ForgeHooks.newChatWithLinks(e.message); - - username.getChatStyle().setColor(BasicTypeParser.parseColor(PermissionHandler.getInstance().getMeta(e.player, "color"))); - EnumChatFormatting color = BasicTypeParser.parseColor(PermissionHandler.getInstance().getMeta(e.player, "textcolor")); - msg.getChatStyle().setColor(color != null ? color : EnumChatFormatting.WHITE); - - e.component = new ChatComponentTranslation("%s%s%s\u00A77: %s", prefix, username, postfix, msg); - } - - @SubscribeEvent(priority = EventPriority.HIGH) - public void onServerCommand(CommandEvent e) - { - if(e.sender instanceof EntityPlayerMP) - { - EntityPlayerMP player = (EntityPlayerMP)e.sender; - if(player.playerNetServerHandler != null && player.getData() != null && player.getData().core().isCommandsMuted()) - { - e.setCanceled(true); - if(player.getData().core().getUnmuteTime() != Long.MAX_VALUE) - { - player.addChatMessage(new ChatComponentTranslation("ultramine.ability.command.muted", - BasicTypeFormatter.formatTime(player.getData().core().getUnmuteTime() - System.currentTimeMillis(), true)) - .setChatStyle(new ChatStyle().setColor(EnumChatFormatting.RED))); - } - else - { - player.addChatMessage(new ChatComponentTranslation("ultramine.ability.command.muted.forever").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.RED))); - } - } - } - } - - @SubscribeEvent - public void onServerTickCommon(TickEvent.ServerTickEvent e) - { - if(e.phase == TickEvent.Phase.START) - { - MinecraftServer server = MinecraftServer.getServer(); - - Teleporter.tick(); - ChunkProfiler.instance().tick(server.getTickCounter()); - } - } - - @SubscribeEvent - @SideOnly(Side.SERVER) - public void onServerTickServer(TickEvent.ServerTickEvent e) - { - if(e.phase == TickEvent.Phase.START) - { - MinecraftServer server = MinecraftServer.getServer(); - server.getBackupManager().tick(); - - AutoDebugInfoConf cfg = ConfigurationHandler.getServerConfig().tools.autoDebugInfo; - if(cfg.enabled && server.getTickCounter() % (cfg.intervalSeconds*20) == 0) - { - double tps = Math.round(server.currentTPS*10)/10d; - double downtime = server.currentWait/1000/1000d; - double pickdowntime = server.pickWait/1000/1000d; - int load = (int)Math.round((50-downtime)/50*100); - int pickload = (int)Math.round((50-pickdowntime)/50*100); - ChatComponentText loadcomp = new ChatComponentText(Integer.toString(load).concat("%")); - ChatComponentText pickloadcomp = new ChatComponentText(Integer.toString(pickload).concat("%")); - ChatComponentText tpscomp = new ChatComponentText(Double.toString(tps)); - loadcomp.getChatStyle().setColor(load > 100 ? RED : DARK_GREEN); - pickloadcomp.getChatStyle().setColor(pickload >= 200 ? RED : DARK_GREEN); - tpscomp.getChatStyle().setColor(tps < 15 ? RED : DARK_GREEN); - - int mobcount = 0; - int itemcount = 0; - - for(WorldServer world : server.getMultiWorld().getLoadedWorlds()) - { - for(Entity ent : GenericIterableFactory.newCastingIterable(world.loadedEntityList, Entity.class)) - { - if(ent.isEntityLiving() && !ent.isEntityPlayer()) - mobcount++; - else if(ent instanceof EntityItem) - itemcount++; - } - } - - ChatComponentTranslation full = new ChatComponentTranslation("ultramine.autobroadcast.debugmsg", loadcomp, pickloadcomp, tpscomp, - Integer.toString(mobcount), Integer.toString(itemcount), server.getConfigurationManager().playerEntityList.size()); - full.getChatStyle().setColor(YELLOW); - - server.addChatMessage(full); - for(EntityPlayerMP player : GenericIterableFactory.newCastingIterable(server.getConfigurationManager().playerEntityList, EntityPlayerMP.class)) - if(PermissionHandler.getInstance().has(player, "show.debuginfo")) - player.addChatMessage(full); - } - - AutoBroacastConf msgcfg = ConfigurationHandler.getServerConfig().tools.autobroadcast; - if(msgcfg.enabled && server.getTickCounter() % (msgcfg.intervalSeconds*20) == 0) - { - if(msgcfg.messages.length != 0) - { - if(msgcfg.showAllMessages) - { - for(String msg : msgcfg.messages) - broadcastMessage(msg); - } - else - { - broadcastMessage(msgcfg.messages[server.getTickCounter() % (msgcfg.intervalSeconds*20*msgcfg.messages.length) / (msgcfg.intervalSeconds*20)]); - } - } - } - } - } - - @SubscribeEvent - @SideOnly(Side.SERVER) - public void onPlayerTickServer(TickEvent.PlayerTickEvent e) - { - if(e.phase == TickEvent.Phase.END && e.side.isServer()) - { - EntityPlayerMP player = (EntityPlayerMP)e.player; - int x = MathHelper.floor_double(player.posX); - int z = MathHelper.floor_double(player.posZ); - if(!player.getServerForPlayer().getBorder().isInsideBorder(x, z)) - { - ChunkPosition pos = player.getServerForPlayer().getBorder().correctPosition(x, z); - player.playerNetServerHandler.setPlayerLocation(pos.chunkPosX, player.lastTickPosY, pos.chunkPosZ, player.rotationYaw, player.rotationPitch); - } - } - } - - private static void broadcastMessage(String msg) - { - ChatComponentText msgcomp = new ChatComponentText(msg); - msgcomp.getChatStyle().setColor(DARK_GREEN); - MinecraftServer.getServer().getConfigurationManager().sendChatMsg(msgcomp); - } - - @SubscribeEvent - public void onPlayerClone(PlayerEvent.Clone e) - { - if(e.entityPlayer.isEntityPlayerMP()) - { - ((EntityPlayerMP)e.entityPlayer).setData(((EntityPlayerMP)e.original).getData()); - ((EntityPlayerMP)e.entityPlayer).setStatisticsFile(MinecraftServer.getServer().getConfigurationManager().func_152602_a(e.entityPlayer)); - } - } - - @SubscribeEvent - public void onLivingDeath(LivingDeathEvent e) - { - if(e.entityLiving.isEntityPlayerMP()) - { - EntityPlayerMP player = (EntityPlayerMP)e.entityLiving; - Teleporter tp = player.getData().core().getTeleporter(); - if(tp != null) - tp.cancel(); - player.getData().core().setLastLocation(WarpLocation.getFromPlayer(player)); - } - } - - @SubscribeEvent(priority = EventPriority.HIGH) - public void onPlayerChangedDimension(PlayerChangedDimensionEvent e) - { - MinecraftServer.getServer().getConfigurationManager().getDataLoader().handlePlayerDimensionChange((EntityPlayerMP)e.player, e.fromDim, e.toDim); - } - - @SideOnly(Side.SERVER) - @SubscribeEvent(priority = EventPriority.HIGHEST) - public void onBreakEvent(BlockEvent.BreakEvent e) - { - if(!e.getPlayer().isEntityPlayerMP() || ((EntityPlayerMP)e.getPlayer()).playerNetServerHandler == null) - return; - if(!PermissionHandler.getInstance().has(e.getPlayer(), "ability.player.blockbreak")) - { - e.setCanceled(true); - e.getPlayer().addChatMessage(new ChatComponentTranslation("ultramine.ability.blockbreak").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.RED))); - } - } - - @SideOnly(Side.SERVER) - @SubscribeEvent(priority = EventPriority.HIGHEST) - public void onPlaceEvent(BlockEvent.PlaceEvent e) - { - if(!e.player.isEntityPlayerMP() || ((EntityPlayerMP)e.player).playerNetServerHandler == null) - return; - if(!PermissionHandler.getInstance().has(e.player, "ability.player.blockplace")) - { - e.setCanceled(true); - e.player.addChatMessage(new ChatComponentTranslation("ultramine.ability.blockplace").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.RED))); - } - } - - @SideOnly(Side.SERVER) - @SubscribeEvent(priority = EventPriority.HIGHEST) - public void onPlayerInteractEvent(PlayerInteractEvent e) - { - if(!e.entityPlayer.isEntityPlayerMP() || ((EntityPlayerMP)e.entityPlayer).playerNetServerHandler == null) - return; - if(!PermissionHandler.getInstance().has(e.entityPlayer, "ability.player.useitem")) - { - e.useItem = Event.Result.DENY; - if(e.entityPlayer.inventory.getCurrentItem() != null) - e.entityPlayer.addChatMessage(new ChatComponentTranslation("ultramine.ability.useitem").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.RED))); - } - if(!PermissionHandler.getInstance().has(e.entityPlayer, "ability.player.useblock")) - { - e.useBlock = Event.Result.DENY; - e.entityPlayer.addChatMessage(new ChatComponentTranslation("ultramine.ability.useblock").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.RED))); - } - - if(e.useItem == Event.Result.DENY && e.useBlock == Event.Result.DENY) - e.setCanceled(true); - } - - @SideOnly(Side.SERVER) - @SubscribeEvent(priority = EventPriority.HIGHEST) - public void onLivingAttackEvent(LivingAttackEvent e) - { - Entity attacker = e.source.getEntity(); - if(attacker != null && attacker.isEntityPlayerMP()) - { - EntityPlayerMP player = (EntityPlayerMP)attacker; - if(player.playerNetServerHandler == null) - return; - if(!PermissionHandler.getInstance().has(player, "ability.player.attack")) - { - e.setCanceled(true); - player.addChatMessage(new ChatComponentTranslation("ultramine.ability.attack").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.RED))); - } - } - } - - @SideOnly(Side.SERVER) - @SubscribeEvent(priority = EventPriority.HIGH) - public void onHoldingsCreate(PlayerHoldingsEvent.CreateEvent e) - { - if(e.holdings.getCurrency() == CurrencyRegistry.GSC) - e.holdings.setBalance(ConfigurationHandler.getServerConfig().tools.economy.startBalance); - } - - @SideOnly(Side.SERVER) - @SubscribeEvent(priority=EventPriority.LOWEST) - public void onPlayerLoggedIn(PlayerLoggedInEvent e) - { - ((EntityPlayerMP)e.player).getData().core().onLogin(); - } -} diff --git a/src/main/java/org/ultramine/server/UMHooks.java b/src/main/java/org/ultramine/server/UMHooks.java deleted file mode 100644 index a003845..0000000 --- a/src/main/java/org/ultramine/server/UMHooks.java +++ /dev/null @@ -1,147 +0,0 @@ -package org.ultramine.server; - -import java.util.UUID; - -import cpw.mods.fml.common.FMLCommonHandler; -import cpw.mods.fml.common.registry.LanguageRegistry; -import net.minecraft.entity.Entity; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.server.MinecraftServer; -import net.minecraft.tileentity.TileEntity; - -import net.minecraft.util.ChatComponentTranslation; -import net.minecraft.util.IChatComponent; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.ultramine.server.event.WorldEventProxy; -import org.ultramine.server.event.WorldUpdateObject; - -import com.mojang.authlib.GameProfile; - -public class UMHooks -{ - private static final Logger log = LogManager.getLogger(); - private static final boolean IS_CLIENT = FMLCommonHandler.instance().getSide().isClient(); - - public static void printStackTrace(Throwable t) - { - log.error("Direct Throwable.printStackTrace() call"); - if(Thread.currentThread().getName().equals("Server thread")) - { - WorldEventProxy wep = WorldEventProxy.getCurrent(); - if(wep != null) - { - int dim = wep.getWorld().provider.dimensionId; - WorldUpdateObject obj = wep.getUpdateObject(); - switch(obj.getType()) - { - case BLOCK_EVENT: - log.error("On block event update [{}]({}, {}, {})", dim, obj.getX(), obj.getY(), obj.getZ()); - break; - case BLOCK_PENDING: - log.error("On block pending update [{}]({}, {}, {})", dim, obj.getX(), obj.getY(), obj.getZ()); - break; - case BLOCK_RANDOM: - log.error("On block random update [{}]({}, {}, {})", dim, obj.getX(), obj.getY(), obj.getZ()); - break; - case ENTITY: - Entity ent = obj.getEntity(); - log.error("On entity update [{}]({}, {}, {}). Entity: {}, Class: {}", dim, ent.posX, ent.posY, ent.posZ, ent, ent.getClass().getName()); - break; - case ENTITY_WEATHER: - Entity went = obj.getEntity(); - log.error("On weather entity update [{}]({}, {}, {}). Entity: {}, Class: {}", dim, went.posX, went.posY, went.posZ, went, went.getClass().getName()); - break; - case PLAYER: - EntityPlayer player = (EntityPlayer)obj.getEntity(); - log.error("On player packet [{}]({}, {}, {}). Entity: {}", dim, player.posX, player.posY, player.posZ, player); - break; - case TILEE_ENTITY: - TileEntity te = obj.getTileEntity(); - log.error("On TileEntity update [{}]({}, {}, {}). Class: {}", dim, te.xCoord, te.yCoord, te.zCoord, te.getClass().getName()); - break; - case WEATHER: - log.error("On weather action at world [{}]", dim); - break; - case UNKNOWN: - log.error("On unknown action at world [{}]", dim); - break; - } - } - else - { - log.error("On unknown action"); - } - } - else - { - log.error("On unknown action in thread " + Thread.currentThread().getName()); - } - - log.error("Invoked here", new Throwable("stacktrace")); - log.error("Original stacktrace", t); - } - - public static GameProfile readObjectOwner(NBTTagCompound nbt) - { - if(IS_CLIENT) - return null; - UUID id = nbt.hasKey("$") ? new UUID(nbt.getLong("$"), nbt.getLong("%")) : null; - String username = nbt.hasKey("#") ? nbt.getString("#") : null; - if(id != null || username != null && !username.isEmpty()) - return MinecraftServer.getServer().getConfigurationManager().getDataLoader().internGameProfile(id, username); - return null; - } - - public static void writeObjectOwner(NBTTagCompound nbt, GameProfile owner) - { - if(IS_CLIENT) - return; - UUID id = owner.getId(); - String username = owner.getName(); - if(id != null) - { - nbt.setLong("$", id.getMostSignificantBits()); - nbt.setLong("%", id.getLeastSignificantBits()); - } - if(username != null) - nbt.setString("#", username); - } - - public static IChatComponent onChatSend(EntityPlayerMP player, IChatComponent msg) - { - if(IS_CLIENT) - return msg; - if(msg instanceof ChatComponentTranslation) - return onChatSend(player, (ChatComponentTranslation) msg); - return msg; - } - - public static IChatComponent onChatSend(EntityPlayerMP player, ChatComponentTranslation msg) - { - String key = msg.getKey(); - Object[] oldArgs = msg.getFormatArgs(); - Object[] newArgs = new Object[oldArgs.length]; - boolean argsChanged = false; - for(int i = 0; i < oldArgs.length; i++) - { - Object o = oldArgs[i]; - Object o1 = o; - if(o instanceof ChatComponentTranslation) - o1 = onChatSend(player, (ChatComponentTranslation)o); - newArgs[i] = o1; - if(o != o1) - argsChanged = true; - } - if(!argsChanged && !key.startsWith("ultramine.") && !key.startsWith("command.")) //TODO add api for all - return msg; - String translated = LanguageRegistry.instance().getStringLocalization(key, player.getTranslator()); - if(translated.isEmpty()) - translated = LanguageRegistry.instance().getStringLocalization(key, "en_US"); - ChatComponentTranslation text = new ChatComponentTranslation(translated.isEmpty() ? key : translated, newArgs); - text.setChatStyle(msg.getChatStyle()); - return text; - } -} diff --git a/src/main/java/org/ultramine/server/UltramineServerModContainer.java b/src/main/java/org/ultramine/server/UltramineServerModContainer.java index 2086798..96c0ed6 100644 --- a/src/main/java/org/ultramine/server/UltramineServerModContainer.java +++ b/src/main/java/org/ultramine/server/UltramineServerModContainer.java @@ -25,11 +25,11 @@ import org.ultramine.server.data.ServerDataLoader; import org.ultramine.server.data.player.PlayerCoreData; import org.ultramine.server.event.ForgeModIdMappingEvent; +import org.ultramine.server.internal.UMEventHandler; import org.ultramine.server.tools.ButtonCommand; import org.ultramine.server.tools.ItemBlocker; import org.ultramine.server.tools.WarpProtection; import org.ultramine.server.util.GlobalExecutors; -import org.ultramine.server.util.SyncServerExecutor; import com.google.common.collect.ImmutableList; import com.google.common.eventbus.EventBus; diff --git a/src/main/java/org/ultramine/server/WatchdogThread.java b/src/main/java/org/ultramine/server/WatchdogThread.java deleted file mode 100644 index e6d8176..0000000 --- a/src/main/java/org/ultramine/server/WatchdogThread.java +++ /dev/null @@ -1,133 +0,0 @@ -package org.ultramine.server; - -import java.lang.management.ManagementFactory; -import java.lang.management.MonitorInfo; -import java.lang.management.ThreadInfo; - -import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import cpw.mods.fml.common.FMLCommonHandler; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - -@SideOnly(Side.SERVER) -public class WatchdogThread extends Thread -{ - private static final Logger log = LogManager.getLogger(); - - private static WatchdogThread instance; - private volatile long lastTick; - private volatile boolean stopping; - - private WatchdogThread() - { - super("Watchdog Thread"); - } - - public static void doStart() - { - if(instance == null) - { - instance = new WatchdogThread(); - instance.start(); - } - } - - - public static void tick() - { - instance.lastTick = System.currentTimeMillis(); - } - - public static void doStop() - { - if(instance != null) - { - instance.stopping = true; - } - } - - @Override - public void run() - { - while(!stopping) - { - // - if(lastTick != 0 && System.currentTimeMillis() > lastTick + ConfigurationHandler.getServerConfig().settings.watchdogThread.timeout*1000) - { - log.log(Level.FATAL, "The server has stopped responding!"); - - log.log(Level.FATAL, "Current Thread State:"); - ThreadInfo[] threads = ManagementFactory.getThreadMXBean().dumpAllThreads(true, true); - - for(ThreadInfo thread : threads) //main thread first - { - if(thread.getThreadName().equals("Server thread")) - displayThreadInfo(thread); - } - - for(ThreadInfo thread : threads) - { - if(!thread.getThreadName().equals("Server thread")) - displayThreadInfo(thread); - } - - log.log(Level.FATAL, "------------------------------"); - - if(ConfigurationHandler.getServerConfig().settings.watchdogThread.restart) - { - try - { - sleep(2000); //await log output - } catch (InterruptedException ex) {} - - Thread.currentThread().interrupt(); - FMLCommonHandler.instance().handleExit(0); - } - - break; - } - - try - { - sleep(10000); - } catch (InterruptedException ex) - { - // interrupt(); - } - } - } - - private static void displayThreadInfo(ThreadInfo thread) - { - if(thread.getThreadState() != State.WAITING) - { - log.log(Level.FATAL, "------------------------------"); - // - log.log(Level.FATAL, "Current Thread: " + thread.getThreadName()); - log.log(Level.FATAL, "\tPID: " + thread.getThreadId() + " | Suspended: " + thread.isSuspended() + " | Native: " + thread.isInNative() + " | State: " - + thread.getThreadState()); - - if(thread.getLockedMonitors().length != 0) - { - log.log(Level.FATAL, "\tThread is waiting on monitor(s):"); - - for(MonitorInfo monitor : thread.getLockedMonitors()) - { - log.log(Level.FATAL, "\t\tLocked on:" + monitor.getLockedStackFrame()); - } - } - - log.log(Level.FATAL, "\tStack:"); - // - StackTraceElement[] stack = thread.getStackTrace(); - - for(int line = 0; line < stack.length; line++) - { - log.log(Level.FATAL, "\t\t" + stack[line].toString()); - } - } - } -} diff --git a/src/main/java/org/ultramine/server/internal/UMEventHandler.java b/src/main/java/org/ultramine/server/internal/UMEventHandler.java new file mode 100644 index 0000000..ce2e9ab --- /dev/null +++ b/src/main/java/org/ultramine/server/internal/UMEventHandler.java @@ -0,0 +1,337 @@ +package org.ultramine.server.internal; + +import org.ultramine.economy.CurrencyRegistry; +import org.ultramine.economy.PlayerHoldingsEvent; +import org.ultramine.server.ConfigurationHandler; +import org.ultramine.server.PermissionHandler; +import org.ultramine.server.Teleporter; +import org.ultramine.server.UltramineServerConfig.ToolsConf.AutoBroacastConf; +import org.ultramine.server.UltramineServerConfig.ToolsConf.AutoDebugInfoConf; +import org.ultramine.server.chunk.ChunkProfiler; +import org.ultramine.server.data.player.PlayerCoreData; +import org.ultramine.server.util.BasicTypeFormatter; +import org.ultramine.server.util.BasicTypeParser; +import org.ultramine.server.util.WarpLocation; + +import cpw.mods.fml.common.eventhandler.Event; +import cpw.mods.fml.common.eventhandler.EventPriority; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import cpw.mods.fml.common.functions.GenericIterableFactory; +import cpw.mods.fml.common.gameevent.PlayerEvent.PlayerChangedDimensionEvent; +import cpw.mods.fml.common.gameevent.PlayerEvent.PlayerLoggedInEvent; +import cpw.mods.fml.common.gameevent.TickEvent; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.entity.Entity; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.server.MinecraftServer; +import net.minecraft.util.ChatComponentStyle; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.ChatComponentTranslation; +import net.minecraft.util.ChatStyle; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.IChatComponent; +import net.minecraft.util.MathHelper; +import net.minecraft.world.ChunkPosition; +import net.minecraft.world.WorldServer; +import static net.minecraft.util.EnumChatFormatting.*; + +import net.minecraftforge.common.ForgeHooks; +import net.minecraftforge.event.CommandEvent; +import net.minecraftforge.event.ServerChatEvent; +import net.minecraftforge.event.entity.living.LivingAttackEvent; +import net.minecraftforge.event.entity.living.LivingDeathEvent; +import net.minecraftforge.event.entity.player.PlayerEvent; +import net.minecraftforge.event.entity.player.PlayerInteractEvent; +import net.minecraftforge.event.world.BlockEvent; + +public class UMEventHandler +{ + @SideOnly(Side.SERVER) + @SubscribeEvent(priority = EventPriority.HIGH) + public void checkChatPermission(ServerChatEvent e) + { + if(e.player.playerNetServerHandler == null || e.player.getData() == null) + return; + PlayerCoreData data = e.player.getData().core(); + if(!PermissionHandler.getInstance().has(e.player, "ability.player.chat")) + { + e.setCanceled(true); + e.player.addChatMessage(new ChatComponentTranslation("ultramine.ability.chat").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.RED))); + } + else if(data.isMuted()) + { + e.setCanceled(true); + if(data.getUnmuteTime() != Long.MAX_VALUE) + { + e.player.addChatMessage(new ChatComponentTranslation("ultramine.ability.chat.muted", + BasicTypeFormatter.formatTime(data.getUnmuteTime() - System.currentTimeMillis(), true)) + .setChatStyle(new ChatStyle().setColor(EnumChatFormatting.RED))); + } + else + { + e.player.addChatMessage(new ChatComponentTranslation("ultramine.ability.chat.muted.forever").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.RED))); + } + } + else if(e.player.isHidden()) + { + e.setCanceled(true); + e.player.addChatMessage(new ChatComponentTranslation("ultramine.hidden.chat").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.RED))); + } + } + + @SubscribeEvent + public void onServerChat(ServerChatEvent e) + { + if(e.player.playerNetServerHandler == null || e.player.getData() == null) + return; + String prefix = PermissionHandler.getInstance().getMeta(e.player, "prefix").replace('&', '\u00A7'); + String postfix = PermissionHandler.getInstance().getMeta(e.player, "postfix").replace('&', '\u00A7'); + + ChatComponentStyle username = (ChatComponentStyle) e.player.func_145748_c_(); + IChatComponent msg = ForgeHooks.newChatWithLinks(e.message); + + username.getChatStyle().setColor(BasicTypeParser.parseColor(PermissionHandler.getInstance().getMeta(e.player, "color"))); + EnumChatFormatting color = BasicTypeParser.parseColor(PermissionHandler.getInstance().getMeta(e.player, "textcolor")); + msg.getChatStyle().setColor(color != null ? color : EnumChatFormatting.WHITE); + + e.component = new ChatComponentTranslation("%s%s%s\u00A77: %s", prefix, username, postfix, msg); + } + + @SubscribeEvent(priority = EventPriority.HIGH) + public void onServerCommand(CommandEvent e) + { + if(e.sender instanceof EntityPlayerMP) + { + EntityPlayerMP player = (EntityPlayerMP)e.sender; + if(player.playerNetServerHandler != null && player.getData() != null && player.getData().core().isCommandsMuted()) + { + e.setCanceled(true); + if(player.getData().core().getUnmuteTime() != Long.MAX_VALUE) + { + player.addChatMessage(new ChatComponentTranslation("ultramine.ability.command.muted", + BasicTypeFormatter.formatTime(player.getData().core().getUnmuteTime() - System.currentTimeMillis(), true)) + .setChatStyle(new ChatStyle().setColor(EnumChatFormatting.RED))); + } + else + { + player.addChatMessage(new ChatComponentTranslation("ultramine.ability.command.muted.forever").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.RED))); + } + } + } + } + + @SubscribeEvent + public void onServerTickCommon(TickEvent.ServerTickEvent e) + { + if(e.phase == TickEvent.Phase.START) + { + MinecraftServer server = MinecraftServer.getServer(); + + Teleporter.tick(); + ChunkProfiler.instance().tick(server.getTickCounter()); + } + } + + @SubscribeEvent + @SideOnly(Side.SERVER) + public void onServerTickServer(TickEvent.ServerTickEvent e) + { + if(e.phase == TickEvent.Phase.START) + { + MinecraftServer server = MinecraftServer.getServer(); + server.getBackupManager().tick(); + + AutoDebugInfoConf cfg = ConfigurationHandler.getServerConfig().tools.autoDebugInfo; + if(cfg.enabled && server.getTickCounter() % (cfg.intervalSeconds*20) == 0) + { + double tps = Math.round(server.currentTPS*10)/10d; + double downtime = server.currentWait/1000/1000d; + double pickdowntime = server.pickWait/1000/1000d; + int load = (int)Math.round((50-downtime)/50*100); + int pickload = (int)Math.round((50-pickdowntime)/50*100); + ChatComponentText loadcomp = new ChatComponentText(Integer.toString(load).concat("%")); + ChatComponentText pickloadcomp = new ChatComponentText(Integer.toString(pickload).concat("%")); + ChatComponentText tpscomp = new ChatComponentText(Double.toString(tps)); + loadcomp.getChatStyle().setColor(load > 100 ? RED : DARK_GREEN); + pickloadcomp.getChatStyle().setColor(pickload >= 200 ? RED : DARK_GREEN); + tpscomp.getChatStyle().setColor(tps < 15 ? RED : DARK_GREEN); + + int mobcount = 0; + int itemcount = 0; + + for(WorldServer world : server.getMultiWorld().getLoadedWorlds()) + { + for(Entity ent : GenericIterableFactory.newCastingIterable(world.loadedEntityList, Entity.class)) + { + if(ent.isEntityLiving() && !ent.isEntityPlayer()) + mobcount++; + else if(ent instanceof EntityItem) + itemcount++; + } + } + + ChatComponentTranslation full = new ChatComponentTranslation("ultramine.autobroadcast.debugmsg", loadcomp, pickloadcomp, tpscomp, + Integer.toString(mobcount), Integer.toString(itemcount), server.getConfigurationManager().playerEntityList.size()); + full.getChatStyle().setColor(YELLOW); + + server.addChatMessage(full); + for(EntityPlayerMP player : GenericIterableFactory.newCastingIterable(server.getConfigurationManager().playerEntityList, EntityPlayerMP.class)) + if(PermissionHandler.getInstance().has(player, "show.debuginfo")) + player.addChatMessage(full); + } + + AutoBroacastConf msgcfg = ConfigurationHandler.getServerConfig().tools.autobroadcast; + if(msgcfg.enabled && server.getTickCounter() % (msgcfg.intervalSeconds*20) == 0) + { + if(msgcfg.messages.length != 0) + { + if(msgcfg.showAllMessages) + { + for(String msg : msgcfg.messages) + broadcastMessage(msg); + } + else + { + broadcastMessage(msgcfg.messages[server.getTickCounter() % (msgcfg.intervalSeconds*20*msgcfg.messages.length) / (msgcfg.intervalSeconds*20)]); + } + } + } + } + } + + @SubscribeEvent + @SideOnly(Side.SERVER) + public void onPlayerTickServer(TickEvent.PlayerTickEvent e) + { + if(e.phase == TickEvent.Phase.END && e.side.isServer()) + { + EntityPlayerMP player = (EntityPlayerMP)e.player; + int x = MathHelper.floor_double(player.posX); + int z = MathHelper.floor_double(player.posZ); + if(!player.getServerForPlayer().getBorder().isInsideBorder(x, z)) + { + ChunkPosition pos = player.getServerForPlayer().getBorder().correctPosition(x, z); + player.playerNetServerHandler.setPlayerLocation(pos.chunkPosX, player.lastTickPosY, pos.chunkPosZ, player.rotationYaw, player.rotationPitch); + } + } + } + + private static void broadcastMessage(String msg) + { + ChatComponentText msgcomp = new ChatComponentText(msg); + msgcomp.getChatStyle().setColor(DARK_GREEN); + MinecraftServer.getServer().getConfigurationManager().sendChatMsg(msgcomp); + } + + @SubscribeEvent + public void onPlayerClone(PlayerEvent.Clone e) + { + if(e.entityPlayer.isEntityPlayerMP()) + { + ((EntityPlayerMP)e.entityPlayer).setData(((EntityPlayerMP)e.original).getData()); + ((EntityPlayerMP)e.entityPlayer).setStatisticsFile(MinecraftServer.getServer().getConfigurationManager().func_152602_a(e.entityPlayer)); + } + } + + @SubscribeEvent + public void onLivingDeath(LivingDeathEvent e) + { + if(e.entityLiving.isEntityPlayerMP()) + { + EntityPlayerMP player = (EntityPlayerMP)e.entityLiving; + Teleporter tp = player.getData().core().getTeleporter(); + if(tp != null) + tp.cancel(); + player.getData().core().setLastLocation(WarpLocation.getFromPlayer(player)); + } + } + + @SubscribeEvent(priority = EventPriority.HIGH) + public void onPlayerChangedDimension(PlayerChangedDimensionEvent e) + { + MinecraftServer.getServer().getConfigurationManager().getDataLoader().handlePlayerDimensionChange((EntityPlayerMP)e.player, e.fromDim, e.toDim); + } + + @SideOnly(Side.SERVER) + @SubscribeEvent(priority = EventPriority.HIGHEST) + public void onBreakEvent(BlockEvent.BreakEvent e) + { + if(!e.getPlayer().isEntityPlayerMP() || ((EntityPlayerMP)e.getPlayer()).playerNetServerHandler == null) + return; + if(!PermissionHandler.getInstance().has(e.getPlayer(), "ability.player.blockbreak")) + { + e.setCanceled(true); + e.getPlayer().addChatMessage(new ChatComponentTranslation("ultramine.ability.blockbreak").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.RED))); + } + } + + @SideOnly(Side.SERVER) + @SubscribeEvent(priority = EventPriority.HIGHEST) + public void onPlaceEvent(BlockEvent.PlaceEvent e) + { + if(!e.player.isEntityPlayerMP() || ((EntityPlayerMP)e.player).playerNetServerHandler == null) + return; + if(!PermissionHandler.getInstance().has(e.player, "ability.player.blockplace")) + { + e.setCanceled(true); + e.player.addChatMessage(new ChatComponentTranslation("ultramine.ability.blockplace").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.RED))); + } + } + + @SideOnly(Side.SERVER) + @SubscribeEvent(priority = EventPriority.HIGHEST) + public void onPlayerInteractEvent(PlayerInteractEvent e) + { + if(!e.entityPlayer.isEntityPlayerMP() || ((EntityPlayerMP)e.entityPlayer).playerNetServerHandler == null) + return; + if(!PermissionHandler.getInstance().has(e.entityPlayer, "ability.player.useitem")) + { + e.useItem = Event.Result.DENY; + if(e.entityPlayer.inventory.getCurrentItem() != null) + e.entityPlayer.addChatMessage(new ChatComponentTranslation("ultramine.ability.useitem").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.RED))); + } + if(!PermissionHandler.getInstance().has(e.entityPlayer, "ability.player.useblock")) + { + e.useBlock = Event.Result.DENY; + e.entityPlayer.addChatMessage(new ChatComponentTranslation("ultramine.ability.useblock").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.RED))); + } + + if(e.useItem == Event.Result.DENY && e.useBlock == Event.Result.DENY) + e.setCanceled(true); + } + + @SideOnly(Side.SERVER) + @SubscribeEvent(priority = EventPriority.HIGHEST) + public void onLivingAttackEvent(LivingAttackEvent e) + { + Entity attacker = e.source.getEntity(); + if(attacker != null && attacker.isEntityPlayerMP()) + { + EntityPlayerMP player = (EntityPlayerMP)attacker; + if(player.playerNetServerHandler == null) + return; + if(!PermissionHandler.getInstance().has(player, "ability.player.attack")) + { + e.setCanceled(true); + player.addChatMessage(new ChatComponentTranslation("ultramine.ability.attack").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.RED))); + } + } + } + + @SideOnly(Side.SERVER) + @SubscribeEvent(priority = EventPriority.HIGH) + public void onHoldingsCreate(PlayerHoldingsEvent.CreateEvent e) + { + if(e.holdings.getCurrency() == CurrencyRegistry.GSC) + e.holdings.setBalance(ConfigurationHandler.getServerConfig().tools.economy.startBalance); + } + + @SideOnly(Side.SERVER) + @SubscribeEvent(priority=EventPriority.LOWEST) + public void onPlayerLoggedIn(PlayerLoggedInEvent e) + { + ((EntityPlayerMP)e.player).getData().core().onLogin(); + } +} diff --git a/src/main/java/org/ultramine/server/internal/UMHooks.java b/src/main/java/org/ultramine/server/internal/UMHooks.java new file mode 100644 index 0000000..d61cf60 --- /dev/null +++ b/src/main/java/org/ultramine/server/internal/UMHooks.java @@ -0,0 +1,147 @@ +package org.ultramine.server.internal; + +import java.util.UUID; + +import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.common.registry.LanguageRegistry; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.server.MinecraftServer; +import net.minecraft.tileentity.TileEntity; + +import net.minecraft.util.ChatComponentTranslation; +import net.minecraft.util.IChatComponent; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.ultramine.server.event.WorldEventProxy; +import org.ultramine.server.event.WorldUpdateObject; + +import com.mojang.authlib.GameProfile; + +public class UMHooks +{ + private static final Logger log = LogManager.getLogger(); + private static final boolean IS_CLIENT = FMLCommonHandler.instance().getSide().isClient(); + + public static void printStackTrace(Throwable t) + { + log.error("Direct Throwable.printStackTrace() call"); + if(Thread.currentThread().getName().equals("Server thread")) + { + WorldEventProxy wep = WorldEventProxy.getCurrent(); + if(wep != null) + { + int dim = wep.getWorld().provider.dimensionId; + WorldUpdateObject obj = wep.getUpdateObject(); + switch(obj.getType()) + { + case BLOCK_EVENT: + log.error("On block event update [{}]({}, {}, {})", dim, obj.getX(), obj.getY(), obj.getZ()); + break; + case BLOCK_PENDING: + log.error("On block pending update [{}]({}, {}, {})", dim, obj.getX(), obj.getY(), obj.getZ()); + break; + case BLOCK_RANDOM: + log.error("On block random update [{}]({}, {}, {})", dim, obj.getX(), obj.getY(), obj.getZ()); + break; + case ENTITY: + Entity ent = obj.getEntity(); + log.error("On entity update [{}]({}, {}, {}). Entity: {}, Class: {}", dim, ent.posX, ent.posY, ent.posZ, ent, ent.getClass().getName()); + break; + case ENTITY_WEATHER: + Entity went = obj.getEntity(); + log.error("On weather entity update [{}]({}, {}, {}). Entity: {}, Class: {}", dim, went.posX, went.posY, went.posZ, went, went.getClass().getName()); + break; + case PLAYER: + EntityPlayer player = (EntityPlayer)obj.getEntity(); + log.error("On player packet [{}]({}, {}, {}). Entity: {}", dim, player.posX, player.posY, player.posZ, player); + break; + case TILEE_ENTITY: + TileEntity te = obj.getTileEntity(); + log.error("On TileEntity update [{}]({}, {}, {}). Class: {}", dim, te.xCoord, te.yCoord, te.zCoord, te.getClass().getName()); + break; + case WEATHER: + log.error("On weather action at world [{}]", dim); + break; + case UNKNOWN: + log.error("On unknown action at world [{}]", dim); + break; + } + } + else + { + log.error("On unknown action"); + } + } + else + { + log.error("On unknown action in thread " + Thread.currentThread().getName()); + } + + log.error("Invoked here", new Throwable("stacktrace")); + log.error("Original stacktrace", t); + } + + public static GameProfile readObjectOwner(NBTTagCompound nbt) + { + if(IS_CLIENT) + return null; + UUID id = nbt.hasKey("$") ? new UUID(nbt.getLong("$"), nbt.getLong("%")) : null; + String username = nbt.hasKey("#") ? nbt.getString("#") : null; + if(id != null || username != null && !username.isEmpty()) + return MinecraftServer.getServer().getConfigurationManager().getDataLoader().internGameProfile(id, username); + return null; + } + + public static void writeObjectOwner(NBTTagCompound nbt, GameProfile owner) + { + if(IS_CLIENT) + return; + UUID id = owner.getId(); + String username = owner.getName(); + if(id != null) + { + nbt.setLong("$", id.getMostSignificantBits()); + nbt.setLong("%", id.getLeastSignificantBits()); + } + if(username != null) + nbt.setString("#", username); + } + + public static IChatComponent onChatSend(EntityPlayerMP player, IChatComponent msg) + { + if(IS_CLIENT) + return msg; + if(msg instanceof ChatComponentTranslation) + return onChatSend(player, (ChatComponentTranslation) msg); + return msg; + } + + public static IChatComponent onChatSend(EntityPlayerMP player, ChatComponentTranslation msg) + { + String key = msg.getKey(); + Object[] oldArgs = msg.getFormatArgs(); + Object[] newArgs = new Object[oldArgs.length]; + boolean argsChanged = false; + for(int i = 0; i < oldArgs.length; i++) + { + Object o = oldArgs[i]; + Object o1 = o; + if(o instanceof ChatComponentTranslation) + o1 = onChatSend(player, (ChatComponentTranslation)o); + newArgs[i] = o1; + if(o != o1) + argsChanged = true; + } + if(!argsChanged && !key.startsWith("ultramine.") && !key.startsWith("command.")) //TODO add api for all + return msg; + String translated = LanguageRegistry.instance().getStringLocalization(key, player.getTranslator()); + if(translated.isEmpty()) + translated = LanguageRegistry.instance().getStringLocalization(key, "en_US"); + ChatComponentTranslation text = new ChatComponentTranslation(translated.isEmpty() ? key : translated, newArgs); + text.setChatStyle(msg.getChatStyle()); + return text; + } +} diff --git a/src/main/java/org/ultramine/server/internal/WatchdogThread.java b/src/main/java/org/ultramine/server/internal/WatchdogThread.java new file mode 100644 index 0000000..c81f721 --- /dev/null +++ b/src/main/java/org/ultramine/server/internal/WatchdogThread.java @@ -0,0 +1,134 @@ +package org.ultramine.server.internal; + +import java.lang.management.ManagementFactory; +import java.lang.management.MonitorInfo; +import java.lang.management.ThreadInfo; + +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import org.ultramine.server.ConfigurationHandler; + +@SideOnly(Side.SERVER) +public class WatchdogThread extends Thread +{ + private static final Logger log = LogManager.getLogger(); + + private static WatchdogThread instance; + private volatile long lastTick; + private volatile boolean stopping; + + private WatchdogThread() + { + super("Watchdog Thread"); + } + + public static void doStart() + { + if(instance == null) + { + instance = new WatchdogThread(); + instance.start(); + } + } + + + public static void tick() + { + instance.lastTick = System.currentTimeMillis(); + } + + public static void doStop() + { + if(instance != null) + { + instance.stopping = true; + } + } + + @Override + public void run() + { + while(!stopping) + { + // + if(lastTick != 0 && System.currentTimeMillis() > lastTick + ConfigurationHandler.getServerConfig().settings.watchdogThread.timeout*1000) + { + log.log(Level.FATAL, "The server has stopped responding!"); + + log.log(Level.FATAL, "Current Thread State:"); + ThreadInfo[] threads = ManagementFactory.getThreadMXBean().dumpAllThreads(true, true); + + for(ThreadInfo thread : threads) //main thread first + { + if(thread.getThreadName().equals("Server thread")) + displayThreadInfo(thread); + } + + for(ThreadInfo thread : threads) + { + if(!thread.getThreadName().equals("Server thread")) + displayThreadInfo(thread); + } + + log.log(Level.FATAL, "------------------------------"); + + if(ConfigurationHandler.getServerConfig().settings.watchdogThread.restart) + { + try + { + sleep(2000); //await log output + } catch (InterruptedException ex) {} + + Thread.currentThread().interrupt(); + FMLCommonHandler.instance().handleExit(0); + } + + break; + } + + try + { + sleep(10000); + } catch (InterruptedException ex) + { + // interrupt(); + } + } + } + + private static void displayThreadInfo(ThreadInfo thread) + { + if(thread.getThreadState() != State.WAITING) + { + log.log(Level.FATAL, "------------------------------"); + // + log.log(Level.FATAL, "Current Thread: " + thread.getThreadName()); + log.log(Level.FATAL, "\tPID: " + thread.getThreadId() + " | Suspended: " + thread.isSuspended() + " | Native: " + thread.isInNative() + " | State: " + + thread.getThreadState()); + + if(thread.getLockedMonitors().length != 0) + { + log.log(Level.FATAL, "\tThread is waiting on monitor(s):"); + + for(MonitorInfo monitor : thread.getLockedMonitors()) + { + log.log(Level.FATAL, "\t\tLocked on:" + monitor.getLockedStackFrame()); + } + } + + log.log(Level.FATAL, "\tStack:"); + // + StackTraceElement[] stack = thread.getStackTrace(); + + for(int line = 0; line < stack.length; line++) + { + log.log(Level.FATAL, "\t\t" + stack[line].toString()); + } + } + } +}