private static void RemoveRequest(TransferMessage msg)
 {
     // search the queue to see if the message is still being processed
     foreach (QueuedMessage q in ServerRequests)
     {
         if (q.MessageIn == msg)
         {
             q.Remove = true;
             break;
         }
     }
 }
 public static AuthEntry GetAuthEntry(TransferMessage msg)
 {
     // go through the auth list and find the corresponding auth entry for the message
     foreach (AuthEntry a in AuthList)
     {
         // confirm authentication id match and accesslevel
         if (a.AuthenticationID == msg.AuthenticationID)
         {
             return(a);
         }
     }
     return(null);
 }
        private static TransferMessage ServerRequestResult(TransferMessage msg)
        {
            // find the queue entry for the message and return the result
            foreach (QueuedMessage q in ServerRequests)
            {
                if (q.MessageIn == msg)
                {
                    return(q.MessageOut);
                }
            }

            return(null);
        }
        private static bool ServerRequestProcessed(TransferMessage msg)
        {
            // search the queue to see if the message is still being processed
            foreach (QueuedMessage q in ServerRequests)
            {
                if (q.MessageIn == msg && !q.Completed)
                {
                    return(false);
                }
            }

            // return true if the message is no longer on the queue or it there and has been completed
            return(true);
        }
        private static string Authenticate(TransferMessage msg)
        {
            if (msg == null)
            {
                // unknown error
                return("Empty message");
            }

            // check to make sure that an authentication entry for this message is on the authentication list
            ArrayList removelist = new ArrayList();

            // default no authentication status
            string errorstatus = "Renew your Session Authentication";

            foreach (AuthEntry a in AuthList)
            {
                // check for entry expiration
                if (a.Timestamp < DateTime.Now - AuthenticationLifetime)
                {
                    removelist.Add(a);
                    continue;
                }

                // confirm authentication id match and accesslevel
                if (a.AuthenticationID == msg.AuthenticationID)
                {
                    // confirm required accesslevel on the msg is below the access level of the auth entry
                    if (a.Level < GetAccessLevel(msg))
                    {
                        // authenticated but insufficient access
                        errorstatus = "Insufficient Access Level";
                    }
                    else
                    {
                        // authenticated and access confirmed
                        errorstatus = null;
                    }
                }
            }

            // clean up the list
            foreach (AuthEntry a in removelist)
            {
                AuthList.Remove(a);
            }

            return(errorstatus);
        }
        private static AccessLevel GetAccessLevel(TransferMessage msg)
        {
            // default accesslevel is admin
            AccessLevel level = AccessLevel.Administrator;

            MethodInfo minfo = msg.GetType().GetMethod("ProcessMessage");

            object [] attr = minfo.GetCustomAttributes(typeof(TransferAccess), false);
            if (attr != null)
            {
                for (int i = 0; i < attr.Length; i++)
                {
                    if (((TransferAccess)attr[i]).Level < level)
                    {
                        level = ((TransferAccess)attr[i]).Level;
                    }
                }
            }

            return(level);
        }
 private static void AddRequest(TransferMessage msg)
 {
     ServerRequests.Add(new QueuedMessage(msg));
 }
 public QueuedMessage(TransferMessage msg)
 {
     MessageIn = msg;
     Completed = false;
 }
        // process incoming messages
        public static byte[] RemoteMessaging_ReceiveMessage(string typeName, byte[] data, out string answerType)
        {
            answerType = null;

            TransferMessage inMsg  = null;
            TransferMessage outMsg = null;

            Type type = Type.GetType(typeName);

            if (type != null)
            {
                inMsg = TransferMessage.Decompress(data, type);

                if (inMsg != null)
                {
                    // check message authentication
                    string authstatus = Authenticate(inMsg);

                    if (authstatus != null)
                    {
                        outMsg = new ErrorMessage(String.Format("Message request refused. {0}", authstatus));
                    }
                    else
                    {
                        // if the message has been tagged for execution in the RunUO server thread
                        // then queue it up and wait for the response
                        if (inMsg.UseMainThread)
                        {
                            AddRequest(inMsg);
                            while (!ServerRequestProcessed(inMsg))
                            {
                                Thread.Sleep(100);
                            }
                            outMsg = ServerRequestResult(inMsg);
                            RemoveRequest(inMsg);
                        }
                        else
                        {
                            // otherwise just run it in the current thread
                            try
                            {
                                // process the message
                                outMsg = inMsg.ProcessMessage();
                            }
                            catch (Exception e)
                            {
                                outMsg = new ErrorMessage(String.Format("Error processing outgoing message. {0}", e.Message));
                            }
                        }
                    }
                }
                else
                {
                    outMsg = new ErrorMessage("Error decompressing incoming message. No zero arg msg constructor? DEBUG: {0} {1}", typeName, data.Length.ToString());
                }
            }
            else
            {
                outMsg = null;
            }

            if (outMsg != null)
            {
                answerType = outMsg.GetType().FullName;
                byte[] result = outMsg.Compress();

                return(result);
            }
            else
            {
                answerType = null;
                return(null);
            }
        }