From 1710ef343b298ed19102405ee14216fa3e00e86b Mon Sep 17 00:00:00 2001 From: "Kristian S. Stangeland" Date: Thu, 13 Sep 2012 16:08:41 +0200 Subject: [PATCH] Syncronize before hacking into the packet list. In addition, copy over any unprocessed packets into the new list. When we're done, we'll also clean up properly by copying over any remaining packets. --- .../protocol/injector/PlayerInjector.java | 90 +++++++++++++------ 1 file changed, 62 insertions(+), 28 deletions(-) diff --git a/ProtocolLib/src/com/comphenix/protocol/injector/PlayerInjector.java b/ProtocolLib/src/com/comphenix/protocol/injector/PlayerInjector.java index 2982dda5..eaf01150 100644 --- a/ProtocolLib/src/com/comphenix/protocol/injector/PlayerInjector.java +++ b/ProtocolLib/src/com/comphenix/protocol/injector/PlayerInjector.java @@ -214,38 +214,54 @@ class PlayerInjector { for (Field field : list.getFields()) { VolatileField overwriter = new VolatileField(field, networkManager, true); - overwriter.setValue(Collections.synchronizedList(new ArrayList() { - @Override - public boolean add(Packet packet) { - - Packet result = null; - - // Check for fake packets and ignored packets - if (packet instanceof FakePacket) { - return true; - } else if (ignoredPackets.contains(packet)) { - ignoredPackets.remove(packet); - } else { - result = handlePacketRecieved(packet); - } - - // A NULL packet indicate cancelling - try { - if (result != null) { - super.add(result); + @SuppressWarnings("unchecked") + List minecraftList = (List) overwriter.getOldValue(); + + synchronized(minecraftList) { + // The list we'll be inserting + List hackedList = new ArrayList() { + @Override + public boolean add(Packet packet) { + + Packet result = null; + + // Check for fake packets and ignored packets + if (packet instanceof FakePacket) { + return true; + } else if (ignoredPackets.contains(packet)) { + ignoredPackets.remove(packet); } else { - // We'll use the FakePacket marker instead of preventing the filters - sendServerPacket(createNegativePacket(packet), true); + result = handlePacketRecieved(packet); } - // Collection.add contract - return true; - - } catch (InvocationTargetException e) { - throw new RuntimeException("Reverting cancelled packet failed.", e.getTargetException()); + // A NULL packet indicate cancelling + try { + if (result != null) { + super.add(result); + } else { + // We'll use the FakePacket marker instead of preventing the filters + sendServerPacket(createNegativePacket(packet), true); + } + + // Collection.add contract + return true; + + } catch (InvocationTargetException e) { + throw new RuntimeException("Reverting cancelled packet failed.", e.getTargetException()); + } } + }; + + // Add every previously stored packet + for (Packet packet : minecraftList) { + hackedList.add(packet); } - })); + + // Don' keep stale packets around + minecraftList.clear(); + overwriter.setValue(Collections.synchronizedList(hackedList)); + } + overridenLists.add(overwriter); } } @@ -341,10 +357,28 @@ class PlayerInjector { } } + @SuppressWarnings("unchecked") public void cleanupAll() { // Clean up for (VolatileField overriden : overridenLists) { - overriden.revertValue(); + List minecraftList = (List) overriden.getOldValue(); + List hacketList = (List) overriden.getValue(); + + if (minecraftList == hacketList) { + return; + } + + // Get a lock before we modify the list + synchronized(hacketList) { + try { + // Copy over current packets + for (Packet packet : (List) overriden.getValue()) { + minecraftList.add(packet); + } + } finally { + overriden.revertValue(); + } + } } overridenLists.clear(); }