@Override protected void cleanHook() { if (serverHandlerRef != null && serverHandlerRef.isCurrentSet()) { writer.copyTo( serverHandlerRef.getValue(), serverHandlerRef.getOldValue(), serverHandler.getClass()); serverHandlerRef.revertValue(); try { if (getNetHandler() != null) { // Restore packet listener try { FieldUtils.writeField( netHandlerField, networkManager, serverHandlerRef.getOldValue(), true); } catch (IllegalAccessException e) { // Oh well e.printStackTrace(); } } } catch (IllegalAccessException e) { e.printStackTrace(); } // Prevent the PlayerQuitEvent from being sent twice if (hasDisconnected) { setDisconnect(serverHandlerRef.getValue(), true); } } serverInjection.revertServerHandler(serverHandler); }
private boolean tryInjectManager() { Class<?> serverClass = serverHandler.getClass(); Enhancer ex = new Enhancer(); Callback sendPacketCallback = new MethodInterceptor() { @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { Object packet = args[0]; if (packet != null) { packet = handlePacketSending(packet); // A NULL packet indicate cancelling if (packet != null) args[0] = packet; else return null; } // Call the method directly return proxy.invokeSuper(obj, args); }; }; Callback noOpCallback = NoOp.INSTANCE; // Share callback filter - that way, we avoid generating a new class for // every logged in player. if (callbackFilter == null) { callbackFilter = new CallbackFilter() { @Override public int accept(Method method) { if (method.equals(sendPacketMethod)) return 0; else return 1; } }; } ex.setClassLoader(classLoader); ex.setSuperclass(serverClass); ex.setCallbacks(new Callback[] {sendPacketCallback, noOpCallback}); ex.setCallbackFilter(callbackFilter); // Find the Minecraft NetServerHandler superclass Class<?> minecraftSuperClass = getFirstMinecraftSuperClass(serverHandler.getClass()); ExistingGenerator generator = ExistingGenerator.fromObjectFields(serverHandler, minecraftSuperClass); DefaultInstances serverInstances = null; // Maybe the proxy instance can help? Object proxyInstance = getProxyServerHandler(); // Use the existing server proxy when we create one if (proxyInstance != null && proxyInstance != serverHandler) { serverInstances = DefaultInstances.fromArray( generator, ExistingGenerator.fromObjectArray(new Object[] {proxyInstance})); } else { serverInstances = DefaultInstances.fromArray(generator); } serverInstances.setNonNull(true); serverInstances.setMaximumRecursion(1); Object proxyObject = serverInstances.forEnhancer(ex).getDefault(serverClass); // Inject it now if (proxyObject != null) { // This will be done by InjectedServerConnection instead // copyTo(serverHandler, proxyObject); serverInjection.replaceServerHandler(serverHandler, proxyObject); serverHandlerRef.setValue(proxyObject); return true; } else { return false; } }