Esempio n. 1
0
        public void set_auth(UUID client, int level, string[] additionalArgs,
                             Destinations source,
                             UUID agentKey, string agentName)
        {
            MainConfiguration mem = MainConfiguration.Instance;

            BotSession.Instance.Logger.info(log: "Existing Admins: " + mem.BotAdmins.Count.ToString());
            if (level < 5 && mem.BotAdmins.Count > 0)
            {
                MHE(source, UUID.Zero, "Authorization failure. You do not have the proper permission level");
                //grid.Self.Chat(, 0, ChatType.Normal);
                return;
            }
            MHE(source, UUID.Zero, "Authorizing..");
            //grid.Self.Chat("Authorizing user..", 0, ChatType.Normal);
            UUID user     = UUID.Parse(additionalArgs[0]);
            int  NewLevel = int.Parse(additionalArgs[1]);

            if (NewLevel <= 0)
            {
                mem.BotAdmins.Remove(user);
                MHE(Destinations.DEST_AGENT, user, "Your access to the main bot has been removed. You will still have access to any command that does not require a access level higher than 0");
                MHE(Destinations.DEST_LOCAL, UUID.Zero, "Access Removed");
                mem.Save();
                return;
            }

            if (NewLevel > level && mem.BotAdmins.Count > 0)
            {
                MHE(source, client, "Cannot authorize higher than your own level");
                return;
            }


            if (!mem.BotAdmins.ContainsKey(user))
            {
                mem.BotAdmins.Add(user, NewLevel);
            }
            else
            {
                mem.BotAdmins[user] = NewLevel;
            }
            MHE(Destinations.DEST_AGENT, user, "You have been granted authorization level " + NewLevel.ToString());
            MHE(source, UUID.Zero, "Authorized");
            mem.Save();
        }
Esempio n. 2
0
        public void Load()
        {
            if (File.Exists("Main.json"))
            {
                File.Move("Main.json", Path.Combine("BotData", "Main.json"));
            }
            inst = new MainConfiguration();
            SerialManager sm = new SerialManager();

            try
            {
                inst = sm.Read <MainConfiguration>("Main");
            }
            catch (FileNotFoundException e)
            {
                BotSession.Instance.Logger.info(true, "Main.json does not exist");
            }
        }
Esempio n. 3
0
        public static void onIMEvent(object sender, InstantMessageEventArgs e)
        {
            if (e.IM.FromAgentID == client.Self.AgentID)
            {
                return;
            }

            MainConfiguration mem = MainConfiguration.Instance;

            UUID SentBy = e.IM.FromAgentID;
            int  Level  = 0;

            if (mem.BotAdmins.ContainsKey(SentBy))
            {
                Level = mem.BotAdmins[SentBy];
            }
            if (e.IM.Dialog == InstantMessageDialog.GroupInvitation)
            {
                if (Level >= 4)
                {
                    client.Self.GroupInviteRespond(e.IM.FromAgentID, e.IM.IMSessionID, true);
                }
                else
                {
                    client.Self.GroupInviteRespond(e.IM.FromAgentID, e.IM.IMSessionID, false);
                    MH(Destinations.DEST_AGENT, e.IM.FromAgentID, "You lack the proper permissions to perform this action");
                }
            }
            else if (e.IM.Dialog == InstantMessageDialog.FriendshipOffered)
            {
                if (Level >= 4)
                {
                    client.Friends.AcceptFriendship(e.IM.FromAgentID, e.IM.IMSessionID);
                    MH(Destinations.DEST_AGENT, e.IM.FromAgentID, "Welcome to my friends list!");
                }
                else
                {
                    MH(Destinations.DEST_AGENT, e.IM.FromAgentID, "You lack proper permission");
                }
            }
            else if (e.IM.Dialog == InstantMessageDialog.RequestTeleport)
            {
                if (Level >= 3)
                {
                    client.Self.TeleportLureRespond(e.IM.FromAgentID, e.IM.IMSessionID, true);
                    MH(Destinations.DEST_AGENT, e.IM.FromAgentID, "Teleporting...");
                }
                else
                {
                    client.Self.TeleportLureRespond(e.IM.FromAgentID, e.IM.IMSessionID, false);
                    MH(Destinations.DEST_AGENT, e.IM.FromAgentID, "You lack permission");
                }
            }
            else if (e.IM.Dialog == InstantMessageDialog.MessageFromObject)
            {
                if (Level >= 5)
                {
                    // For this to work the object must have been granted auth!!!!!
                    Dictionary <string, string> args = new Dictionary <string, string>();
                    args.Add("type", "im");
                    args.Add("source", "obj");
                    args.Add("request", e.IM.Message);
                    args.Add("from", e.IM.FromAgentID.ToString());
                    args.Add("from_sess", e.IM.IMSessionID.ToString());
                    args.Add("fromName", e.IM.FromAgentName);
                    passArguments(JsonConvert.SerializeObject(args));
                }
                else
                {
                    // If auth is insufficient, ignore it.
                }
            }
            else if (e.IM.Dialog == InstantMessageDialog.MessageFromAgent || e.IM.Dialog == InstantMessageDialog.SessionSend)
            {
                //if (e.IM.Message.Substring(0, 1) != "!") return;
                string msgs = e.IM.Message;
                //string msgs = e.IM.Message.Substring(1);
                // Perform a few tests before live deployment
                if (IsGroup(e.IM.IMSessionID))
                {
                    Dictionary <string, string> args = new Dictionary <string, string>();
                    args.Add("type", "group");
                    args.Add("source", "agent");
                    args.Add("request", msgs);
                    args.Add("from", e.IM.FromAgentID.ToString());
                    args.Add("from_sess", e.IM.IMSessionID.ToString());
                    args.Add("fromName", e.IM.FromAgentName);
                    passArguments(JsonConvert.SerializeObject(args));
                }
                else
                {
                    Dictionary <string, string> args = new Dictionary <string, string>();
                    args.Add("type", "im");
                    args.Add("source", "agent");
                    args.Add("request", msgs);
                    args.Add("from", e.IM.FromAgentID.ToString());
                    args.Add("from_sess", "");
                    args.Add("fromName", e.IM.FromAgentName);
                    passArguments(JsonConvert.SerializeObject(args));
                }
            }
        }
Esempio n. 4
0
        public static unsafe void Main(string[] args)
        {
            File.WriteAllText("PID.lock", Process.GetCurrentProcess().Id.ToString());

            if (!Directory.Exists("BotData"))
            {
                Directory.CreateDirectory("BotData");
            }


            Console.WriteLine("Setting up Main Configuration");
            Log = new Logger("BotCore5");
            BotSession.Instance.Logger     = Log;
            BotSession.Instance.LaunchTime = DateTime.Now;
            ZHash.Instance.NewKey();
            ZHash.Instance.Key = "Test";
            Console.WriteLine("ZHash (Test): " + ZHash.Instance.Key);
            MainConfiguration.Instance.Load();
            MainConfiguration conf = MainConfiguration.Instance;

            //MasterObjectCaches = ObjectCaches.Instance;

            if (args.Length == 2)
            {
                // Check if this is activation command
                if (args[0] == "-a")
                {
                    MainConfiguration.Instance.ActivationCode = args[1];
                    MainConfiguration.Instance.Save();
                    return;
                }
            }
            else if (args.Length == 4)
            {
                if (args[0] == "-l")
                {
                    MainConfiguration.Instance.first    = args[1];
                    MainConfiguration.Instance.last     = args[2];
                    MainConfiguration.Instance.password = args[3];
                    MainConfiguration.Instance.Save();
                    return;
                }
            }
            // Initiate bot login
            // Main thread must be caught in the bot loop so it does not terminate early.
            // Other programs may hook into the bot to control it

            /*
             * if (conf.ActivationCode != "")
             * {
             *
             *  License L = new License();
             *  L.NewKey();
             *  L.InitUniqueMachine();
             *  L.Key = conf.ActivationCode;
             *  License def = new License();
             *  def.NewKey();
             *  def.InitUniqueMachine();
             *  string Reply;
             *  HttpWebRequest _request = (HttpWebRequest)WebRequest.Create("http://bak.cloud.xsinode.net/act_handle.php?r=verify&act=" + conf.ActivationCode + "&LIC=" + L.Key + "&mac="+def.Key);
             *  using (HttpWebResponse response = (HttpWebResponse)_request.GetResponse())
             *  using (Stream str = response.GetResponseStream())
             *  using (StreamReader sr = new StreamReader(str))
             *  {
             *      Reply = sr.ReadToEnd();
             *  }
             *
             *  string[] ReplyData = Reply.Split('|');
             *  if(ReplyData[0] == "deny")
             *  {
             *      WebClient wc = new WebClient();
             *      if (File.Exists("Activator.exe")) File.Delete("Activator.exe");
             *      wc.DownloadFile("http://bak.cloud.xsinode.net/znibot/Activator.exe", "Activator.exe");
             *      int E_CODE = -1;
             *      if (ReplyData[1] == "TOO_MANY") E_CODE = 90;
             *      else if (ReplyData[1] == "EXPIRED") E_CODE = 32;
             *      else if (ReplyData[1] == "INVALID") E_CODE = 100;
             *      else E_CODE = 55;
             *
             *      string batchContents = "@echo off" +
             *          "\ntimeout 5\n" +
             *          "cd " + Directory.GetCurrentDirectory()+"\n" +
             *          "Activator.exe -d -m " + E_CODE.ToString();
             *      File.WriteAllText("denyAct.bat", batchContents);
             *      Process p = Process.Start("denyAct.bat");
             *
             *      return;
             *
             *  } else if(ReplyData[0] == "allow")
             *  {
             *      // Handle expiry on server!
             *      // Activate now
             *  }
             *  else
             *  {
             *
             *      WebClient wc = new WebClient();
             *      if (File.Exists("Activator.exe")) File.Delete("Activator.exe");
             *      wc.DownloadFile("http://bak.cloud.xsinode.net/znibot/Activator.exe", "Activator.exe");
             *      int E_CODE = 55; // Unknown reply. Activator will not permit logging in until the server can be reached safely.
             *
             *      string batchContents = "@echo off" +
             *          "\ntimeout 5\n" +
             *          "cd " + Directory.GetCurrentDirectory() + "\n" +
             *          "Activator.exe -d -m " + E_CODE.ToString();
             *      File.WriteAllText("denyAct.bat", batchContents);
             *      Process p = Process.Start("denyAct.bat");
             *
             *      return;
             *  }
             * }
             * else
             * {
             *  Console.WriteLine("ERROR: You must have an activation code set prior to running Bot.exe!!\n \n[Please run Activator with the Confirmation Number]");
             *  Console.ReadKey();
             *  return;
             * }
             */
            BotSession.Instance.MSGSVC.MessageEvent += MSGSVC_onChat;
            BotSession.Instance.MSGSVC.MessageEvent += MSGSVC_onIM;
            BotSession.Instance.MSGSVC.MessageEvent += MSGSVC_onGroupMessage;


            string fna = null;
            string lna = null;
            string pwd = null;

            if (conf.first == null || conf.first == "")
            {
                if (args.Length == 0)
                {
                    Log.info(false, "Please enter your avatar's first name:  ");
                    fna = Console.ReadLine();

                    Log.info(false, "Please enter the last name: ");
                    lna = Console.ReadLine();
                    Log.info(false, "Now enter your password: "******"ZBotCore";
                    conf.ConfigVersion = 1.0f;
                }
                else
                {
                    Log.info(false, "Loading...");
                    Log.info(false, "FirstName: " + args[0]);
                    fna = args[0];
                    lna = args[1];
                    pwd = args[2];

                    // Continue boot
                }
                conf.first    = fna;
                conf.last     = lna;
                conf.password = pwd;
                conf.Save();
            }
            else
            {
                fna = conf.first;
                lna = conf.last;
                pwd = conf.password;
            }

            bool startupSeq = true;

            if (File.Exists("ObjectCache.bdf"))
            {
                File.Delete("ObjectCache.bdf");
            }
            client.Self.ChatFromSimulator += onChatRecv;
            client.Self.GroupChatJoined   += onJoinGroupChat;
            client.Self.IM += onIMEvent;
            client.Groups.GroupRoleDataReply += CacheGroupRoles;
            //client.Objects.ObjectUpdate += onObjectUpdate;
            //client.Objects.ObjectProperties += onObjectProperties;

            //client.Network.SimChanged += onSimChange; // Recache prims for this sim


            //client.Objects.TerseObjectUpdate += onObjectTerseUpdate;


            client.Settings.OBJECT_TRACKING       = true;
            client.Settings.ALWAYS_DECODE_OBJECTS = true;
            client.Settings.USE_ASSET_CACHE       = true;
            client.Throttle.Asset               = 100000;
            client.Throttle.Land                = 100000;
            client.Throttle.Task                = 100000;
            client.Throttle.Total               = 100000;
            client.Settings.LOG_RESENDS         = false;
            client.Settings.LOG_ALL_CAPS_ERRORS = false;
            client.Settings.LOG_DISKCACHE       = false;



            client.Settings.ALWAYS_REQUEST_OBJECTS = true;

            Console.WriteLine("Logging in...");

            bool LoggedIn = client.Network.Login(fna, lna, pwd, BotStr, BotVer.ToString());

            Console.WriteLine("Logged In: " + LoggedIn.ToString());

            if (!LoggedIn)
            {
                Console.WriteLine("Check Creds:\n \nFirst Name: '" + fna + "'\nLast Name: '" + lna + "'\nPWD: '" + pwd + "'\nBotStr: '" + BotStr + "'\nBotVer: " + BotVer.ToString() + "\n \nLogin Message: " + client.Network.LoginMessage);
            }
            if (LoggedIn)
            {
                // Setup BotSession Singleton!
                BotSession.Instance.grid   = client;
                BotSession.Instance.Logger = Log;

                Thread prompter = new Thread(() => {
                    BotSession.Instance.Logger.DoPrompt();
                });

                prompter.Start();
                CM = new CommandManager();

                MainConfiguration.Instance.Save(); // Flush the config, to update the file format

                g_ZPrograms = new List <IProgram>();
                // Scan folder for plugins, then load
                FileInfo[] files = new DirectoryInfo(Directory.GetCurrentDirectory()).GetFiles();
                foreach (FileInfo fi in files)
                {
                    try
                    {
                        if (fi.Extension.ToLower() == ".dll")
                        {
                            PluginActivator PA      = new PluginActivator();
                            Assembly        asm     = PA.LoadLibrary(fi.FullName);
                            List <IProgram> plugins = PA.Activate(asm);
                            foreach (IProgram prog in plugins)
                            {
                                try
                                {
                                    if (!g_ZPrograms.Contains(prog))
                                    {
                                        Console.WriteLine("Plugin [" + prog.ProgramName + "] found (" + fi.FullName + ") loaded and activated");
                                        prog.run();
                                        g_ZPrograms.Add(prog);
                                    }
                                }
                                catch (Exception e) { }
                            }
                        }
                    }catch (Exception e)
                    {
                        Console.WriteLine("Could not load file: " + fi.FullName + " as a Bot Plugin");
                    }
                }

                CommandRegistry.Instance.LocateCommands();
                if (!File.Exists("BotData/Inventory.blob"))
                {
                    BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.Store.RootFolder.OwnerID, BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);

                    BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.Animation), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
                    BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.Bodypart), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
                    BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.CallingCard), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
                    BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.Clothing), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
                    BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.Folder), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
                    BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.Gesture), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
                    BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.ImageJPEG), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
                    BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.ImageTGA), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
                    BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.Landmark), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
                    BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.Link), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
                    BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.LinkFolder), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
                    BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.LSLBytecode), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
                    BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.LSLText), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
                    BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.Mesh), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
                    BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.Notecard), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
                    BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.Object), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
                    BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.Person), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
                    BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.Simstate), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
                    BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.Sound), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
                    BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.SoundWAV), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
                    BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.Texture), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
                    BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.TextureTGA), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
                    BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.Unknown), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
                    BotSession.Instance.grid.Inventory.RequestFolderContents(BotSession.Instance.grid.Inventory.FindFolderForType(AssetType.Widget), BotSession.Instance.grid.Inventory.Store.Owner, true, true, InventorySortOrder.SystemFoldersToTop);
                }
                //else
                //BotSession.Instance.grid.Inventory.Store.RestoreFromDisk("BotData/Inventory.blob");


                int iLastInvLength = 0;
                while (g_iIsRunning)
                {
                    if (iLastInvLength != BotSession.Instance.grid.Inventory.Store.Items.Count)
                    {
                        //BotSession.Instance.grid.Inventory.Store.SaveToDisk("BotData/Inventory.blob");
                        //iLastInvLength = BotSession.Instance.grid.Inventory.Store.Items.Count;
                    }
                    string consoleCmd = "N/A";
                    try
                    {
                        consoleCmd = BotSession.Instance.Logger.CheckForNewCmd();
                    }catch (Exception e)
                    {
                        // no command is set yet!
                    }

                    switch (consoleCmd)
                    {
                    case "N/A":
                    {
                        break;
                    }

                    default:
                    {
                        // Run command!
                        Dictionary <string, string> argsx = new Dictionary <string, string>();
                        argsx.Add("type", "console");
                        argsx.Add("source", "null");
                        argsx.Add("request", consoleCmd);
                        argsx.Add("from", "");
                        argsx.Add("from_sess", "");
                        argsx.Add("fromName", "CONSOLE");
                        passArguments(JsonConvert.SerializeObject(argsx));
                        break;
                    }
                    }
                    // Pass to the command handlers

                    client.Self.RetrieveInstantMessages();
                    if (client.Network.Connected == false)
                    {
                        g_iIsRunning = false;                                    // Quit the program and restart immediately!
                    }
                    Thread.Sleep(1000);


                    if (conf.ConfigFor == "Main")
                    {
                        MessageFactory.Post(Destinations.DEST_LOCAL, "Alert: Main.json is not fully initialized. Setting default values", UUID.Zero);

                        conf.ConfigFor     = "BOT";
                        conf.ConfigVersion = 1.0f;
                        // data contains nothing at the moment.
                        SM.Write <MainConfiguration>("Main", conf);
                        conf = null;
                        conf = SM.Read <MainConfiguration>("Main");

                        if (conf.ConfigFor == "BOT")
                        {
                            MessageFactory.Post(Destinations.DEST_LOCAL, "Main.json has been created", UUID.Zero);
                        }
                        else
                        {
                            MessageFactory.Post(Destinations.DEST_LOCAL, "Main.json is invalid. Cannot continue", UUID.Zero);
                            g_iIsRunning = false;
                        }
                    }
                    else
                    {
                        Flavor = conf.ConfigFor;
                    }

                    //msg(MessageHandler.Destinations.DEST_LOCAL, UUID.Zero, "Commands found: " + registry.Cmds.Count.ToString());


                    if (startupSeq)
                    {
                        registry = CommandRegistry.Instance;
                        registry.LocateCommands();
                        GroupsCache = new Dictionary <UUID, Group>();
                        ReloadGroupsCache();
                        //ReloadGroupsCache();
                        try
                        {
                            Log.info(true, g_ZPrograms.Count.ToString() + " programs linked");
                            //if (g_ZPrograms.Count > 0) msg(MessageHandler.Destinations.DEST_LOCAL, UUID.Zero, "Default Program [" + conf.MainProgramDLL + "] has been loaded, " + programCount.ToString() + " plugin(s) loaded");
                            registry.LocateCommands();

                            //msg(MessageHandler.Destinations.DEST_LOCAL, UUID.Zero, "Commands found: " + registry.Cmds.Count.ToString());

                            GroupsCache = new Dictionary <UUID, Group>();
                            ReloadGroupsCache();
                        }
                        catch (Exception E)
                        {
                            string Msg   = E.Message;
                            string STACK = E.StackTrace.Replace("ZNI", "");
                            Msg = Msg.Replace("ZNI", "");
                            Log.info(true, "Generic Exception Caught: " + Msg + " [0x0A]");
                            int    i;
                            int *  ptr  = &i;
                            IntPtr addr = (IntPtr)ptr;
                            MessageFactory.Post(Destinations.DEST_LOCAL, "Generic Exception Caught: " + Msg + " [0x0A, 0x" + addr.ToString("x") + "]\nSTACK: " + STACK, UUID.Zero);
                        }
                        if (File.Exists("XUP"))
                        {
                            File.Delete("XUP");

                            MessageFactory.Post(Destinations.DEST_LOCAL, $"Updated to version {BotStr} - {BotVer}", UUID.Zero);
                        }
                    }

                    foreach (IProgram plugin in g_ZPrograms)
                    {
                        plugin.getTick(); // Trigger a tick event!!!
                    }



                    //MasterObjectCaches.Save();
                    if (startupSeq)
                    {
                        startupSeq = false;
                    }


                    if (BotSession.Instance.LaunchTime.AddHours(MainConfiguration.Instance.AutoRelogAfterHours) < DateTime.Now)
                    {
                        // Initiate a relog
                        try
                        {
                            prompter.Interrupt();
                            prompter.Abort();
                        }catch (Exception e)
                        {
                            client.Self.Chat(e.Message, 0, ChatType.Normal);
                        }
                        client.Self.Chat("Automatic relog in progress", 0, ChatType.Whisper);
                        g_iIsRunning = false;
                        client.Network.Logout();
                    }
                    //if (MasterObjectCaches.RegionPrims.Count == 0 && client.Network.Connected)
                    //{

                    //    onSimChange(null, new SimChangedEventArgs(client.Network.CurrentSim));
                    //}

                    if (BotSession.Instance.EnqueueExit)
                    {
                        g_iIsRunning = false;
                    }

                    if (BotSession.Instance.EnqueueGroupRefresh)
                    {
                        BotSession.Instance.EnqueueGroupRefresh = false;
                        ReloadGroupsCache();
                    }

                    BotSession.Instance.MSGSVC.PopMessage();
                }

                prompter.Interrupt();
                client.Network.Logout();
            }
            while (client.Network.Connected)
            {
            }

            if (BotSession.Instance.WaitForFiveMinutes)
            {
                AutoResetEvent are = new AutoResetEvent(false);
                are.WaitOne(TimeSpan.FromMinutes(5));
            }
            File.Delete("PID.lock");
            Environment.Exit(0);

            //System.Console.WriteLine("PAUSING. PRESS ANY KEY TO EXIT");
            //System.Console.ReadKey();
        }