Commit Graph

814 Commits

Author SHA1 Message Date
Kristian S. Stangeland
e56c0fec00 A possible fix for a rare but game-breaking deadlock.
Calling remove() in the main thread will block the main thread, which 
may lead to a deadlock:
    http://pastebin.com/L3SBVKzp

ProtocolLib executes this close() method through a PlayerQuitEvent in 
the main thread, which has implicitly aquired a lock on 
SimplePluginManager (see SimplePluginManager.callEvent(Event)). 
Unfortunately, the remove() method will schedule the removal on one of 
the Netty worker threads if it's called from a different thread, 
blocking until the removal has been confirmed.
 
This is bad enough (Rule #1: Don't block the main thread), but the real 
trouble starts if the same worker thread happens to be handling a server
ping connection when this removal task is scheduled. In that case, it 
may attempt to invoke an asynchronous ServerPingEvent 
(see PacketStatusListener) using SimplePluginManager.callEvent(). But, 
since this has already been locked by the main thread, we end up with a 
deadlock. The main thread is waiting for the worker thread to process 
the task, and the worker thread is waiting for the main thread to 
finish executing PlayerQuitEvent.

TLDR: Concurrenty is hard.
2013-12-24 02:15:22 +01:00
Kristian S. Stangeland
16dd2d5d1b Add support for legacy mod packet IDs (such as 211). May fix issue #32 2013-12-22 20:10:51 +01:00
Kristian S. Stangeland
db8d08f602 Add a mechanism for printing debug reports. 2013-12-22 17:31:31 +01:00
Kristian S. Stangeland
d71bea9f8a Don't pass NULL to ConcurrentHashMap when reading or removing.
May fix issue 181 on BukkitDev.
2013-12-22 01:01:35 +01:00
Kristian S. Stangeland
5267e73311 Adding TinyProtocol to the example directory. 2013-12-21 19:37:02 +01:00
Kristian S. Stangeland
d62955dc71 Moving ItemDisguise to an examples folder. 2013-12-21 19:17:06 +01:00
Kristian S. Stangeland
af58dd8d03 Add the ability to look up PacketType from class. 2013-12-19 04:45:30 +01:00
Kristian S. Stangeland
acea92ef5c Switch to using PacketType in the built-in commands.
The format is now as follows:
    /packet add server play 0-255.
    
It may be possible to look up packet types by name later.
2013-12-19 02:17:06 +01:00
Kristian S. Stangeland
6bd8bd2ca2 Handle plugin reloading properly, uninjecting all player channels.
This should prevent any crashes if the plugin is reloaded during 
a player login.
2013-12-17 16:45:01 +01:00
Kristian S. Stangeland
5805150d8c Call the updated player instance in the temporary player.
This allows us to provide additional information to our PacketEvent 
(mostly OfflinePlayer information), without sacrificing sendMessage() 
or getAddress(), which doesn't work in CraftPlayer during login.
2013-12-17 11:53:26 +01:00
Kristian S. Stangeland
9d972b90ac Update the player instance during PlayerLoginEvent as well.
This ensures that we at least have an OfflinePlayer when certain
packets are intercepted, instead of the TemporaryPlayer created 
by ProtocolLib.
2013-12-17 11:07:44 +01:00
Kristian S. Stangeland
936e0f0e82 Actually fix the ServerPing wrapper. 2013-12-15 22:54:59 +01:00
Kristian S. Stangeland
aedd97dfef Ensure ProtocolLib functions in 1.6.4 and below. 2013-12-14 19:17:48 +01:00
Kristian S. Stangeland
96f24167bb Don't synchronize with the main thread when registering async listeners 2013-12-14 18:08:08 +01:00
Kristian S. Stangeland
88a2385b1e Set the correct option when calling optionAsync(). 2013-12-14 17:49:51 +01:00
Kristian S. Stangeland
f41efdec60 Make it possible to modify the player list in the ping packet. 2013-12-14 17:35:29 +01:00
Kristian S. Stangeland
a6f4aaa09a Fix a race condition we created while fixing another race condition.
They're everywhere.
2013-12-14 16:32:12 +01:00
Kristian S. Stangeland
b52ea72903 Don't override the network manager list unnecessarily. 2013-12-14 05:02:43 +01:00
Kristian S. Stangeland
85d415de7c Correct a missing noEntryValue in Spigot.
Again.
2013-12-14 04:39:12 +01:00
Kristian S. Stangeland
9b349299a0 Significantly reduce the possibility of a race condition.
The vanilla server bootstrap (ServerConnectionChannel) is executed 
asynchronously when a new channel object has been registered in an event
loop, much before it is ready to accept a new client connection. It is 
here the whole channel handler pipeline is set up, along with a 
NetworkManager responsible for reading and writing packets. 

The trouble starts when the bootstrap class adds the created 
NetworkManager to a list (f) of managers in  ServerConnection. This list
is regularly inspected by the main thread (in order to process packets 
on the main thread) and includes a clean up procedure 
(ServerConnection#61) in case it detects a disconnected network manager.

Unfortunately, the network manager IS considered disconnected for a 
moment when its added to the list, so the main thread MAY end up 
getting to the network manager before Netty has connected the channel.
This is still very rare under normal circumstances, but because 
ProtocolLib does a lot of initial processing in the channel handler, the
asynchronous thread gets hold up for a long while the first time a 
player connects to the server, allowing the main thread sufficient time 
to catch up and evict the network manager.

The partial solution here is to synchronize on the network manager list,
stopping the main thread from processing network managers when we are 
preparing our new connection. 

But I suspect the best solution would be to correct the root of the 
problem, and correct the race condition in the server itself. This 
could be done by only adding the network manager when the channel is
active
(see ChannelInboundHandler.channelActive).
2013-12-14 04:05:12 +01:00
Kristian S. Stangeland
c568481da3 Correctly clean up the old injection handler. 2013-12-13 21:34:03 +01:00
Kristian S. Stangeland
74d83b3ed6 Add support for the latest build of Spigot.
See commit 8b2b731ea5deda5607058849f2ca9ec2e3bf003f in SpigotMC/
Spigot-Server.
2013-12-13 20:35:00 +01:00
Kristian S. Stangeland
e7273385cf Merge pull request #27 from ttaylorr/master
Update Readme.md to include Java and YAML syntax highlighting
2013-12-12 21:57:41 -08:00
Taylor Blau
517eeb9f3f Update Readme.md to include Java and YAML syntax highlighting 2013-12-12 12:02:57 -05:00
Kristian S. Stangeland
bec5706e33 Merge pull request #26 from YukonAppleGeek/master
Fix ConcurrentPlayerMap to use SafeCacheBuilder
2013-12-11 03:33:14 -08:00
YukonAppleGeek
d166baf721 Fix ConcurrentPlayerMap to use SafeCacheBuilder 2013-12-10 19:18:58 -08:00
Kristian S. Stangeland
922fb94804 Added support for cloing ServerPing packets. 2013-12-11 03:55:25 +01:00
Kristian S. Stangeland
ee53fc0d5f Starting to add unit tests for PacketType. 2013-12-10 22:57:43 +01:00
Kristian S. Stangeland
17a5b06577 Adding a new ChunkCoordIntPair wrapper. 2013-12-10 22:35:29 +01:00
Kristian S. Stangeland
745a0846ea Bumping to 3.0.2-SNAPSHOT 2013-12-10 19:43:24 +01:00
Kristian S. Stangeland
726374e7f5 Bumping to 3.0.1 2013-12-10 16:38:33 +01:00
Kristian S. Stangeland
9a07979733 Ensure the new style listener gets the correct GamePhase in 1.6.4.
Also adding in a test image for our ServerPing wrapper.
2013-12-10 16:38:23 +01:00
Kristian S. Stangeland
c23e5c98f8 Release of 3.0.0 2013-12-10 16:27:46 +01:00
Kristian S. Stangeland
ab0ef6d37c A couple of small last minute bug fixes. 2013-12-10 16:27:30 +01:00
Kristian S. Stangeland
9b0d4294cb Adding a converter for block fields. 2013-12-10 13:21:31 +01:00
Kristian S. Stangeland
c3ae43c75f Added wrappers for every enum in the packets. 2013-12-10 12:17:15 +01:00
Kristian S. Stangeland
bdc739317b Added a wrapper for ServerPing fields. 2013-12-09 23:09:08 +01:00
Kristian S. Stangeland
e8759d0b72 Refactor the wrapper classes so they inherit from a common class. 2013-12-09 17:19:07 +01:00
Kristian S. Stangeland
143ed2ff02 Moving accessor methods to a separate "Accessors" factory class. 2013-12-09 12:03:30 +01:00
Kristian S. Stangeland
b70c7fa775 Update the player reference (from TemporaryPlayer) as soon as possible. 2013-12-09 00:02:44 +01:00
Kristian S. Stangeland
154d73ae51 Added the ability to read and modify server-side chat messages.
This introduces the new WrappedChatComponent class, which can be 
accessed through PacketContainer.getChatComponents().
2013-12-08 23:45:35 +01:00
Kristian S. Stangeland
1aaf272878 Don't attempt to inject closed channels. Fixes issue #23 2013-12-08 19:50:59 +01:00
Kristian S. Stangeland
20524c1c3c Don't catch any exceptions in the underlying decoder in ProtocolLib. 2013-12-08 19:44:38 +01:00
Kristian S. Stangeland
feae8dd400 Add some debug information to the mssing decoder/encoder exception. 2013-12-08 14:37:50 +01:00
Kristian S. Stangeland
be95fbc430 Only patch the encoder if it was found. 2013-12-08 14:34:55 +01:00
Kristian S. Stangeland
b947ed1193 Synchronize before attempting to modify thread-safe fields.
We also re-wrap proxied lists in Collections.synchronizedList(). May 
fix ticket #157 on BukkitDev.
2013-12-08 07:47:25 +01:00
Kristian S. Stangeland
a74d2ca8bc Prevent cancelled packets from been cancelled over and over again. 2013-12-08 00:51:46 +01:00
Kristian S. Stangeland
fa55e2cb27 Remove any references to Guava in Minecraft. 2013-12-07 19:52:02 +01:00
Kristian S. Stangeland
029b19d94c Run onPacketSending() on the main thread if not otherwise stated.
Now onPacketSending() should only be executed on the main thread, 
unless the listener has specified ListenerOption.ASYNC. This option
is off by default, however.

This ensures that older plugins that assume onPacketSending() doesn't
crash the server. They SHOULD use the ASYNC option if possible, as
this explicit synchronization will slow down the STATUS 
protocol somewhat.
2013-12-07 19:14:03 +01:00
Kristian S. Stangeland
4d11cfa8e8 It is an error to pass an empty type array. 2013-12-07 17:39:06 +01:00