diff --git a/src/main/java/net/minecraft/entity/Entity.java b/src/main/java/net/minecraft/entity/Entity.java index e7834dd..e0165d1 100644 --- a/src/main/java/net/minecraft/entity/Entity.java +++ b/src/main/java/net/minecraft/entity/Entity.java @@ -29,6 +29,7 @@ import net.minecraft.entity.item.EntityMinecart; import net.minecraft.entity.item.EntityPainting; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.item.Item; @@ -792,7 +793,8 @@ f = 1.0F; } - this.playSound(this.getSwimSound(), f, 1.0F + (this.rand.nextFloat() - this.rand.nextFloat()) * 0.4F); + if(!isEntityPlayerMP() || !((EntityPlayerMP)this).isHidden()) + this.playSound(this.getSwimSound(), f, 1.0F + (this.rand.nextFloat() - this.rand.nextFloat()) * 0.4F); } this.func_145780_a(j1, k, l, block); @@ -886,6 +888,8 @@ protected void func_145780_a(int p_145780_1_, int p_145780_2_, int p_145780_3_, Block p_145780_4_) { + if(isEntityPlayerMP() && ((EntityPlayerMP)this).isHidden()) + return; Block.SoundType soundtype = p_145780_4_.stepSound; if (this.worldObj.getBlock(p_145780_1_, p_145780_2_ + 1, p_145780_3_) == Blocks.snow_layer) diff --git a/src/main/java/net/minecraft/entity/EntityLivingBase.java b/src/main/java/net/minecraft/entity/EntityLivingBase.java index 2d2e3cb..afff0d2 100644 --- a/src/main/java/net/minecraft/entity/EntityLivingBase.java +++ b/src/main/java/net/minecraft/entity/EntityLivingBase.java @@ -171,7 +171,7 @@ block = this.worldObj.getBlock(i, j - 1, k); } } - else if (!this.worldObj.isRemote && this.fallDistance > 3.0F) + else if (!this.worldObj.isRemote && this.fallDistance > 3.0F && (!isEntityPlayerMP() || !((EntityPlayerMP)this).isHidden())) { this.worldObj.playAuxSFX(2006, i, j, k, MathHelper.ceiling_float_int(this.fallDistance - 3.0F)); } diff --git a/src/main/java/net/minecraft/entity/EntityTracker.java b/src/main/java/net/minecraft/entity/EntityTracker.java index d5ba1b7..c58b4b3 100644 --- a/src/main/java/net/minecraft/entity/EntityTracker.java +++ b/src/main/java/net/minecraft/entity/EntityTracker.java @@ -38,6 +38,7 @@ import net.minecraft.world.chunk.Chunk; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.ultramine.permission.MinecraftPermissions; import cpw.mods.fml.common.registry.EntityRegistry; @@ -339,6 +340,55 @@ } } + /*===================================== ULTRAMINE START =====================================*/ + + public EntityTrackerEntry findPlayerTracker(EntityPlayerMP player) + { + for(Object o : trackedEntities) + { + EntityTrackerEntry ent = (EntityTrackerEntry)o; + if(ent.myEntity == player) + return ent; + } + + return null; + } + + public void hidePlayer(EntityPlayerMP player) + { + EntityTrackerEntry playerTracker = findPlayerTracker(player); + if(playerTracker != null) + { + for(Object o : trackedEntities) + { + EntityTrackerEntry ent = (EntityTrackerEntry)o; + if(ent.myEntity.isEntityPlayerMP()) + { + EntityPlayerMP watcher = (EntityPlayerMP)ent.myEntity; + if(!watcher.hasPermission(MinecraftPermissions.SEE_INVISIBLE_PLAYERS)) + playerTracker.removePlayerFromTracker(watcher); + } + } + } + } + + public void showPlayer(EntityPlayerMP player) + { + EntityTrackerEntry playerTracker = findPlayerTracker(player); + if(playerTracker != null) + { + for(Object o : trackedEntities) + { + EntityTrackerEntry ent = (EntityTrackerEntry)o; + if(ent.myEntity.isEntityPlayerMP()) + { + EntityPlayerMP watcher = (EntityPlayerMP)ent.myEntity; + playerTracker.tryStartWachingThis(watcher); + } + } + } + } + /* ======================================== FORGE START =====================================*/ // don't expose the EntityTrackerEntry directly so mods can't mess with the data in there as easily diff --git a/src/main/java/net/minecraft/entity/EntityTrackerEntry.java b/src/main/java/net/minecraft/entity/EntityTrackerEntry.java index 6c6e723..4dc72ae 100644 --- a/src/main/java/net/minecraft/entity/EntityTrackerEntry.java +++ b/src/main/java/net/minecraft/entity/EntityTrackerEntry.java @@ -56,6 +56,7 @@ import net.minecraft.world.storage.MapData; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.ultramine.permission.MinecraftPermissions; import cpw.mods.fml.common.network.internal.FMLNetworkHandler; @@ -355,6 +356,8 @@ { if (!this.trackingPlayers.contains(p_73117_1_) && (this.isPlayerWatchingThisChunk(p_73117_1_) || this.myEntity.forceSpawn)) { + if(myEntity.isEntityPlayerMP() && ((EntityPlayerMP)myEntity).isHidden() && !p_73117_1_.hasPermission(MinecraftPermissions.SEE_INVISIBLE_PLAYERS)) + return; this.trackingPlayers.add(p_73117_1_); Packet packet = this.func_151260_c(); p_73117_1_.playerNetServerHandler.sendPacket(packet); diff --git a/src/main/java/net/minecraft/entity/player/EntityPlayerMP.java b/src/main/java/net/minecraft/entity/player/EntityPlayerMP.java index 1118689..16a2890 100644 --- a/src/main/java/net/minecraft/entity/player/EntityPlayerMP.java +++ b/src/main/java/net/minecraft/entity/player/EntityPlayerMP.java @@ -65,6 +65,7 @@ import net.minecraft.network.play.server.S30PacketWindowItems; import net.minecraft.network.play.server.S31PacketWindowProperty; import net.minecraft.network.play.server.S36PacketSignEditorOpen; +import net.minecraft.network.play.server.S38PacketPlayerListItem; import net.minecraft.network.play.server.S39PacketPlayerAbilities; import net.minecraft.network.play.server.S3FPacketCustomPayload; import net.minecraft.potion.PotionEffect; @@ -1039,7 +1040,7 @@ /** * Переносит игрока в другой мир без использования порталов. Обратите * внимение: сначала нужно установить координаты назначения - * setPlayerLocation(), а потом уже переносить в другой мир. + * setPosition(), а потом уже переносить в другой мир. */ public void transferToDimension(int dim) { @@ -1053,4 +1054,29 @@ { this.field_147103_bO = stats; } + + public void hide() + { + if(!isHidden()) + { + getData().core().setHidden(true); + ((WorldServer)worldObj).getEntityTracker().hidePlayer(this); + mcServer.getConfigurationManager().sendPacketToAllPlayers(new S38PacketPlayerListItem(getTabListName(), false, 9999)); + } + } + + public void show() + { + if(isHidden()) + { + getData().core().setHidden(false); + ((WorldServer)worldObj).getEntityTracker().showPlayer(this); + mcServer.getConfigurationManager().sendPacketToAllPlayers(new S38PacketPlayerListItem(getTabListName(), true, ping)); + } + } + + public boolean isHidden() + { + return getData().core().isHidden(); + } } diff --git a/src/main/java/net/minecraft/inventory/ContainerChest.java b/src/main/java/net/minecraft/inventory/ContainerChest.java index a069884..1c98542 100644 --- a/src/main/java/net/minecraft/inventory/ContainerChest.java +++ b/src/main/java/net/minecraft/inventory/ContainerChest.java @@ -1,6 +1,8 @@ package net.minecraft.inventory; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.item.ItemStack; public class ContainerChest extends Container @@ -8,12 +10,16 @@ private IInventory lowerChestInventory; private int numRows; private static final String __OBFID = "CL_00001742"; + + private final boolean notifyInventory; public ContainerChest(IInventory p_i1806_1_, IInventory p_i1806_2_) { this.lowerChestInventory = p_i1806_2_; this.numRows = p_i1806_2_.getSizeInventory() / 9; - p_i1806_2_.openInventory(); + notifyInventory = !(p_i1806_1_ instanceof InventoryPlayer && ((InventoryPlayer)p_i1806_1_).player.isEntityPlayerMP() && ((EntityPlayerMP)((InventoryPlayer)p_i1806_1_).player).isHidden()); + if(notifyInventory) + p_i1806_2_.openInventory(); int i = (this.numRows - 4) * 18; int j; int k; @@ -83,7 +89,8 @@ public void onContainerClosed(EntityPlayer p_75134_1_) { super.onContainerClosed(p_75134_1_); - this.lowerChestInventory.closeInventory(); + if(notifyInventory) + this.lowerChestInventory.closeInventory(); } public IInventory getLowerChestInventory() diff --git a/src/main/java/net/minecraft/network/NetHandlerPlayServer.java b/src/main/java/net/minecraft/network/NetHandlerPlayServer.java index 678e0f7..8148da2 100644 --- a/src/main/java/net/minecraft/network/NetHandlerPlayServer.java +++ b/src/main/java/net/minecraft/network/NetHandlerPlayServer.java @@ -642,7 +642,8 @@ this.serverController.func_147132_au(); ChatComponentTranslation chatcomponenttranslation = new ChatComponentTranslation("multiplayer.player.left", new Object[] {this.playerEntity.func_145748_c_()}); chatcomponenttranslation.getChatStyle().setColor(EnumChatFormatting.YELLOW); - this.serverController.getConfigurationManager().sendPacketToAllPlayers(new S02PacketChat(chatcomponenttranslation, true)); + if(!playerEntity.isHidden() && !playerEntity.hasPermission(MinecraftPermissions.HIDE_JOIN_MESSAGE)) + this.serverController.getConfigurationManager().sendPacketToAllPlayers(new S02PacketChat(chatcomponenttranslation, true)); this.playerEntity.mountEntityAndWakeUp(); this.serverController.getConfigurationManager().playerLoggedOut(this.playerEntity); diff --git a/src/main/java/net/minecraft/server/management/ServerConfigurationManager.java b/src/main/java/net/minecraft/server/management/ServerConfigurationManager.java index 412f421..cf62f0d 100644 --- a/src/main/java/net/minecraft/server/management/ServerConfigurationManager.java +++ b/src/main/java/net/minecraft/server/management/ServerConfigurationManager.java @@ -22,6 +22,7 @@ import java.util.UUID; import java.util.Map.Entry; +import net.minecraft.command.CommandBase; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityList; import net.minecraft.entity.player.EntityPlayer; @@ -176,7 +177,8 @@ } chatcomponenttranslation.getChatStyle().setColor(EnumChatFormatting.YELLOW); - sendPacketToAllPlayers(new S02PacketChat(chatcomponenttranslation, true)); + if(!p_72355_2_.isHidden() && !p_72355_2_.hasPermission(MinecraftPermissions.HIDE_JOIN_MESSAGE)) + sendPacketToAllPlayers(new S02PacketChat(chatcomponenttranslation, true)); this.playerLoggedIn(p_72355_2_); nethandlerplayserver.setPlayerLocation(p_72355_2_.posX, p_72355_2_.posY, p_72355_2_.posZ, p_72355_2_.rotationYaw, p_72355_2_.rotationPitch); this.updateTimeAndWeatherForPlayer(p_72355_2_, worldserver); @@ -314,7 +316,17 @@ public void playerLoggedIn(final EntityPlayerMP par1EntityPlayerMP) { - this.sendPacketToAllPlayers(new S38PacketPlayerListItem(par1EntityPlayerMP.getTabListName(), true, 1000)); + if(!par1EntityPlayerMP.isHidden()) + this.sendPacketToAllPlayers(new S38PacketPlayerListItem(par1EntityPlayerMP.getTabListName(), true, 1000)); + else + { + for(Object o : playerEntityList) + { + EntityPlayerMP p = (EntityPlayerMP)o; + if(p.hasPermission(MinecraftPermissions.SEE_INVISIBLE_PLAYERS)) + p.playerNetServerHandler.sendPacket(new S38PacketPlayerListItem(par1EntityPlayerMP.getTabListName(), true, 1000)); + } + } this.playerEntityList.add(par1EntityPlayerMP); usernameToPlayerMap.put(par1EntityPlayerMP.getGameProfile().getName().toLowerCase(), par1EntityPlayerMP); final WorldServer worldserver = this.mcServer.worldServerForDimension(par1EntityPlayerMP.dimension); @@ -325,11 +337,16 @@ worldserver.spawnEntityInWorld(par1EntityPlayerMP); func_72375_a(par1EntityPlayerMP, (WorldServer)null); + boolean seeInvisible = par1EntityPlayerMP.hasPermission(MinecraftPermissions.SEE_INVISIBLE_PLAYERS); for (int i = 0; i < this.playerEntityList.size(); ++i) { EntityPlayerMP entityplayermp1 = (EntityPlayerMP)this.playerEntityList.get(i); - par1EntityPlayerMP.playerNetServerHandler.sendPacket(new S38PacketPlayerListItem(entityplayermp1.getTabListName(), true, entityplayermp1.ping)); + if(!entityplayermp1.isHidden() || seeInvisible) + par1EntityPlayerMP.playerNetServerHandler.sendPacket(new S38PacketPlayerListItem(entityplayermp1.getTabListName(), true, entityplayermp1.ping)); } + + if(par1EntityPlayerMP.isHidden()) + CommandBase.func_152374_a(par1EntityPlayerMP, null, 1, "ultramine.notify.loggedhidden"); } public void updatePlayerPertinentChunks(EntityPlayerMP p_72358_1_) @@ -680,7 +697,17 @@ if (this.playerPingIndex < this.playerEntityList.size()) { EntityPlayerMP entityplayermp = (EntityPlayerMP)this.playerEntityList.get(this.playerPingIndex); - this.sendPacketToAllPlayers(new S38PacketPlayerListItem(entityplayermp.getTabListName(), true, entityplayermp.ping)); + if(!entityplayermp.isHidden()) + this.sendPacketToAllPlayers(new S38PacketPlayerListItem(entityplayermp.getTabListName(), true, entityplayermp.ping)); + else + { + for(Object o : playerEntityList) + { + EntityPlayerMP p = (EntityPlayerMP)o; + if(p.hasPermission(MinecraftPermissions.SEE_INVISIBLE_PLAYERS)) + p.playerNetServerHandler.sendPacket(new S38PacketPlayerListItem(entityplayermp.getTabListName(), true, entityplayermp.ping)); + } + } } } @@ -707,25 +734,28 @@ public String func_152609_b(boolean p_152609_1_) { - String s = ""; - ArrayList arraylist = Lists.newArrayList(this.playerEntityList); + StringBuilder sb = new StringBuilder(512); - for (int i = 0; i < arraylist.size(); ++i) + for (int i = 0; i < playerEntityList.size(); ++i) { - if (i > 0) + EntityPlayerMP player = (EntityPlayerMP)playerEntityList.get(i); + if(!player.isHidden()) { - s = s + ", "; - } + if (i > 0) + { + sb.append(", "); + } - s = s + ((EntityPlayerMP)arraylist.get(i)).getCommandSenderName(); + sb.append(player.getCommandSenderName()); - if (p_152609_1_) - { - s = s + " (" + ((EntityPlayerMP)arraylist.get(i)).getUniqueID().toString() + ")"; + if (p_152609_1_) + { + sb.append(" (").append(player.getUniqueID().toString()).append(")"); + } } } - return s; + return sb.toString(); } public String[] getAllUsernames() diff --git a/src/main/java/org/ultramine/commands/CommandContext.java b/src/main/java/org/ultramine/commands/CommandContext.java index 3c408c1..73df0e7 100644 --- a/src/main/java/org/ultramine/commands/CommandContext.java +++ b/src/main/java/org/ultramine/commands/CommandContext.java @@ -117,6 +117,11 @@ { CommandBase.func_152373_a(sender, null, messageKey, messageArgs); } + + public void notifyOtherAdmins(String messageKey, Object... messageArgs) + { + CommandBase.func_152374_a(sender, null, 1, messageKey, messageArgs); + } public void checkSenderPermission(String permission) { diff --git a/src/main/java/org/ultramine/commands/basic/BasicCommands.java b/src/main/java/org/ultramine/commands/basic/BasicCommands.java index 0dfe268..3e88d1e 100644 --- a/src/main/java/org/ultramine/commands/basic/BasicCommands.java +++ b/src/main/java/org/ultramine/commands/basic/BasicCommands.java @@ -426,4 +426,28 @@ ctx.get("player").asOfflinePlayer().sendMessage(GREEN, GREEN, "command.unmute.notify"); ctx.sendMessage("command.unmute.success", data.getProfile().getName()); } + + @Command( + name = "vanish", + group = "admin", + aliases = {"hide"}, + permissions = {"command.admin.vanish"}, + syntax = {""} + ) + public static void vanish(CommandContext ctx) + { + EntityPlayerMP player = ctx.getSenderAsPlayer(); + if(player.isHidden()) + { + player.show(); + ctx.sendMessage("command.unmute.success.show"); + ctx.notifyOtherAdmins("command.unmute.notify.show"); + } + else + { + player.hide(); + ctx.sendMessage("command.unmute.success.hide"); + ctx.notifyOtherAdmins("command.unmute.notify.hide"); + } + } } diff --git a/src/main/java/org/ultramine/permission/MinecraftPermissions.java b/src/main/java/org/ultramine/permission/MinecraftPermissions.java index 22305a5..c3a074a 100644 --- a/src/main/java/org/ultramine/permission/MinecraftPermissions.java +++ b/src/main/java/org/ultramine/permission/MinecraftPermissions.java @@ -7,4 +7,7 @@ public static final String ALLOW_SPAM = "minecraft.allow_spam"; public static final String IGNORE_SPAWN_PROTECTION = "minecraft.ignore_spawn_prot"; public static final String IGNORE_WHITE_LIST = "minecraft.ignore_white_list"; + + public static final String SEE_INVISIBLE_PLAYERS = "ability.admin.seeinvisibleplayers"; + public static final String HIDE_JOIN_MESSAGE = "ability.admin.hidejoinmessage"; } diff --git a/src/main/java/org/ultramine/server/UMEventHandler.java b/src/main/java/org/ultramine/server/UMEventHandler.java index f85d83f..d9aa270 100644 --- a/src/main/java/org/ultramine/server/UMEventHandler.java +++ b/src/main/java/org/ultramine/server/UMEventHandler.java @@ -66,6 +66,11 @@ 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 diff --git a/src/main/java/org/ultramine/server/UltramineServerModContainer.java b/src/main/java/org/ultramine/server/UltramineServerModContainer.java index 7fcbc11..18707fc 100644 --- a/src/main/java/org/ultramine/server/UltramineServerModContainer.java +++ b/src/main/java/org/ultramine/server/UltramineServerModContainer.java @@ -18,6 +18,7 @@ import org.ultramine.commands.syntax.DefaultCompleters; import org.ultramine.economy.EconomyCommands; import org.ultramine.permission.IPermissionManager; +import org.ultramine.permission.MinecraftPermissions; import org.ultramine.permission.commands.BasicPermissionCommands; import org.ultramine.server.chunk.ChunkProfiler; import org.ultramine.server.data.Databases; @@ -154,7 +155,9 @@ } e.getPermissionHandler().setGroupMeta(IPermissionManager.DEFAULT_GROUP_NAME, IPermissionManager.GLOBAL_WORLD, "color", "7"); e.getPermissionHandler().addToGroup("admin", IPermissionManager.GLOBAL_WORLD, "*"); + e.getPermissionHandler().addToGroup("admin", IPermissionManager.GLOBAL_WORLD, "^"+MinecraftPermissions.HIDE_JOIN_MESSAGE); e.getPermissionHandler().setGroupMeta("admin", IPermissionManager.GLOBAL_WORLD, "color", "c"); + e.getPermissionHandler().setGroupMeta("admin", IPermissionManager.GLOBAL_WORLD, "tablistcolor", "c"); e.getPermissionHandler().setGroupMeta("admin", IPermissionManager.GLOBAL_WORLD, "prefix", "&4[admin] "); if(e.getSide().isServer()) diff --git a/src/main/java/org/ultramine/server/data/player/PlayerCoreData.java b/src/main/java/org/ultramine/server/data/player/PlayerCoreData.java index eeed0c2..b575c02 100644 --- a/src/main/java/org/ultramine/server/data/player/PlayerCoreData.java +++ b/src/main/java/org/ultramine/server/data/player/PlayerCoreData.java @@ -17,6 +17,7 @@ private final PlayerAccount account; private long unmuteTime; private boolean commandsMuted; + private boolean hidden; //undatabased private Teleporter teleporter; @@ -136,6 +137,16 @@ return isMuted() && commandsMuted; } + public boolean isHidden() + { + return hidden; + } + + public void setHidden(boolean hidden) + { + this.hidden = hidden; + } + @Override public void writeToNBT(NBTTagCompound nbt) { @@ -154,6 +165,7 @@ nbt.setTag("acc", accnbt); nbt.setLong("m", unmuteTime); nbt.setBoolean("mc", commandsMuted); + nbt.setBoolean("h", hidden); } @Override @@ -169,5 +181,6 @@ account.readFromNBT(nbt.getCompoundTag("acc")); unmuteTime = nbt.getLong("m"); commandsMuted = nbt.getBoolean("mc"); + hidden = nbt.getBoolean("h"); } } diff --git a/src/main/resources/assets/ultramine/lang/en_US.lang b/src/main/resources/assets/ultramine/lang/en_US.lang index 0ade4ed..cfaa800 100644 --- a/src/main/resources/assets/ultramine/lang/en_US.lang +++ b/src/main/resources/assets/ultramine/lang/en_US.lang @@ -17,6 +17,9 @@ ultramine.ability.attack=You don't have permissions to damage entities ultramine.ability.chat=You don't have permissions to chat +ultramine.notify.loggedhidden=Joined the server in invisibility +ultramine.hidden.chat=You can't write to chat in invisibility + #Command generic commands.generic.world.invalid=Can't find world '%s' commands.generic.itemstack.data=Failed to parse item data: %s @@ -339,3 +342,10 @@ command.unmute.fail=The player is not muted command.unmute.notify=You has been unmuted command.unmute.success=Player %s has been unmuted + +command.unmute.usage=/vanish +command.unmute.description=Makes you invisible for other players +command.unmute.success.hide=Now you're invisible +command.unmute.success.show=Now you're visible +command.unmute.notify.hide=became invisible +command.unmute.notify.show=became visible diff --git a/src/main/resources/assets/ultramine/lang/ru_RU.lang b/src/main/resources/assets/ultramine/lang/ru_RU.lang index 5c857c9..15b298b 100644 --- a/src/main/resources/assets/ultramine/lang/ru_RU.lang +++ b/src/main/resources/assets/ultramine/lang/ru_RU.lang @@ -17,6 +17,9 @@ ultramine.ability.attack=У вас нет права наносить урон ultramine.ability.chat=У вас нет прав писать в чате +ultramine.notify.loggedhidden=Присоединился к игре невидимым +ultramine.hidden.chat=Вы не можете писать в чат в невидимости + #Command generic commands.generic.world.invalid=Указанный мир не существует или неинициализирован '%s' commands.generic.itemstack.data=Не удалось разобрать предмет: %s @@ -339,3 +342,10 @@ command.unmute.fail=Указанный игрок не замьючен command.unmute.notify=Вам возвращено право писать в чат command.unmute.success=Игроку %s теперь разрешено писать в чат + +command.unmute.usage=/vanish +command.unmute.description=Делает вас невидимым для других игроков +command.unmute.success.hide=Вы в невидимости +command.unmute.success.show=Теперь вас видно +command.unmute.notify.hide=зашел в невидимость +command.unmute.notify.show=вышел из невидимости