public void run() {
   while (true) {
     LinkedList<PacketCallbackStruct> list = null;
     try {
       queuedPacketCallbacksLock.lock();
       try {
         queuedPacketCallbacksNotEmpty.await();
       } catch (Exception e) {
         Log.error(
             "RDPServer.PacketCallbackThread: queuedPacketCallbacksNotEmpty.await() caught exception "
                 + e.getMessage());
       }
       list = queuedPacketCallbacks;
       queuedPacketCallbacks = new LinkedList<PacketCallbackStruct>();
     } finally {
       queuedPacketCallbacksLock.unlock();
     }
     if (Log.loggingNet)
       Log.net("RDPServer.PacketCallbackThread: Got " + list.size() + " queued packets");
     for (PacketCallbackStruct pcs : list) {
       try {
         callbackProcessPacket(pcs.cb, pcs.con, pcs.packet);
       } catch (Exception e) {
         Log.exception("RDPServer.PacketCallbackThread: ", e);
       }
     }
   }
 }
 public void handleMessage(Message msg, int flags) {
   try {
     lock.lock();
     if (activated == false) return; // return true;
     if (msg.getMsgType() == Behavior.MSG_TYPE_COMMAND) {
       Behavior.CommandMessage cmdMsg = (Behavior.CommandMessage) msg;
       String command = cmdMsg.getCmd();
       // Remove the executor, because anything we do will
       // end the current execution.
       Engine.getExecutor().remove(this);
       if (Log.loggingDebug)
         Log.debug(
             "BaseBehavior.onMessage: command = "
                 + command
                 + "; oid = "
                 + obj.getOid()
                 + "; name "
                 + obj.getName());
       if (command.equals(MSG_CMD_TYPE_GOTO)) {
         GotoCommandMessage gotoMsg = (GotoCommandMessage) msg;
         Point destination = gotoMsg.getDestination();
         mode = MSG_CMD_TYPE_GOTO;
         roamingBehavior = true;
         gotoSetup(destination, gotoMsg.getSpeed());
       } else if (command.equals(MSG_CMD_TYPE_STOP)) {
         followTarget = null;
         pathState.clear();
         obj.getWorldNode().setDir(new MVVector(0, 0, 0));
         obj.updateWorldNode();
         mode = MSG_CMD_TYPE_STOP;
         // If roamingBehavior is set, that means that we
         // used formerly had a roaming behavior, so send
         // an ArrivedEventMessage so that the other
         // behavior starts up again.
         if (roamingBehavior) {
           try {
             Engine.getAgent().sendBroadcast(new ArrivedEventMessage(obj));
           } catch (Exception e) {
             Log.error(
                 "BaseBehavior.onMessage: Error sending ArrivedEventMessage, error was '"
                     + e.getMessage()
                     + "'");
             throw new RuntimeException(e);
           }
         }
       } else if (command.equals(BaseBehavior.MSG_CMD_TYPE_FOLLOW)) {
         FollowCommandMessage followMsg = (FollowCommandMessage) msg;
         mode = MSG_CMD_TYPE_FOLLOW;
         followSetup(followMsg.getTarget(), followMsg.getSpeed());
       }
     } else if (msg.getMsgType() == WorldManagerClient.MSG_TYPE_MOB_PATH_CORRECTION) {
       Engine.getExecutor().remove(this);
       interpolatePath();
       interpolatingPath = false;
     }
     // return true;
   } finally {
     lock.unlock();
   }
 }
 static void callbackProcessPacket(
     ClientConnection.MessageCallback pcb, ClientConnection clientCon, RDPPacket packet) {
   if (packet.isNul()) {
     return;
   }
   byte[] data = packet.getData();
   MVByteBuffer buf = new MVByteBuffer(data);
   RDPConnection con = (RDPConnection) clientCon;
   // If this is a multiple-message message . . .
   if (buf.getLong() == -1 && buf.getInt() == RDPConnection.aggregatedMsgId) {
     con.aggregatedReceives++;
     PacketAggregator.allAggregatedReceives++;
     // Get the count of sub buffers
     int size = buf.getInt();
     con.receivedMessagesAggregated += size;
     PacketAggregator.allReceivedMessagesAggregated += size;
     if (Log.loggingNet)
       Log.net(
           "RDPServer.callbackProcessPacket: processing aggregated message with "
               + size
               + " submessages");
     MVByteBuffer subBuf = null;
     for (int i = 0; i < size; i++) {
       try {
         subBuf = buf.getByteBuffer();
       } catch (Exception e) {
         Log.error("In CallbackThread, error getting aggregated subbuffer: " + e.getMessage());
       }
       if (subBuf != null) pcb.processPacket(con, subBuf);
     }
   } else {
     con.unaggregatedReceives++;
     PacketAggregator.allUnaggregatedReceives++;
     buf.rewind();
     pcb.processPacket(con, buf);
   }
 }