In one case, closing a client while it was already closing on
another thread (say because the server is shutting down and
you are exiting at the same time) would cause an NPE if you
caught it just right. Now the thing checking and setting the
connection state is synchronized to avoid the race.
The other more subtle one was caused by sending out the 'connected'
event before the services were all started. It's quite common for
application code to start doing stuff when the 'connected' event comes
through like sending messages and stuff. If the services hadn't been
fully started then even the serializers might not be registered yet...
and that = bad.
Now the client doesn't send the 'connected' event until the services
are started. This should be safe and one could argue that it's more
'correct' but there is some small chance that it screws up certain
use-cases. However, if a real use-case comes up that's not solved by
a service then we can always add some kind of prestarted event.
Sometimes, when the BetterCharacterControl is not moving, it flickers due it physics being always active. The reason for it being always active is that on the prePhysicsTick method it always set the rigidBody's linear velocity (and the method PhysicsRigidBody.setLinearVelocity(Vector3f) reactivates the physics each time is called).
The fix consist on just comparing if the current velocity and the setting one aren't the same and, thus, not setting it (using ZERO_TOLERANCE instead 0 to best results).
used to either watch traffic or debug serialization
issues, etc..
Went ahead and instrumented the service manager while
I was at it... and fixed a potential NPE in the AbstractService's
toString() method.
Fixed a bug in the DefaultClient where it couldn't be shutdown
if attempted before the services had been started.
(And I do realize I have the benefit of analyzing the aftermath, hindsight is 20/20, etc.) Included a big long comment about the right way to implement this optimization.
a client are running on the same instance. This should cover
99% of the cases where this would come up... and the others
can't really use this service anyway and so must disable it.
already registered. This avoids one of the issues of a client
running in the same JVM as a server that already registered these
classes. This was the easy fix.
same JVM. a) this makes a good example of self-hosted style
LAN multiplayer games, and b) it causes the serialization bug
to show up so I can fix it. (Already fixed it and that commit
will be next... it's almost like TDD.)
to make a more complete example. It should now be relatively
well behaved through all normal shutdown paths.
Modified the server to gracefully close the client connections
when shutting down rather than just letting the sockets die.