Example #1
0
        public static bool ScanMemory()
        {
            ReadMemoryResults readMemoryResults = ReadMemoryManager.ReadMemory();
            ParseMemoryResults parseMemoryResults = Parser.ParseLogResults(readMemoryResults);

            if (parseMemoryResults != null) {
                lastResults = parseMemoryResults;
                if (parseMemoryResults.newDamage) {
                    GlobalDataManager.UpdateDamage();
                }
            }

            if (readMemoryResults != null && readMemoryResults.newAdvances.Count > 0) {
                if (SettingsManager.getSettingBool("AutoScreenshotAdvance")) {
                    MainForm.mainForm.Invoke((MethodInvoker)delegate {
                        ScreenshotManager.saveScreenshot("Advance", ScreenshotManager.takeScreenshot());
                    });
                }
                if (SettingsManager.getSettingBool("CopyAdvances")) {
                    foreach (object obj in readMemoryResults.newAdvances) {
                        MainForm.mainForm.Invoke((MethodInvoker)delegate {
                            Clipboard.SetText(obj.ToString());
                        });
                    }
                }
                readMemoryResults.newAdvances.Clear();
            }

            if (parseMemoryResults != null && parseMemoryResults.death) {
                if (SettingsManager.getSettingBool("AutoScreenshotDeath")) {
                    MainForm.mainForm.Invoke((MethodInvoker)delegate {
                        ScreenshotManager.saveScreenshot("Death", ScreenshotManager.takeScreenshot());
                    });
                }
                parseMemoryResults.death = false;
            }

            if (parseMemoryResults != null) {
                if (parseMemoryResults.newEventMessages.Count > 0) {
                    if (SettingsManager.getSettingBool("EnableEventNotifications")) {
                        foreach (Tuple<Event, string> tpl in parseMemoryResults.newEventMessages) {
                            Event ev = tpl.Item1;
                            Creature cr = StorageManager.getCreature(ev.creatureid);
                            MainForm.mainForm.Invoke((MethodInvoker)delegate {
                                if (!SettingsManager.getSettingBool("UseRichNotificationType")) {
                                    PopupManager.ShowSimpleNotification("Event in " + ev.location, tpl.Item2, cr.image);
                                } else {
                                    PopupManager.ShowSimpleNotification(new SimpleTextNotification(cr.image, "Event in " + ev.location, tpl.Item2));
                                }
                            });
                        }
                    }
                    parseMemoryResults.newEventMessages.Clear();
                }
            }

            if (SettingsManager.getSettingBool("LookMode") && readMemoryResults != null) {
                foreach (string msg in parseMemoryResults.newLooks) {
                    string itemName = Parser.parseLookItem(msg).ToLower();
                    if (StorageManager.itemExists(itemName)) {
                        MainForm.mainForm.Invoke((MethodInvoker)delegate {
                            CommandManager.ExecuteCommand("item@" + itemName);
                        });
                    } else if (StorageManager.creatureExists(itemName) ||
                        (itemName.Contains("dead ") && (itemName = itemName.Replace("dead ", "")) != null && StorageManager.creatureExists(itemName)) ||
                        (itemName.Contains("slain ") && (itemName = itemName.Replace("slain ", "")) != null && StorageManager.creatureExists(itemName))) {
                        MainForm.mainForm.Invoke((MethodInvoker)delegate {
                            CommandManager.ExecuteCommand("creature@" + itemName);
                        });
                    } else {
                        NPC npc = StorageManager.getNPC(itemName);
                        if (npc != null) {
                            MainForm.mainForm.Invoke((MethodInvoker)delegate {
                                CommandManager.ExecuteCommand("npc@" + itemName);
                            });
                        }
                    }
                }
                parseMemoryResults.newLooks.Clear();
            }

            List<string> commands = parseMemoryResults == null ? new List<string>() : parseMemoryResults.newCommands.ToList();
            commands.Reverse();

            foreach (string command in commands) {
                MainForm.mainForm.Invoke((MethodInvoker)delegate {
                    if (!CommandManager.ExecuteCommand(command, parseMemoryResults) && SettingsManager.getSettingBool("EnableUnrecognizedNotifications")) {
                        if (!SettingsManager.getSettingBool("UseRichNotificationType")) {
                            PopupManager.ShowSimpleNotification("Unrecognized command", "Unrecognized command: " + command, StyleManager.GetImage("tibia.png"));
                        } else {
                            PopupManager.ShowSimpleNotification(new SimpleTextNotification(null, "Unrecognized command", "Unrecognized command: " + command));
                        }
                    }
                });
            }
            if (parseMemoryResults != null) {
                if (parseMemoryResults.newItems.Count > 0) {
                    MainForm.mainForm.Invoke((MethodInvoker)delegate {
                        LootDatabaseManager.UpdateLoot();
                    });
                }
                foreach (Tuple<Creature, List<Tuple<Item, int>>> tpl in parseMemoryResults.newItems) {
                    Creature cr = tpl.Item1;
                    List<Tuple<Item, int>> items = tpl.Item2;
                    bool showNotification = PopupManager.ShowDropNotification(tpl);
                    if (showNotification) {
                        if (!SettingsManager.getSettingBool("UseRichNotificationType")) {
                            Console.WriteLine("Rich Notification");
                            PopupManager.ShowSimpleNotification(cr.displayname, cr.displayname + " dropped a valuable item.", cr.image);
                        } else {
                            MainForm.mainForm.Invoke((MethodInvoker)delegate {
                                PopupManager.ShowSimpleNotification(new SimpleLootNotification(cr, items));
                            });
                        }

                        if (SettingsManager.getSettingBool("AutoScreenshotItemDrop")) {
                            // Take a screenshot if Tibialyzer is set to take screenshots of valuable loot
                            Bitmap screenshot = ScreenshotManager.takeScreenshot();
                            if (screenshot == null) continue;
                            // Add a notification to the screenshot
                            SimpleLootNotification screenshotNotification = new SimpleLootNotification(cr, items);
                            Bitmap notification = new Bitmap(screenshotNotification.Width, screenshotNotification.Height);
                            screenshotNotification.DrawToBitmap(notification, new Rectangle(0, 0, screenshotNotification.Width, screenshotNotification.Height));
                            foreach (Control c in screenshotNotification.Controls) {
                                c.DrawToBitmap(notification, new Rectangle(c.Location, c.Size));
                            }
                            screenshotNotification.Dispose();
                            int widthOffset = notification.Width + 10;
                            int heightOffset = notification.Height + 10;
                            if (screenshot.Width > widthOffset && screenshot.Height > heightOffset) {
                                using (Graphics gr = Graphics.FromImage(screenshot)) {
                                    gr.DrawImage(notification, new Point(screenshot.Width - widthOffset, screenshot.Height - heightOffset));
                                }
                            }
                            notification.Dispose();
                            MainForm.mainForm.Invoke((MethodInvoker)delegate {
                                ScreenshotManager.saveScreenshot("Loot", screenshot);
                            });
                        }
                    }
                }
            }
            return readMemoryResults != null;
        }
Example #2
0
        public static ParseMemoryResults ParseLogResults(ReadMemoryResults res)
        {
            if (res == null) return null;
            ParseMemoryResults o = new ParseMemoryResults();
            // first we add the new parsed damage logs to the totalDamageResults
            o.newDamage = GlobalDataManager.UpdateDamageInformation(res.damageDealt);
            // now that we have updated the damage results, fill in the DPS meter, we use damage from the last 15 minutes for this
            List<string> times = TimestampManager.getLatestTimes(15);
            GlobalDataManager.GenerateDamageResults(o.damagePerSecond, times);

            // similar to damage, we keep a totalExperienceResults list
            // first update it with the new information
            int newExperience = GlobalDataManager.UpdateExperience(res.exp);

            // now compute the experience per hour
            // we use the same formula Tibia itself does so we get the same value
            // this formula is basically, take the experience in the last 15 minutes and multiply it by 4
            o.expPerHour = GlobalDataManager.GetTotalExperience(times).Item1;

            // Parse event messages
            foreach(Tuple<Event, string> newEvent in GlobalDataManager.UpdateEventInformation(res.eventMessages)) {
                o.newEventMessages.Add(newEvent);
            }

            // Update the look information
            foreach(string newLook in GlobalDataManager.UpdateLookInformation(res.lookMessages)) {
                o.newLooks.Add(newLook);
            }

            // Update death information
            o.death = GlobalDataManager.UpdateDeaths(res.deaths);

            // now parse any new commands given by users
            foreach(string newCommand in GlobalDataManager.UpdateCommands(res.commands)) {
                o.newCommands.Add(newCommand);
            }

            // check new urls
            GlobalDataManager.UpdateURLs(res.urls);

            Parser.ParseLootMessages(HuntManager.activeHunt, res.itemDrops, o.newItems, true, true);
            HuntManager.activeHunt.totalExp += newExperience;

            readWatch.Stop();
            if (newExperience == 0) {
                if (ticksSinceExperience < 120) {
                    ticksSinceExperience += readWatch.Elapsed.TotalSeconds;
                }
            } else {
                ticksSinceExperience = 0;
            }
            if (ticksSinceExperience < 120) {
                HuntManager.activeHunt.totalTime += readWatch.Elapsed.TotalSeconds;
            }
            readWatch.Restart();
            HuntManager.SaveHunts();
            return o;
        }
Example #3
0
        public static bool ScanMemory()
        {
            ReadMemoryResults  readMemoryResults  = ReadMemoryManager.ReadMemory();
            ParseMemoryResults parseMemoryResults = Parser.ParseLogResults(readMemoryResults);

            if (parseMemoryResults != null)
            {
                lastResults = parseMemoryResults;
                if (parseMemoryResults.newDamage)
                {
                    GlobalDataManager.UpdateDamage();
                }
            }

            if (readMemoryResults != null && readMemoryResults.newAdvances.Count > 0)
            {
                if (SettingsManager.getSettingBool("AutoScreenshotAdvance"))
                {
                    MainForm.mainForm.Invoke((MethodInvoker) delegate {
                        ScreenshotManager.saveScreenshot("Advance", ScreenshotManager.takeScreenshot());
                    });
                }
                if (SettingsManager.getSettingBool("CopyAdvances"))
                {
                    foreach (object obj in readMemoryResults.newAdvances)
                    {
                        MainForm.mainForm.Invoke((MethodInvoker) delegate {
                            Clipboard.SetText(obj.ToString());
                        });
                    }
                }
                readMemoryResults.newAdvances.Clear();
            }

            if (parseMemoryResults != null && parseMemoryResults.death)
            {
                if (SettingsManager.getSettingBool("AutoScreenshotDeath"))
                {
                    MainForm.mainForm.Invoke((MethodInvoker) delegate {
                        ScreenshotManager.saveScreenshot("Death", ScreenshotManager.takeScreenshot());
                    });
                }
                parseMemoryResults.death = false;
            }

            if (parseMemoryResults != null)
            {
                if (parseMemoryResults.newEventMessages.Count > 0)
                {
                    if (SettingsManager.getSettingBool("EnableEventNotifications"))
                    {
                        foreach (Tuple <Event, string> tpl in parseMemoryResults.newEventMessages)
                        {
                            Event    ev = tpl.Item1;
                            Creature cr = StorageManager.getCreature(ev.creatureid);
                            MainForm.mainForm.Invoke((MethodInvoker) delegate {
                                if (!SettingsManager.getSettingBool("UseRichNotificationType"))
                                {
                                    PopupManager.ShowSimpleNotification("Event in " + ev.location, tpl.Item2, cr.image);
                                }
                                else
                                {
                                    PopupManager.ShowSimpleNotification(new SimpleTextNotification(cr.image, "Event in " + ev.location, tpl.Item2));
                                }
                            });
                        }
                    }
                    parseMemoryResults.newEventMessages.Clear();
                }
            }

            if (SettingsManager.getSettingBool("LookMode") && readMemoryResults != null)
            {
                foreach (string msg in parseMemoryResults.newLooks)
                {
                    string itemName = Parser.parseLookItem(msg).ToLower();
                    if (StorageManager.itemExists(itemName))
                    {
                        MainForm.mainForm.Invoke((MethodInvoker) delegate {
                            CommandManager.ExecuteCommand("item@" + itemName);
                        });
                    }
                    else if (StorageManager.creatureExists(itemName) ||
                             (itemName.Contains("dead ") && (itemName = itemName.Replace("dead ", "")) != null && StorageManager.creatureExists(itemName)) ||
                             (itemName.Contains("slain ") && (itemName = itemName.Replace("slain ", "")) != null && StorageManager.creatureExists(itemName)))
                    {
                        MainForm.mainForm.Invoke((MethodInvoker) delegate {
                            CommandManager.ExecuteCommand("creature@" + itemName);
                        });
                    }
                    else
                    {
                        NPC npc = StorageManager.getNPC(itemName);
                        if (npc != null)
                        {
                            MainForm.mainForm.Invoke((MethodInvoker) delegate {
                                CommandManager.ExecuteCommand("npc@" + itemName);
                            });
                        }
                    }
                }
                parseMemoryResults.newLooks.Clear();
            }

            List <string> commands = parseMemoryResults == null ? new List <string>() : parseMemoryResults.newCommands.ToList();

            commands.Reverse();

            foreach (string command in commands)
            {
                MainForm.mainForm.Invoke((MethodInvoker) delegate {
                    if (!CommandManager.ExecuteCommand(command, parseMemoryResults) && SettingsManager.getSettingBool("EnableUnrecognizedNotifications"))
                    {
                        if (!SettingsManager.getSettingBool("UseRichNotificationType"))
                        {
                            PopupManager.ShowSimpleNotification("Unrecognized command", "Unrecognized command: " + command, StyleManager.GetImage("tibia.png"));
                        }
                        else
                        {
                            PopupManager.ShowSimpleNotification(new SimpleTextNotification(null, "Unrecognized command", "Unrecognized command: " + command));
                        }
                    }
                });
            }
            if (parseMemoryResults != null)
            {
                if (parseMemoryResults.newItems.Count > 0)
                {
                    MainForm.mainForm.Invoke((MethodInvoker) delegate {
                        LootDatabaseManager.UpdateLoot();
                    });
                }
                foreach (Tuple <Creature, List <Tuple <Item, int> > > tpl in parseMemoryResults.newItems)
                {
                    Creature cr = tpl.Item1;
                    List <Tuple <Item, int> > items = tpl.Item2;
                    bool showNotification           = PopupManager.ShowDropNotification(tpl);
                    if (showNotification)
                    {
                        if (!SettingsManager.getSettingBool("UseRichNotificationType"))
                        {
                            Console.WriteLine("Rich Notification");
                            PopupManager.ShowSimpleNotification(cr.displayname, cr.displayname + " dropped a valuable item.", cr.image);
                        }
                        else
                        {
                            MainForm.mainForm.Invoke((MethodInvoker) delegate {
                                PopupManager.ShowSimpleNotification(new SimpleLootNotification(cr, items));
                            });
                        }

                        if (SettingsManager.getSettingBool("AutoScreenshotItemDrop"))
                        {
                            // Take a screenshot if Tibialyzer is set to take screenshots of valuable loot
                            Bitmap screenshot = ScreenshotManager.takeScreenshot();
                            if (screenshot == null)
                            {
                                continue;
                            }
                            // Add a notification to the screenshot
                            SimpleLootNotification screenshotNotification = new SimpleLootNotification(cr, items);
                            Bitmap notification = new Bitmap(screenshotNotification.Width, screenshotNotification.Height);
                            screenshotNotification.DrawToBitmap(notification, new Rectangle(0, 0, screenshotNotification.Width, screenshotNotification.Height));
                            foreach (Control c in screenshotNotification.Controls)
                            {
                                c.DrawToBitmap(notification, new Rectangle(c.Location, c.Size));
                            }
                            screenshotNotification.Dispose();
                            int widthOffset  = notification.Width + 10;
                            int heightOffset = notification.Height + 10;
                            if (screenshot.Width > widthOffset && screenshot.Height > heightOffset)
                            {
                                using (Graphics gr = Graphics.FromImage(screenshot)) {
                                    gr.DrawImage(notification, new Point(screenshot.Width - widthOffset, screenshot.Height - heightOffset));
                                }
                            }
                            notification.Dispose();
                            MainForm.mainForm.Invoke((MethodInvoker) delegate {
                                ScreenshotManager.saveScreenshot("Loot", screenshot);
                            });
                        }
                    }
                }
            }
            return(readMemoryResults != null);
        }
        private ParseMemoryResults ParseLogResults(ReadMemoryResults res)
        {
            if (res == null) return null;
            ParseMemoryResults o = new ParseMemoryResults();
            // first we add the new parsed damage logs to the totalDamageResults
            foreach (KeyValuePair<string, Dictionary<string, int>> kvp in res.damageDealt) {
                string player = kvp.Key;
                Dictionary<string, int> playerDamage = kvp.Value;
                if (!totalDamageResults.ContainsKey(player)) totalDamageResults.Add(player, new Dictionary<string, int>());
                foreach (KeyValuePair<string, int> kvp2 in playerDamage) {
                    string timestamp = kvp2.Key;
                    int damage = kvp2.Value;
                    // if the damage for the given timestamp does not exist yet, add it
                    if (!totalDamageResults[player].ContainsKey(timestamp)) totalDamageResults[player].Add(timestamp, damage);
                    // if it does exist, select the biggest of the two
                    // the reason we select the biggest of the two is:
                    // - if the timestamp is 'the current time', totalDamageResults may hold an old value, so we update it
                    // - if timestamp is old, a part of the log for the time could have already been removed (because the log was full)
                    //    so the 'new' damage is only part of the damage for this timestamp
                    else if (totalDamageResults[player][timestamp] < damage) totalDamageResults[player][timestamp] = damage;
                }
            }
            // now that we have updated the damage results, fill in the DPS meter, we use damage from the last 15 minutes for this
            List<string> times = getLatestTimes(15);
            foreach (KeyValuePair<string, Dictionary<string, int>> kvp in totalDamageResults) {
                string player = kvp.Key;
                int damage = 0;
                int minutes = 0;
                foreach (string t in times) {
                    if (totalDamageResults[player].ContainsKey(t)) {
                        damage += totalDamageResults[player][t];
                        minutes++;
                    }
                }
                if (damage > 0) {
                    o.damagePerSecond.Add(player, new Tuple<int, int>(damage, minutes));
                }
            }

            // similar to damage, we keep a totalExperienceResults list
            // first update it with the new information
            int newExperience = 0;
            foreach (KeyValuePair<string, int> kvp in res.exp) {
                string time = kvp.Key;
                int experience = kvp.Value;
                if (!totalExperienceResults.ContainsKey(time)) {
                    totalExperienceResults.Add(time, experience);
                    newExperience += experience;
                } else if (totalExperienceResults[time] < experience) {
                    newExperience += experience - totalExperienceResults[time];
                    totalExperienceResults[time] = experience;
                }
            }
            // now compute the experience per hour
            // we use the same formula Tibia itself does so we get the same value
            // this formula is basically, take the experience in the last 15 minutes and multiply it by 4
            foreach (string t in times) {
                if (totalExperienceResults.ContainsKey(t)) o.expPerHour += totalExperienceResults[t];
            }
            o.expPerHour *= 4;

            // Parse event messages
            foreach (Tuple<Event, string> tpl in res.eventMessages) {
                if (!eventMessages.Contains(tpl.Item2)) {
                    eventMessages.Add(tpl.Item2);
                    o.newEventMessages.Add(tpl);
                }
            }

            // Update the look information
            foreach (KeyValuePair<string, List<string>> kvp in res.lookMessages) {
                string t = kvp.Key;
                List<string> currentMessages = kvp.Value;
                if (!totalLooks.ContainsKey(t)) totalLooks[t] = new List<string>();
                if (currentMessages.Count > totalLooks[t].Count) {
                    List<string> unseenLooks = new List<string>();
                    List<string> lookList = totalLooks[t].ToArray().ToList();
                    foreach (string lookMessage in currentMessages) {
                        if (!totalLooks[t].Contains(lookMessage)) {
                            unseenLooks.Add(lookMessage);
                            o.newLooks.Add(lookMessage);
                        } else {
                            totalLooks[t].Remove(lookMessage);
                        }
                    }
                    lookList.AddRange(unseenLooks);
                    totalLooks[t] = lookList;
                }
            }

            // Update death information
            foreach (KeyValuePair<string, bool> kvp in res.deaths) {
                if (!totalDeaths.ContainsKey(kvp.Key)) {
                    totalDeaths.Add(kvp.Key, false);
                }
                if (kvp.Value && !totalDeaths[kvp.Key]) {
                    o.death = true;
                    totalDeaths[kvp.Key] = true;
                }
            }

            // now parse any new commands given by users
            foreach (KeyValuePair<string, List<Tuple<string, string>>> kvp in res.commands) {
                string t = kvp.Key;
                List<Tuple<string, string>> currentCommands = kvp.Value;
                if (!totalCommands.ContainsKey(t)) totalCommands[t] = new List<Tuple<string, string>>();
                if (currentCommands.Count > totalCommands[t].Count) {
                    List<Tuple<string, string>> unseenCommands = new List<Tuple<string, string>>();
                    List<Tuple<string, string>> commandsList = totalCommands[t].ToArray().ToList(); // create a copy of the list
                    foreach (Tuple<string, string> command in currentCommands) {
                        if (!totalCommands[t].Contains(command)) {
                            unseenCommands.Add(command);
                            string player = command.Item1;
                            string cmd = command.Item2;
                            if (SettingsManager.getSetting("Names").Contains(player)) {
                                o.newCommands.Add(cmd);
                            }
                        } else {
                            totalCommands[t].Remove(command);
                        }
                    }
                    commandsList.AddRange(unseenCommands);
                    totalCommands[t] = commandsList;
                }
            }

            // check new urls
            foreach (KeyValuePair<string, List<Tuple<string, string>>> kvp in res.urls) {
                string t = kvp.Key;
                List<Tuple<string, string>> currentURLs = kvp.Value;
                if (!totalURLs.ContainsKey(t)) {
                    totalURLs.Add(t, currentURLs);
                } else if (currentURLs.Count > totalURLs[t].Count) {
                    totalURLs[t] = currentURLs;
                }
            }

            ParseLootMessages(activeHunt, res.itemDrops, o.newItems, true, true);
            activeHunt.totalExp += newExperience;

            readWatch.Stop();
            if (newExperience == 0) {
                if (ticksSinceExperience < 120) {
                    ticksSinceExperience += readWatch.Elapsed.TotalSeconds;
                }
            } else {
                ticksSinceExperience = 0;
            }
            if (ticksSinceExperience < 120) {
                activeHunt.totalTime += readWatch.Elapsed.TotalSeconds;
            }
            readWatch.Restart();
            saveHunts();
            return o;
        }
Example #5
0
        public static ParseMemoryResults ParseLogResults(ReadMemoryResults res)
        {
            if (res == null)
            {
                return(null);
            }
            ParseMemoryResults o = new ParseMemoryResults();

            // first we add the new parsed damage logs to the totalDamageResults
            o.newDamage = GlobalDataManager.UpdateDamageInformation(res.damageDealt);
            // now that we have updated the damage results, fill in the DPS meter, we use damage from the last 15 minutes for this
            List <string> times = TimestampManager.getLatestTimes(15);

            GlobalDataManager.GenerateDamageResults(o.damagePerSecond, times);

            // similar to damage, we keep a totalExperienceResults list
            // first update it with the new information
            int newExperience = GlobalDataManager.UpdateExperience(res.exp);

            // now compute the experience per hour
            // we use the same formula Tibia itself does so we get the same value
            // this formula is basically, take the experience in the last 15 minutes and multiply it by 4
            o.expPerHour = GlobalDataManager.GetExperiencePerHour();

            // Parse event messages
            foreach (Tuple <Event, string> newEvent in GlobalDataManager.UpdateEventInformation(res.eventMessages))
            {
                o.newEventMessages.Add(newEvent);
            }

            // Update the look information
            foreach (string newLook in GlobalDataManager.UpdateLookInformation(res.lookMessages))
            {
                o.newLooks.Add(newLook);
            }

            // Update death information
            o.death = GlobalDataManager.UpdateDeaths(res.deaths);

            // now parse any new commands given by users
            foreach (string newCommand in GlobalDataManager.UpdateCommands(res.commands))
            {
                o.newCommands.Add(newCommand);
            }

            // check new urls
            GlobalDataManager.UpdateURLs(res.urls);


            HuntManager.AddUsedItems(HuntManager.activeHunt, res.usingMessages);
            Parser.ParseLootMessages(HuntManager.activeHunt, res.itemDrops, o.newItems, true, true);
            HuntManager.activeHunt.totalExp += newExperience;

            readWatch.Stop();
            if (newExperience == 0)
            {
                if (ticksSinceExperience < 120)
                {
                    ticksSinceExperience += readWatch.Elapsed.TotalSeconds;
                }
            }
            else
            {
                ticksSinceExperience = 0;
            }
            if (ticksSinceExperience < 120)
            {
                HuntManager.activeHunt.totalTime += readWatch.Elapsed.TotalSeconds;
            }
            readWatch.Restart();
            HuntManager.SaveHunts();
            return(o);
        }
        public bool ExecuteCommand(string command, ParseMemoryResults parseMemoryResults = null)
        {
            try {
                if (parseMemoryResults == null) {
                    parseMemoryResults = lastResults;
                }
                string comp = command.Trim().ToLower();
                Console.WriteLine(command);
                if (comp.StartsWith("creature" + MainForm.commandSymbol)) { //creature@
                    string[] split = command.Split(commandSymbol);
                    string parameter = split[1].Trim().ToLower();
                    Creature cr = getCreature(parameter);
                    if (cr != null) {
                        ShowCreatureDrops(cr, command);
                    } else {
                        List<TibiaObject> creatures = searchCreature(parameter);
                        if (creatures.Count == 1) {
                            ShowCreatureDrops(creatures[0].AsCreature(), command);
                        } else if (creatures.Count > 1) {
                            ShowCreatureList(creatures, "Creature List", command);
                        }
                    }
                } else if (comp.StartsWith("look" + MainForm.commandSymbol)) { //look@
                    string parameter = command.Split(commandSymbol)[1].Trim().ToLower();
                    if (parameter == "on") {
                        SettingsManager.setSetting("LookMode", "True");
                    } else if (parameter == "off") {
                        SettingsManager.setSetting("LookMode", "False");
                    } else {
                        List<string> times = getLatestTimes(5);
                        List<TibiaObject> items = new List<TibiaObject>();
                        foreach (string t in times) {
                            if (!totalLooks.ContainsKey(t)) continue;
                            foreach (string message in totalLooks[t]) {
                                string itemName = parseLookItem(message).ToLower();
                                Item item = getItem(itemName);

                                if (item != null) {
                                    items.Add(item);
                                } else {
                                    Creature cr = getCreature(itemName);
                                    if (cr != null) {
                                        items.Add(cr);
                                    }
                                }
                            }
                        }
                        if (items.Count == 1) {
                            if (items[0] is Item) {
                                ShowItemNotification("item" + MainForm.commandSymbol + items[0].GetName().ToLower());
                            } else if (items[0] is Creature) {
                                ShowCreatureDrops(items[0].AsCreature(), command);
                            }
                        } else if (items.Count > 1) {
                            ShowCreatureList(items, "Looked At Items", command);
                        }
                    }
                } else if (comp.StartsWith("stats" + MainForm.commandSymbol)) { //stats@
                    string name = command.Split(commandSymbol)[1].Trim().ToLower();
                    Creature cr = getCreature(name);
                    if (cr != null) {
                        ShowCreatureStats(cr, command);
                    }
                } else if (comp.StartsWith("close" + MainForm.commandSymbol)) { //close@
                                                                                // close all notifications
                    for (int i = 0; i < NotificationFormGroups.Length; i++) {
                        if (NotificationFormGroups[i] != null) {
                            NotificationFormGroups[i].close();
                        }
                    }
                    ClearSimpleNotifications();
                } else if (comp.StartsWith("delete" + MainForm.commandSymbol)) { //delete@
                    string parameter = command.Split(commandSymbol)[1].Trim().ToLower();
                    int killCount;
                    if (int.TryParse(parameter, out killCount)) {
                        deleteCreatureWithThreshold(killCount);
                    } else {
                        Creature cr = getCreature(parameter);
                        if (cr != null) {
                            deleteCreatureFromLog(cr);
                        }
                    }
                } else if (comp.StartsWith("skin" + MainForm.commandSymbol)) { //skin@
                    string[] split = command.Split(commandSymbol);
                    string parameter = split[1].Trim().ToLower();
                    int count = 1;
                    Creature cr = getCreature(parameter);
                    if (cr != null) {
                        if (split.Length > 2)
                            int.TryParse(split[2], out count);
                        insertSkin(cr, count);
                    } else {
                        int.TryParse(parameter, out count);
                        // find creature with highest killcount with a skin and skin that
                        int kills = -1;
                        lock (hunts) {
                            foreach (KeyValuePair<Creature, int> kvp in activeHunt.loot.killCount) {
                                if (kvp.Value > kills && kvp.Key.skin != null) {
                                    cr = kvp.Key;
                                    kills = kvp.Value;
                                }
                            }
                        }
                        if (cr != null) {
                            insertSkin(cr, count);
                        }
                    }
                } else if (comp.StartsWith("city" + MainForm.commandSymbol)) { //city@
                    string parameter = command.Split(commandSymbol)[1].Trim().ToLower();
                    if (cityNameMap.ContainsKey(parameter)) {
                        City city = cityNameMap[parameter];
                        ShowCityDisplayForm(city, command);
                    }
                } else if (comp.StartsWith("damage" + MainForm.commandSymbol)) { //damage@
                    if (parseMemoryResults != null) {
                        string[] splits = command.Split(commandSymbol);
                        string screenshot_path = "";
                        string parameter = splits[1].Trim().ToLower();
                        if (parameter == "screenshot" && splits.Length > 2) {
                            parameter = "";
                            screenshot_path = splits[2];
                        }
                        ShowDamageMeter(parseMemoryResults.damagePerSecond, command, parameter, screenshot_path);
                    }
                } else if (comp.StartsWith("exp" + MainForm.commandSymbol)) { //exp@
                    string title = "Experience";
                    string text = "Currently gaining " + (parseMemoryResults == null ? "unknown" : ((int)parseMemoryResults.expPerHour).ToString()) + " experience an hour.";
                    Image image = StyleManager.GetImage("tibia.png");
                    if (!SettingsManager.getSettingBool("UseRichNotificationType")) {
                        ShowSimpleNotification(title, text, image);
                    } else {
                        ShowSimpleNotification(new SimpleTextNotification(null, title, text));
                    }
                } else if (comp.StartsWith("loot" + MainForm.commandSymbol)) { //loot@
                    string[] splits = command.Split(commandSymbol);
                    string screenshot_path = "";
                    string parameter = splits[1].Trim().ToLower();
                    if (parameter == "screenshot" && splits.Length > 2) {
                        parameter = "";
                        screenshot_path = splits[2];
                    }

                    Hunt currentHunt = activeHunt;
                    if (splits.Length >= 2 && splits[1] != "") {
                        foreach (Hunt h in hunts) {
                            if (h.name.ToLower().Contains(splits[1].ToLower())) {
                                currentHunt = h;
                                break;
                            }
                        }
                    }
                    // display loot notification
                    ShowLootDrops(currentHunt, command, screenshot_path);
                } else if (comp.StartsWith("clipboard" + MainForm.commandSymbol)) { //clipboard@
                    // Copy loot message to the clipboard
                    // clipboard@damage copies the damage information to the clipboard
                    // clipboard@<creature> copies the loot of a specific creature to the clipboard
                    // clipboard@ copies all loot to the clipboard
                    string creatureName = command.Split(commandSymbol)[1].Trim().ToLower();
                    Creature lootCreature = null;
                    if (creatureName == "damage" && parseMemoryResults != null) {
                        var damageInformation = DamageChart.GenerateDamageInformation(parseMemoryResults.damagePerSecond, "");
                        string damageString = "Damage Dealt: ";
                        foreach (var damage in damageInformation) {
                            damageString += String.Format("{0}: {1:N1}%; ", damage.name, damage.percentage);
                        }
                        Clipboard.SetText(damageString.Substring(0, damageString.Length - 2));
                        return true;
                    } else if (creatureName != "") {
                        lootCreature = getCreature(creatureName);
                    }

                    var tpl = LootDropForm.GenerateLootInformation(activeHunt, "", lootCreature);
                    var creatureKills = tpl.Item1;
                    var itemDrops = tpl.Item2;

                    string lootString = "";
                    if (creatureKills.Count == 1) {
                        foreach (KeyValuePair<Creature, int> kvp in creatureKills) {
                            lootString = "Total Loot of " + kvp.Value.ToString() + " " + kvp.Key.GetName() + (kvp.Value > 1 ? "s" : "") + ": ";
                        }
                    } else {
                        int totalKills = 0;
                        foreach (KeyValuePair<Creature, int> kvp in creatureKills) {
                            totalKills += kvp.Value;
                        }
                        lootString = "Total Loot of " + totalKills + " Kills: ";
                    }
                    foreach (Tuple<Item, int> kvp in itemDrops) {
                        lootString += kvp.Item2 + " " + kvp.Item1.displayname + (kvp.Item2 > 1 ? "s" : "") + ", ";
                    }
                    lootString = lootString.Substring(0, lootString.Length - 2) + ".";
                    Clipboard.SetText(lootString);
                } else if (comp.StartsWith("reset" + MainForm.commandSymbol)) { //reset@
                    string parameter = command.Split(commandSymbol)[1].Trim().ToLower();
                    int time = 0;
                    if (parameter == "old") {
                        clearOldLog(activeHunt);
                    } else if (int.TryParse(parameter, out time) && time > 0) {
                        clearOldLog(activeHunt, time);
                    } else {
                        lock (hunts) {
                            foreach (Hunt h in hunts) {
                                if (h.name.ToLower() == parameter.ToLower()) {
                                    // reset@<hunt> resets the specified hunt
                                    resetHunt(h);
                                    return true;
                                }
                            }
                        }
                        //reset@ loot deletes all loot from the currently active hunt
                        resetHunt(activeHunt);
                    }
                    refreshHunts();
                    ignoreStamp = createStamp();
                } else if (comp.StartsWith("refresh" + MainForm.commandSymbol)) { //refresh@
                                                                                  // refresh: refresh duration on current form, or if no current form, repeat last command without removing it from stack
                                                                                  /*if (tooltipForm != null && !tooltipForm.IsDisposed) {
                                                                                      try {
                                                                                          (tooltipForm as NotificationForm).ResetTimer();
                                                                                      } catch {
                                                                                      }
                                                                                  } else if (command_stack.Count > 0) {*/
                    MainForm.mainForm.ExecuteCommand(command_stack.Peek().command);
                    //}
                    return true;
                } else if (comp.StartsWith("switch" + MainForm.commandSymbol)) { //switch@
                                                                                 // switch: switch to hunt
                    string parameter = command.Split(commandSymbol)[1].Trim().ToLower();
                    lock (hunts) {
                        foreach (Hunt h in hunts) {
                            if (h.name.ToLower().Contains(parameter)) {
                                activeHunt = h;
                                saveHunts();
                                break;
                            }
                        }
                    }
                } else if (comp.StartsWith("item" + MainForm.commandSymbol)) { //item@
                                                                               //show the item with all the NPCs that sell it
                    ShowItemNotification(command);
                } else if (comp.StartsWith("task" + MainForm.commandSymbol)) { //task@
                    string parameter = command.Split(commandSymbol)[1].Trim().ToLower();
                    if (taskList.Keys.Contains(parameter)) {
                        ShowCreatureList(taskList[parameter].ToList<TibiaObject>(), taskList[parameter][0].groupname, command);
                    } else {
                        int id = -1;
                        int.TryParse(parameter, out id);
                        List<TibiaObject> tasks = new List<TibiaObject>();
                        foreach (KeyValuePair<string, List<Task>> kvp in taskList) {
                            foreach (Task t in kvp.Value) {
                                if (id >= 0 && t.id == id) {
                                    ShowTaskNotification(t, command);
                                    return true;
                                } else {
                                    if (t.GetName().ToLower().Contains(parameter)) {
                                        tasks.Add(t);
                                    }
                                }
                            }
                        }
                        if (tasks.Count == 1) {
                            ShowTaskNotification(tasks[0] as Task, command);
                        } else {
                            ShowCreatureList(tasks, String.Format("Tasks Containing \"{0}\"", parameter), command);
                        }

                    }
                } else if (comp.StartsWith("category" + MainForm.commandSymbol)) { //category@
                                                                                   // list all items with the specified category
                    string parameter = command.Split(commandSymbol)[1].Trim().ToLower();
                    List<TibiaObject> items = getItemsByCategory(parameter);
                    if (items.Count == 1) {
                        ShowItemNotification("item" + MainForm.commandSymbol + items[0].GetName().ToLower());
                    } else if (items.Count > 1) {
                        ShowCreatureList(items, "Category: " + parameter, command, true);
                    }
                } else if (comp.StartsWith("hunt" + MainForm.commandSymbol)) { //hunt@
                    string[] splits = command.Split(commandSymbol);
                    string parameter = splits[1].Trim().ToLower();
                    int page = 0;
                    if (splits.Length > 2 && int.TryParse(splits[2], out page)) { }
                    if (cities.Contains(parameter)) {
                        List<HuntingPlace> huntingPlaces = getHuntsInCity(parameter);
                        ShowCreatureList(huntingPlaces.ToList<TibiaObject>(), "Hunts in " + parameter, command);
                        return true;
                    }
                    HuntingPlace h = getHunt(parameter);
                    if (h != null) {
                        ShowHuntingPlace(h, command);
                        return true;
                    }
                    Creature cr = getCreature(parameter);
                    if (cr != null) {
                        List<HuntingPlace> huntingPlaces = getHuntsForCreature(cr.id);
                        ShowCreatureList(huntingPlaces.ToList<TibiaObject>(), "Hunts containing creature " + ToTitle(parameter), command);
                        return true;
                    }
                    int minlevel = -1, maxlevel = -1;
                    int level;
                    if (int.TryParse(parameter, out level)) {
                        minlevel = (int)(level * 0.8);
                        maxlevel = (int)(level * 1.2);
                    } else if (parameter.Contains('-')) {
                        string[] split = parameter.Split('-');
                        int.TryParse(split[0].Trim(), out minlevel);
                        int.TryParse(split[1].Trim(), out maxlevel);
                    }
                    if (minlevel >= 0 && maxlevel >= 0) {
                        List<HuntingPlace> huntingPlaces = getHuntsForLevels(minlevel, maxlevel);
                        huntingPlaces = huntingPlaces.OrderBy(o => o.level).ToList();
                        ShowCreatureList(huntingPlaces.ToList<TibiaObject>(), "Hunts between levels " + minlevel.ToString() + "-" + maxlevel.ToString(), command);
                        return true;
                    } else {
                        string title;
                        List<HuntingPlace> huntList = searchHunt(parameter);
                        title = "Hunts Containing \"" + parameter + "\"";
                        if (huntList.Count == 1) {
                            ShowHuntingPlace(huntList[0], command);
                        } else if (huntList.Count > 1) {
                            ShowCreatureList(huntList.ToList<TibiaObject>(), title, command);
                        }
                    }
                } else if (comp.StartsWith("npc" + MainForm.commandSymbol)) { //npc@
                    string parameter = command.Split(commandSymbol)[1].Trim().ToLower();
                    NPC npc = getNPC(parameter);
                    if (npc != null) {
                        ShowNPCForm(npc, command);
                    } else if (cities.Contains(parameter)) {
                        ShowCreatureList(getNPCWithCity(parameter), "NPC List", command);
                    } else {
                        ShowCreatureList(searchNPC(parameter), "NPC List", command);
                    }
                } else if (comp.StartsWith("savelog" + MainForm.commandSymbol)) {
                    saveLog(activeHunt, command.Split(commandSymbol)[1].Trim().Replace("'", "\\'"));
                } else if (comp.StartsWith("loadlog" + MainForm.commandSymbol)) {
                    loadLog(activeHunt, command.Split(commandSymbol)[1].Trim().Replace("'", "\\'"));
                } else if (comp.StartsWith("setdiscardgoldratio" + MainForm.commandSymbol)) {
                    double val;
                    if (double.TryParse(command.Split(commandSymbol)[1].Trim(), out val)) {
                        setGoldRatio(val);
                    }
                } else if (comp.StartsWith("wiki" + MainForm.commandSymbol)) {
                    string parameter = command.Split(commandSymbol)[1].Trim();
                    string response = "";
                    using (WebClient client = new WebClient()) {
                        response = client.DownloadString(String.Format("http://tibia.wikia.com/api/v1/Search/List?query={0}&limit=1&minArticleQuality=10&batch=1&namespaces=0", parameter));
                    }
                    Regex regex = new Regex("\"url\":\"([^\"]+)\"");
                    Match m = regex.Match(response);
                    var gr = m.Groups[1];
                    OpenUrl(gr.Value.Replace("\\/", "/"));
                } else if (comp.StartsWith("char" + MainForm.commandSymbol)) {
                    string parameter = command.Split(commandSymbol)[1].Trim();
                    OpenUrl("https://secure.tibia.com/community/?subtopic=characters&name=" + parameter);
                } else if (comp.StartsWith("setconvertgoldratio" + MainForm.commandSymbol)) {
                    string parameter = command.Split(commandSymbol)[1].Trim();
                    string[] split = parameter.Split('-');
                    if (split.Length < 2) return true;
                    int stackable = 0;
                    if (split[0] == "1") stackable = 1;
                    double val;
                    if (double.TryParse(split[1], out val)) {
                        setConvertRatio(val, stackable == 1);
                    }
                } else if (comp.StartsWith("recent" + MainForm.commandSymbol) || comp.StartsWith("url" + MainForm.commandSymbol) || comp.StartsWith("last" + MainForm.commandSymbol)) {
                    bool url = comp.StartsWith("url" + MainForm.commandSymbol);
                    int type = url ? 1 : 0;
                    string parameter = command.Split(commandSymbol)[1].Trim().ToLower();
                    if (comp.StartsWith("last" + MainForm.commandSymbol)) parameter = "1";
                    List<Command> command_list = getRecentCommands(type).Select(o => new Command() { player = o.Item1, command = o.Item2 }).ToList();
                    command_list.Reverse();
                    int number;
                    //recent@<number> opens the last <number> command, so recent@1 opens the last command
                    if (int.TryParse(parameter, out number)) {
                        if (number > 0 && number <= command_list.Count) {
                            ListNotification.OpenCommand(command_list[number - 1].command, type); ;
                            return true;
                        }
                    } else {
                        //recent@<player> opens the last
                        bool found = false;
                        foreach (Command comm in command_list) {
                            if (comm.player.ToLower() == parameter) {
                                ListNotification.OpenCommand(command_list[number].command, type);
                                found = true;
                                break;
                            }
                        }
                        if (found) return true;
                    }
                    ShowListNotification(command_list, type, command);
                } else if (comp.StartsWith("spell" + MainForm.commandSymbol)) { // spell@
                    string[] splits = command.Split(commandSymbol);
                    string parameter = splits[1].Trim().ToLower();
                    int initialVocation = -1;
                    if (splits.Length > 2 && int.TryParse(splits[2], out initialVocation)) { }
                    Spell spell = getSpell(parameter);
                    if (spell != null) {
                        ShowSpellNotification(spell, initialVocation, command);
                    } else {
                        List<TibiaObject> spellList = new List<TibiaObject>();
                        string title;
                        if (Constants.vocations.Contains(parameter)) {
                            spellList = getSpellsForVocation(parameter);
                            title = ToTitle(parameter) + " Spells";
                        } else {
                            spellList = searchSpell(parameter);
                            if (spellList.Count == 0) {
                                spellList = searchSpellWords(parameter);
                            }
                            title = "Spells Containing \"" + parameter + "\"";
                        }
                        if (spellList.Count == 1) {
                            ShowSpellNotification(spellList[0].AsSpell(), initialVocation, command);
                        } else if (spellList.Count > 1) {
                            ShowCreatureList(spellList, title, command);
                        }
                    }
                } else if (comp.StartsWith("outfit" + MainForm.commandSymbol)) { // outfit@
                    string parameter = command.Split(commandSymbol)[1].Trim().ToLower();
                    Outfit outfit = getOutfit(parameter);
                    if (outfit != null) {
                        ShowOutfitNotification(outfit, command);
                    } else {
                        string title;
                        List<TibiaObject> outfitList = searchOutfit(parameter);
                        title = "Outfits Containing \"" + parameter + "\"";
                        if (outfitList.Count == 1) {
                            ShowOutfitNotification(outfitList[0].AsOutfit(), command);
                        } else if (outfitList.Count > 1) {
                            ShowCreatureList(outfitList, title, command);
                        }
                    }
                } else if (comp.StartsWith("quest" + MainForm.commandSymbol)) { // quest@
                    string[] splits = command.Split(commandSymbol);
                    string parameter = splits[1].Trim().ToLower();
                    int page = 0;
                    if (splits.Length > 2 && int.TryParse(splits[2], out page)) { }
                    List<Quest> questList = new List<Quest>();
                    if (questNameMap.ContainsKey(parameter)) {
                        ShowQuestNotification(questNameMap[parameter], command);
                    } else {
                        string title;
                        if (cities.Contains(parameter)) {
                            title = "Quests In " + parameter;
                            foreach (Quest q in questIdMap.Values) {
                                if (q.city.ToLower() == parameter) {
                                    questList.Add(q);
                                }
                            }
                        } else {
                            title = "Quests Containing \"" + parameter + "\"";
                            string[] splitStrings = parameter.Split(' ');
                            foreach (Quest quest in questIdMap.Values) {
                                bool found = true;
                                foreach (string str in splitStrings) {
                                    if (!quest.name.ToLower().Contains(str)) {
                                        found = false;
                                        break;
                                    }
                                }
                                if (found) {
                                    questList.Add(quest);
                                }
                            }
                        }
                        if (questList.Count == 1) {
                            ShowQuestNotification(questList[0], command);
                        } else if (questList.Count > 1) {
                            ShowCreatureList(questList.ToList<TibiaObject>(), title, command);
                            //ShowQuestList(questList, title, command, page);
                        }
                    }
                } else if (comp.StartsWith("guide" + MainForm.commandSymbol)) { // guide@
                    string[] splits = command.Split(commandSymbol);
                    string parameter = splits[1].Trim().ToLower();
                    int page = 0;
                    string mission = "";
                    if (splits.Length > 2 && int.TryParse(splits[2], out page)) { }
                    if (splits.Length > 3) { mission = splits[3]; }
                    List<Quest> questList = new List<Quest>();
                    if (questNameMap.ContainsKey(parameter)) {
                        ShowQuestGuideNotification(questNameMap[parameter], command, page, mission);
                    } else {
                        string title;
                        foreach (Quest quest in questIdMap.Values) {
                            if (quest.name.ToLower().Contains(parameter)) {
                                questList.Add(quest);
                            }
                        }
                        title = "Quests Containing \"" + parameter + "\"";
                        if (questList.Count == 1) {
                            ShowQuestGuideNotification(questList[0], command, page, mission);
                        } else if (questList.Count > 1) {
                            ShowCreatureList(questList.ToList<TibiaObject>(), title, command);
                        }
                    }
                } else if (comp.StartsWith("direction" + MainForm.commandSymbol)) { // direction@
                    string[] splits = command.Split(commandSymbol);
                    string parameter = splits[1].Trim().ToLower();
                    int page = 0;
                    if (splits.Length > 2 && int.TryParse(splits[2], out page)) { }
                    List<HuntingPlace> huntList = new List<HuntingPlace>();
                    HuntingPlace h = getHunt(parameter);
                    if (h != null) {
                        ShowHuntGuideNotification(h, command, page);
                    } else {
                        string title;
                        huntList = searchHunt(parameter);
                        title = "Hunts Containing \"" + parameter + "\"";
                        if (huntList.Count == 1) {
                            ShowHuntGuideNotification(huntList[0], command, page);
                        } else if (huntList.Count > 1) {
                            ShowCreatureList(huntList.ToList<TibiaObject>(), title, command);
                        }
                    }
                } else if (comp.StartsWith("mount" + MainForm.commandSymbol)) { // mount@
                    string parameter = command.Split(commandSymbol)[1].Trim().ToLower();
                    Mount m = getMount(parameter);
                    if (m != null) {
                        ShowMountNotification(m, command);
                    } else {
                        string title;
                        List<TibiaObject> mountList = searchMount(parameter);
                        title = "Mounts Containing \"" + parameter + "\"";
                        if (mountList.Count == 1) {
                            ShowMountNotification(mountList[0].AsMount(), command);
                        } else if (mountList.Count > 1) {
                            ShowCreatureList(mountList, title, command);
                        }
                    }
                } else if (comp.StartsWith("pickup" + MainForm.commandSymbol)) {
                    string parameter = command.Split(commandSymbol)[1].Trim().ToLower();
                    Item item = getItem(parameter);
                    if (item != null) {
                        setItemDiscard(item, false);
                    }
                } else if (comp.StartsWith("nopickup" + MainForm.commandSymbol)) {
                    string parameter = command.Split(commandSymbol)[1].Trim().ToLower();
                    Item item = getItem(parameter);
                    if (item != null) {
                        setItemDiscard(item, true);
                    }
                } else if (comp.StartsWith("convert" + MainForm.commandSymbol)) {
                    string parameter = command.Split(commandSymbol)[1].Trim().ToLower();
                    Item item = getItem(parameter);
                    if (item != null) {
                        setItemConvert(item, true);
                    }
                } else if (comp.StartsWith("noconvert" + MainForm.commandSymbol)) {
                    string parameter = command.Split(commandSymbol)[1].Trim().ToLower();
                    Item item = getItem(parameter);
                    if (item != null) {
                        setItemConvert(item, false);
                    }
                } else if (comp.StartsWith("setval" + MainForm.commandSymbol)) {
                    string parameter = command.Split(commandSymbol)[1].Trim();
                    if (!parameter.Contains('=')) return true;
                    string[] split = parameter.Split('=');
                    string item = split[0].Trim().ToLower().Replace("'", "\\'");
                    long value = 0;
                    if (long.TryParse(split[1].Trim(), out value)) {
                        Item it = getItem(split[0]);
                        if (it != null) {
                            setItemValue(it, value);
                        }
                    }
                } else if (comp.StartsWith("screenshot" + MainForm.commandSymbol)) {
                    saveScreenshot("Screenshot", takeScreenshot());
                } else {
                    bool found = false;
                    foreach (string city in cities) {
                        if (comp.StartsWith(city + MainForm.commandSymbol)) {
                            string itemName = command.Split(commandSymbol)[1].Trim().ToLower();
                            Item item = getItem(itemName);
                            if (item != null) {
                                NPC npc = getNPCSellingItemInCity(item.id, city);
                                if (npc != null) {
                                    ShowNPCForm(npc, command);
                                }
                            } else {
                                Spell spell = getSpell(itemName);
                                if (spell != null) {
                                    NPC npc = getNPCTeachingSpellInCity(spell.id, city);
                                    if (npc != null) {
                                        ShowNPCForm(npc, command);
                                    }
                                }
                            }

                            found = true;
                        }
                    }
                    // else try custom commands
                    foreach(SystemCommand c in customCommands) {
                        if (c.tibialyzer_command.Trim().Length > 0 && comp.StartsWith(c.tibialyzer_command + commandSymbol)) {
                            string[] parameters = command.Split(commandSymbol);
                            string systemCallParameters = c.parameters;
                            int i = 0;
                            while(true) {
                                if (systemCallParameters.Contains("{" + i.ToString() + "}")) {
                                    systemCallParameters = systemCallParameters.Replace("{" + i.ToString() + "}", parameters.Length > i + 1 ? parameters[i + 1].Trim() : "");
                                } else {
                                    break;
                                }
                                i++;
                            }
                            ProcessStartInfo procStartInfo = new ProcessStartInfo(c.command, systemCallParameters);

                            procStartInfo.UseShellExecute = true;

                            // Do not show the cmd window to the user.
                            procStartInfo.CreateNoWindow = true;
                            procStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
                            Process.Start(procStartInfo);
                            return true;
                        }
                    }
                    if (found) return true;
                    //if we get here we didn't find any command
                    return false;
                }
                return true;
            } catch (Exception e) {
                DisplayWarning(String.Format("Tibialyzer Exception While Processing Command \"{0}\".\nMessage: {1} ", command, e.Message));
                Console.WriteLine(e.Message);
                return true;
            }
        }
Example #7
0
        public static bool ExecuteCommand(string command, ParseMemoryResults parseMemoryResults = null)
        {
            try {
                if (parseMemoryResults == null)
                {
                    parseMemoryResults = ScanningManager.lastResults;
                }
                string comp = command.Trim().ToLower();
                Console.WriteLine(command);
                if (comp.StartsWith("creature" + Constants.CommandSymbol))   //creature@
                {
                    string[] split     = command.Split(Constants.CommandSymbol);
                    string   parameter = split[1].Trim().ToLower();
                    Creature cr        = StorageManager.getCreature(parameter);
                    if (cr != null)
                    {
                        NotificationManager.ShowCreatureDrops(cr, command);
                    }
                    else
                    {
                        List <TibiaObject> creatures = StorageManager.searchCreature(parameter);
                        if (creatures.Count == 1)
                        {
                            NotificationManager.ShowCreatureDrops(creatures[0].AsCreature(), command);
                        }
                        else if (creatures.Count > 1)
                        {
                            NotificationManager.ShowCreatureList(creatures, "Creature List", command);
                        }
                    }
                }
                else if (comp.StartsWith("look" + Constants.CommandSymbol))     //look@
                {
                    string parameter = command.Split(Constants.CommandSymbol)[1].Trim().ToLower();
                    if (parameter == "on")
                    {
                        SettingsManager.setSetting("LookMode", "True");
                    }
                    else if (parameter == "off")
                    {
                        SettingsManager.setSetting("LookMode", "False");
                    }
                    else
                    {
                        List <string>      times = TimestampManager.getLatestTimes(5);
                        List <TibiaObject> items = new List <TibiaObject>();
                        foreach (string message in GlobalDataManager.GetLookInformation(times))
                        {
                            string itemName = Parser.parseLookItem(message).ToLower();
                            Item   item     = StorageManager.getItem(itemName);

                            if (item != null)
                            {
                                items.Add(item);
                            }
                            else
                            {
                                Creature cr = StorageManager.getCreature(itemName);
                                if (cr != null)
                                {
                                    items.Add(cr);
                                }
                            }
                        }
                        if (items.Count == 1)
                        {
                            if (items[0] is Item)
                            {
                                NotificationManager.ShowItemNotification("item" + Constants.CommandSymbol + items[0].GetName().ToLower());
                            }
                            else if (items[0] is Creature)
                            {
                                NotificationManager.ShowCreatureDrops(items[0].AsCreature(), command);
                            }
                        }
                        else if (items.Count > 1)
                        {
                            NotificationManager.ShowCreatureList(items, "Looked At Items", command);
                        }
                    }
                }
                else if (comp.StartsWith("stats" + Constants.CommandSymbol))     //stats@
                {
                    string   name = command.Split(Constants.CommandSymbol)[1].Trim().ToLower();
                    Creature cr   = StorageManager.getCreature(name);
                    if (cr != null)
                    {
                        NotificationManager.ShowCreatureStats(cr, command);
                    }
                }
                else if (comp.StartsWith("close" + Constants.CommandSymbol))     //close@
                                                                                 // close all notifications
                {
                    NotificationManager.ClearNotifications();
                    PopupManager.ClearSimpleNotifications();
                }
                else if (comp.StartsWith("delete" + Constants.CommandSymbol))     //delete@
                {
                    string parameter = command.Split(Constants.CommandSymbol)[1].Trim().ToLower();
                    int    killCount;
                    if (int.TryParse(parameter, out killCount))
                    {
                        HuntManager.deleteCreatureWithThreshold(killCount);
                    }
                    else
                    {
                        Creature cr = StorageManager.getCreature(parameter);
                        if (cr != null)
                        {
                            HuntManager.deleteCreatureFromLog(cr);
                        }
                    }
                }
                else if (comp.StartsWith("skin" + Constants.CommandSymbol))     //skin@
                {
                    string[] split     = command.Split(Constants.CommandSymbol);
                    string   parameter = split[1].Trim().ToLower();
                    int      count     = 1;
                    Creature cr        = StorageManager.getCreature(parameter);
                    if (cr != null)
                    {
                        if (split.Length > 2)
                        {
                            int.TryParse(split[2], out count);
                        }
                        HuntManager.InsertSkin(cr, count);
                    }
                    else
                    {
                        int.TryParse(parameter, out count);
                        // find creature with highest killcount with a skin and skin that
                        cr = HuntManager.GetHighestKillCreature(HuntManager.activeHunt);
                        if (cr != null)
                        {
                            HuntManager.InsertSkin(cr, count);
                        }
                    }
                }
                else if (comp.StartsWith("city" + Constants.CommandSymbol))     //city@
                {
                    string parameter = command.Split(Constants.CommandSymbol)[1].Trim().ToLower();
                    if (StorageManager.cityNameMap.ContainsKey(parameter))
                    {
                        City city = StorageManager.cityNameMap[parameter];
                        NotificationManager.ShowCityDisplayForm(city, command);
                    }
                }
                else if (comp.StartsWith("damage" + Constants.CommandSymbol))     //damage@
                {
                    if (parseMemoryResults != null)
                    {
                        string[] splits          = command.Split(Constants.CommandSymbol);
                        string   screenshot_path = "";
                        string   parameter       = splits[1].Trim().ToLower();
                        if (parameter == "screenshot" && splits.Length > 2)
                        {
                            parameter       = "";
                            screenshot_path = splits[2];
                        }
                        NotificationManager.ShowDamageMeter(parseMemoryResults.damagePerSecond, command, parameter, screenshot_path);
                    }
                }
                else if (comp.StartsWith("experience" + Constants.CommandSymbol))     //experience@
                {
                    if (parseMemoryResults != null)
                    {
                        NotificationManager.ShowExperienceChartNotification(command);
                    }
                }
                else if (comp.StartsWith("remindme" + Constants.CommandSymbol))     //remindme@
                {
                    string[] splits = command.Split(Constants.CommandSymbol);
                    string   time = splits[1].ToLower().Replace(" ", "").Replace("\t", "").Replace("\n", "") + 's'; //remove all whitespace
                    int      timeInSeconds = 0;
                    int      startIndex = 0, endIndex = 0;
                    for (int i = 0; i < time.Length; i++)
                    {
                        if (time[i].isDigit())
                        {
                            endIndex = i + 1;
                        }
                        else if (endIndex > startIndex)
                        {
                            int value = int.Parse(time.Substring(startIndex, endIndex - startIndex));
                            if (time[i] == 'm')
                            {
                                value *= 60;
                            }
                            else if (time[i] == 'h')
                            {
                                value *= 3600;
                            }
                            timeInSeconds += value;
                            startIndex     = i + 1;
                            endIndex       = startIndex;
                        }
                        else
                        {
                            startIndex = i + 1;
                        }
                    }
                    if (timeInSeconds > 0)
                    {
                        Image iconImage = null;
                        if (splits.Length > 4)
                        {
                            string        icon    = splits[4];
                            TibiaObject[] objects = new TibiaObject[] { StorageManager.getItem(icon), StorageManager.getCreature(icon), StorageManager.getNPC(icon), StorageManager.getMount(icon), StorageManager.getSpell(icon), StorageManager.getOutfit(icon) };
                            foreach (var obj in objects)
                            {
                                if (obj != null)
                                {
                                    iconImage = obj.GetImage();
                                    if (iconImage != null)
                                    {
                                        break;
                                    }
                                }
                            }
                        }
                        string title   = splits.Length > 2 ? splits[2] : "Reminder!";
                        string message = splits.Length > 3 ? splits[3] : String.Format("Reminder from {0} seconds ago!", timeInSeconds);

                        const int notificationWarningTime = 5;

                        if (timeInSeconds <= notificationWarningTime)
                        {
                            PopupManager.ShowSimpleNotification(new SimpleTimerNotification(iconImage, title, message, timeInSeconds));
                        }
                        else
                        {
                            System.Timers.Timer timer = new System.Timers.Timer(1000 * (timeInSeconds - notificationWarningTime));
                            timer.Elapsed += (sender, e) => {
                                timer.Enabled = false;
                                timer.Dispose();

                                MainForm.mainForm.Invoke((MethodInvoker) delegate {
                                    PopupManager.ShowSimpleNotification(new SimpleTimerNotification(iconImage, title, message, notificationWarningTime));
                                });
                            };
                            timer.Enabled = true;
                        }
                    }
                }
                else if (comp.StartsWith("exp" + Constants.CommandSymbol))     //exp@
                {
                    string title = "Experience";
                    string text  = "Currently gaining " + (parseMemoryResults == null ? "unknown" : ((int)parseMemoryResults.expPerHour).ToString()) + " experience an hour.";
                    Image  image = StyleManager.GetImage("tibia.png");
                    if (!SettingsManager.getSettingBool("UseRichNotificationType"))
                    {
                        PopupManager.ShowSimpleNotification(title, text, image);
                    }
                    else
                    {
                        PopupManager.ShowSimpleNotification(new SimpleTextNotification(null, title, text));
                    }
                }
                else if (comp.StartsWith("waste" + Constants.CommandSymbol))     //waste@
                {
                    NotificationManager.ShowWasteForm(HuntManager.activeHunt, command);
                }
                else if (comp.StartsWith("summary" + Constants.CommandSymbol))     //summary@
                {
                    NotificationManager.ShowSummaryForm(command);
                }
                else if (comp.StartsWith("loot" + Constants.CommandSymbol))     //loot@
                {
                    string[] splits          = command.Split(Constants.CommandSymbol);
                    string   screenshot_path = "";
                    string   parameter       = splits[1].Trim().ToLower();
                    if (parameter == "screenshot" && splits.Length > 2)
                    {
                        parameter       = "";
                        screenshot_path = splits[2];
                    }

                    Hunt currentHunt = HuntManager.activeHunt;
                    if (splits.Length >= 2 && splits[1] != "")
                    {
                        Hunt h = HuntManager.GetHunt(splits[1]);
                        if (h != null)
                        {
                            currentHunt = h;
                        }
                    }
                    // display loot notification
                    NotificationManager.ShowLootDrops(currentHunt, command, screenshot_path);
                }
                else if (comp.StartsWith("clipboard" + Constants.CommandSymbol))     //clipboard@
                // Copy loot message to the clipboard
                // clipboard@damage copies the damage information to the clipboard
                // clipboard@<creature> copies the loot of a specific creature to the clipboard
                // clipboard@ copies all loot to the clipboard
                {
                    string   creatureName = command.Split(Constants.CommandSymbol)[1].Trim().ToLower();
                    Creature lootCreature = null;
                    if (creatureName == "damage" && parseMemoryResults != null)
                    {
                        var    damageInformation = DamageChart.GenerateDamageInformation(parseMemoryResults.damagePerSecond, "");
                        string damageString      = "Damage Dealt: ";
                        foreach (var damage in damageInformation)
                        {
                            damageString += String.Format("{0}: {1:N1}%; ", damage.name, damage.percentage);
                        }
                        Clipboard.SetText(damageString.Substring(0, damageString.Length - 2));
                        return(true);
                    }
                    else if (creatureName != "")
                    {
                        lootCreature = StorageManager.getCreature(creatureName);
                    }

                    var tpl           = LootDropForm.GenerateLootInformation(HuntManager.activeHunt, "", lootCreature);
                    var creatureKills = tpl.Item1;
                    var itemDrops     = tpl.Item2;

                    string lootString = "";
                    if (creatureKills.Count == 1)
                    {
                        foreach (KeyValuePair <Creature, int> kvp in creatureKills)
                        {
                            lootString = "Total Loot of " + kvp.Value.ToString() + " " + kvp.Key.GetName() + (kvp.Value > 1 ? "s" : "") + ": ";
                        }
                    }
                    else
                    {
                        int totalKills = 0;
                        foreach (KeyValuePair <Creature, int> kvp in creatureKills)
                        {
                            totalKills += kvp.Value;
                        }
                        lootString = "Total Loot of " + totalKills + " Kills: ";
                    }
                    foreach (Tuple <Item, int> kvp in itemDrops)
                    {
                        lootString += kvp.Item2 + " " + kvp.Item1.displayname + (kvp.Item2 > 1 ? "s" : "") + ", ";
                    }
                    lootString = lootString.Substring(0, lootString.Length - 2) + ".";
                    Clipboard.SetText(lootString);
                }
                else if (comp.StartsWith("reset" + Constants.CommandSymbol))     //reset@
                {
                    string parameter = command.Split(Constants.CommandSymbol)[1].Trim().ToLower();
                    int    time      = 0;
                    if (parameter == "old")
                    {
                        HuntManager.clearOldLog(HuntManager.activeHunt);
                    }
                    else if (int.TryParse(parameter, out time) && time > 0)
                    {
                        HuntManager.clearOldLog(HuntManager.activeHunt, time);
                    }
                    else
                    {
                        // reset@<hunt> resets the specified hunt
                        if (parameter.Length > 0 && HuntManager.resetHunt(parameter))
                        {
                            return(true);
                        }
                        else
                        {
                            //reset@ deletes all loot from the currently active hunt
                            HuntManager.resetHunt(HuntManager.activeHunt);
                        }
                    }
                    MainForm.mainForm.refreshHunts();
                    ReadMemoryManager.ignoreStamp = TimestampManager.createStamp();
                }
                else if (comp.StartsWith("refresh" + Constants.CommandSymbol))     //refresh@
                                                                                   // refresh: refresh duration on current form, or if no current form, repeat last command without removing it from stack

                /*if (tooltipForm != null && !tooltipForm.IsDisposed) {
                 *  try {
                 *      (tooltipForm as NotificationForm).ResetTimer();
                 *  } catch {
                 *  }
                 * } else if (command_stack.Count > 0) {*/
                {
                    ExecuteCommand(NotificationManager.LastCommand().command);
                    //}
                    return(true);
                }
                else if (comp.StartsWith("switch" + Constants.CommandSymbol))     //switch@
                                                                                  // switch: switch to hunt
                {
                    string parameter = command.Split(Constants.CommandSymbol)[1].Trim().ToLower();
                    HuntManager.SwitchHunt(parameter);
                    HuntManager.SaveHunts();
                }
                else if (comp.StartsWith("item" + Constants.CommandSymbol))     //item@
                                                                                //show the item with all the NPCs that sell it
                {
                    NotificationManager.ShowItemNotification(command);
                }
                else if (comp.StartsWith("task" + Constants.CommandSymbol))     //task@
                {
                    string parameter = command.Split(Constants.CommandSymbol)[1].Trim().ToLower();
                    if (StorageManager.taskList.Keys.Contains(parameter))
                    {
                        NotificationManager.ShowCreatureList(StorageManager.taskList[parameter].ToList <TibiaObject>(), StorageManager.taskList[parameter][0].groupname, command);
                    }
                    else
                    {
                        int id = -1;
                        int.TryParse(parameter, out id);
                        List <TibiaObject> tasks = new List <TibiaObject>();
                        foreach (KeyValuePair <string, List <Task> > kvp in StorageManager.taskList)
                        {
                            foreach (Task t in kvp.Value)
                            {
                                if (id >= 0 && t.id == id)
                                {
                                    NotificationManager.ShowTaskNotification(t, command);
                                    return(true);
                                }
                                else
                                {
                                    if (t.GetName().Contains(parameter, StringComparison.OrdinalIgnoreCase))
                                    {
                                        tasks.Add(t);
                                    }
                                }
                            }
                        }
                        if (tasks.Count == 1)
                        {
                            NotificationManager.ShowTaskNotification(tasks[0] as Task, command);
                        }
                        else
                        {
                            NotificationManager.ShowCreatureList(tasks, String.Format("Tasks Containing \"{0}\"", parameter), command);
                        }
                    }
                }
                else if (comp.StartsWith("category" + Constants.CommandSymbol))     //category@
                                                                                    // list all items with the specified category
                {
                    string             parameter = command.Split(Constants.CommandSymbol)[1].Trim().ToLower();
                    List <TibiaObject> items     = StorageManager.getItemsByCategory(parameter);
                    if (items.Count == 1)
                    {
                        NotificationManager.ShowItemNotification("item" + Constants.CommandSymbol + items[0].GetName().ToLower());
                    }
                    else if (items.Count > 1)
                    {
                        NotificationManager.ShowCreatureList(items, "Category: " + parameter, command, true);
                    }
                }
                else if (comp.StartsWith("hunt" + Constants.CommandSymbol))     //hunt@
                {
                    string[] splits    = command.Split(Constants.CommandSymbol);
                    string   parameter = splits[1].Trim().ToLower();
                    int      page      = 0;
                    if (splits.Length > 2 && int.TryParse(splits[2], out page))
                    {
                    }
                    if (Constants.cities.Contains(parameter))
                    {
                        List <HuntingPlace> huntingPlaces = StorageManager.getHuntsInCity(parameter);
                        NotificationManager.ShowCreatureList(huntingPlaces.ToList <TibiaObject>(), "Hunts in " + parameter, command);
                        return(true);
                    }
                    HuntingPlace h = StorageManager.getHunt(parameter);
                    if (h != null)
                    {
                        NotificationManager.ShowHuntingPlace(h, command);
                        return(true);
                    }
                    Creature cr = StorageManager.getCreature(parameter);
                    if (cr != null)
                    {
                        List <HuntingPlace> huntingPlaces = StorageManager.getHuntsForCreature(cr.id);
                        NotificationManager.ShowCreatureList(huntingPlaces.ToList <TibiaObject>(), "Hunts containing creature " + parameter.ToTitle(), command);
                        return(true);
                    }
                    int minlevel = -1, maxlevel = -1;
                    int level;
                    if (int.TryParse(parameter, out level))
                    {
                        minlevel = (int)(level * 0.8);
                        maxlevel = (int)(level * 1.2);
                    }
                    else if (parameter.Contains('-'))
                    {
                        string[] split = parameter.Split('-');
                        int.TryParse(split[0].Trim(), out minlevel);
                        int.TryParse(split[1].Trim(), out maxlevel);
                    }
                    if (minlevel >= 0 && maxlevel >= 0)
                    {
                        List <HuntingPlace> huntingPlaces = StorageManager.getHuntsForLevels(minlevel, maxlevel);
                        huntingPlaces = huntingPlaces.OrderBy(o => o.level).ToList();
                        NotificationManager.ShowCreatureList(huntingPlaces.ToList <TibiaObject>(), "Hunts between levels " + minlevel.ToString() + "-" + maxlevel.ToString(), command);
                        return(true);
                    }
                    else
                    {
                        string title;
                        List <HuntingPlace> huntList = StorageManager.searchHunt(parameter);
                        title = "Hunts Containing \"" + parameter + "\"";
                        if (huntList.Count == 1)
                        {
                            NotificationManager.ShowHuntingPlace(huntList[0], command);
                        }
                        else if (huntList.Count > 1)
                        {
                            NotificationManager.ShowCreatureList(huntList.ToList <TibiaObject>(), title, command);
                        }
                    }
                }
                else if (comp.StartsWith("npc" + Constants.CommandSymbol))     //npc@
                {
                    string parameter = command.Split(Constants.CommandSymbol)[1].Trim().ToLower();
                    NPC    npc       = StorageManager.getNPC(parameter);
                    if (npc != null)
                    {
                        NotificationManager.ShowNPCForm(npc, command);
                    }
                    else if (Constants.cities.Contains(parameter))
                    {
                        NotificationManager.ShowCreatureList(StorageManager.getNPCWithCity(parameter), "NPC List", command);
                    }
                    else
                    {
                        NotificationManager.ShowCreatureList(StorageManager.searchNPC(parameter), "NPC List", command);
                    }
                }
                else if (comp.StartsWith("savelog" + Constants.CommandSymbol))
                {
                    HuntManager.SaveLog(HuntManager.activeHunt, command.Split(Constants.CommandSymbol)[1].Trim().Replace("'", "\\'"));
                }
                else if (comp.StartsWith("loadlog" + Constants.CommandSymbol))
                {
                    HuntManager.LoadLog(HuntManager.activeHunt, command.Split(Constants.CommandSymbol)[1].Trim().Replace("'", "\\'"));
                }
                else if (comp.StartsWith("setdiscardgoldratio" + Constants.CommandSymbol))
                {
                    double val;
                    if (double.TryParse(command.Split(Constants.CommandSymbol)[1].Trim(), out val))
                    {
                        StorageManager.setGoldRatio(val);
                    }
                }
                else if (comp.StartsWith("wiki" + Constants.CommandSymbol))
                {
                    string parameter = command.Split(Constants.CommandSymbol)[1].Trim();
                    string response  = "";
                    using (WebClient client = new WebClient()) {
                        response = client.DownloadString(String.Format("http://tibia.wikia.com/api/v1/Search/List?query={0}&limit=1&minArticleQuality=10&batch=1&namespaces=0", parameter));
                    }
                    Regex regex = new Regex("\"url\":\"([^\"]+)\"");
                    Match m     = regex.Match(response);
                    var   gr    = m.Groups[1];
                    MainForm.OpenUrl(gr.Value.Replace("\\/", "/"));
                }
                else if (comp.StartsWith("char" + Constants.CommandSymbol))
                {
                    string parameter = command.Split(Constants.CommandSymbol)[1].Trim();
                    MainForm.OpenUrl("https://secure.tibia.com/community/?subtopic=characters&name=" + parameter);
                }
                else if (comp.StartsWith("setconvertgoldratio" + Constants.CommandSymbol))
                {
                    string   parameter = command.Split(Constants.CommandSymbol)[1].Trim();
                    string[] split     = parameter.Split('-');
                    if (split.Length < 2)
                    {
                        return(true);
                    }
                    int stackable = 0;
                    if (split[0] == "1")
                    {
                        stackable = 1;
                    }
                    double val;
                    if (double.TryParse(split[1], out val))
                    {
                        StorageManager.setConvertRatio(val, stackable == 1);
                    }
                }
                else if (comp.StartsWith("recent" + Constants.CommandSymbol) || comp.StartsWith("url" + Constants.CommandSymbol) || comp.StartsWith("last" + Constants.CommandSymbol))
                {
                    bool   url       = comp.StartsWith("url" + Constants.CommandSymbol);
                    int    type      = url ? 1 : 0;
                    string parameter = command.Split(Constants.CommandSymbol)[1].Trim().ToLower();
                    if (comp.StartsWith("last" + Constants.CommandSymbol))
                    {
                        parameter = "1";
                    }
                    List <Command> command_list = GlobalDataManager.GetRecentCommands(type).Select(o => new Command()
                    {
                        player = o.Item1, command = o.Item2
                    }).ToList();
                    command_list.Reverse();
                    int number;
                    //recent@<number> opens the last <number> command, so recent@1 opens the last command
                    if (int.TryParse(parameter, out number))
                    {
                        if (number > 0 && number <= command_list.Count)
                        {
                            ListNotification.OpenCommand(command_list[number - 1].command, type);;
                            return(true);
                        }
                    }
                    else
                    {
                        //recent@<player> opens the last
                        bool found = false;
                        foreach (Command comm in command_list)
                        {
                            if (comm.player.ToLower() == parameter)
                            {
                                ListNotification.OpenCommand(command_list[number].command, type);
                                found = true;
                                break;
                            }
                        }
                        if (found)
                        {
                            return(true);
                        }
                    }
                    NotificationManager.ShowListNotification(command_list, type, command);
                }
                else if (comp.StartsWith("spell" + Constants.CommandSymbol))     // spell@
                {
                    string[] splits          = command.Split(Constants.CommandSymbol);
                    string   parameter       = splits[1].Trim().ToLower();
                    int      initialVocation = -1;
                    if (splits.Length > 2 && int.TryParse(splits[2], out initialVocation))
                    {
                    }
                    Spell spell = StorageManager.getSpell(parameter);
                    if (spell != null)
                    {
                        NotificationManager.ShowSpellNotification(spell, initialVocation, command);
                    }
                    else
                    {
                        List <TibiaObject> spellList = new List <TibiaObject>();
                        string             title;
                        if (Constants.vocations.Contains(parameter))
                        {
                            spellList = StorageManager.getSpellsForVocation(parameter);
                            title     = parameter.ToTitle() + " Spells";
                        }
                        else
                        {
                            spellList = StorageManager.searchSpell(parameter);
                            if (spellList.Count == 0)
                            {
                                spellList = StorageManager.searchSpellWords(parameter);
                            }
                            title = "Spells Containing \"" + parameter + "\"";
                        }
                        if (spellList.Count == 1)
                        {
                            NotificationManager.ShowSpellNotification(spellList[0].AsSpell(), initialVocation, command);
                        }
                        else if (spellList.Count > 1)
                        {
                            NotificationManager.ShowCreatureList(spellList, title, command);
                        }
                    }
                }
                else if (comp.StartsWith("outfit" + Constants.CommandSymbol))     // outfit@
                {
                    string parameter = command.Split(Constants.CommandSymbol)[1].Trim().ToLower();
                    Outfit outfit    = StorageManager.getOutfit(parameter);
                    if (outfit != null)
                    {
                        NotificationManager.ShowOutfitNotification(outfit, command);
                    }
                    else
                    {
                        string             title;
                        List <TibiaObject> outfitList = StorageManager.searchOutfit(parameter);
                        title = "Outfits Containing \"" + parameter + "\"";
                        if (outfitList.Count == 1)
                        {
                            NotificationManager.ShowOutfitNotification(outfitList[0].AsOutfit(), command);
                        }
                        else if (outfitList.Count > 1)
                        {
                            NotificationManager.ShowCreatureList(outfitList, title, command);
                        }
                    }
                }
                else if (comp.StartsWith("quest" + Constants.CommandSymbol))     // quest@
                {
                    string[] splits    = command.Split(Constants.CommandSymbol);
                    string   parameter = splits[1].Trim().ToLower();
                    int      page      = 0;
                    if (splits.Length > 2 && int.TryParse(splits[2], out page))
                    {
                    }
                    List <Quest> questList = new List <Quest>();
                    if (StorageManager.questNameMap.ContainsKey(parameter))
                    {
                        NotificationManager.ShowQuestNotification(StorageManager.questNameMap[parameter], command);
                    }
                    else
                    {
                        string title;
                        if (Constants.cities.Contains(parameter))
                        {
                            title = "Quests In " + parameter;
                            foreach (Quest q in StorageManager.questIdMap.Values)
                            {
                                if (q.city.ToLower() == parameter)
                                {
                                    questList.Add(q);
                                }
                            }
                        }
                        else
                        {
                            title = "Quests Containing \"" + parameter + "\"";
                            string[] splitStrings = parameter.Split(' ');
                            foreach (Quest quest in StorageManager.questIdMap.Values)
                            {
                                bool found = true;
                                foreach (string str in splitStrings)
                                {
                                    if (!quest.name.Contains(str, StringComparison.OrdinalIgnoreCase))
                                    {
                                        found = false;
                                        break;
                                    }
                                }
                                if (found)
                                {
                                    questList.Add(quest);
                                }
                            }
                        }
                        if (questList.Count == 1)
                        {
                            NotificationManager.ShowQuestNotification(questList[0], command);
                        }
                        else if (questList.Count > 1)
                        {
                            NotificationManager.ShowCreatureList(questList.ToList <TibiaObject>(), title, command);
                            //ShowQuestList(questList, title, command, page);
                        }
                    }
                }
                else if (comp.StartsWith("guide" + Constants.CommandSymbol))     // guide@
                {
                    string[] splits    = command.Split(Constants.CommandSymbol);
                    string   parameter = splits[1].Trim().ToLower();
                    int      page      = 0;
                    string   mission   = "";
                    if (splits.Length > 2 && int.TryParse(splits[2], out page))
                    {
                    }
                    if (splits.Length > 3)
                    {
                        mission = splits[3];
                    }
                    List <Quest> questList = new List <Quest>();
                    if (StorageManager.questNameMap.ContainsKey(parameter))
                    {
                        NotificationManager.ShowQuestGuideNotification(StorageManager.questNameMap[parameter], command, page, mission);
                    }
                    else
                    {
                        string title;
                        foreach (Quest quest in StorageManager.questIdMap.Values)
                        {
                            if (quest.name.Contains(parameter, StringComparison.OrdinalIgnoreCase))
                            {
                                questList.Add(quest);
                            }
                        }
                        title = "Quests Containing \"" + parameter + "\"";
                        if (questList.Count == 1)
                        {
                            NotificationManager.ShowQuestGuideNotification(questList[0], command, page, mission);
                        }
                        else if (questList.Count > 1)
                        {
                            NotificationManager.ShowCreatureList(questList.ToList <TibiaObject>(), title, command);
                        }
                    }
                }
                else if (comp.StartsWith("direction" + Constants.CommandSymbol))     // direction@
                {
                    string[] splits    = command.Split(Constants.CommandSymbol);
                    string   parameter = splits[1].Trim().ToLower();
                    int      page      = 0;
                    if (splits.Length > 2 && int.TryParse(splits[2], out page))
                    {
                    }
                    List <HuntingPlace> huntList = new List <HuntingPlace>();
                    HuntingPlace        h        = StorageManager.getHunt(parameter);
                    if (h != null)
                    {
                        NotificationManager.ShowHuntGuideNotification(h, command, page);
                    }
                    else
                    {
                        string title;
                        huntList = StorageManager.searchHunt(parameter);
                        title    = "Hunts Containing \"" + parameter + "\"";
                        if (huntList.Count == 1)
                        {
                            NotificationManager.ShowHuntGuideNotification(huntList[0], command, page);
                        }
                        else if (huntList.Count > 1)
                        {
                            NotificationManager.ShowCreatureList(huntList.ToList <TibiaObject>(), title, command);
                        }
                    }
                }
                else if (comp.StartsWith("mount" + Constants.CommandSymbol))     // mount@
                {
                    string parameter = command.Split(Constants.CommandSymbol)[1].Trim().ToLower();
                    Mount  m         = StorageManager.getMount(parameter);
                    if (m != null)
                    {
                        NotificationManager.ShowMountNotification(m, command);
                    }
                    else
                    {
                        string             title;
                        List <TibiaObject> mountList = StorageManager.searchMount(parameter);
                        title = "Mounts Containing \"" + parameter + "\"";
                        if (mountList.Count == 1)
                        {
                            NotificationManager.ShowMountNotification(mountList[0].AsMount(), command);
                        }
                        else if (mountList.Count > 1)
                        {
                            NotificationManager.ShowCreatureList(mountList, title, command);
                        }
                    }
                }
                else if (comp.StartsWith("pickup" + Constants.CommandSymbol))
                {
                    string parameter = command.Split(Constants.CommandSymbol)[1].Trim().ToLower();
                    Item   item      = StorageManager.getItem(parameter);
                    if (item != null)
                    {
                        StorageManager.setItemDiscard(item, false);
                    }
                }
                else if (comp.StartsWith("nopickup" + Constants.CommandSymbol))
                {
                    string parameter = command.Split(Constants.CommandSymbol)[1].Trim().ToLower();
                    Item   item      = StorageManager.getItem(parameter);
                    if (item != null)
                    {
                        StorageManager.setItemDiscard(item, true);
                    }
                }
                else if (comp.StartsWith("convert" + Constants.CommandSymbol))
                {
                    string parameter = command.Split(Constants.CommandSymbol)[1].Trim().ToLower();
                    Item   item      = StorageManager.getItem(parameter);
                    if (item != null)
                    {
                        StorageManager.setItemConvert(item, true);
                    }
                }
                else if (comp.StartsWith("noconvert" + Constants.CommandSymbol))
                {
                    string parameter = command.Split(Constants.CommandSymbol)[1].Trim().ToLower();
                    Item   item      = StorageManager.getItem(parameter);
                    if (item != null)
                    {
                        StorageManager.setItemConvert(item, false);
                    }
                }
                else if (comp.StartsWith("setval" + Constants.CommandSymbol))
                {
                    string parameter = command.Split(Constants.CommandSymbol)[1].Trim();
                    if (!parameter.Contains('='))
                    {
                        return(true);
                    }
                    string[] split = parameter.Split('=');
                    string   item  = split[0].Trim().ToLower().Replace("'", "\\'");
                    long     value = 0;
                    if (long.TryParse(split[1].Trim(), out value))
                    {
                        Item it = StorageManager.getItem(split[0]);
                        if (it != null)
                        {
                            StorageManager.setItemValue(it, value);
                        }
                    }
                }
                else if (comp.StartsWith("screenshot" + Constants.CommandSymbol))
                {
                    ScreenshotManager.saveScreenshot("Screenshot", ScreenshotManager.takeScreenshot());
                }
                else
                {
                    bool found = false;
                    foreach (string city in Constants.cities)
                    {
                        if (comp.StartsWith(city + Constants.CommandSymbol))
                        {
                            string itemName = command.Split(Constants.CommandSymbol)[1].Trim().ToLower();
                            Item   item     = StorageManager.getItem(itemName);
                            if (item != null)
                            {
                                NPC npc = StorageManager.getNPCSellingItemInCity(item.id, city);
                                if (npc != null)
                                {
                                    NotificationManager.ShowNPCForm(npc, command);
                                }
                            }
                            else
                            {
                                Spell spell = StorageManager.getSpell(itemName);
                                if (spell != null)
                                {
                                    NPC npc = StorageManager.getNPCTeachingSpellInCity(spell.id, city);
                                    if (npc != null)
                                    {
                                        NotificationManager.ShowNPCForm(npc, command);
                                    }
                                }
                            }

                            found = true;
                        }
                    }
                    // else try custom commands
                    foreach (SystemCommand c in MainForm.mainForm.GetCustomCommands())
                    {
                        if (c.tibialyzer_command.Trim().Length > 0 && comp.StartsWith(c.tibialyzer_command + Constants.CommandSymbol))
                        {
                            string[] parameters           = command.Split(Constants.CommandSymbol);
                            string   systemCallParameters = c.parameters;
                            int      i = 0;
                            while (true)
                            {
                                if (systemCallParameters.Contains("{" + i.ToString() + "}"))
                                {
                                    systemCallParameters = systemCallParameters.Replace("{" + i.ToString() + "}", parameters.Length > i + 1 ? parameters[i + 1].Trim() : "");
                                }
                                else
                                {
                                    break;
                                }
                                i++;
                            }
                            ProcessStartInfo procStartInfo = new ProcessStartInfo(c.command, systemCallParameters);

                            procStartInfo.UseShellExecute = true;

                            // Do not show the cmd window to the user.
                            procStartInfo.CreateNoWindow = true;
                            procStartInfo.WindowStyle    = ProcessWindowStyle.Hidden;
                            Process.Start(procStartInfo);
                            return(true);
                        }
                    }
                    if (found)
                    {
                        return(true);
                    }
                    //if we get here we didn't find any command
                    return(false);
                }
                return(true);
            } catch (Exception e) {
                MainForm.mainForm.DisplayWarning(String.Format("Tibialyzer Exception While Processing Command \"{0}\".\nMessage: {1} ", command, e.Message));
                Console.WriteLine(e.Message);
                return(true);
            }
        }
Example #8
0
        public static bool ExecuteCommand(string command, ParseMemoryResults parseMemoryResults = null)
        {
            try {
                if (parseMemoryResults == null) {
                    parseMemoryResults = ScanningManager.lastResults;
                }
                string comp = command.Trim().ToLower();
                Console.WriteLine(command);
                if (comp.StartsWith("creature" + Constants.CommandSymbol)) { //creature@
                    string[] split = command.Split(Constants.CommandSymbol);
                    string parameter = split[1].Trim().ToLower();
                    Creature cr = StorageManager.getCreature(parameter);
                    if (cr != null) {
                        NotificationManager.ShowCreatureDrops(cr, command);
                    } else {
                        List<TibiaObject> creatures = StorageManager.searchCreature(parameter);
                        if (creatures.Count == 1) {
                            NotificationManager.ShowCreatureDrops(creatures[0].AsCreature(), command);
                        } else if (creatures.Count > 1) {
                            NotificationManager.ShowCreatureList(creatures, "Creature List", command);
                        }
                    }
                } else if (comp.StartsWith("achievement" + Constants.CommandSymbol)) { //achievement@
                    string[] split = command.Split(Constants.CommandSymbol);
                    string parameter = split[1].Trim().ToLower();
                    Achievement a = StorageManager.getAchievement(parameter);
                    if (a != null) {
                        NotificationManager.ShowAchievement(a, command);
                    } else {
                        List<TibiaObject> achievements = StorageManager.searchAchievement(parameter);
                        if (achievements.Count == 1) {
                            NotificationManager.ShowAchievement(achievements[0] as Achievement, command);
                        } else if (achievements.Count > 1) {
                            NotificationManager.ShowCreatureList(achievements, "Achievements", command);
                        }
                    }
                } else if (comp.StartsWith("player" + Constants.CommandSymbol)) { //player@
                    Player player = new Player();
                    player.name = command.Split(Constants.CommandSymbol)[1].Trim().ToLower();
                    if (player.GatherInformationOnline(true)) {
                        NotificationManager.ShowPlayer(player, command);
                    }
                } else if (comp.StartsWith("look" + Constants.CommandSymbol)) { //look@
                    string parameter = command.Split(Constants.CommandSymbol)[1].Trim().ToLower();
                    if (parameter == "on") {
                        SettingsManager.setSetting("LookMode", "True");
                    } else if (parameter == "off") {
                        SettingsManager.setSetting("LookMode", "False");
                    } else {
                        List<string> times = TimestampManager.getLatestTimes(5);
                        List<TibiaObject> items = new List<TibiaObject>();
                        foreach (string message in GlobalDataManager.GetLookInformation(times)) {
                            string itemName = Parser.parseLookItem(message).Item1.ToLower();
                            Item item = StorageManager.getItem(itemName);

                            if (item != null) {
                                items.Add(item);
                            } else {
                                Creature cr = StorageManager.getCreature(itemName);
                                if (cr != null) {
                                    items.Add(cr);
                                }
                            }
                        }
                        if (items.Count == 1) {
                            if (items[0] is Item) {
                                NotificationManager.ShowItemNotification("item" + Constants.CommandSymbol + items[0].GetName().ToLower());
                            } else if (items[0] is Creature) {
                                NotificationManager.ShowCreatureDrops(items[0].AsCreature(), command);
                            }
                        } else if (items.Count > 1) {
                            NotificationManager.ShowCreatureList(items, "Looked At Items", command);
                        }
                    }
                } else if (comp.StartsWith("stats" + Constants.CommandSymbol)) { //stats@
                    string name = command.Split(Constants.CommandSymbol)[1].Trim().ToLower();
                    Creature cr = StorageManager.getCreature(name);
                    if (cr != null) {
                        NotificationManager.ShowCreatureStats(cr, command);
                    }
                } else if (comp.StartsWith("close" + Constants.CommandSymbol)) { //close@
                                                                                 // close all notifications
                    NotificationManager.ClearNotifications();
                    PopupManager.ClearSimpleNotifications();
                } else if (comp.StartsWith("delete" + Constants.CommandSymbol)) { //delete@
                    string parameter = command.Split(Constants.CommandSymbol)[1].Trim().ToLower();
                    int killCount;
                    if (int.TryParse(parameter, out killCount)) {
                        HuntManager.deleteCreatureWithThreshold(killCount);
                    } else {
                        Creature cr = StorageManager.getCreature(parameter);
                        if (cr != null) {
                            HuntManager.deleteCreatureFromLog(cr);
                        }
                    }
                } else if (comp.StartsWith("addloot" + Constants.CommandSymbol)) { //addloot@
                    string[] split = command.Split(Constants.CommandSymbol);
                    Item item = StorageManager.getItem(split[1].Trim().ToLower());
                    int count = 1;
                    if (split.Length > 2) int.TryParse(split[2], out count);
                    HuntManager.AddLoot(HuntManager.activeHunt, item, count);
                } else if (comp.StartsWith("addwaste" + Constants.CommandSymbol)) { //addwaste@
                    string[] split = command.Split(Constants.CommandSymbol);
                    string parameter = split[1].Trim().ToLower();
                    int count = 1;
                    Item item = StorageManager.getItem(parameter);
                    if (split.Length > 2) int.TryParse(split[2], out count);
                    HuntManager.AddUsedItems(HuntManager.activeHunt, item, count);
                } else if (comp.StartsWith("skin" + Constants.CommandSymbol)) { //skin@
                    string[] split = command.Split(Constants.CommandSymbol);
                    string parameter = split[1].Trim().ToLower();
                    int count = 1;
                    Creature cr = StorageManager.getCreature(parameter);
                    if (cr != null) {
                        if (split.Length > 2)
                            int.TryParse(split[2], out count);
                        HuntManager.InsertSkin(cr, count);
                    } else {
                        int.TryParse(parameter, out count);
                        // find creature with highest killcount with a skin and skin that
                        cr = HuntManager.GetHighestKillCreature(HuntManager.activeHunt);
                        if (cr != null) {
                            HuntManager.InsertSkin(cr, count);
                        }
                    }
                } else if (comp.StartsWith("city" + Constants.CommandSymbol)) { //city@
                    string parameter = command.Split(Constants.CommandSymbol)[1].Trim().ToLower();
                    if (StorageManager.cityNameMap.ContainsKey(parameter)) {
                        City city = StorageManager.cityNameMap[parameter];
                        NotificationManager.ShowCityDisplayForm(city, command);
                    }
                } else if (comp.StartsWith("damage" + Constants.CommandSymbol)) { //damage@
                    if (parseMemoryResults != null) {
                        string[] splits = command.Split(Constants.CommandSymbol);
                        string screenshot_path = "";
                        string parameter = splits[1].Trim().ToLower();
                        if (parameter == "screenshot" && splits.Length > 2) {
                            parameter = "";
                            screenshot_path = splits[2];
                        }
                        NotificationManager.ShowDamageMeter(parseMemoryResults.DamagePerSecond, command, DamageChartType.DamageDealt, parameter, screenshot_path);
                    }
                } else if (comp.StartsWith("damagetaken" + Constants.CommandSymbol)) { //damagetaken@
                    if (parseMemoryResults != null) {
                        string[] splits = command.Split(Constants.CommandSymbol);
                        string parameter = splits[1].Trim().ToLower();
                        NotificationManager.ShowDamageMeter(parseMemoryResults.DamageTakenPerSecond, command, DamageChartType.DamageTaken, parameter);
                    }
                } else if (comp.StartsWith("healing" + Constants.CommandSymbol)) { //healing@
                    if (parseMemoryResults != null) {
                        string[] splits = command.Split(Constants.CommandSymbol);
                        string parameter = splits[1].Trim().ToLower();
                        NotificationManager.ShowDamageMeter(parseMemoryResults.HealingPerSecond, command, DamageChartType.HealingDone, parameter);
                    }
                } else if (comp.StartsWith("experience" + Constants.CommandSymbol)) { //experience@
                    if (parseMemoryResults != null) {
                        NotificationManager.ShowExperienceChartNotification(command);
                    }
                } else if (comp.StartsWith("remindme" + Constants.CommandSymbol)) { //remindme@
                    string[] splits = command.Split(Constants.CommandSymbol);
                    string time = splits[1].ToLower().Replace(" ", "").Replace("\t", "").Replace("\n", "") + 's'; //remove all whitespace
                    int timeInSeconds = 0;
                    int startIndex = 0, endIndex = 0;
                    for (int i = 0; i < time.Length; i++) {
                        if (time[i].isDigit()) {
                            endIndex = i + 1;
                        } else if (endIndex > startIndex) {
                            int value = int.Parse(time.Substring(startIndex, endIndex - startIndex));
                            if (time[i] == 'm') {
                                value *= 60;
                            } else if (time[i] == 'h') {
                                value *= 3600;
                            }
                            timeInSeconds += value;
                            startIndex = i + 1;
                            endIndex = startIndex;
                        } else {
                            startIndex = i + 1;
                        }
                    }
                    if (timeInSeconds > 0) {
                        Image iconImage = null;
                        if (splits.Length > 4) {
                            string icon = splits[4];
                            TibiaObject[] objects = new TibiaObject[] { StorageManager.getItem(icon), StorageManager.getCreature(icon), StorageManager.getNPC(icon), StorageManager.getMount(icon), StorageManager.getSpell(icon), StorageManager.getOutfit(icon) };
                            foreach (var obj in objects) {
                                if (obj != null) {
                                    iconImage = obj.GetImage();
                                    if (iconImage != null) {
                                        break;
                                    }
                                }
                            }
                        }
                        string title = splits.Length > 2 ? splits[2] : "Reminder!";
                        string message = splits.Length > 3 ? splits[3] : String.Format("Reminder from {0} seconds ago!", timeInSeconds);

                        const int notificationWarningTime = 5;

                        if (timeInSeconds <= notificationWarningTime) {
                            PopupManager.ShowSimpleNotification(new SimpleTimerNotification(iconImage, title, message, timeInSeconds));
                        } else {
                            MainForm.mainForm.Invoke((MethodInvoker)delegate {
                                System.Threading.Tasks.Task.Delay(1000 * (timeInSeconds - notificationWarningTime)).ContinueWith(x => {
                                    try {
                                        MainForm.mainForm.Invoke((MethodInvoker)delegate {
                                            PopupManager.ShowSimpleNotification(new SimpleTimerNotification(iconImage, title, message, notificationWarningTime));
                                        });
                                    } catch {

                                    }
                                 });
                            });
                        }
                    }
                } else if (comp.StartsWith("exp" + Constants.CommandSymbol)) { //exp@
                    string title = "Experience";
                    string text = "Currently gaining " + (parseMemoryResults == null ? "unknown" : ((int)parseMemoryResults.expPerHour).ToString()) + " experience an hour.";
                    Image image = StyleManager.GetImage("tibia.png");
                    if (!SettingsManager.getSettingBool("UseRichNotificationType")) {
                        PopupManager.ShowSimpleNotification(title, text, image);
                    } else {
                        PopupManager.ShowSimpleNotification(new SimpleTextNotification(null, title, text));
                    }
                } else if (comp.StartsWith("waste" + Constants.CommandSymbol)) { //waste@
                    NotificationManager.ShowWasteForm(HuntManager.activeHunt, command);
                } else if (comp.StartsWith("summary" + Constants.CommandSymbol)) { //summary@
                    string[] splits = command.Split(Constants.CommandSymbol);
                    string screenshot_path = "";
                    string parameter = splits[1].Trim().ToLower();
                    if (parameter == "screenshot" && splits.Length > 2) {
                        parameter = "";
                        screenshot_path = splits[2];
                    }

                    NotificationManager.ShowSummaryForm(command, screenshot_path);
                } else if (comp.StartsWith("loot" + Constants.CommandSymbol)) { //loot@
                    string[] splits = command.Split(Constants.CommandSymbol);
                    string screenshot_path = "";
                    string parameter = splits[1].Trim().ToLower();
                    if (parameter == "screenshot" && splits.Length > 2) {
                        parameter = "";
                        screenshot_path = splits[2];
                    }

                    Hunt currentHunt = HuntManager.activeHunt;
                    if (splits.Length >= 2 && splits[1] != "") {
                        Hunt h = HuntManager.GetHunt(splits[1]);
                        if (h != null) {
                            currentHunt = h;
                        }
                    }
                    // display loot notification
                    NotificationManager.ShowLootDrops(currentHunt, command, screenshot_path);
                } else if (comp.StartsWith("clipboard" + Constants.CommandSymbol)) { //clipboard@
                    // Copy loot message to the clipboard
                    // clipboard@damage copies the damage information to the clipboard
                    // clipboard@<creature> copies the loot of a specific creature to the clipboard
                    // clipboard@ copies all loot to the clipboard
                    string creatureName = command.Split(Constants.CommandSymbol)[1].Trim().ToLower();
                    Creature lootCreature = null;
                    if (creatureName == "damage" && parseMemoryResults != null) {
                        var damageInformation = DamageChart.GenerateDamageInformation(parseMemoryResults.DamagePerSecond, "").Item2;
                        string damageString = "Damage Dealt: ";
                        foreach (var damage in damageInformation) {
                            damageString += String.Format("{0}: {1:N1}%; ", damage.name, damage.percentage);
                        }
                        Clipboard.SetText(damageString.Substring(0, damageString.Length - 2));
                        return true;
                    } else if (creatureName != "") {
                        lootCreature = StorageManager.getCreature(creatureName);
                    }

                    var tpl = LootDropForm.GenerateLootInformation(HuntManager.activeHunt, "", lootCreature);
                    var creatureKills = tpl.Item1;
                    var itemDrops = tpl.Item2;

                    string lootString = "";
                    if (creatureKills.Count == 1) {
                        foreach (KeyValuePair<Creature, int> kvp in creatureKills) {
                            lootString = "Total Loot of " + kvp.Value.ToString() + " " + kvp.Key.GetName() + (kvp.Value > 1 ? "s" : "") + ": ";
                        }
                    } else {
                        int totalKills = 0;
                        foreach (KeyValuePair<Creature, int> kvp in creatureKills) {
                            totalKills += kvp.Value;
                        }
                        lootString = "Total Loot of " + totalKills + " Kills: ";
                    }
                    foreach (Tuple<Item, int> kvp in itemDrops) {
                        lootString += kvp.Item2 + " " + kvp.Item1.displayname + (kvp.Item2 > 1 ? "s" : "") + ", ";
                    }
                    lootString = lootString.Substring(0, lootString.Length - 2) + ".";
                    Clipboard.SetText(lootString);
                } else if (comp.StartsWith("reset" + Constants.CommandSymbol)) { //reset@
                    string parameter = command.Split(Constants.CommandSymbol)[1].Trim().ToLower();
                    int time = 0;
                    if (parameter == "old") {
                        HuntManager.clearOldLog(HuntManager.activeHunt);
                    } else if (int.TryParse(parameter, out time) && time > 0) {
                        HuntManager.clearOldLog(HuntManager.activeHunt, time);
                    } else {
                        // reset@<hunt> resets the specified hunt
                        if (parameter.Length > 0 && HuntManager.resetHunt(parameter)) {
                            return true;
                        } else {
                            //reset@ deletes all loot from the currently active hunt
                            HuntManager.resetHunt(HuntManager.activeHunt);
                        }
                    }
                    MainForm.mainForm.refreshHunts();
                    ReadMemoryManager.ignoreStamp = TimestampManager.createStamp();
                } else if (comp.StartsWith("refresh" + Constants.CommandSymbol)) { //refresh@
                                                                                   // refresh: refresh duration on current form, or if no current form, repeat last command without removing it from stack
                                                                                   /*if (tooltipForm != null && !tooltipForm.IsDisposed) {
                                                                                       try {
                                                                                           (tooltipForm as NotificationForm).ResetTimer();
                                                                                       } catch {
                                                                                       }
                                                                                   } else if (command_stack.Count > 0) {*/
                    ExecuteCommand(NotificationManager.LastCommand().command);
                    //}
                    return true;
                } else if (comp.StartsWith("switch" + Constants.CommandSymbol)) { //switch@
                                                                                  // switch: switch to hunt
                    string parameter = command.Split(Constants.CommandSymbol)[1].Trim().ToLower();
                    HuntManager.SwitchHunt(parameter);
                    HuntManager.SaveHunts();
                } else if (comp.StartsWith("item" + Constants.CommandSymbol)) { //item@
                                                                                //show the item with all the NPCs that sell it
                    NotificationManager.ShowItemNotification(command);
                } else if (comp.StartsWith("task" + Constants.CommandSymbol)) { //task@
                    string parameter = command.Split(Constants.CommandSymbol)[1].Trim().ToLower();
                    if (StorageManager.taskList.Keys.Contains(parameter)) {
                        NotificationManager.ShowCreatureList(StorageManager.taskList[parameter].ToList<TibiaObject>(), StorageManager.taskList[parameter][0].groupname, command);
                    } else {
                        int id = -1;
                        int.TryParse(parameter, out id);
                        List<TibiaObject> tasks = new List<TibiaObject>();
                        foreach (KeyValuePair<string, List<Task>> kvp in StorageManager.taskList) {
                            foreach (Task t in kvp.Value) {
                                if (id >= 0 && t.id == id) {
                                    NotificationManager.ShowTaskNotification(t, command);
                                    return true;
                                } else {
                                    if (t.GetName().Contains(parameter, StringComparison.OrdinalIgnoreCase)) {
                                        tasks.Add(t);
                                    }
                                }
                            }
                        }
                        if (tasks.Count == 1) {
                            NotificationManager.ShowTaskNotification(tasks[0] as Task, command);
                        } else {
                            NotificationManager.ShowCreatureList(tasks, String.Format("Tasks Containing \"{0}\"", parameter), command);
                        }

                    }
                } else if (comp.StartsWith("hud" + Constants.CommandSymbol)) { //hud@
                    HUDManager.ShowHUD(comp.Split(Constants.CommandSymbol)[1]);
                } else if (comp.StartsWith("closehud" + Constants.CommandSymbol)) { //closehud@
                    HUDManager.CloseHUD(comp.Split(Constants.CommandSymbol)[1]);
                } else if (comp.StartsWith("map" + Constants.CommandSymbol)) { //map@
                    Coordinate startCoordinate = null;
                    string[] splits = comp.Split(Constants.CommandSymbol);
                    if (splits.Length > 1) {
                        string cityName = splits[1].Trim().ToLower();
                        if (Constants.cityCoordinates.ContainsKey(cityName)) {
                            return ExecuteCommand("map@" + Constants.cityCoordinates[cityName]);
                        }
                        Coordinate targetCoordinate = new Coordinate();
                        string[] coords = splits[1].Split(',');
                        if (coords.Length >= 3) {
                            if (int.TryParse(coords[0], out targetCoordinate.x) && int.TryParse(coords[1], out targetCoordinate.y) && int.TryParse(coords[2], out targetCoordinate.z)) {
                                startCoordinate = targetCoordinate;
                            }
                        }
                    }
                    NotificationManager.ShowMapForm(startCoordinate, command);
                } else if (comp.StartsWith("route" + Constants.CommandSymbol)) { //route@
                    string[] splits = comp.Split(Constants.CommandSymbol);
                    Coordinate targetCoordinate = new Coordinate();
                    TibiaObject imageObject = null;
                    if (splits.Length > 1) {
                        string cityName = splits[1].Trim().ToLower();
                        if (Constants.cityCoordinates.ContainsKey(cityName)) {
                            return ExecuteCommand("route@" + Constants.cityCoordinates[cityName]);
                        }
                        string[] coords = splits[1].Split(',');
                        if (coords.Length >= 3) {
                            if (int.TryParse(coords[0], out targetCoordinate.x) && int.TryParse(coords[1], out targetCoordinate.y) && int.TryParse(coords[2], out targetCoordinate.z)) {
                                if (splits.Length > 2) {
                                    imageObject = StorageManager.getItem(splits[2]);
                                    if (imageObject == null) {
                                        imageObject = StorageManager.getCreature(splits[2]);
                                        if (imageObject == null) {
                                            imageObject = StorageManager.getNPC(splits[2]);
                                            if (imageObject == null) {
                                                imageObject = StorageManager.getMount(splits[2]);
                                                if (imageObject == null) {
                                                    imageObject = StorageManager.getOutfit(splits[2]);
                                                    if (imageObject == null) {
                                                        imageObject = StorageManager.getSpell(splits[2]);
                                                        if (imageObject == null) {
                                                            imageObject = StorageManager.getHunt(splits[2]);
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                                NotificationManager.ShowRoute(targetCoordinate, imageObject, command);
                            }
                        }
                    }
                } else if (comp.StartsWith("registerdoor" + Constants.CommandSymbol)) { //registerdoor@
                    using (StreamWriter writer = new StreamWriter("doors", true)) {
                        MemoryReader.UpdateBattleList();
                        writer.WriteLine(String.Format("{0},{1},{2}", MemoryReader.X, MemoryReader.Y, MemoryReader.Z));
                    }
                } else if (comp.StartsWith("registerteleport" + Constants.CommandSymbol)) { //registerteleport@
                    if (teleportCoordinatePrev == null) {
                        MemoryReader.UpdateBattleList();
                        teleportCoordinatePrev = new Coordinate(MemoryReader.X, MemoryReader.Y, MemoryReader.Z);
                    } else {
                        string teleportName = "Stairs";
                        if (comp.Split('@')[1].Length > 0) {
                            teleportName = comp.Split('@')[1];
                        }
                        MemoryReader.UpdateBattleList();
                        using (StreamWriter writer = new StreamWriter("teleports", true)) {
                            writer.WriteLine(String.Format("{0},{1},{2}-{3},{4},{5}-{6}", teleportCoordinatePrev.x, teleportCoordinatePrev.y, teleportCoordinatePrev.z, MemoryReader.X, MemoryReader.Y, MemoryReader.Z, teleportName));
                        }
                        teleportCoordinatePrev = null;
                    }
                } else if (comp.StartsWith("category" + Constants.CommandSymbol)) { //category@
                                                                                    // list all items with the specified category
                    string parameter = command.Split(Constants.CommandSymbol)[1].Trim().ToLower();
                    List<TibiaObject> items = StorageManager.getItemsByCategory(parameter);
                    if (items.Count == 1) {
                        NotificationManager.ShowItemNotification("item" + Constants.CommandSymbol + items[0].GetName().ToLower());
                    } else if (items.Count > 1) {
                        NotificationManager.ShowCreatureList(items, "Category: " + parameter, command, true);
                    }
                } else if (comp.StartsWith("hunt" + Constants.CommandSymbol)) { //hunt@
                    string[] splits = command.Split(Constants.CommandSymbol);
                    string parameter = splits[1].Trim().ToLower();
                    int page = 0;
                    if (splits.Length > 2 && int.TryParse(splits[2], out page)) { }
                    if (Constants.cities.Contains(parameter)) {
                        List<HuntingPlace> huntingPlaces = StorageManager.getHuntsInCity(parameter);
                        NotificationManager.ShowCreatureList(huntingPlaces.ToList<TibiaObject>(), "Hunts in " + parameter, command);
                        return true;
                    }
                    HuntingPlace h = StorageManager.getHunt(parameter);
                    if (h != null) {
                        NotificationManager.ShowHuntingPlace(h, command);
                        return true;
                    }
                    Creature cr = StorageManager.getCreature(parameter);
                    if (cr != null) {
                        List<HuntingPlace> huntingPlaces = StorageManager.getHuntsForCreature(cr.id);
                        NotificationManager.ShowCreatureList(huntingPlaces.ToList<TibiaObject>(), "Hunts containing creature " + parameter.ToTitle(), command);
                        return true;
                    }
                    int minlevel = -1, maxlevel = -1;
                    int level;
                    if (int.TryParse(parameter, out level)) {
                        minlevel = (int)(level * 0.8);
                        maxlevel = (int)(level * 1.2);
                    } else if (parameter.Contains('-')) {
                        string[] split = parameter.Split('-');
                        int.TryParse(split[0].Trim(), out minlevel);
                        int.TryParse(split[1].Trim(), out maxlevel);
                    }
                    if (minlevel >= 0 && maxlevel >= 0) {
                        List<HuntingPlace> huntingPlaces = StorageManager.getHuntsForLevels(minlevel, maxlevel);
                        huntingPlaces = huntingPlaces.OrderBy(o => o.level).ToList();
                        NotificationManager.ShowCreatureList(huntingPlaces.ToList<TibiaObject>(), "Hunts between levels " + minlevel.ToString() + "-" + maxlevel.ToString(), command);
                        return true;
                    } else {
                        string title;
                        List<HuntingPlace> huntList = StorageManager.searchHunt(parameter);
                        title = "Hunts Containing \"" + parameter + "\"";
                        if (huntList.Count == 1) {
                            NotificationManager.ShowHuntingPlace(huntList[0], command);
                        } else if (huntList.Count > 1) {
                            NotificationManager.ShowCreatureList(huntList.ToList<TibiaObject>(), title, command);
                        }
                    }
                } else if (comp.StartsWith("npc" + Constants.CommandSymbol)) { //npc@
                    string parameter = command.Split(Constants.CommandSymbol)[1].Trim().ToLower();
                    NPC npc = StorageManager.getNPC(parameter);
                    if (npc != null) {
                        NotificationManager.ShowNPCForm(npc, command);
                    } else if (Constants.cities.Contains(parameter)) {
                        NotificationManager.ShowCreatureList(StorageManager.getNPCWithCity(parameter), "NPC List", command);
                    } else {
                        NotificationManager.ShowCreatureList(StorageManager.searchNPC(parameter), "NPC List", command);
                    }
                } else if (comp.StartsWith("savelog" + Constants.CommandSymbol)) {
                    HuntManager.SaveLog(HuntManager.activeHunt, command.Split(Constants.CommandSymbol)[1].Trim().Replace("'", "\\'"));
                } else if (comp.StartsWith("loadlog" + Constants.CommandSymbol)) {
                    HuntManager.LoadLog(HuntManager.activeHunt, command.Split(Constants.CommandSymbol)[1].Trim().Replace("'", "\\'"));
                } else if (comp.StartsWith("setdiscardgoldratio" + Constants.CommandSymbol)) {
                    double val;
                    if (double.TryParse(command.Split(Constants.CommandSymbol)[1].Trim(), out val)) {
                        StorageManager.setGoldRatio(val);
                    }
                } else if (comp.StartsWith("wiki" + Constants.CommandSymbol)) {
                    string parameter = command.Split(Constants.CommandSymbol)[1].Trim();
                    string response = "";
                    using (WebClient client = new WebClient()) {
                        response = client.DownloadString(String.Format("http://tibia.wikia.com/api/v1/Search/List?query={0}&limit=1&minArticleQuality=10&batch=1&namespaces=0", parameter));
                    }
                    Regex regex = new Regex("\"url\":\"([^\"]+)\"");
                    Match m = regex.Match(response);
                    var gr = m.Groups[1];
                    MainForm.OpenUrl(gr.Value.Replace("\\/", "/"));
                } else if (comp.StartsWith("char" + Constants.CommandSymbol)) {
                    string parameter = command.Split(Constants.CommandSymbol)[1].Trim();
                    MainForm.OpenUrl("https://secure.tibia.com/community/?subtopic=characters&name=" + parameter);
                } else if (comp.StartsWith("setconvertgoldratio" + Constants.CommandSymbol)) {
                    string parameter = command.Split(Constants.CommandSymbol)[1].Trim();
                    string[] split = parameter.Split('-');
                    if (split.Length < 2) return true;
                    int stackable = 0;
                    if (split[0] == "1") stackable = 1;
                    double val;
                    if (double.TryParse(split[1], out val)) {
                        StorageManager.setConvertRatio(val, stackable == 1);
                    }
                } else if (comp.StartsWith("recent" + Constants.CommandSymbol) || comp.StartsWith("url" + Constants.CommandSymbol) || comp.StartsWith("last" + Constants.CommandSymbol)) {
                    bool url = comp.StartsWith("url" + Constants.CommandSymbol);
                    int type = url ? 1 : 0;
                    string parameter = command.Split(Constants.CommandSymbol)[1].Trim().ToLower();
                    if (comp.StartsWith("last" + Constants.CommandSymbol)) parameter = "1";
                    List<Command> command_list = GlobalDataManager.GetRecentCommands(type).Select(o => new Command() { player = o.Item1, command = o.Item2 }).ToList();
                    command_list.Reverse();
                    int number;
                    //recent@<number> opens the last <number> command, so recent@1 opens the last command
                    if (int.TryParse(parameter, out number)) {
                        if (number > 0 && number <= command_list.Count) {
                            ListNotification.OpenCommand(command_list[number - 1].command, type); ;
                            return true;
                        }
                    } else {
                        //recent@<player> opens the last
                        bool found = false;
                        foreach (Command comm in command_list) {
                            if (comm.player.ToLower() == parameter) {
                                ListNotification.OpenCommand(command_list[number].command, type);
                                found = true;
                                break;
                            }
                        }
                        if (found) return true;
                    }
                    NotificationManager.ShowListNotification(command_list, type, command);
                } else if (comp.StartsWith("spell" + Constants.CommandSymbol)) { // spell@
                    string[] splits = command.Split(Constants.CommandSymbol);
                    string parameter = splits[1].Trim().ToLower();
                    int initialVocation = -1;
                    if (splits.Length > 2 && int.TryParse(splits[2], out initialVocation)) { }
                    Spell spell = StorageManager.getSpell(parameter);
                    if (spell != null) {
                        NotificationManager.ShowSpellNotification(spell, initialVocation, command);
                    } else {
                        List<TibiaObject> spellList = new List<TibiaObject>();
                        string title;
                        if (Constants.vocations.Contains(parameter)) {
                            spellList = StorageManager.getSpellsForVocation(parameter);
                            title = parameter.ToTitle() + " Spells";
                        } else {
                            spellList = StorageManager.searchSpell(parameter);
                            if (spellList.Count == 0) {
                                spellList = StorageManager.searchSpellWords(parameter);
                            }
                            title = "Spells Containing \"" + parameter + "\"";
                        }
                        if (spellList.Count == 1) {
                            NotificationManager.ShowSpellNotification(spellList[0].AsSpell(), initialVocation, command);
                        } else if (spellList.Count > 1) {
                            NotificationManager.ShowCreatureList(spellList, title, command);
                        }
                    }
                } else if (comp.StartsWith("outfit" + Constants.CommandSymbol)) { // outfit@
                    string parameter = command.Split(Constants.CommandSymbol)[1].Trim().ToLower();
                    Outfit outfit = StorageManager.getOutfit(parameter);
                    if (outfit != null) {
                        NotificationManager.ShowOutfitNotification(outfit, command);
                    } else {
                        string title;
                        List<TibiaObject> outfitList = StorageManager.searchOutfit(parameter);
                        title = "Outfits Containing \"" + parameter + "\"";
                        if (outfitList.Count == 1) {
                            NotificationManager.ShowOutfitNotification(outfitList[0].AsOutfit(), command);
                        } else if (outfitList.Count > 1) {
                            NotificationManager.ShowCreatureList(outfitList, title, command);
                        }
                    }
                } else if (comp.StartsWith("quest" + Constants.CommandSymbol)) { // quest@
                    string[] splits = command.Split(Constants.CommandSymbol);
                    string parameter = splits[1].Trim().ToLower();
                    int page = 0;
                    if (splits.Length > 2 && int.TryParse(splits[2], out page)) { }
                    List<Quest> questList = new List<Quest>();
                    if (StorageManager.questNameMap.ContainsKey(parameter)) {
                        NotificationManager.ShowQuestNotification(StorageManager.questNameMap[parameter], command);
                    } else {
                        string title;
                        if (Constants.cities.Contains(parameter)) {
                            title = "Quests In " + parameter;
                            foreach (Quest q in StorageManager.questIdMap.Values) {
                                if (q.city.ToLower() == parameter) {
                                    questList.Add(q);
                                }
                            }
                        } else {
                            title = "Quests Containing \"" + parameter + "\"";
                            string[] splitStrings = parameter.Split(' ');
                            foreach (Quest quest in StorageManager.questIdMap.Values) {
                                bool found = true;
                                foreach (string str in splitStrings) {
                                    if (!quest.name.Contains(str, StringComparison.OrdinalIgnoreCase)) {
                                        found = false;
                                        break;
                                    }
                                }
                                if (found) {
                                    questList.Add(quest);
                                }
                            }
                        }
                        if (questList.Count == 1) {
                            NotificationManager.ShowQuestNotification(questList[0], command);
                        } else if (questList.Count > 1) {
                            NotificationManager.ShowCreatureList(questList.ToList<TibiaObject>(), title, command);
                            //ShowQuestList(questList, title, command, page);
                        }
                    }
                } else if (comp.StartsWith("guide" + Constants.CommandSymbol)) { // guide@
                    string[] splits = command.Split(Constants.CommandSymbol);
                    string parameter = splits[1].Trim().ToLower();
                    int page = 0;
                    string mission = "";
                    if (splits.Length > 2 && int.TryParse(splits[2], out page)) { }
                    if (splits.Length > 3) { mission = splits[3]; }
                    List<Quest> questList = new List<Quest>();
                    if (StorageManager.questNameMap.ContainsKey(parameter)) {
                        NotificationManager.ShowQuestGuideNotification(StorageManager.questNameMap[parameter], command, page, mission);
                    } else {
                        string title;
                        foreach (Quest quest in StorageManager.questIdMap.Values) {
                            if (quest.name.Contains(parameter, StringComparison.OrdinalIgnoreCase)) {
                                questList.Add(quest);
                            }
                        }
                        title = "Quests Containing \"" + parameter + "\"";
                        if (questList.Count == 1) {
                            NotificationManager.ShowQuestGuideNotification(questList[0], command, page, mission);
                        } else if (questList.Count > 1) {
                            NotificationManager.ShowCreatureList(questList.ToList<TibiaObject>(), title, command);
                        }
                    }
                } else if (comp.StartsWith("direction" + Constants.CommandSymbol)) { // direction@
                    string[] splits = command.Split(Constants.CommandSymbol);
                    string parameter = splits[1].Trim().ToLower();
                    int page = 0;
                    if (splits.Length > 2 && int.TryParse(splits[2], out page)) { }
                    List<HuntingPlace> huntList = new List<HuntingPlace>();
                    HuntingPlace h = StorageManager.getHunt(parameter);
                    if (h != null) {
                        NotificationManager.ShowHuntGuideNotification(h, command, page);
                    } else {
                        string title;
                        huntList = StorageManager.searchHunt(parameter);
                        title = "Hunts Containing \"" + parameter + "\"";
                        if (huntList.Count == 1) {
                            NotificationManager.ShowHuntGuideNotification(huntList[0], command, page);
                        } else if (huntList.Count > 1) {
                            NotificationManager.ShowCreatureList(huntList.ToList<TibiaObject>(), title, command);
                        }
                    }
                } else if (comp.StartsWith("mount" + Constants.CommandSymbol)) { // mount@
                    string parameter = command.Split(Constants.CommandSymbol)[1].Trim().ToLower();
                    Mount m = StorageManager.getMount(parameter);
                    if (m != null) {
                        NotificationManager.ShowMountNotification(m, command);
                    } else {
                        string title;
                        List<TibiaObject> mountList = StorageManager.searchMount(parameter);
                        title = "Mounts Containing \"" + parameter + "\"";
                        if (mountList.Count == 1) {
                            NotificationManager.ShowMountNotification(mountList[0].AsMount(), command);
                        } else if (mountList.Count > 1) {
                            NotificationManager.ShowCreatureList(mountList, title, command);
                        }
                    }
                } else if (comp.StartsWith("pickup" + Constants.CommandSymbol)) {
                    string parameter = command.Split(Constants.CommandSymbol)[1].Trim().ToLower();
                    Item item = StorageManager.getItem(parameter);
                    if (item != null) {
                        StorageManager.setItemDiscard(item, false);
                    }
                } else if (comp.StartsWith("nopickup" + Constants.CommandSymbol)) {
                    string parameter = command.Split(Constants.CommandSymbol)[1].Trim().ToLower();
                    Item item = StorageManager.getItem(parameter);
                    if (item != null) {
                        StorageManager.setItemDiscard(item, true);
                    }
                } else if (comp.StartsWith("convert" + Constants.CommandSymbol)) {
                    string parameter = command.Split(Constants.CommandSymbol)[1].Trim().ToLower();
                    Item item = StorageManager.getItem(parameter);
                    if (item != null) {
                        StorageManager.setItemConvert(item, true);
                    }
                } else if (comp.StartsWith("noconvert" + Constants.CommandSymbol)) {
                    string parameter = command.Split(Constants.CommandSymbol)[1].Trim().ToLower();
                    Item item = StorageManager.getItem(parameter);
                    if (item != null) {
                        StorageManager.setItemConvert(item, false);
                    }
                } else if (comp.StartsWith("setval" + Constants.CommandSymbol)) {
                    string parameter = command.Split(Constants.CommandSymbol)[1].Trim();
                    if (!parameter.Contains('=')) return true;
                    string[] split = parameter.Split('=');
                    string item = split[0].Trim().ToLower().Replace("'", "\\'");
                    long value = 0;
                    if (long.TryParse(split[1].Trim(), out value)) {
                        Item it = StorageManager.getItem(split[0]);
                        if (it != null) {
                            StorageManager.setItemValue(it, value);
                        }
                    }
                } else if (comp.StartsWith("screenshot" + Constants.CommandSymbol)) {
                    ScreenshotManager.saveScreenshot("Screenshot", ScreenshotManager.takeScreenshot());
                } else if (comp.StartsWith("lootcount" + Constants.CommandSymbol)) {
                    var sum = GlobalDataManager.GetLootValue();
                    string title = "Loot Value";
                    string text = "Loot value is currently: " + sum;
                    Image image = StyleManager.GetImage("tibia.png");
                    if (!SettingsManager.getSettingBool("UseRichNotificationType")) {
                        PopupManager.ShowSimpleNotification(title, text, image);
                    } else {
                        PopupManager.ShowSimpleNotification(new SimpleTextNotification(null, title, text));
                    }
                } else if (comp.StartsWith("lootcountclear" + Constants.CommandSymbol)) {
                    GlobalDataManager.ClearLootValue();
                } else {
                    bool found = false;
                    foreach (string city in Constants.cities) {
                        if (comp.StartsWith(city + Constants.CommandSymbol)) {
                            string itemName = command.Split(Constants.CommandSymbol)[1].Trim().ToLower();
                            Item item = StorageManager.getItem(itemName);
                            if (item != null) {
                                NPC npc = StorageManager.getNPCSellingItemInCity(item.id, city);
                                if (npc != null) {
                                    NotificationManager.ShowNPCForm(npc, command);
                                }
                            } else {
                                Spell spell = StorageManager.getSpell(itemName);
                                if (spell != null) {
                                    NPC npc = StorageManager.getNPCTeachingSpellInCity(spell.id, city);
                                    if (npc != null) {
                                        NotificationManager.ShowNPCForm(npc, command);
                                    }
                                }
                            }

                            found = true;
                        }
                    }
                    // else try custom commands
                    foreach (SystemCommand c in MainForm.mainForm.GetCustomCommands()) {
                        if (c.tibialyzer_command.Trim().Length > 0 && comp.StartsWith(c.tibialyzer_command + Constants.CommandSymbol)) {
                            string[] parameters = command.Split(Constants.CommandSymbol);
                            string systemCallParameters = c.parameters;
                            int i = 0;
                            while (true) {
                                if (systemCallParameters.Contains("{" + i.ToString() + "}")) {
                                    systemCallParameters = systemCallParameters.Replace("{" + i.ToString() + "}", parameters.Length > i + 1 ? parameters[i + 1].Trim() : "");
                                } else {
                                    break;
                                }
                                i++;
                            }
                            ProcessStartInfo procStartInfo = new ProcessStartInfo(c.command, systemCallParameters);

                            procStartInfo.UseShellExecute = true;

                            // Do not show the cmd window to the user.
                            procStartInfo.CreateNoWindow = true;
                            procStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
                            Process.Start(procStartInfo);
                            return true;
                        }
                    }
                    if (found) return true;
                    //if we get here we didn't find any command
                    return false;
                }
                return true;
            } catch (Exception e) {
                MainForm.mainForm.DisplayWarning(String.Format("Tibialyzer Exception While Processing Command \"{0}\".\nMessage: {1} ", command, e.Message));
                Console.WriteLine(e.Message);
                return true;
            }
        }
        private bool ScanMemory()
        {
            ReadMemoryResults readMemoryResults = ReadMemory();
            ParseMemoryResults parseMemoryResults = ParseLogResults(readMemoryResults);

            if (parseMemoryResults != null) {
                lastResults = parseMemoryResults;
            }
            if (readMemoryResults != null && readMemoryResults.newAdvances.Count > 0) {
                if (SettingsManager.getSettingBool("AutoScreenshotAdvance")) {
                    this.Invoke((MethodInvoker)delegate {
                        saveScreenshot("Advance", takeScreenshot());
                    });
                }
                if (SettingsManager.getSettingBool("CopyAdvances")) {
                    foreach (object obj in readMemoryResults.newAdvances) {
                        this.Invoke((MethodInvoker)delegate {
                            Clipboard.SetText(obj.ToString());
                        });
                    }
                }
                readMemoryResults.newAdvances.Clear();
            }

            if (parseMemoryResults != null && parseMemoryResults.death) {
                if (SettingsManager.getSettingBool("AutoScreenshotDeath")) {
                    this.Invoke((MethodInvoker)delegate {
                        saveScreenshot("Death", takeScreenshot());
                    });
                }
                parseMemoryResults.death = false;
            }

            if (parseMemoryResults != null) {
                if (parseMemoryResults.newEventMessages.Count > 0) {
                    if (SettingsManager.getSettingBool("EnableEventNotifications")) {
                        foreach (Tuple<Event, string> tpl in parseMemoryResults.newEventMessages) {
                            Event ev = tpl.Item1;
                            Creature cr = getCreature(ev.creatureid);
                            this.Invoke((MethodInvoker)delegate {
                                if (!SettingsManager.getSettingBool("UseRichNotificationType")) {
                                    ShowSimpleNotification("Event in " + ev.location, tpl.Item2, cr.image);
                                } else {
                                    ShowSimpleNotification(new SimpleTextNotification(cr.image, "Event in " + ev.location, tpl.Item2));
                                }
                            });
                        }
                    }
                    parseMemoryResults.newEventMessages.Clear();
                }
            }

            if (SettingsManager.getSettingBool("LookMode") && readMemoryResults != null) {
                foreach (string msg in parseMemoryResults.newLooks) {
                    string itemName = parseLookItem(msg).ToLower();
                    if (itemExists(itemName)) {
                        this.Invoke((MethodInvoker)delegate {
                            this.ExecuteCommand("item@" + itemName);
                        });
                    } else if (creatureExists(itemName) ||
                        (itemName.Contains("dead ") && (itemName = itemName.Replace("dead ", "")) != null && creatureExists(itemName)) ||
                        (itemName.Contains("slain ") && (itemName = itemName.Replace("slain ", "")) != null && creatureExists(itemName))) {
                        this.Invoke((MethodInvoker)delegate {
                            this.ExecuteCommand("creature@" + itemName);
                        });
                    } else {
                        NPC npc = getNPC(itemName);
                        if (npc != null) {
                            this.Invoke((MethodInvoker)delegate {
                                this.ExecuteCommand("npc@" + itemName);
                            });
                        }
                    }
                }
                parseMemoryResults.newLooks.Clear();
            }

            List<string> commands = parseMemoryResults == null ? new List<string>() : parseMemoryResults.newCommands.ToArray().ToList();
            commands.Reverse();

            foreach (string command in commands) {
                this.Invoke((MethodInvoker)delegate {
                    if (!ExecuteCommand(command, parseMemoryResults) && SettingsManager.getSettingBool("EnableUnrecognizedNotifications")) {
                        if (!SettingsManager.getSettingBool("UseRichNotificationType")) {
                            ShowSimpleNotification("Unrecognized command", "Unrecognized command: " + command, tibia_image);
                        } else {
                            ShowSimpleNotification(new SimpleTextNotification(null, "Unrecognized command", "Unrecognized command: " + command));
                        }
                    }
                });
            }
            if (parseMemoryResults != null) {
                if (parseMemoryResults.newItems.Count > 0) {
                    this.Invoke((MethodInvoker)delegate {
                        for (int i = 0; i < NotificationFormGroups.Length; i++) {
                            if (NotificationFormGroups[i] != null && NotificationFormGroups[i] is LootDropForm) {
                                (NotificationFormGroups[i] as LootDropForm).UpdateLoot();
                            }
                        }
                        if (logButton.Enabled == false) {
                            refreshHuntLog(getSelectedHunt());
                        }
                    });
                }
                foreach (Tuple<Creature, List<Tuple<Item, int>>> tpl in parseMemoryResults.newItems) {
                    Creature cr = tpl.Item1;
                    List<Tuple<Item, int>> items = tpl.Item2;
                    bool showNotification = ShowDropNotification(tpl);
                    if (showNotification) {
                        if (SettingsManager.getSettingBool("AutoScreenshotItemDrop")) {
                            // Take a screenshot if Tibialyzer is set to take screenshots of valuable loot
                            Bitmap screenshot = takeScreenshot();
                            if (screenshot == null) continue;
                            // Add a notification to the screenshot
                            SimpleLootNotification screenshotNotification = new SimpleLootNotification(cr, items);
                            Bitmap notification = new Bitmap(screenshotNotification.Width, screenshotNotification.Height);
                            screenshotNotification.DrawToBitmap(notification, new Rectangle(0, 0, screenshotNotification.Width, screenshotNotification.Height));
                            foreach (Control c in screenshotNotification.Controls) {
                                c.DrawToBitmap(notification, new Rectangle(c.Location, c.Size));
                            }
                            screenshotNotification.Dispose();
                            int widthOffset = notification.Width + 10;
                            int heightOffset = notification.Height + 10;
                            if (screenshot.Width > widthOffset && screenshot.Height > heightOffset) {
                                using (Graphics gr = Graphics.FromImage(screenshot)) {
                                    gr.DrawImage(notification, new Point(screenshot.Width - widthOffset, screenshot.Height - heightOffset));
                                }
                            }
                            notification.Dispose();
                            this.Invoke((MethodInvoker)delegate {
                                saveScreenshot("Loot", screenshot);
                            });
                        }

                        if (!SettingsManager.getSettingBool("UseRichNotificationType")) {
                            ShowSimpleNotification(cr.displayname, cr.displayname + " dropped a valuable item.", cr.image);
                        } else {
                            this.Invoke((MethodInvoker)delegate {
                                ShowSimpleNotification(new SimpleLootNotification(cr, items));
                            });
                        }
                    }
                }
            }
            return readMemoryResults != null;
        }
        private bool ScanMemory() {
            ReadMemoryResults readMemoryResults = ReadMemory();
            ParseMemoryResults parseMemoryResults = ParseLogResults(readMemoryResults);

            if (parseMemoryResults != null) {
                lastResults = parseMemoryResults;
            }
            if (readMemoryResults != null && readMemoryResults.newAdvances.Count > 0) {
                if (getSettingBool("AutoScreenshotAdvance")) {
                    this.Invoke((MethodInvoker)delegate {
                        saveScreenshot("Advance", takeScreenshot());
                    });
                }
                if (copyAdvances) {
                    foreach (object obj in readMemoryResults.newAdvances) {
                        this.Invoke((MethodInvoker)delegate {
                            Clipboard.SetText(obj.ToString());
                        });
                    }
                }
                readMemoryResults.newAdvances.Clear();
            }

            if (parseMemoryResults != null && parseMemoryResults.death) {
                if (getSettingBool("AutoScreenshotDeath")) {
                    this.Invoke((MethodInvoker)delegate {
                        saveScreenshot("Death", takeScreenshot());
                    });
                }
                parseMemoryResults.death = false;
            }

            if (parseMemoryResults != null) {
                if (parseMemoryResults.newEventMessages.Count > 0) {
                    if (getSettingBool("EnableEventNotifications")) {
                        foreach (Tuple<Event, string> tpl in parseMemoryResults.newEventMessages) {
                            Event ev = tpl.Item1;
                            Creature cr = getCreature(ev.creatureid);
                            this.Invoke((MethodInvoker)delegate {
                                if (!lootNotificationRich) {
                                    ShowSimpleNotification("Event in " + ev.location, tpl.Item2, cr.image);
                                } else {
                                    ShowSimpleNotification(new SimpleTextNotification(cr.image, "Event in " + ev.location, tpl.Item2));
                                }
                            });
                        }
                    }
                    parseMemoryResults.newEventMessages.Clear();
                }
            }

            if (getSettingBool("LookMode") && readMemoryResults != null) {
                foreach (string msg in parseMemoryResults.newLooks) {
                    string itemName = parseLookItem(msg).ToLower();
                    if (itemExists(itemName)) {
                        this.Invoke((MethodInvoker)delegate {
                            this.ExecuteCommand("item@" + itemName);
                        });
                    } else if (creatureExists(itemName) ||
                        (itemName.Contains("dead ") && (itemName = itemName.Replace("dead ", "")) != null && creatureExists(itemName)) ||
                        (itemName.Contains("slain ") && (itemName = itemName.Replace("slain ", "")) != null && creatureExists(itemName))) {
                        this.Invoke((MethodInvoker)delegate {
                            this.ExecuteCommand("creature@" + itemName);
                        });
                    } else {
                        NPC npc = getNPC(itemName);
                        if (npc != null) {
                            this.Invoke((MethodInvoker)delegate {
                                this.ExecuteCommand("npc@" + itemName);
                            });
                        }
                    }
                }
                parseMemoryResults.newLooks.Clear();
            }

            List<string> commands = parseMemoryResults == null ? new List<string>() : parseMemoryResults.newCommands.ToArray().ToList();
            commands.Reverse();

            foreach (string command in commands) {
                this.Invoke((MethodInvoker)delegate {
                    if (!ExecuteCommand(command, parseMemoryResults) && getSettingBool("EnableUnrecognizedNotifications")) {
                        if (!lootNotificationRich) {
                            ShowSimpleNotification("Unrecognized command", "Unrecognized command: " + command, tibia_image);
                        } else {
                            ShowSimpleNotification(new SimpleTextNotification(null, "Unrecognized command", "Unrecognized command: " + command));
                        }
                    }
                });
            }
            if (parseMemoryResults != null) {
                foreach (Tuple<Creature, List<Tuple<Item, int>>> tpl in parseMemoryResults.newItems) {
                    Creature cr = tpl.Item1;
                    List<Tuple<Item, int>> items = tpl.Item2;
                    bool showNotification = false;
                    if (getSettingBool("AlwaysShowLoot")) {
                        // If AlwaysShowLoot is enabled, we always show a notification, as long as the creature is part of the hunts' creature list
                        if (activeHunt.trackAllCreatures) {
                            showNotification = true;
                        } else {
                            string[] creatures = activeHunt.trackedCreatures.Split('\n');
                            for (int i = 0; i < creatures.Length; i++) {
                                creatures[i] = creatures[i].ToLower();
                            }
                            if (creatures.Contains(cr.GetName().ToLower())) {
                                showNotification = true;
                            }
                        }
                    }

                    foreach (Tuple<Item, int> tpl2 in items) {
                        Item item = tpl2.Item1;
                        bool showNotificationValue = item.GetMaxValue() >= notification_value && showNotificationsValue;
                        bool showNotificationRatio = getSettingBool("ShowNotificationsGoldRatio") && (item.GetMaxValue() / item.capacity) >= getSettingDouble("NotificationGoldRatio");
                        bool showNotificationSpecific = showNotificationsSpecific && settings["NotificationItems"].Contains(item.displayname.ToLower());
                        if (((!showNotificationsValue || showNotificationValue) && (!getSettingBool("ShowNotificationsGoldRatio") || showNotificationRatio) && (getSettingBool("ShowNotificationsGoldRatio") || showNotificationsValue)) || showNotificationSpecific) {
                            showNotification = true;
                            if (getSettingBool("AutoScreenshotItemDrop")) {
                                // Take a screenshot if Tibialyzer is set to take screenshots of valuable loot
                                Bitmap screenshot = takeScreenshot();
                                if (screenshot == null) continue;
                                // Add a notification to the screenshot
                                SimpleLootNotification screenshotNotification = new SimpleLootNotification(cr, items);
                                Bitmap notification = new Bitmap(screenshotNotification.Width, screenshotNotification.Height);
                                screenshotNotification.DrawToBitmap(notification, new Rectangle(0, 0, screenshotNotification.Width, screenshotNotification.Height));
                                foreach (Control c in screenshotNotification.Controls) {
                                    c.DrawToBitmap(notification, new Rectangle(c.Location, c.Size));
                                }
                                screenshotNotification.Dispose();
                                int widthOffset = notification.Width + 10;
                                int heightOffset = notification.Height + 10;
                                if (screenshot.Width > widthOffset && screenshot.Height > heightOffset) {
                                    using (Graphics gr = Graphics.FromImage(screenshot)) {
                                        gr.DrawImage(notification, new Point(screenshot.Width - widthOffset, screenshot.Height - heightOffset));
                                    }
                                }
                                notification.Dispose();
                                this.Invoke((MethodInvoker)delegate {
                                    saveScreenshot("Loot", screenshot);
                                });
                            }
                            if (this.showNotifications && !lootNotificationRich) {
                                ShowSimpleNotification(cr.displayname, cr.displayname + " dropped a " + item.displayname + ".", cr.image);
                            }
                        }
                    }
                    if (this.showNotifications && showNotification && lootNotificationRich) {
                        this.Invoke((MethodInvoker)delegate {
                            ShowSimpleNotification(new SimpleLootNotification(cr, items));
                        });
                    }
                }
            }
            return readMemoryResults != null;
        }
        public bool ExecuteCommand(string command, ParseMemoryResults parseMemoryResults = null) {
            try {
                if (parseMemoryResults == null) {
                    parseMemoryResults = lastResults;
                }
                string comp = command.Trim().ToLower();
                Console.WriteLine(command);
                if (comp.StartsWith("creature" + MainForm.commandSymbol)) { //creature@
                    string[] split = command.Split(commandSymbol);
                    string parameter = split[1].Trim().ToLower();
                    Creature cr = getCreature(parameter);
                    if (cr != null) {
                        ShowCreatureDrops(cr, command);
                    } else {
                        List<TibiaObject> creatures = searchCreature(parameter);
                        if (creatures.Count == 1) {
                            ShowCreatureDrops(creatures[0].AsCreature(), command);
                        } else if (creatures.Count > 1) {
                            ShowCreatureList(creatures, "Creature List", command);
                        }
                    }
                } else if (comp.StartsWith("look" + MainForm.commandSymbol)) { //look@
                    string parameter = command.Split(commandSymbol)[1].Trim().ToLower();
                    if (parameter == "on") {
                        if (!settings.ContainsKey("LookMode")) settings.Add("LookMode", new List<string>());
                        settings["LookMode"].Clear(); settings["LookMode"].Add("True");
                        saveSettings();
                    } else if (parameter == "off") {
                        if (!settings.ContainsKey("LookMode")) settings.Add("LookMode", new List<string>());
                        settings["LookMode"].Clear(); settings["LookMode"].Add("False");
                        saveSettings();
                    } else {
                        List<string> times = getLatestTimes(5);
                        List<TibiaObject> items = new List<TibiaObject>();
                        foreach (string t in times) {
                            if (!totalLooks.ContainsKey(t)) continue;
                            foreach (string message in totalLooks[t]) {
                                string itemName = parseLookItem(message).ToLower();
                                Item item = getItem(itemName);

                                if (item != null) {
                                    items.Add(item);
                                } else {
                                    Creature cr = getCreature(itemName);
                                    if (cr != null) {
                                        items.Add(cr);
                                    }
                                }
                            }
                        }
                        if (items.Count == 1) {
                            if (items[0] is Item) {
                                ShowItemNotification("item" + MainForm.commandSymbol + items[0].GetName().ToLower());
                            } else if (items[0] is Creature) {
                                ShowCreatureDrops(items[0].AsCreature(), command);
                            }
                        } else if (items.Count > 1) {
                            ShowCreatureList(items, "Looked At Items", command);
                        }
                    }
                } else if (comp.StartsWith("stats" + MainForm.commandSymbol)) { //stats@
                    string name = command.Split(commandSymbol)[1].Trim().ToLower();
                    Creature cr = getCreature(name);
                    if (cr != null) {
                        ShowCreatureStats(cr, command);
                    }
                } else if (comp.StartsWith("close" + MainForm.commandSymbol)) { //close@
                                                                                // close all notifications
                    if (tooltipForm != null) {
                        tooltipForm.Close();
                    }
                    ClearSimpleNotifications();
                } else if (comp.StartsWith("delete" + MainForm.commandSymbol)) { //delete@
                    string parameter = command.Split(commandSymbol)[1].Trim().ToLower();
                    int killCount;
                    if (int.TryParse(parameter, out killCount)) {
                        deleteCreatureWithThreshold(killCount);
                    } else {
                        Creature cr = getCreature(parameter);
                        if (cr != null) {
                            deleteCreatureFromLog(cr);
                        }
                    }
                } else if (comp.StartsWith("skin" + MainForm.commandSymbol)) { //skin@
                    string[] split = command.Split(commandSymbol);
                    string parameter = split[1].Trim().ToLower();
                    int count = 1;
                    Creature cr = getCreature(parameter);
                    if (cr != null) {
                        if (split.Length > 2)
                            int.TryParse(split[2], out count);
                        insertSkin(cr, count);
                    } else {
                        int.TryParse(parameter, out count);
                        // find creature with highest killcount with a skin and skin that
                        int kills = -1;
                        lock (hunts) {
                            foreach (KeyValuePair<Creature, int> kvp in activeHunt.loot.killCount) {
                                if (kvp.Value > kills && kvp.Key.skin != null) {
                                    cr = kvp.Key;
                                    kills = kvp.Value;
                                }
                            }
                        }
                        if (cr != null) {
                            insertSkin(cr, count);
                        }
                    }
                } else if (comp.StartsWith("city" + MainForm.commandSymbol)) { //city@
                    string parameter = command.Split(commandSymbol)[1].Trim().ToLower();
                    if (cityNameMap.ContainsKey(parameter)) {
                        City city = cityNameMap[parameter];
                        ShowCityDisplayForm(city, command);
                    }
                } else if (comp.StartsWith("damage" + MainForm.commandSymbol) && parseMemoryResults != null) { //damage@
                    string[] splits = command.Split(commandSymbol);
                    string screenshot_path = "";
                    string parameter = splits[1].Trim().ToLower();
                    if (parameter == "screenshot" && splits.Length > 2) {
                        parameter = "";
                        screenshot_path = splits[2];
                    }
                    ShowDamageMeter(parseMemoryResults.damagePerSecond, command, parameter, screenshot_path);
                } else if (comp.StartsWith("exp" + MainForm.commandSymbol)) { //exp@
                    string title = "Experience";
                    string text = "Currently gaining " + (parseMemoryResults == null ? "unknown" : ((int)parseMemoryResults.expPerHour).ToString()) + " experience an hour.";
                    Image image = tibia_image;
                    if (!lootNotificationRich) {
                        ShowSimpleNotification(title, text, image);
                    } else {
                        ShowSimpleNotification(new SimpleTextNotification(null, title, text));
                    }
                } else if (comp.StartsWith("loot" + MainForm.commandSymbol) || comp.StartsWith("clipboard" + MainForm.commandSymbol)) { //loot@ clipboard@
                    string[] splits = command.Split(commandSymbol);
                    bool clipboard = comp.StartsWith("clipboard" + MainForm.commandSymbol);
                    string screenshot_path = "";
                    string parameter = splits[1].Trim().ToLower();
                    if (parameter == "screenshot" && splits.Length > 2) {
                        parameter = "";
                        screenshot_path = splits[2];
                    }


                    Creature lootCreature = null;
                    if (splits.Length >= 3 && splits[2] != "") {
                        lootCreature = getCreature(splits[2]);
                    }
                    bool raw = false; // raw mode means 'display everything and don't convert anything to gold'
                    bool all = false; //all mode means 'display everything' (i.e. ignore discard flag on items)
                    if (splits.Length >= 4 && splits[3] != "") {
                        if (splits[3] == "raw") {
                            raw = true;
                            all = true;
                        } else if (splits[3] == "all") {
                            all = true;
                        }
                    }

                    // first handle creature kills
                    lock (hunts) {
                        Dictionary<Creature, int> creatureKills;
                        Hunt currentHunt = activeHunt;
                        if (splits.Length >= 2 && splits[1] != "") {
                            foreach (Hunt h in hunts) {
                                if (h.name.ToLower().Contains(splits[1].ToLower())) {
                                    currentHunt = h;
                                    break;
                                }
                            }
                        }
                        if (lootCreature != null) {
                            //the command is loot@<creature>, so we only display the kills and loot from the specified creature
                            creatureKills = new Dictionary<Creature, int>();
                            if (currentHunt.loot.killCount.ContainsKey(lootCreature)) {
                                creatureKills.Add(lootCreature, currentHunt.loot.killCount[lootCreature]);
                            } else {
                                return true; // if there are no kills of the specified creature, just skip the command
                            }
                        } else if (currentHunt.trackAllCreatures || currentHunt.trackedCreatures.Length == 0) {
                            creatureKills = currentHunt.loot.killCount; //display all creatures
                        } else {
                            // only display tracked creatures
                            creatureKills = new Dictionary<Creature, int>();
                            foreach (string creature in currentHunt.lootCreatures) {
                                Creature cr = getCreature(creature.ToLower());
                                if (cr == null) continue;
                                if (!currentHunt.loot.killCount.ContainsKey(cr)) continue;

                                creatureKills.Add(cr, currentHunt.loot.killCount[cr]);
                            }

                        }

                        // now handle item drops, gather a count for every item
                        List<Tuple<Item, int>> itemDrops = new List<Tuple<Item, int>>();
                        Dictionary<Item, int> itemCounts = new Dictionary<Item, int>();
                        foreach (KeyValuePair<Creature, Dictionary<Item, int>> kvp in currentHunt.loot.creatureLoot) {
                            if (lootCreature != null && kvp.Key != lootCreature) continue; // if lootCreature is specified, only consider loot from the specified creature
                            if (!currentHunt.trackAllCreatures && currentHunt.trackedCreatures.Length > 0 && !currentHunt.lootCreatures.Contains(kvp.Key.GetName().ToLower())) continue;
                            foreach (KeyValuePair<Item, int> kvp2 in kvp.Value) {
                                Item item = kvp2.Key;
                                int value = kvp2.Value;
                                if (!itemCounts.ContainsKey(item)) itemCounts.Add(item, value);
                                else itemCounts[item] += value;
                            }
                        }
                        // now we do item conversion
                        long extraGold = 0;
                        foreach (KeyValuePair<Item, int> kvp in itemCounts) {
                            Item item = kvp.Key;
                            int count = kvp.Value;
                            // discard items that are set to be discarded (as long as all/raw mode is not enabled)
                            if (item.discard && !all) continue;
                            // convert items to gold (as long as raw mode is not enabled), always gather up all the gold coins found
                            if ((!raw && item.convert_to_gold) || item.displayname == "gold coin" || item.displayname == "platinum coin" || item.displayname == "crystal coin") {
                                extraGold += Math.Max(item.actual_value, item.vendor_value) * count;
                            } else {
                                itemDrops.Add(new Tuple<Item, int>(item, count));
                            }
                        }

                        // handle coin drops, we always convert the gold to the highest possible denomination (so if gold = 10K, we display a crystal coin)
                        long currentGold = extraGold;
                        if (currentGold > 10000) {
                            itemDrops.Add(new Tuple<Item, int>(getItem("crystal coin"), (int)(currentGold / 10000)));
                            currentGold = currentGold % 10000;
                        }
                        if (currentGold > 100) {
                            itemDrops.Add(new Tuple<Item, int>(getItem("platinum coin"), (int)(currentGold / 100)));
                            currentGold = currentGold % 100;
                        }
                        if (currentGold > 0) {
                            itemDrops.Add(new Tuple<Item, int>(getItem("gold coin"), (int)(currentGold)));
                        }

                        // now order by value so most valuable items are placed first
                        // we use a special value for the gold coins so the gold is placed together in the order crystal > platinum > gold
                        // gold coins = <gold total> - 2, platinum coins = <gold total> - 1, crystal coins = <gold total>
                        itemDrops = itemDrops.OrderByDescending(o => o.Item1.displayname == "gold coin" ? extraGold - 2 : (o.Item1.displayname == "platinum coin" ? extraGold - 1 : (o.Item1.displayname == "crystal coin" ? extraGold : Math.Max(o.Item1.actual_value, o.Item1.vendor_value) * o.Item2))).ToList();

                        if (clipboard) {
                            // Copy loot message to the clipboard
                            // clipboard@<creature> copies the loot of a specific creature to the clipboard
                            // clipboard@ copies all loot to the clipboard
                            string lootString = "";
                            if (creatureKills.Count == 1) {
                                foreach (KeyValuePair<Creature, int> kvp in creatureKills) {
                                    lootString = "Total Loot of " + kvp.Value.ToString() + " " + kvp.Key.GetName() + (kvp.Value > 1 ? "s" : "") + ": ";
                                }
                            } else {
                                int totalKills = 0;
                                foreach (KeyValuePair<Creature, int> kvp in creatureKills) {
                                    totalKills += kvp.Value;
                                }
                                lootString = "Total Loot of " + totalKills + " Kills: ";
                            }
                            foreach (Tuple<Item, int> kvp in itemDrops) {
                                lootString += kvp.Item2 + " " + kvp.Item1.displayname + (kvp.Item2 > 1 ? "s" : "") + ", ";
                            }
                            lootString = lootString.Substring(0, lootString.Length - 2) + ".";
                            Clipboard.SetText(lootString);
                        } else {
                            // display loot notification
                            ShowLootDrops(creatureKills, itemDrops, currentHunt, command, screenshot_path);
                        }
                    }
                } else if (comp.StartsWith("reset" + MainForm.commandSymbol)) { //reset@
                    string parameter = command.Split(commandSymbol)[1].Trim().ToLower();
                    int time = 0;
                    if (parameter == "old") {
                        clearOldLog(activeHunt);
                    } else if (int.TryParse(parameter, out time) && time > 0) {
                        clearOldLog(activeHunt, time);
                    } else {
                        lock (hunts) {
                            foreach (Hunt h in hunts) {
                                if (h.name.ToLower() == parameter.ToLower()) {
                                    // reset@<hunt> resets the specified hunt
                                    resetHunt(h);
                                    return true;
                                }
                            }
                        }
                        //reset@ loot deletes all loot from the currently active hunt
                        resetHunt(activeHunt);
                    }
                    refreshHunts();
                    ignoreStamp = createStamp();
                } else if (comp.StartsWith("refresh" + MainForm.commandSymbol)) { //refresh@
                                                                                  // refresh: refresh duration on current form, or if no current form, repeat last command without removing it from stack
                    if (tooltipForm != null && !tooltipForm.IsDisposed) {
                        try {
                            (tooltipForm as NotificationForm).ResetTimer();
                        } catch {
                        }
                    } else if (command_stack.Count > 0) {
                        MainForm.mainForm.ExecuteCommand(command_stack.Peek().command);
                    }
                    return true;
                } else if (comp.StartsWith("switch" + MainForm.commandSymbol)) { //switch@
                                                                                 // switch: switch to hunt
                    string parameter = command.Split(commandSymbol)[1].Trim().ToLower();
                    lock (hunts) {
                        foreach (Hunt h in hunts) {
                            if (h.name.ToLower().Contains(parameter)) {
                                activeHunt = h;
                                saveHunts();
                                break;
                            }
                        }
                    }
                } else if (comp.StartsWith("item" + MainForm.commandSymbol)) { //item@
                                                                               //show the item with all the NPCs that sell it
                    ShowItemNotification(command);
                } else if (comp.StartsWith("task" + MainForm.commandSymbol)) { //task@
                    string parameter = command.Split(commandSymbol)[1].Trim().ToLower();
                    if (taskList.Keys.Contains(parameter)) {
                        ShowCreatureList(taskList[parameter].ToList<TibiaObject>(), taskList[parameter][0].groupname, command);
                    } else {
                        int id = -1;
                        int.TryParse(parameter, out id);
                        List<TibiaObject> tasks = new List<TibiaObject>();
                        foreach (KeyValuePair<string, List<Task>> kvp in taskList) {
                            foreach (Task t in kvp.Value) {
                                if (id >= 0 && t.id == id) {
                                    ShowTaskNotification(t, command);
                                    return true;
                                } else {
                                    if (t.GetName().ToLower().Contains(parameter)) {
                                        tasks.Add(t);
                                    }
                                }
                            }
                        }
                        if (tasks.Count == 1) {
                            ShowTaskNotification(tasks[0] as Task, command);
                        } else {
                            ShowCreatureList(tasks, String.Format("Tasks Containing \"{0}\"", parameter), command);
                        }

                    }
                } else if (comp.StartsWith("category" + MainForm.commandSymbol)) { //category@
                                                                                   // list all items with the specified category
                    string parameter = command.Split(commandSymbol)[1].Trim().ToLower();
                    List<TibiaObject> items = getItemsByCategory(parameter);
                    if (items.Count == 1) {
                        ShowItemNotification("item" + MainForm.commandSymbol + items[0].GetName().ToLower());
                    } else if (items.Count > 1) {
                        ShowCreatureList(items, "Category: " + parameter, command, true);
                    }
                } else if (comp.StartsWith("hunt" + MainForm.commandSymbol)) { //hunt@
                    string[] splits = command.Split(commandSymbol);
                    string parameter = splits[1].Trim().ToLower();
                    int page = 0;
                    if (splits.Length > 2 && int.TryParse(splits[2], out page)) ;
                    if (cities.Contains(parameter)) {
                        List<HuntingPlace> huntingPlaces = getHuntsInCity(parameter);
                        ShowCreatureList(huntingPlaces.ToList<TibiaObject>(), "Hunts in " + parameter, command);
                        return true;
                    }
                    HuntingPlace h = getHunt(parameter);
                    if (h != null) {
                        ShowHuntingPlace(h, command);
                        return true;
                    }
                    Creature cr = getCreature(parameter);
                    if (cr != null) {
                        List<HuntingPlace> huntingPlaces = getHuntsForCreature(cr.id);
                        ShowCreatureList(huntingPlaces.ToList<TibiaObject>(), "Hunts containing creature " + ToTitle(parameter), command);
                        return true;
                    }
                    int minlevel = -1, maxlevel = -1;
                    int level;
                    if (int.TryParse(parameter, out level)) {
                        minlevel = (int)(level * 0.8);
                        maxlevel = (int)(level * 1.2);
                    } else if (parameter.Contains('-')) {
                        string[] split = parameter.Split('-');
                        int.TryParse(split[0].Trim(), out minlevel);
                        int.TryParse(split[1].Trim(), out maxlevel);
                    }
                    if (minlevel >= 0 && maxlevel >= 0) {
                        List<HuntingPlace> huntingPlaces = getHuntsForLevels(minlevel, maxlevel);
                        huntingPlaces = huntingPlaces.OrderBy(o => o.level).ToList();
                        ShowCreatureList(huntingPlaces.ToList<TibiaObject>(), "Hunts between levels " + minlevel.ToString() + "-" + maxlevel.ToString(), command);
                        return true;
                    } else {
                        string title;
                        List<HuntingPlace> huntList = searchHunt(parameter);
                        title = "Hunts Containing \"" + parameter + "\"";
                        if (huntList.Count == 1) {
                            ShowHuntingPlace(huntList[0], command);
                        } else if (huntList.Count > 1) {
                            ShowCreatureList(huntList.ToList<TibiaObject>(), title, command);
                        }
                    }
                } else if (comp.StartsWith("npc" + MainForm.commandSymbol)) { //npc@
                    string parameter = command.Split(commandSymbol)[1].Trim().ToLower();
                    NPC npc = getNPC(parameter);
                    if (npc != null) {
                        ShowNPCForm(npc, command);
                    } else if (cities.Contains(parameter)) {
                        ShowCreatureList(getNPCWithCity(parameter), "NPC List", command);
                    } else {
                        ShowCreatureList(searchNPC(parameter), "NPC List", command);
                    }
                } else if (comp.StartsWith("savelog" + MainForm.commandSymbol)) {
                    saveLog(activeHunt, command.Split(commandSymbol)[1].Trim().Replace("'", "\\'"));
                } else if (comp.StartsWith("loadlog" + MainForm.commandSymbol)) {
                    loadLog(activeHunt, command.Split(commandSymbol)[1].Trim().Replace("'", "\\'"));
                } else if (comp.StartsWith("setdiscardgoldratio" + MainForm.commandSymbol)) {
                    double val;
                    if (double.TryParse(command.Split(commandSymbol)[1].Trim(), out val)) {
                        setGoldRatio(val);
                    }
                } else if (comp.StartsWith("wiki" + MainForm.commandSymbol)) {
                    string parameter = command.Split(commandSymbol)[1].Trim();
                    string response = "";
                    using (WebClient client = new WebClient()) {
                        response = client.DownloadString(String.Format("http://tibia.wikia.com/api/v1/Search/List?query={0}&limit=1&minArticleQuality=10&batch=1&namespaces=0", parameter));
                    }
                    Regex regex = new Regex("\"url\":\"([^\"]+)\"");
                    Match m = regex.Match(response);
                    var gr = m.Groups[1];
                    OpenUrl(gr.Value.Replace("\\/", "/"));
                } else if (comp.StartsWith("char" + MainForm.commandSymbol)) {
                    string parameter = command.Split(commandSymbol)[1].Trim();
                    OpenUrl("https://secure.tibia.com/community/?subtopic=characters&name=" + parameter);
                } else if (comp.StartsWith("setconvertgoldratio" + MainForm.commandSymbol)) {
                    string parameter = command.Split(commandSymbol)[1].Trim();
                    string[] split = parameter.Split('-');
                    if (split.Length < 2) return true;
                    int stackable = 0;
                    if (split[0] == "1") stackable = 1;
                    double val;
                    if (double.TryParse(split[1], out val)) {
                        setConvertRatio(val, stackable == 1);
                    }
                } else if (comp.StartsWith("recent" + MainForm.commandSymbol) || comp.StartsWith("url" + MainForm.commandSymbol) || comp.StartsWith("last" + MainForm.commandSymbol)) {
                    bool url = comp.StartsWith("url" + MainForm.commandSymbol);
                    int type = url ? 1 : 0;
                    string parameter = command.Split(commandSymbol)[1].Trim().ToLower();
                    if (comp.StartsWith("last" + MainForm.commandSymbol)) parameter = "1";
                    List<Command> command_list = getRecentCommands(type).Select(o => new Command() { player = o.Item1, command = o.Item2 }).ToList();
                    command_list.Reverse();
                    int number;
                    //recent@<number> opens the last <number> command, so recent@1 opens the last command
                    if (int.TryParse(parameter, out number)) {
                        if (number > 0 && number <= command_list.Count) {
                            ListNotification.OpenCommand(command_list[number - 1].command, type); ;
                            return true;
                        }
                    } else {
                        //recent@<player> opens the last 
                        bool found = false;
                        foreach (Command comm in command_list) {
                            if (comm.player.ToLower() == parameter) {
                                ListNotification.OpenCommand(command_list[number].command, type);
                                found = true;
                                break;
                            }
                        }
                        if (found) return true;
                    }
                    ShowListNotification(command_list, type, command);
                } else if (comp.StartsWith("spell" + MainForm.commandSymbol)) { // spell@
                    string[] splits = command.Split(commandSymbol);
                    string parameter = splits[1].Trim().ToLower();
                    int initialVocation = -1;
                    if (splits.Length > 2 && int.TryParse(splits[2], out initialVocation)) ;
                    Spell spell = getSpell(parameter);
                    if (spell != null) {
                        ShowSpellNotification(spell, initialVocation, command);
                    } else {
                        List<TibiaObject> spellList = new List<TibiaObject>();
                        string title;
                        if (vocationImages.Keys.Contains(parameter)) {
                            spellList = getSpellsForVocation(parameter);
                            title = ToTitle(parameter) + " Spells";
                        } else {
                            spellList = searchSpell(parameter);
                            if (spellList.Count == 0) {
                                spellList = searchSpellWords(parameter);
                            }
                            title = "Spells Containing \"" + parameter + "\"";
                        }
                        if (spellList.Count == 1) {
                            ShowSpellNotification(spellList[0].AsSpell(), initialVocation, command);
                        } else if (spellList.Count > 1) {
                            ShowCreatureList(spellList, title, command);
                        }
                    }
                } else if (comp.StartsWith("outfit" + MainForm.commandSymbol)) { // outfit@
                    string parameter = command.Split(commandSymbol)[1].Trim().ToLower();
                    Outfit outfit = getOutfit(parameter);
                    if (outfit != null) {
                        ShowOutfitNotification(outfit, command);
                    } else {
                        string title;
                        List<TibiaObject> outfitList = searchOutfit(parameter);
                        title = "Outfits Containing \"" + parameter + "\"";
                        if (outfitList.Count == 1) {
                            ShowOutfitNotification(outfitList[0].AsOutfit(), command);
                        } else if (outfitList.Count > 1) {
                            ShowCreatureList(outfitList, title, command);
                        }
                    }
                } else if (comp.StartsWith("quest" + MainForm.commandSymbol)) { // quest@
                    string[] splits = command.Split(commandSymbol);
                    string parameter = splits[1].Trim().ToLower();
                    int page = 0;
                    if (splits.Length > 2 && int.TryParse(splits[2], out page)) ;
                    List<Quest> questList = new List<Quest>();
                    if (questNameMap.ContainsKey(parameter)) {
                        ShowQuestNotification(questNameMap[parameter], command);
                    } else {
                        string title;
                        if (cities.Contains(parameter)) {
                            title = "Quests In " + parameter;
                            foreach (Quest q in questIdMap.Values) {
                                if (q.city.ToLower() == parameter) {
                                    questList.Add(q);
                                }
                            }
                        } else {
                            title = "Quests Containing \"" + parameter + "\"";
                            string[] splitStrings = parameter.Split(' ');
                            foreach (Quest quest in questIdMap.Values) {
                                bool found = true;
                                foreach (string str in splitStrings) {
                                    if (!quest.name.ToLower().Contains(str)) {
                                        found = false;
                                        break;
                                    }
                                }
                                if (found) {
                                    questList.Add(quest);
                                }
                            }
                        }
                        if (questList.Count == 1) {
                            ShowQuestNotification(questList[0], command);
                        } else if (questList.Count > 1) {
                            ShowCreatureList(questList.ToList<TibiaObject>(), title, command);
                            //ShowQuestList(questList, title, command, page);
                        }
                    }
                } else if (comp.StartsWith("guide" + MainForm.commandSymbol)) { // guide@
                    string[] splits = command.Split(commandSymbol);
                    string parameter = splits[1].Trim().ToLower();
                    int page = 0;
                    string mission = "";
                    if (splits.Length > 2 && int.TryParse(splits[2], out page)) ;
                    if (splits.Length > 3) { mission = splits[3]; }
                    List<Quest> questList = new List<Quest>();
                    if (questNameMap.ContainsKey(parameter)) {
                        ShowQuestGuideNotification(questNameMap[parameter], command, page, mission);
                    } else {
                        string title;
                        foreach (Quest quest in questIdMap.Values) {
                            if (quest.name.ToLower().Contains(parameter)) {
                                questList.Add(quest);
                            }
                        }
                        title = "Quests Containing \"" + parameter + "\"";
                        if (questList.Count == 1) {
                            ShowQuestGuideNotification(questList[0], command, page, mission);
                        } else if (questList.Count > 1) {
                            ShowCreatureList(questList.ToList<TibiaObject>(), title, command);
                        }
                    }
                } else if (comp.StartsWith("direction" + MainForm.commandSymbol)) { // direction@
                    string[] splits = command.Split(commandSymbol);
                    string parameter = splits[1].Trim().ToLower();
                    int page = 0;
                    if (splits.Length > 2 && int.TryParse(splits[2], out page)) ;
                    List<HuntingPlace> huntList = new List<HuntingPlace>();
                    HuntingPlace h = getHunt(parameter);
                    if (h != null) {
                        ShowHuntGuideNotification(h, command, page);
                    } else {
                        string title;
                        huntList = searchHunt(parameter);
                        title = "Hunts Containing \"" + parameter + "\"";
                        if (huntList.Count == 1) {
                            ShowHuntGuideNotification(huntList[0], command, page);
                        } else if (huntList.Count > 1) {
                            ShowCreatureList(huntList.ToList<TibiaObject>(), title, command);
                        }
                    }
                } else if (comp.StartsWith("mount" + MainForm.commandSymbol)) { // mount@
                    string parameter = command.Split(commandSymbol)[1].Trim().ToLower();
                    Mount m = getMount(parameter);
                    if (m != null) {
                        ShowMountNotification(m, command);
                    } else {
                        string title;
                        List<TibiaObject> mountList = searchMount(parameter);
                        title = "Mounts Containing \"" + parameter + "\"";
                        if (mountList.Count == 1) {
                            ShowMountNotification(mountList[0].AsMount(), command);
                        } else if (mountList.Count > 1) {
                            ShowCreatureList(mountList, title, command);
                        }
                    }
                } else if (comp.StartsWith("pickup" + MainForm.commandSymbol)) {
                    string parameter = command.Split(commandSymbol)[1].Trim().ToLower();
                    Item item = getItem(parameter);
                    if (item != null) {
                        setItemDiscard(item, false);
                    }
                } else if (comp.StartsWith("nopickup" + MainForm.commandSymbol)) {
                    string parameter = command.Split(commandSymbol)[1].Trim().ToLower();
                    Item item = getItem(parameter);
                    if (item != null) {
                        setItemDiscard(item, true);
                    }
                } else if (comp.StartsWith("convert" + MainForm.commandSymbol)) {
                    string parameter = command.Split(commandSymbol)[1].Trim().ToLower();
                    Item item = getItem(parameter);
                    if (item != null) {
                        setItemConvert(item, true);
                    }
                } else if (comp.StartsWith("noconvert" + MainForm.commandSymbol)) {
                    string parameter = command.Split(commandSymbol)[1].Trim().ToLower();
                    Item item = getItem(parameter);
                    if (item != null) {
                        setItemConvert(item, false);
                    }
                } else if (comp.StartsWith("setval" + MainForm.commandSymbol)) {
                    string parameter = command.Split(commandSymbol)[1].Trim();
                    if (!parameter.Contains('=')) return true;
                    string[] split = parameter.Split('=');
                    string item = split[0].Trim().ToLower().Replace("'", "\\'");
                    long value = 0;
                    if (long.TryParse(split[1].Trim(), out value)) {
                        Item it = getItem(split[0]);
                        if (it != null) {
                            setItemValue(it, value);
                        }
                    }
                } else if (comp.StartsWith("screenshot" + MainForm.commandSymbol)) {
                    saveScreenshot("Screenshot", takeScreenshot());
                } else {
                    bool found = false;
                    foreach (string city in cities) {
                        if (comp.StartsWith(city + MainForm.commandSymbol)) {
                            string itemName = command.Split(commandSymbol)[1].Trim().ToLower();
                            Item item = getItem(itemName);
                            if (item != null) {
                                NPC npc = getNPCSellingItemInCity(item.id, city);
                                if (npc != null) {
                                    ShowNPCForm(npc, command);
                                }
                            } else {
                                Spell spell = getSpell(itemName);
                                if (spell != null) {
                                    NPC npc = getNPCTeachingSpellInCity(spell.id, city);
                                    if (npc != null) {
                                        ShowNPCForm(npc, command);
                                    }
                                }
                            }

                            found = true;
                        }
                    }
                    if (found) return true;
                    //if we get here we didn't find any command
                    return false;
                }
                return true;
            } catch(Exception e) {
                Console.WriteLine(e.Message);
                if (!shownException) {
                    shownException = true;
                    this.exceptionLabel.Text = String.Format("Tibialyzer Exception While Processing Command \"{0}\".\nMessage: {1} ", command, e.Message);
                    this.exceptionLabel.Visible = true;
                }
                return true;
            }
        }