From 2bf78bc61ce087a4a5c28a1d8919fd50a15622b8 Mon Sep 17 00:00:00 2001 From: Nick Date: Fri, 30 Oct 2015 16:54:59 -0700 Subject: [PATCH] Divination Sigil no longer spams chat --- .../AlchemicalWizardry.java | 3 + .../api/util/helper/TextHelper.java | 14 -- .../alchemicalWizardry/item/ItemBindable.java | 2 +- .../item/sigil/ItemSigilBase.java | 9 +- .../item/sigil/ItemSigilDivination.java | 7 +- .../AlchemicalWizardryPacketHandler.java | 31 +++ .../alchemicalWizardry/util/ChatUtil.java | 233 ++++++++++++++++++ .../util/helper/TextHelper.java | 41 +++ .../assets/alchemicalwizardry/lang/en_US.lang | 11 +- 9 files changed, 324 insertions(+), 27 deletions(-) delete mode 100644 src/main/java/WayofTime/alchemicalWizardry/api/util/helper/TextHelper.java create mode 100644 src/main/java/WayofTime/alchemicalWizardry/network/AlchemicalWizardryPacketHandler.java create mode 100644 src/main/java/WayofTime/alchemicalWizardry/util/ChatUtil.java create mode 100644 src/main/java/WayofTime/alchemicalWizardry/util/helper/TextHelper.java diff --git a/src/main/java/WayofTime/alchemicalWizardry/AlchemicalWizardry.java b/src/main/java/WayofTime/alchemicalWizardry/AlchemicalWizardry.java index 5a1f2381..bcbdbcd6 100644 --- a/src/main/java/WayofTime/alchemicalWizardry/AlchemicalWizardry.java +++ b/src/main/java/WayofTime/alchemicalWizardry/AlchemicalWizardry.java @@ -1,6 +1,7 @@ package WayofTime.alchemicalWizardry; import WayofTime.alchemicalWizardry.api.util.helper.LogHelper; +import WayofTime.alchemicalWizardry.network.AlchemicalWizardryPacketHandler; import WayofTime.alchemicalWizardry.registry.ModBlocks; import WayofTime.alchemicalWizardry.registry.ModEntities; import WayofTime.alchemicalWizardry.registry.ModItems; @@ -67,6 +68,8 @@ public class AlchemicalWizardry { @Mod.EventHandler public void init(FMLPreInitializationEvent event) { + AlchemicalWizardryPacketHandler.init(); + proxy.init(); } diff --git a/src/main/java/WayofTime/alchemicalWizardry/api/util/helper/TextHelper.java b/src/main/java/WayofTime/alchemicalWizardry/api/util/helper/TextHelper.java deleted file mode 100644 index 1a964c92..00000000 --- a/src/main/java/WayofTime/alchemicalWizardry/api/util/helper/TextHelper.java +++ /dev/null @@ -1,14 +0,0 @@ -package WayofTime.alchemicalWizardry.api.util.helper; - -import net.minecraft.util.StatCollector; - -public class TextHelper { - - public static String getFormattedText(String string) { - return string.replaceAll("&", "\u00A7"); - } - - public static String localize(String key, Object ... format) { - return getFormattedText(StatCollector.translateToLocalFormatted(key, format)); - } -} diff --git a/src/main/java/WayofTime/alchemicalWizardry/item/ItemBindable.java b/src/main/java/WayofTime/alchemicalWizardry/item/ItemBindable.java index 393ac631..7ed9b470 100644 --- a/src/main/java/WayofTime/alchemicalWizardry/item/ItemBindable.java +++ b/src/main/java/WayofTime/alchemicalWizardry/item/ItemBindable.java @@ -6,7 +6,7 @@ import WayofTime.alchemicalWizardry.api.NBTHolder; import WayofTime.alchemicalWizardry.api.iface.IBindable; import WayofTime.alchemicalWizardry.api.util.helper.BindableHelper; import WayofTime.alchemicalWizardry.api.util.helper.NetworkHelper; -import WayofTime.alchemicalWizardry.api.util.helper.TextHelper; +import WayofTime.alchemicalWizardry.util.helper.TextHelper; import com.google.common.base.Strings; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; diff --git a/src/main/java/WayofTime/alchemicalWizardry/item/sigil/ItemSigilBase.java b/src/main/java/WayofTime/alchemicalWizardry/item/sigil/ItemSigilBase.java index 906267a0..2ffd3aeb 100644 --- a/src/main/java/WayofTime/alchemicalWizardry/item/sigil/ItemSigilBase.java +++ b/src/main/java/WayofTime/alchemicalWizardry/item/sigil/ItemSigilBase.java @@ -3,6 +3,7 @@ package WayofTime.alchemicalWizardry.item.sigil; import WayofTime.alchemicalWizardry.AlchemicalWizardry; import WayofTime.alchemicalWizardry.api.NBTHolder; import WayofTime.alchemicalWizardry.api.iface.ISigil; +import WayofTime.alchemicalWizardry.util.helper.TextHelper; import WayofTime.alchemicalWizardry.item.ItemBindable; import lombok.Getter; import net.minecraft.entity.player.EntityPlayer; @@ -21,6 +22,7 @@ public class ItemSigilBase extends ItemBindable implements ISigil { private final String name; private boolean toggleable; + protected final String tooltipBase; public ItemSigilBase(String name, int energyUsed) { super(); @@ -29,6 +31,7 @@ public class ItemSigilBase extends ItemBindable implements ISigil { setEnergyUsed(energyUsed); this.name = name; + this.tooltipBase = "tooltip.AlchemicalWizardry.sigil." + name + "."; } public ItemSigilBase(String name) { @@ -54,10 +57,8 @@ public class ItemSigilBase extends ItemBindable implements ISigil { @SuppressWarnings("unchecked") public void addInformation(ItemStack stack, EntityPlayer player, List tooltip, boolean advanced) { - String desc = "tooltip.sigil." + name + ".desc"; - - if (StatCollector.canTranslate(desc)) - tooltip.add(StatCollector.translateToLocal(desc)); + if (StatCollector.canTranslate(tooltipBase + "desc")) + tooltip.add(TextHelper.localize(tooltipBase + "desc")); super.addInformation(stack, player, tooltip, advanced); } diff --git a/src/main/java/WayofTime/alchemicalWizardry/item/sigil/ItemSigilDivination.java b/src/main/java/WayofTime/alchemicalWizardry/item/sigil/ItemSigilDivination.java index e8a04a73..27bbb4cd 100644 --- a/src/main/java/WayofTime/alchemicalWizardry/item/sigil/ItemSigilDivination.java +++ b/src/main/java/WayofTime/alchemicalWizardry/item/sigil/ItemSigilDivination.java @@ -3,7 +3,8 @@ package WayofTime.alchemicalWizardry.item.sigil; import WayofTime.alchemicalWizardry.api.iface.IBloodAltar; import WayofTime.alchemicalWizardry.api.util.helper.BindableHelper; import WayofTime.alchemicalWizardry.api.util.helper.NetworkHelper; -import WayofTime.alchemicalWizardry.api.util.helper.TextHelper; +import WayofTime.alchemicalWizardry.util.ChatUtil; +import WayofTime.alchemicalWizardry.util.helper.TextHelper; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; @@ -26,14 +27,14 @@ public class ItemSigilDivination extends ItemSigilBase { int currentEssence = NetworkHelper.getCurrentEssence(BindableHelper.getOwnerName(stack)); if (position == null) { - player.addChatComponentMessage(new ChatComponentText(TextHelper.localize("message.divinationsigil.currentessence", currentEssence))); + ChatUtil.sendNoSpam(player, new ChatComponentText(TextHelper.localize(tooltipBase + "currentEssence", currentEssence))); return stack; } else { if (position.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK) { TileEntity tile = world.getTileEntity(position.getBlockPos()); if (!(tile instanceof IBloodAltar)) { - player.addChatComponentMessage(new ChatComponentText(TextHelper.localize("message.divinationsigil.currentessence", currentEssence))); + ChatUtil.sendNoSpam(player, new ChatComponentText(TextHelper.localize(tooltipBase + "currentEssence", currentEssence))); return stack; } } diff --git a/src/main/java/WayofTime/alchemicalWizardry/network/AlchemicalWizardryPacketHandler.java b/src/main/java/WayofTime/alchemicalWizardry/network/AlchemicalWizardryPacketHandler.java new file mode 100644 index 00000000..57b7855c --- /dev/null +++ b/src/main/java/WayofTime/alchemicalWizardry/network/AlchemicalWizardryPacketHandler.java @@ -0,0 +1,31 @@ +package WayofTime.alchemicalWizardry.network; + +import WayofTime.alchemicalWizardry.AlchemicalWizardry; +import WayofTime.alchemicalWizardry.util.ChatUtil; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.tileentity.TileEntity; +import net.minecraftforge.fml.common.network.NetworkRegistry; +import net.minecraftforge.fml.common.network.simpleimpl.IMessage; +import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper; +import net.minecraftforge.fml.relauncher.Side; + +public class AlchemicalWizardryPacketHandler { + + public static final SimpleNetworkWrapper INSTANCE = new SimpleNetworkWrapper(AlchemicalWizardry.MODID); + + public static void init() { + INSTANCE.registerMessage(ChatUtil.PacketNoSpamChat.Handler.class, ChatUtil.PacketNoSpamChat.class, 0, Side.CLIENT); + } + + public static void sendToAllAround(IMessage message, TileEntity te, int range) { + INSTANCE.sendToAllAround(message, new NetworkRegistry.TargetPoint(te.getWorld().provider.getDimensionId(), te.getPos().getX(), te.getPos().getY(), te.getPos().getZ(), range)); + } + + public static void sendToAllAround(IMessage message, TileEntity te) { + sendToAllAround(message, te, 64); + } + + public static void sendTo(IMessage message, EntityPlayerMP player) { + INSTANCE.sendTo(message, player); + } +} diff --git a/src/main/java/WayofTime/alchemicalWizardry/util/ChatUtil.java b/src/main/java/WayofTime/alchemicalWizardry/util/ChatUtil.java new file mode 100644 index 00000000..aff7fd3d --- /dev/null +++ b/src/main/java/WayofTime/alchemicalWizardry/util/ChatUtil.java @@ -0,0 +1,233 @@ +package WayofTime.alchemicalWizardry.util; + +import WayofTime.alchemicalWizardry.network.AlchemicalWizardryPacketHandler; +import WayofTime.alchemicalWizardry.util.helper.TextHelper; +import io.netty.buffer.ByteBuf; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiNewChat; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.ChatComponentTranslation; +import net.minecraft.util.IChatComponent; +import net.minecraftforge.fml.common.network.ByteBufUtils; +import net.minecraftforge.fml.common.network.simpleimpl.IMessage; +import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; +import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; + +public class ChatUtil { + + public static class PacketNoSpamChat implements IMessage { + + private IChatComponent[] chatLines; + + public PacketNoSpamChat() { + chatLines = new IChatComponent[0]; + } + + private PacketNoSpamChat(IChatComponent... lines) { + // this is guaranteed to be >1 length by accessing methods + this.chatLines = lines; + } + + @Override + public void toBytes(ByteBuf buf) { + buf.writeInt(chatLines.length); + for (IChatComponent c : chatLines) { + ByteBufUtils.writeUTF8String(buf, IChatComponent.Serializer.componentToJson(c)); + } + } + + @Override + public void fromBytes(ByteBuf buf) { + chatLines = new IChatComponent[buf.readInt()]; + for (int i = 0; i < chatLines.length; i++) { + chatLines[i] = IChatComponent.Serializer.jsonToComponent(ByteBufUtils.readUTF8String(buf)); + } + } + + public static class Handler implements IMessageHandler { + + @Override + public IMessage onMessage(PacketNoSpamChat message, MessageContext ctx) { + sendNoSpamMessages(message.chatLines); + return null; + } + } + } + + private static final int DELETION_ID = 8675309; + private static int lastAdded; + + private static void sendNoSpamMessages(IChatComponent[] messages) { + GuiNewChat chat = Minecraft.getMinecraft().ingameGUI.getChatGUI(); + for (int i = DELETION_ID + messages.length - 1; i <= lastAdded; i++) { + chat.deleteChatLine(i); + } + for (int i = 0; i < messages.length; i++) { + chat.printChatMessageWithOptionalDeletion(messages[i], DELETION_ID + i); + } + lastAdded = DELETION_ID + messages.length - 1; + } + + /** + * Returns a standard {@link ChatComponentText} for the given {@link String}. + * + * @param s + * The string to wrap. + * @return An {@link IChatComponent} containing the string. + */ + public static IChatComponent wrap(String s) { + return new ChatComponentText(s); + } + + /** + * @see #wrap(String) + */ + public static IChatComponent[] wrap(String... s) { + IChatComponent[] ret = new IChatComponent[s.length]; + for (int i = 0; i < ret.length; i++) { + ret[i] = wrap(s[i]); + } + return ret; + } + + /** + * Returns a translatable chat component for the given string and format args. + * + * @param s + * The string to format + * @param args + * The args to apply to the format + */ + public static IChatComponent wrapFormatted(String s, Object... args) { + return new ChatComponentTranslation(s, args); + } + + /** + * Simply sends the passed lines to the player in a chat message. + * + * @param player + * The player to send the chat to + * @param lines + * The lines to send + */ + public static void sendChat(EntityPlayer player, String... lines) { + sendChat(player, wrap(lines)); + } + + /** + * Localizes the lines before sending them. + * + * @see #sendChat(EntityPlayer, String...) + */ + public static void sendChatUnloc(EntityPlayer player, String... unlocLines) { + sendChat(player, TextHelper.localizeAll(unlocLines)); + } + + /** + * Sends all passed chat components to the player. + * + * @param player + * The player to send the chat lines to. + * @param lines + * The {@link IChatComponent chat components} to send.yes + */ + public static void sendChat(EntityPlayer player, IChatComponent... lines) { + for (IChatComponent c : lines) { + player.addChatComponentMessage(c); + } + } + + /** + * Localizes the strings before sending them. + * + * @see #sendNoSpamClient(String...) + */ + public static void sendNoSpamClientUnloc(String... unlocLines) { + sendNoSpamClient(TextHelper.localizeAll(unlocLines)); + } + + /** + * Same as {@link #sendNoSpamClient(IChatComponent...)}, but wraps the Strings + * automatically. + * + * @param lines + * The chat lines to send + * @see #wrap(String) + */ + public static void sendNoSpamClient(String... lines) { + sendNoSpamClient(wrap(lines)); + } + + /** + * Skips the packet sending, unsafe to call on servers. + * + * @see #sendNoSpam(EntityPlayerMP, IChatComponent...) + */ + public static void sendNoSpamClient(IChatComponent... lines) { + sendNoSpamMessages(lines); + } + + /** + * Localizes the strings before sending them. + * + * @see #sendNoSpam(EntityPlayer, String...) + */ + public static void sendNoSpamUnloc(EntityPlayer player, String... unlocLines) { + sendNoSpam(player, TextHelper.localizeAll(unlocLines)); + } + + /** + * @see #wrap(String) + * @see #sendNoSpam(EntityPlayer, IChatComponent...) + */ + public static void sendNoSpam(EntityPlayer player, String... lines) { + sendNoSpam(player, wrap(lines)); + } + + /** + * First checks if the player is instanceof {@link EntityPlayerMP} before + * casting. + * + * @see #sendNoSpam(EntityPlayerMP, IChatComponent...) + */ + public static void sendNoSpam(EntityPlayer player, IChatComponent... lines) { + if (player instanceof EntityPlayerMP) { + sendNoSpam((EntityPlayerMP) player, lines); + } + } + + /** + * Localizes the strings before sending them. + * + * @see #sendNoSpam(EntityPlayerMP, String...) + */ + public static void sendNoSpamUnloc(EntityPlayerMP player, String... unlocLines) { + sendNoSpam(player, TextHelper.localizeAll(unlocLines)); + } + + /** + * @see #wrap(String) + * @see #sendNoSpam(EntityPlayerMP, IChatComponent...) + */ + public static void sendNoSpam(EntityPlayerMP player, String... lines) { + sendNoSpam(player, wrap(lines)); + } + + /** + * Sends a chat message to the client, deleting past messages also sent via + * this method. + *

+ * Credit to RWTema for the idea + * + * @param player + * The player to send the chat message to + * @param lines + * The chat lines to send. + */ + public static void sendNoSpam(EntityPlayerMP player, IChatComponent... lines) { + if (lines.length > 0) + AlchemicalWizardryPacketHandler.INSTANCE.sendTo(new PacketNoSpamChat(lines), player); + } +} diff --git a/src/main/java/WayofTime/alchemicalWizardry/util/helper/TextHelper.java b/src/main/java/WayofTime/alchemicalWizardry/util/helper/TextHelper.java new file mode 100644 index 00000000..d27af864 --- /dev/null +++ b/src/main/java/WayofTime/alchemicalWizardry/util/helper/TextHelper.java @@ -0,0 +1,41 @@ +package WayofTime.alchemicalWizardry.util.helper; + +import com.google.common.collect.Lists; +import net.minecraft.util.StatCollector; +import scala.actors.threadpool.Arrays; + +import java.util.List; + +public class TextHelper { + + public static String getFormattedText(String string) { + return string.replaceAll("&", "\u00A7"); + } + + public static String localize(String key, Object ... format) { + return getFormattedText(StatCollector.translateToLocalFormatted(key, format)); + } + + /** + * Localizes all strings in a list, using the prefix. + * + * @param unloc + * The list of unlocalized strings. + * @return A list of localized versions of the passed strings. + */ + public static List localizeAll(List unloc) { + List ret = Lists.newArrayList(); + for (String s : unloc) + ret.add(localize(s)); + + return ret; + } + + public static String[] localizeAll(String... unloc) { + String[] ret = new String[unloc.length]; + for (int i = 0; i < ret.length; i++) + ret[i] = localize(unloc[i]); + + return ret; + } +} diff --git a/src/main/resources/assets/alchemicalwizardry/lang/en_US.lang b/src/main/resources/assets/alchemicalwizardry/lang/en_US.lang index ebf2482b..8d6fdbcd 100644 --- a/src/main/resources/assets/alchemicalwizardry/lang/en_US.lang +++ b/src/main/resources/assets/alchemicalwizardry/lang/en_US.lang @@ -62,8 +62,9 @@ tile.AlchemicalWizardry.fluid.lifeEssence.name=Life Essence # Tooltips tooltip.AlchemicalWizardry.orb.desc=Stores raw Life Essence tooltip.AlchemicalWizardry.orb.owner=Added by: %s -tooltip.AlchemicalWizardry.currentOwner=&oOwner: %s -tooltip.sigil.air.desc=I feel lighter already... -tooltip.sigil.bloodLight.desc=I see a light! -tooltip.sigil.compression.desc=Hands of Diamonds -tooltip.sigil.divination.desc=Peer into the soul \ No newline at end of file +tooltip.AlchemicalWizardry.currentOwner=Owner: %s +tooltip.AlchemicalWizardry.sigil.air.desc=&oI feel lighter already... +tooltip.AlchemicalWizardry.sigil.bloodLight.desc=&oI see a light! +tooltip.AlchemicalWizardry.sigil.compression.desc=&oHands of Diamonds +tooltip.AlchemicalWizardry.sigil.divination.desc=&oPeer into the soul +tooltip.AlchemicalWizardry.sigil.divination.currentEssence=Current Essence: %d LP \ No newline at end of file