[K-Relay] Modified LootHelper Plugin

Posts 1–6 of 6 · Page 1 of 1
[K-Relay] Modified LootHelper Plugin
Hey everyone. This is my modified LootHelper plugin for k-relay. The original LootHelper plugin had just a few minor things i wanted to change. So this is essentially the same as before, but now it has a few extra options.

If you dont know, the original LootHelper plugin has these features:
- Custom Quest for Bags (only blue/cyan/white bags)
- Notification over bags (1 at a time) of the contents inside (only blue/cyan/white bags)
- Auto loot items by name, set in the settings (only blue/cyan/white bags)

I modified the plugin so now it has these features:
- Set which bags trigger Custom Quests (default setting: Blue, Cyan, White)
- Set which bags have notifications over them of their content (default setting: Blue, Cyan, White, Red)
- Set which bags you autoloot from (default setting: Purple, Egg, Blue, Cyan, White, Red)
- Added auto loot by item tier (weapon/armor default: 11, ring default: 5, ability default: 6, egg default: 1)
- Almost 2x faster autolooting then before.
- No longer restricted to 1 notification over 1 bag at a time. All bags that are in the bag notification setting will show at the same time.

I think that is all the modifications i made. I just wanted the plugin to have more flexibility, the core functionality was already great.

 
SETTINGS
This is a list of the settings you will see in the settings gui, the description, and the default value
Setting Description Default Value
LootNotifications Show notifications over bags True
AutoLoot Loot items from bags automatically True
AutoLootList Comma delimited string of item names that you want to auto loot Health Potion, Magic Potion, Potion of Life, Potion of Mana, Potion of Dexterity, Potion of Vitality, Potion of Defense, Potion of Speed, Potion of Wisdom, Potion of Attack
LootQuests Allow the current quest to be set to a bag True
NotificationColor The text color of the notifications Aqua
LootBags Comma delimited string containing which bags to autoloot from. Accepted values: Normal,Pink,Purple,Egg,Blue,Cyan,White,Red Purple, Egg, Blue, Cyan, White, Red
NotifBags Comma delimited string containing which bags to show notifications over. Accepted values: Normal,Pink,Purple,Egg,Blue,Cyan,White,Red Blue, Cyan, White, Red
QuestBags Comma delimited string containing which bags can trigger the custom quests. Accepted values: Normal,Pink,Purple,Egg,Blue,Cyan,White,Red Blue, Cyan, White
AutoLootWeaponTier The minimum Tier of weapon to autoloot 11
AutoLootArmorTier The minimum Tier of armor to autoloot 11
AutoLootAbilityTier The minimum Tier of ability to autoloot 6
AutoLootRingTier The minimum Tier of ring to autoloot 5
AutoLootEggTier The minimum Tier of egg to autoloot. 0 = common, 3 = legendary 1



Image showing how all the bags can have notifications at the same time


The new settings gui with all the different settings you can change (these are my settings i play with)



Scans:
https://virusscan.jotti.org/en-US/fi...job/76u0dmgjum
https://www.virustotal.com/en/file/f...is/1480781880/

As always, Enjoy


(source of the main .cs file if anyone wants it)
 
SOURCE
Code:
using Lib_K_Relay;
using Lib_K_Relay.GameData;
using Lib_K_Relay.Interface;
using Lib_K_Relay.Networking;
using Lib_K_Relay.Networking.Packets;
using Lib_K_Relay.Networking.Packets.Client;
using Lib_K_Relay.Networking.Packets.DataObjects;
using Lib_K_Relay.Networking.Packets.Server;
using Lib_K_Relay.Utilities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LootHelper
{
    class LootState
    {
        public Dictionary<int, int[]> LootBagItems = new Dictionary<int, int[]>();
        public Dictionary<int, Location> LootBagLocations = new Dictionary<int, Location>();
        public Dictionary<int, string> LootBagTypes = new Dictionary<int, string>();
        public Dictionary<int, int> BagLastNotif = new Dictionary<int, int>();
        public int LastLoot = 0;
        public int CustomQuest = -1;
        public int OriginalQuest = -1;
    }
    public class LootHelper : IPlugin
    {
        private Dictionary<Client, LootState> _states = new Dictionary<Client, LootState>();

        public string GetAuthor()
        { return "KrazyShank / Kronks (Modified by Todddddd)"; }

        public string GetName()
        { return "Loot Helper"; }

        public string GetDescription()
        { return "Allows you to enable loot notifications, loot quests, and autoloot."; }

        public string[] GetCommands()
        { return new string[] { "/loothelper settings" }; }

        public void Initialize(Proxy proxy)
        {
            proxy.ClientConnected += (c) => _states.Add(c, new LootState());
            proxy.ClientDisconnected += (c) => _states.Remove(c);

            proxy.HookPacket(PacketType.MOVE, OnMove);
            proxy.HookPacket(PacketType.UPDATE, OnUpdate);
            proxy.HookPacket(PacketType.NEWTICK, OnNewTick);
            proxy.HookPacket(PacketType.QUESTOBJID, OnQuestObjId);
            proxy.HookCommand("loothelper", OnLootHelperCommand);
        }

        private void OnLootHelperCommand(Client client, string command, string[] args)
        {
            PluginUtils.ShowGenericSettingsGUI(LootHelperConfig.Default, "Loot Helper Settings");
        }

        private string BagTypeToString(short ObjectType)
        {
            switch (ObjectType)
            {
                case (short)Bags.Normal:
                    return "Normal";
                case (short)Bags.Pink:
                    return "Pink";
                case (short)Bags.Purple:
                case (short)Bags.Purple2:
                    return "Purple";
                case (short)Bags.Egg:
                    return "Egg";
                case (short)Bags.Blue:
                    return "Blue";
                case (short)Bags.Cyan:
                    return "Cyan";
                case (short)Bags.White:
                case (short)Bags.White2:
                case (short)Bags.White3:
                    return "White";
                case (short)Bags.Red:
                    return "Red";
                default:
                    return null;
            }
        }

        private bool CheckLootTier(int itemId)
        {
            byte tier = (byte)GameData.Items.ByID((ushort)itemId).Tier;
            byte st = GameData.Items.ByID((ushort)itemId).SlotType;

            switch (st)
            {
                case 1: //Swords
                case 2: //Daggers
                case 3: //Bows
                case 8: //Wands
                case 17: //Staffs
                case 24: //Katanas
                    if (tier >= LootHelperConfig.Default.AutoLootWeaponTier)
                        return true;
                    else
                        return false;
                case 6: //Leather Armor
                case 7: //Heavy Armor
                case 14: //Robes
                    if (tier >= LootHelperConfig.Default.AutoLootArmorTier)
                        return true;
                    else
                        return false;
                case 9: //Ring
                    if (tier >= LootHelperConfig.Default.AutoLootRingTier)
                        return true;
                    else
                        return false;
                case 4: //Tomes
                case 5: //Shield
                case 11: //Spells
                case 12: //Seals
                case 13: //Cloak
                case 15: //Quiver
                case 16: //Helms
                case 18: //Poisons
                case 19: //Skulls
                case 20: //Traps
                case 21: //Orbs
                case 22: //Prisms
                case 23: //Scepters
                case 25: //Shurikens
                    if (tier >= LootHelperConfig.Default.AutoLootAbilityTier)
                        return true;
                    else
                        return false;
                default:
                    return false;
            }
        }

        private void OnMove(Client client, Packet packet)
        {
            if (!_states.ContainsKey(client)) return;
            LootState state = _states[client];

            foreach (int bagId in state.LootBagItems.Keys)
            {
                if (state.LootBagTypes[bagId] == null) continue;
                float distance = state.LootBagLocations[bagId].DistanceTo(client.PlayerData.Pos);
                if (LootHelperConfig.Default.LootBags.Contains(state.LootBagTypes[bagId], StringComparison.OrdinalIgnoreCase))
                {
                    if (LootHelperConfig.Default.AutoLoot && Environment.TickCount - state.LastLoot > 550 && distance <= 1)
                    {
                        for (int bi = 0; bi < state.LootBagItems[bagId].Length; bi++)
                        {
                            if (state.LootBagItems[bagId][bi] == -1)
                                continue;

                            bool next = true;
                            if (LootHelperConfig.Default.AutoLootList.Contains(ReverseLookup(state.LootBagItems[bagId][bi])))
                                next = false;
                            else if (CheckLootTier(state.LootBagItems[bagId][bi]))
                                next = false;

                            if (next)
                                continue;

                            state.LastLoot = Environment.TickCount;
                            for (int i = 4; i < client.PlayerData.Slot.Length; i++)
                            {
                                if (client.PlayerData.Slot[i] == -1)
                                {
                                    InvSwapPacket invSwap = (InvSwapPacket)Packet.Create(PacketType.INVSWAP);
                                    invSwap.Time = client.Time + 10;
                                    invSwap.Position = client.PlayerData.Pos;

                                    invSwap.SlotObject1 = new SlotObject();
                                    invSwap.SlotObject1.ObjectId = bagId;
                                    invSwap.SlotObject1.SlotId = (byte)bi;
                                    invSwap.SlotObject1.ObjectType = state.LootBagItems[bagId][bi];

                                    invSwap.SlotObject2 = new SlotObject();
                                    invSwap.SlotObject2.ObjectId = client.ObjectId;
                                    invSwap.SlotObject2.SlotId = (byte)(i);
                                    invSwap.SlotObject2.ObjectType = -1;

                                    client.SendToServer(invSwap);
                                    break;
                                }
                            }
                        }
                    }
                }
                if (LootHelperConfig.Default.NotifBags.Contains(state.LootBagTypes[bagId], StringComparison.OrdinalIgnoreCase))
                {
                    if (!state.BagLastNotif.ContainsKey(bagId))
                        state.BagLastNotif.Add(bagId, 0);

                    if (LootHelperConfig.Default.LootNotifications && Environment.TickCount - state.BagLastNotif[bagId] > 2000 && distance < 15)
                    {
                        state.BagLastNotif[bagId] = Environment.TickCount;
                        string message = "";

                        foreach (int item in state.LootBagItems[bagId])
                            if (item != -1) message += ReverseLookup(item) + "\\n";

                        if (message.Length > 3)
                            client.SendToClient(PluginUtils.CreateNotification(bagId, LootHelperConfig.Default.NotificationColor.ToArgb(), message));
                    }
                }
            }
        }

        private void OnUpdate(Client client, Packet packet)
        {
            LootState state = _states[client];
            UpdatePacket update = (UpdatePacket)packet;
            // New Objects
            foreach (Entity entity in update.NewObjs)
            {
                string type = BagTypeToString(entity.ObjectType);
                if (type == null) continue;
                if (LootHelperConfig.Default.LootBags.Contains(type, StringComparison.OrdinalIgnoreCase) || LootHelperConfig.Default.NotifBags.Contains(type, StringComparison.OrdinalIgnoreCase))
                {
                    if (LootHelperConfig.Default.QuestBags.Contains(type, StringComparison.OrdinalIgnoreCase))
                    {
                        if (LootHelperConfig.Default.LootQuests)
                        {
                            state.CustomQuest = entity.Status.ObjectId;
                            QuestObjIdPacket questObjId = (QuestObjIdPacket)Packet.Create(PacketType.QUESTOBJID);
                            questObjId.ObjectId = entity.Status.ObjectId;
                            client.SendToClient(questObjId);
                        }
                    }

                    int bagId = entity.Status.ObjectId;
                    // Set the bag type
                    if (!state.LootBagTypes.ContainsKey(bagId))
                        state.LootBagTypes.Add(bagId, type);
                    else
                        state.LootBagTypes[bagId] = type;
                    // Set the bag contents to empty
                    if (!state.LootBagItems.ContainsKey(bagId))
                        state.LootBagItems.Add(bagId, new int[] { -1, -1, -1, -1, -1, -1, -1, -1 });
                    else
                        state.LootBagItems[bagId] = new int[] { -1, -1, -1, -1, -1, -1, -1, -1 };
                    // Set the bag location
                    if (!state.LootBagLocations.ContainsKey(bagId))
                        state.LootBagLocations.Add(bagId, entity.Status.Position);
                    else
                        state.LootBagLocations[bagId] = entity.Status.Position;
                    // Fill in the bag contents
                    foreach (StatData statData in entity.Status.Data)
                    {
                        if (statData.Id >= 8 && statData.Id <= 15)
                            state.LootBagItems[bagId][statData.Id - 8] = statData.IntValue;
                    }
                }
            }

            // Removed Objects
            foreach (int drop in update.Drops)
            {
                if (drop == state.CustomQuest && state.OriginalQuest != -1)
                {
                    QuestObjIdPacket questObjId = (QuestObjIdPacket)Packet.Create(PacketType.QUESTOBJID);
                    questObjId.ObjectId = state.OriginalQuest;
                    client.SendToClient(questObjId);

                    state.OriginalQuest = -1;
                    state.CustomQuest = -1;
                }

                if (state.LootBagItems.ContainsKey(drop))
                {
                    state.LootBagItems.Remove(drop);
                    state.LootBagLocations.Remove(drop);
                }
            }
        }

        private void OnNewTick(Client client, Packet packet)
        {
            LootState state = _states[client];
            NewTickPacket newTick = (NewTickPacket)packet;

            // Updated Objects
            foreach (Status status in newTick.Statuses)
            {
                if (state.LootBagItems.ContainsKey(status.ObjectId))
                {
                    foreach (StatData statData in status.Data)
                    {
                        if (statData.Id >= 8 && statData.Id <= 15)
                            state.LootBagItems[status.ObjectId][statData.Id - 8] = statData.IntValue;
                    }
                }
            }
        }

        private void OnQuestObjId(Client client, Packet packet)
        {
            _states[client].OriginalQuest = (packet as QuestObjIdPacket).ObjectId;
        }

        private string ReverseLookup(int itemId)
        {
            return GameData.Items.ByID((ushort)itemId).Name;
        }
    }

    public static class StringExtensions
    {
        public static bool Contains(this string source, string toCheck, StringComparison comp)
        {
            return source.IndexOf(toCheck, comp) >= 0;
        }
    }
}
LootHelper_mpgh.net.zip7 KB · 269 downloads Clean
Thanks man, you're doing some really quality work for ROTMG. I had an idea for a plugin, could you make an auto potion drinker? For pots that are on the ground, assuming your potion reserve is full, and your health is below 50%. I took a look at the autonexus plugin just to see what it would take, but I got a bit confused because of how it deals with damage rather than directly with health status. Also /firstpost
Looks good.

Approved, post back results
I'm trying to compile the source code using Visual Studio 2015 at the moment, but I've run into dead end. I want to customize the plugin a little bit but before I do that I just want to recreate the .dll file. I've created a new class project and pasted the code in and added Lib K Relay as a reference but I don't know what to do about this 'LootHelperConfig' error I'm getting. I'm guessing it has something to do with LootHelper.dll.config file, but then again I could be totally wrong. I have never used Microsoft Visual Studio before or really coded before so forgive me if I sound like a total newbie. So I just need help on knowing what to do about this 'LootHelperCongif' error.

I'm getting 15 of the exact error message, which is: "The name 'LootHelperConfig' does not exist in the current context"

Please let me know if there's anything else needed about the errors. Any help would be appreciated, thanks.
Quote Originally Posted by mrperson909 View Post
I'm trying to compile the source code using Visual Studio 2015 at the moment, but I've run into dead end. I want to customize the plugin a little bit but before I do that I just want to recreate the .dll file. I've created a new class project and pasted the code in and added Lib K Relay as a reference but I don't know what to do about this 'LootHelperConfig' error I'm getting. I'm guessing it has something to do with LootHelper.dll.config file, but then again I could be totally wrong. I have never used Microsoft Visual Studio before or really coded before so forgive me if I sound like a total newbie. So I just need help on knowing what to do about this 'LootHelperCongif' error.

I'm getting 15 of the exact error message, which is: "The name 'LootHelperConfig' does not exist in the current context"

Please let me know if there's anything else needed about the errors. Any help would be appreciated, thanks.
you need to add a config file called loothelperconfig, and add all the different config options to it.
Quote Originally Posted by toddddd View Post
you need to add a config file called loothelperconfig, and add all the different config options to it.
Thank you so much
Posts 1–6 of 6 · Page 1 of 1

Post a Reply

Similar Threads

Tags for this Thread

None

Need help?