Exemplo n.º 1
0
        private static void SearchChunk(IEnumerable <string> chunk, ReadMemoryResults res, bool readChatMessages = true, bool readLogMessages = true)
        {
            List <int> stamps = TimestampManager.getLatestStamps(3, ignoreStamp);

            foreach (string it in chunk)
            {
                string logMessage = it;
                string t          = logMessage.Substring(0, 5);
                int    hour       = int.Parse(logMessage.Substring(0, 2));
                int    minute     = int.Parse(logMessage.Substring(3, 2));
                if (!stamps.Contains(TimestampManager.getStamp(hour, minute)))
                {
                    continue;                                                            // the log message is not recent, so we skip parsing it
                }
                if (flashClient)
                {
                    // there is some inconsistency with log messages, certain log messages use "12:00: Message.", others use "12:00 Message"
                    // if there is a : after the timestamp we remove it
                    if (logMessage[5] == ':')
                    {
                        logMessage = logMessage.Remove(5, 1);
                    }
                }

                string message = logMessage.Substring(6); // message without timestamp
                if (readLogMessages)
                {
                    if (logMessage.Length > 14 && logMessage.Substring(5, 9) == " You see " && logMessage[logMessage.Length - 1] == '.')
                    {
                        // the message contains "you see", so it's a look message
                        if (!res.lookMessages.ContainsKey(t))
                        {
                            res.lookMessages.Add(t, new List <string>());
                        }
                        if (!skipDuplicateCommands || !res.lookMessages[t].Contains(logMessage))
                        {
                            res.lookMessages[t].Add(logMessage);
                        }
                        continue;
                    }
                    else if (message.Contains(':'))
                    {
                        if (logMessage.Length > 14 && logMessage.Substring(5, 9) == " Loot of ")   // loot drop message
                        {
                            if (!res.itemDrops.ContainsKey(t))
                            {
                                res.itemDrops.Add(t, new List <string>());
                            }
                            res.itemDrops[t].Add(logMessage);
                            continue;
                        }
                    }
                    else if (logMessage.Length > 17 && logMessage.Substring(5, 12) == " You gained " && logMessage.EndsWith("experience points."))
                    {
                        // the message is an experience string, "You gained x experience."
                        try {
                            int experience = int.Parse(logMessage.Substring(17).Split(' ')[0]);
                            if (!res.exp.ContainsKey(t))
                            {
                                res.exp.Add(t, experience);
                            }
                            else
                            {
                                res.exp[t] = res.exp[t] + experience;
                            }
                        } catch {
                        }
                        continue;
                    }
                    else if (logMessage.Length == 19 && logMessage.Substring(5, 14) == " You are dead.")
                    {
                        if (!res.deaths.ContainsKey(t))
                        {
                            res.deaths.Add(t, true);
                        }
                    }
                    else if (logMessage.Length > 18)
                    {
                        string[] split = message.Split(' ');
                        int      index = split.IndexOf("hitpoints");
                        if (index > 0)
                        {
                            int ind;
                            // damage log message (X loses Y hitpoints due to an attack by Z.)
                            int damage = 0;
                            if (!int.TryParse(split[index - 1], out damage))
                            {
                                continue;
                            }
                            string player;
                            if (logMessage.Substring(logMessage.Length - 12) == "your attack.")
                            {
                                // X lost Y hitpoints because of your attack.
                                // attacker is the player himself
                                player = "You";
                            }
                            else if (split.Contains("by"))
                            {
                                // X lost Y hitpoints because of an attack by Z.
                                // Z is the attacker => after the word "by"
                                player = "";
                                ind    = split.IndexOf("by") + 1;
                                for (int i = ind; i < split.Length; i++)
                                {
                                    player = (player == "" ? player : player + " ") + split[i];
                                }
                            }
                            else
                            {
                                continue;
                            }
                            string splitTerm;
                            if (split.Contains("loses"))
                            {
                                splitTerm = "loses";
                            }
                            else if (split.Contains("lose"))
                            {
                                splitTerm = "lose";
                            }
                            else
                            {
                                continue;
                            }
                            ind = split.IndexOf(splitTerm);
                            string target = "";
                            for (int i = 0; i < ind; i++)
                            {
                                target = (target == "" ? target : target + " ") + split[i];
                            }
                            if (!res.damageDealt.ContainsKey(player))
                            {
                                res.damageDealt.Add(player, new Dictionary <string, DamageEntry>());
                            }
                            DamageEntry damageEntry;
                            if (!res.damageDealt[player].ContainsKey(t))
                            {
                                damageEntry        = new DamageEntry();
                                damageEntry.damage = damage;
                                damageEntry.targetDamage.Add(target, damage);
                                res.damageDealt[player].Add(t, damageEntry);
                            }
                            else
                            {
                                damageEntry         = res.damageDealt[player][t];
                                damageEntry.damage += damage;
                                if (damageEntry.targetDamage.ContainsKey(target))
                                {
                                    damageEntry.targetDamage[target] += damage;
                                }
                                else
                                {
                                    damageEntry.targetDamage.Add(target, damage);
                                }
                            }
                            continue;
                        }
                        else
                        {
                            index = split.IndexOf("hitpoints.");
                            if (index > 0)
                            {
                                // heal log message (X healed Y for Z hitpoints.)
                                int healing = 0;
                                if (!int.TryParse(split[index - 1], out healing))
                                {
                                    continue;
                                }

                                int forIndex = split.IndexOf("for");
                                if (forIndex <= 0)
                                {
                                    continue;
                                }


                                string splitTerm;
                                if (split.Contains("heal"))
                                {
                                    splitTerm = "heal";
                                }
                                else if (split.Contains("healed"))
                                {
                                    splitTerm = "healed";
                                }
                                else
                                {
                                    continue;
                                }
                                int healIndex = split.IndexOf(splitTerm);
                                if (healIndex >= forIndex)
                                {
                                    continue;
                                }

                                string source = "";
                                for (int i = 0; i < healIndex; i++)
                                {
                                    if (split[i] == "was" || split[i] == "were")
                                    {
                                        break;
                                    }
                                    if (split[i] == "by")
                                    {
                                        continue;
                                    }
                                    source = (source == "" ? source : source + " ") + split[i];
                                }
                                string target = "";
                                for (int i = healIndex + 1; i < forIndex; i++)
                                {
                                    if (split[i] == "was" || split[i] == "were")
                                    {
                                        break;
                                    }
                                    if (split[i] == "by")
                                    {
                                        continue;
                                    }
                                    target = (target == "" ? target : target + " ") + split[i];
                                }
                                if (target == "yourself" || target == "itself" || target == "himself" || target == "herself")
                                {
                                    target = source;
                                }

                                if (target.Length == 0 || source.Length == 0)
                                {
                                    continue;
                                }

                                if (split.Contains("by"))
                                {
                                    // X healed Y for Z. => X is the source and Y is the target (default)
                                    // X was healed by Y for Z. => X is the target and Y is the source, so swap source and target
                                    string temp = source;
                                    source = target;
                                    target = temp;
                                }

                                if (!res.healingDone.ContainsKey(source))
                                {
                                    res.healingDone.Add(source, new Dictionary <string, DamageEntry>());
                                }
                                DamageEntry healingEntry;
                                if (!res.healingDone[source].ContainsKey(t))
                                {
                                    healingEntry        = new DamageEntry();
                                    healingEntry.damage = healing;
                                    healingEntry.targetDamage.Add(target, healing);
                                    res.healingDone[source].Add(t, healingEntry);
                                }
                                else
                                {
                                    healingEntry         = res.healingDone[source][t];
                                    healingEntry.damage += healing;
                                    if (healingEntry.targetDamage.ContainsKey(target))
                                    {
                                        healingEntry.targetDamage[target] += healing;
                                    }
                                    else
                                    {
                                        healingEntry.targetDamage.Add(target, healing);
                                    }
                                }
                            }
                            else if (logMessage.Substring(5, 14) == " You advanced " && logMessage.Contains("level", StringComparison.OrdinalIgnoreCase))
                            {
                                // advancement log message (You advanced from level x to level x + 1.)
                                if (logMessage[logMessage.Length - 1] == '.')
                                {
                                    if (GlobalDataManager.AddLevelAdvance(logMessage))
                                    {
                                        res.newAdvances.Add(logMessage);
                                    }
                                    continue;
                                }
                            }
                            else if (logMessage.Substring(5, 7) == " Using " && logMessage.Substring(logMessage.Length - 3, 3) == "...")
                            {
                                // using log message (Using one of X items...)
                                var values = Parser.ParseUsingMessage(logMessage);
                                if (!res.usingMessages.ContainsKey(values.Item1))
                                {
                                    res.usingMessages.Add(values.Item1, new Dictionary <string, HashSet <int> >());
                                }
                                if (!res.usingMessages[values.Item1].ContainsKey(t))
                                {
                                    res.usingMessages[values.Item1].Add(t, new HashSet <int>());
                                }
                                res.usingMessages[values.Item1][t].Add(values.Item2);
                                continue;
                            }
                            else if (logMessage.Length > 50 && logMessage.Substring(5, 45) == " Congratulations! You earned the achievement ")
                            {
                                Achievement achievement = StorageManager.getAchievement(Parser.GetAchievement(logMessage));
                                if (achievement != null)
                                {
                                    res.achievements.Add(new Tuple <Achievement, string>(achievement, logMessage));
                                }
                                else
                                {
                                    Console.WriteLine("Unrecognized achievement {0}.", Parser.GetAchievement(logMessage));
                                }
                            }
                            else
                            {
                                foreach (Event ev in StorageManager.eventIdMap.Values)
                                {
                                    foreach (string evMessage in ev.eventMessages)
                                    {
                                        if (logMessage.Length == evMessage.Length + 6 && logMessage.Contains(evMessage.Trim(), StringComparison.OrdinalIgnoreCase))
                                        {
                                            res.eventMessages.Add(new Tuple <Event, string>(ev, logMessage));
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                if (readChatMessages)
                {
                    if (message.Contains(':'))
                    {
                        if (logMessage.Length > 14 && logMessage.Substring(5, 9) == " Loot of ")   // loot drop message
                        {
                            continue;
                        }
                        else     // if the message contains the ':' symbol but is not a loot drop message, it is a chat message, i.e. a command or url
                                 // we only split at most once, because the chat message can contain the ':' symbol as well and we don't want to discard that
                        {
                            string[] split   = message.Split(new char[] { ':' }, 2);
                            string   command = split[1];
                            // now get the player name, we have to discard the level that is between brackets
                            // players can also have spaces in their name, so we take that into account
                            string[] playersplit = split[0].Split(' ');
                            string   player      = "";
                            foreach (string str in playersplit)
                            {
                                if (str.Contains('['))
                                {
                                    break;
                                }
                                player = (player == "" ? player : player + " ") + str;
                            }
                            if (player == "http" || player == "https")
                            {
                                continue;                                        // I don't remember why we do this, possible http link in a log message? not sure
                            }
                            if (command.Contains('@'))
                            {
                                // @ symbol symbolizes a command, so if there is an @ symbol, we treat the string as a command
                                if (!res.commands.ContainsKey(t))
                                {
                                    res.commands.Add(t, new List <Tuple <string, string> >());
                                }
                                var tpl = new Tuple <string, string>(player, command);
                                if (!skipDuplicateCommands || !res.commands[t].Contains(tpl))
                                {
                                    res.commands[t].Add(tpl);
                                }
                            }
                            else if (command.Contains("www") || command.Contains("http") || command.Contains(".com") || command.Contains(".net") || command.Contains(".tv") || command.Contains(".br"))
                            {
                                // check if the command is an url, we aren't really smart about this, just check for a couple of common url-like things
                                if (!res.urls.ContainsKey(t))
                                {
                                    res.urls.Add(t, new List <Tuple <string, string> >());
                                }
                                res.urls[t].Add(new Tuple <string, string>(player, command));
                            }
                        }
                    }
                }
            }
        }
Exemplo n.º 2
0
        public static bool ScanMemory()
        {
            ReadMemoryResults  readMemoryResults  = ReadMemoryManager.ReadMemory();
            ParseMemoryResults parseMemoryResults = Parser.ParseLogResults(readMemoryResults);

            EquipmentManager.UpdateUsedItems();

            if (parseMemoryResults != null)
            {
                lastResults = parseMemoryResults;
                if (parseMemoryResults.newDamage || parseMemoryResults.newHealing)
                {
                    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 (parseMemoryResults.newAchievements.Count > 0)
                {
                    foreach (Tuple <Achievement, string> tpl in parseMemoryResults.newAchievements)
                    {
                        Achievement achievement = tpl.Item1;
                        if (SettingsManager.getSettingBool("EnableEventNotifications"))
                        {
                            MainForm.mainForm.Invoke((MethodInvoker) delegate {
                                if (!SettingsManager.getSettingBool("UseRichNotificationType"))
                                {
                                    PopupManager.ShowSimpleNotification("Achievement earned!", tpl.Item2, achievement.GetImage());
                                }
                                else
                                {
                                    PopupManager.ShowSimpleNotification(new SimpleTextNotification(achievement.GetImage(), "Achievement earned!", tpl.Item2));
                                }
                            });
                        }
                        if (SettingsManager.getSettingBool("CopyAdvances"))
                        {
                            MainForm.mainForm.Invoke((MethodInvoker) delegate {
                                Clipboard.SetText(tpl.Item2.ToString());
                            });
                        }
                    }
                }
            }

            if (SettingsManager.getSettingBool("LookMode") && readMemoryResults != null)
            {
                foreach (string msg in parseMemoryResults.newLooks)
                {
                    Player player = Parser.parseLookPlayer(msg);
                    if (player != null)
                    {
                        MainForm.mainForm.Invoke((MethodInvoker) delegate {
                            NotificationManager.ShowPlayer(player, "player@" + player.name);
                        });
                    }
                    else
                    {
                        var    itemInfo = Parser.parseLookItem(msg);
                        string itemName = itemInfo.Item1.ToLower();
                        if (StorageManager.itemExists(itemName))
                        {
                            MainForm.mainForm.Invoke((MethodInvoker) delegate {
                                CommandManager.ExecuteCommand("item@" + itemName);
                                var item = StorageManager.getItem(itemName);
                                if (item != null)
                                {
                                    GlobalDataManager.AddLootValue(item.GetMaxValue() * itemInfo.Item2);
                                }
                            });
                        }
                        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)
            {
                lock (RecentDrops) {
                    if (RecentDrops.Count + parseMemoryResults.newItems.Count > MaxRecentDropsTracked && RecentDrops.Count > 0)
                    {
                        RecentDrops.RemoveRange(0, Math.Min(RecentDrops.Count - 1, parseMemoryResults.newItems.Count - (MaxRecentDropsTracked - RecentDrops.Count)));
                    }
                    foreach (var tpl in parseMemoryResults.newItems)
                    {
                        RecentDrops.Add(tpl);
                    }
                }
                if (parseMemoryResults.newItems.Count > 0)
                {
                    MainForm.mainForm.Invoke((MethodInvoker) delegate {
                        LootDatabaseManager.UpdateLoot();
                    });
                }
                foreach (var 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, tpl.Item3));
                            });
                        }
                    }
                    if (SettingsManager.getSettingBool("AutoScreenshotItemDrop"))
                    {
                        int screenshotValue = SettingsManager.getSettingInt("ScreenshotRareItemValue");
                        if (screenshotValue > 0)
                        {
                            foreach (var itemTpl in items)
                            {
                                if (itemTpl.Item1.GetMaxValue() >= screenshotValue)
                                {
                                    // 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, null);
                                    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);
                                    });
                                    break;
                                }
                            }
                        }
                    }
                }
            }
            return(readMemoryResults != null);
        }