diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java index ee045f3..b4258c2 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -1481,6 +1481,7 @@ public double currentTPS = 20; private long catchupTime = 0; public long currentWait = TICK_TIME; + public final long startTime = System.currentTimeMillis(); private final MultiWorld multiworld = new MultiWorld(this); private IPermissionManager permissionManager; diff --git a/src/main/java/net/minecraft/world/World.java b/src/main/java/net/minecraft/world/World.java index 246951a..51e8427 100644 --- a/src/main/java/net/minecraft/world/World.java +++ b/src/main/java/net/minecraft/world/World.java @@ -4048,6 +4048,11 @@ return true; } + public int getActiveChunkSetSize() + { + return activeChunkSet.size(); + } + protected boolean isChunkLoaderEnabled() { return true; diff --git a/src/main/java/org/ultramine/commands/CommandContext.java b/src/main/java/org/ultramine/commands/CommandContext.java index 5628be8..83cd0c9 100644 --- a/src/main/java/org/ultramine/commands/CommandContext.java +++ b/src/main/java/org/ultramine/commands/CommandContext.java @@ -9,7 +9,9 @@ import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.Item; import net.minecraft.server.MinecraftServer; +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.world.WorldServer; @@ -121,16 +123,28 @@ throw new CommandException("commands.generic.permission"); } - public void sendMessage(EnumChatFormatting color, String msg, Object... args) + public void sendMessage(EnumChatFormatting tplColor, EnumChatFormatting argsColor, String msg, Object... args) { + for(int i = 0; i < args.length; i++) + { + Object o = args[i]; + if(!(o instanceof IChatComponent)) + args[i] = new ChatComponentText(o.toString()).setChatStyle(new ChatStyle().setColor(argsColor)); + } + ChatComponentTranslation comp = new ChatComponentTranslation(msg, args); - comp.getChatStyle().setColor(color); + comp.getChatStyle().setColor(tplColor); sender.addChatMessage(comp); } + public void sendMessage(EnumChatFormatting argsColor, String msg, Object... args) + { + sendMessage(EnumChatFormatting.GOLD, argsColor, msg, args); + } + public void sendMessage(String msg, Object... args) { - sendMessage(EnumChatFormatting.GOLD, msg, args); + sendMessage(EnumChatFormatting.GOLD, EnumChatFormatting.YELLOW, msg, args); } public void throwBadUsage() diff --git a/src/main/java/org/ultramine/commands/basic/BasicCommands.java b/src/main/java/org/ultramine/commands/basic/BasicCommands.java index ffcf186..8aa519f 100644 --- a/src/main/java/org/ultramine/commands/basic/BasicCommands.java +++ b/src/main/java/org/ultramine/commands/basic/BasicCommands.java @@ -3,6 +3,7 @@ import java.util.Map; import net.minecraft.server.MinecraftServer; +import static net.minecraft.util.EnumChatFormatting.*; import org.ultramine.commands.Command; import org.ultramine.commands.CommandContext; @@ -81,7 +82,7 @@ ctx.getSenderAsPlayer(); ctx.sendMessage("command.homelist.head"); for(Map.Entry ent : ctx.getSenderAsPlayer().getData().core().getHomes().entrySet()) - ctx.sendMessage(" - %s [%s](%s, %s, %s)", ent.getKey(), ent.getValue().dimension, (int)ent.getValue().x, (int)ent.getValue().y, (int)ent.getValue().z); + ctx.sendMessage(GOLD, " - %s [%s](%s, %s, %s)", ent.getKey(), ent.getValue().dimension, (int)ent.getValue().x, (int)ent.getValue().y, (int)ent.getValue().z); } @Command( @@ -153,6 +154,6 @@ ctx.getSenderAsPlayer(); ctx.sendMessage("command.warplist.head"); for(Map.Entry ent : MinecraftServer.getServer().getConfigurationManager().getDataLoader().getWarps().entrySet()) - ctx.sendMessage(" - %s [%s](%s, %s, %s)", ent.getKey(), ent.getValue().dimension, (int)ent.getValue().x, (int)ent.getValue().y, (int)ent.getValue().z); + ctx.sendMessage(GOLD, " - %s [%s](%s, %s, %s)", ent.getKey(), ent.getValue().dimension, (int)ent.getValue().x, (int)ent.getValue().y, (int)ent.getValue().z); } } diff --git a/src/main/java/org/ultramine/commands/basic/TechCommands.java b/src/main/java/org/ultramine/commands/basic/TechCommands.java new file mode 100644 index 0000000..f2f7bda --- /dev/null +++ b/src/main/java/org/ultramine/commands/basic/TechCommands.java @@ -0,0 +1,96 @@ +package org.ultramine.commands.basic; + +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.Item; +import net.minecraft.item.ItemBlock; +import net.minecraft.server.MinecraftServer; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.ChatComponentTranslation; +import static net.minecraft.util.EnumChatFormatting.*; +import net.minecraft.world.WorldServer; + +import org.ultramine.commands.Command; +import org.ultramine.commands.CommandContext; + +public class TechCommands +{ + @Command( + name = "id", + group = "technical", + permissions = {"command.id"}, + syntax = {"<%id>"} + ) + public static void id(CommandContext ctx) + { + Item item = ctx.get("id").asItem(); + ctx.sendMessage("ID: %s", Item.itemRegistry.getNameForObject(item)); + ctx.sendMessage("Internal ID: %s", Item.itemRegistry.getIDForObject(item)); + ctx.sendMessage("Unlocalized name: %s", new ChatComponentText(item.getUnlocalizedName())); + ctx.sendMessage("Localized name: %s", new ChatComponentTranslation(item.getUnlocalizedName()+".name")); + ctx.sendMessage("Is block: %s", item instanceof ItemBlock); + ctx.sendMessage("Class name: %s", item.getClass().getName()); + } + + @Command( + name = "uptime", + aliases = {"ticks", "lagometer"}, + group = "technical", + permissions = {"command.uptime"} + ) + public static void uptime(CommandContext ctx) + { + double tps = Math.round(MinecraftServer.getServer().currentTPS*10)/10d; + double downtime = MinecraftServer.getServer().currentWait/1000/1000d; + int load = (int)Math.round((50-downtime)/50*100); + int uptime = (int)((System.currentTimeMillis() - MinecraftServer.getServer().startTime)/1000); + ctx.sendMessage(DARK_GREEN, "command.uptime.msg.up", String.format("%dd %dh %dm %ds", uptime/(60*60*24), uptime/(60*60)%24, uptime/60%60, uptime%60)); + ctx.sendMessage(load > 100 ? RED : DARK_GREEN, "command.uptime.msg.load", Integer.toString(load).concat("%")); + ctx.sendMessage(tps < 15 ? RED : DARK_GREEN, "command.uptime.msg.tps", Double.toString(tps), + Integer.toString((int)(tps/20*100)).concat("%")); + } + + @Command( + name = "debuginfo", + group = "technical", + permissions = {"command.debuginfo"}, + syntax = { + "", + "", + "" + } + ) + public static void debuginfo(CommandContext ctx) + { + if(ctx.contains("world") || ctx.getArgs().length == 0) + { + WorldServer world = ctx.contains("world") ? ctx.get("world").asWorld() : ctx.getSenderAsPlayer().getServerForPlayer(); + ctx.sendMessage("World: %s, Dimension: %s", world.getWorldInfo().getWorldName(), world.provider.dimensionId); + ctx.sendMessage("Chunks loaded: %s", world.theChunkProviderServer.getLoadedChunkCount()); + ctx.sendMessage("Chunks active: %s", world.getActiveChunkSetSize()); + ctx.sendMessage("Chunks for unload: %s", world.theChunkProviderServer.chunksToUnload.size()); + ctx.sendMessage("Players: %s", world.playerEntities.size()); + ctx.sendMessage("Entities: %s", world.loadedEntityList.size()); + ctx.sendMessage("TileEntities: %s", world.loadedTileEntityList.size()); + } + else + { + EntityPlayerMP player = ctx.get("player").asPlayer(); + ctx.sendMessage("Username: %s", player.getCommandSenderName()); + ctx.sendMessage("UUID: %s", player.getGameProfile().getId()); + ctx.sendMessage("Chunk send rate: %s", player.getChunkMgr().getRate()); + ctx.sendMessage("View distance: %s", player.getRenderDistance()); + } + } + + @Command( + name = "memstat", + group = "technical", + permissions = {"command.memstat"} + ) + public static void memstat(CommandContext ctx) + { + ctx.sendMessage("Heap max: %sm", Runtime.getRuntime().maxMemory() >> 20); + ctx.sendMessage("Heap total: %sm", Runtime.getRuntime().totalMemory() >> 20); + ctx.sendMessage("Heap free: %sm", Runtime.getRuntime().freeMemory() >> 20); + } +} diff --git a/src/main/java/org/ultramine/commands/basic/VanillaCommands.java b/src/main/java/org/ultramine/commands/basic/VanillaCommands.java index eef2842..7801a80 100644 --- a/src/main/java/org/ultramine/commands/basic/VanillaCommands.java +++ b/src/main/java/org/ultramine/commands/basic/VanillaCommands.java @@ -3,7 +3,6 @@ import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.server.MinecraftServer; import net.minecraft.util.ChatComponentTranslation; -import net.minecraft.util.EnumChatFormatting; import net.minecraft.world.EnumDifficulty; import net.minecraft.world.WorldServer; @@ -35,7 +34,7 @@ { EntityPlayerMP dst = context.get("dst").asPlayer(); Teleporter.tpNow(target, dst); - context.sendMessage(EnumChatFormatting.GOLD, "command.tp.success.player", target.getCommandSenderName(), dst.getCommandSenderName()); + context.sendMessage("command.tp.success.player", target.getCommandSenderName(), dst.getCommandSenderName()); } else if(context.contains("x") && context.contains("y") && context.contains("z")) { @@ -44,7 +43,7 @@ double y = context.get("y").asCoordinate(target.posY); double z = context.get("z").asCoordinate(target.posZ); Teleporter.tpNow(target, world.provider.dimensionId, x, y, z); - context.sendMessage(EnumChatFormatting.GOLD, "command.tp.success.coordinate", + context.sendMessage("command.tp.success.coordinate", target.getCommandSenderName(), world.getWorldInfo().getWorldName(), x, y, z); } } diff --git a/src/main/java/org/ultramine/server/UltramineServerModContainer.java b/src/main/java/org/ultramine/server/UltramineServerModContainer.java index 7294075..dbf8eb5 100644 --- a/src/main/java/org/ultramine/server/UltramineServerModContainer.java +++ b/src/main/java/org/ultramine/server/UltramineServerModContainer.java @@ -28,6 +28,7 @@ import cpw.mods.fml.relauncher.Side; import org.ultramine.commands.basic.BasicCommands; +import org.ultramine.commands.basic.TechCommands; import org.ultramine.commands.basic.VanillaCommands; import org.ultramine.commands.syntax.DefaultCompleters; import org.ultramine.permission.commands.BasicPermissionCommands; @@ -94,6 +95,7 @@ e.registerCommands(BasicPermissionCommands.class); e.registerCommands(VanillaCommands.class); e.registerCommands(BasicCommands.class); + e.registerCommands(TechCommands.class); e.getPermissionHandler().createGroup(OpPermissionProxySet.OP_GROUP, "*"); } diff --git a/src/main/java/org/ultramine/server/chunk/ChunkSendManager.java b/src/main/java/org/ultramine/server/chunk/ChunkSendManager.java index 25477e0..e3be59e 100644 --- a/src/main/java/org/ultramine/server/chunk/ChunkSendManager.java +++ b/src/main/java/org/ultramine/server/chunk/ChunkSendManager.java @@ -352,6 +352,11 @@ return movX >= -radius && movX <= radius ? movZ >= -radius && movZ <= radius : false; } + public double getRate() + { + return rate; + } + diff --git a/src/main/resources/assets/ultramine/lang/en_US.lang b/src/main/resources/assets/ultramine/lang/en_US.lang index 83ae1f7..0055ebf 100644 --- a/src/main/resources/assets/ultramine/lang/en_US.lang +++ b/src/main/resources/assets/ultramine/lang/en_US.lang @@ -81,3 +81,19 @@ command.warplist.usage=/warplist command.warplist.description=Displays list of all server warps command.warplist.head=Warp list: + +#Technical commands +command.id.usage=/id +command.id.description=Displays information about specified item id + +command.uptime.usage=/uptime +command.uptime.description=Displays server's up time and load information +command.uptime.msg.up=UP: %s +command.uptime.msg.load=Load average: %s +command.uptime.msg.tps=Ticks per second: %s/20 (%s) + +command.debuginfo.usage=/debuginfo [world/player] +command.debuginfo.description=Some debug information + +command.memstat.usage=/memstat +command.memstat.description=Displays max, current allocated and free memory